CVBS: Add gm7122 driver.
authorShenZhengyi <szy@rock-chips.com>
Sat, 23 May 2015 07:49:05 +0000 (15:49 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Sat, 23 May 2015 08:17:32 +0000 (16:17 +0800)
      If you use it, should add board information to dts file, such as i2c address, sleep pin.
      like that:
gm7122_tve@44 {
compatible = "gm7122_tve";
reg = <0x44>;
rockchip,source = <0>; //0: LCDC0; 1: LCDC1
rockchip,prop = <PRMRY>;//<EXTEND>
gpio-reset = <&gpio0 GPIO_A1 GPIO_ACTIVE_HIGH>;
gpio-sleep = <&gpio0 GPIO_C6 GPIO_ACTIVE_HIGH>;
status = "okay";
};

Signed-off-by: ShenZhengyi <szy@rock-chips.com>
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/video/rockchip/tve/Kconfig
drivers/video/rockchip/tve/Makefile
drivers/video/rockchip/tve/gm7122/Kconfig [new file with mode: 0644]
drivers/video/rockchip/tve/gm7122/Makefile [new file with mode: 0644]
drivers/video/rockchip/tve/gm7122/gm7122_tve.c [new file with mode: 0644]
drivers/video/rockchip/tve/gm7122/gm7122_tve.h [new file with mode: 0644]

index 83c2c0e58a38bddc90b0f51d456d6e7ccda86bff..802f8ed1f8a0407eca0da33203546401e6a2f990 100644 (file)
@@ -11,4 +11,4 @@ menuconfig RK_TVENCODER
 source "drivers/video/rockchip/tve/rk1000/Kconfig"
 source "drivers/video/rockchip/tve/rk3036/Kconfig"
 source "drivers/video/rockchip/tve/rk610/Kconfig"
-
+source "drivers/video/rockchip/tve/gm7122/Kconfig"
index ae38690889fd2de24bd46de7c5769124fc239160..d99fb3587dd2c450287c1084ea767047b1cdb906 100644 (file)
@@ -1,6 +1,8 @@
 #
 # Makefile for tv encoder.
 #
+
 obj-$(CONFIG_RK610_TVOUT)              += rk610/
 obj-$(CONFIG_RK3036_TV_ENCODER)                += rk3036/
 obj-$(CONFIG_RK1000_TVOUT)             += rk1000/
+obj-$(CONFIG_GM7122_TV_ENCODER)                += gm7122/
diff --git a/drivers/video/rockchip/tve/gm7122/Kconfig b/drivers/video/rockchip/tve/gm7122/Kconfig
new file mode 100644 (file)
index 0000000..c047687
--- /dev/null
@@ -0,0 +1,6 @@
+config GM7122_TV_ENCODER
+       bool "gm7122 tv encoder support"
+       depends on RK_TVENCODER
+       default n
+       help
+               Support GM7122 output CVBS.
diff --git a/drivers/video/rockchip/tve/gm7122/Makefile b/drivers/video/rockchip/tve/gm7122/Makefile
new file mode 100644 (file)
index 0000000..580a99b
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# Makefile for the gm7122 tv encoder control.
+#
+obj-$(CONFIG_GM7122_TV_ENCODER)        += gm7122_tve.o
diff --git a/drivers/video/rockchip/tve/gm7122/gm7122_tve.c b/drivers/video/rockchip/tve/gm7122/gm7122_tve.c
new file mode 100644 (file)
index 0000000..0781532
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * gm7122_tve.c
+ *
+ * Driver for rockchip gm7122 tv encoder control
+ * Copyright (C) 2015
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/rk_fb.h>
+#include <linux/display-sys.h>
+#include <linux/rockchip/grf.h>
+#include <linux/rockchip/iomap.h>
+#include "gm7122_tve.h"
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/mfd/core.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/syscon.h>
+
+static const struct fb_videomode gm7122_cvbs_mode[] = {
+/*name         refresh         xres    yres    pixclock        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI                            flag */
+{"NTSC",       60,             720,    480,    27000000,       57,     19,     15,     4,      62,     3,      0,              FB_VMODE_INTERLACED,            0},
+{"PAL",                50,             720,    576,    27000000,       62,     14,     17,     2,      68,     5,      0,              FB_VMODE_INTERLACED,            0},
+};
+
+static struct gm7122_tve *gm7122_tve;
+
+static int cvbsformat;
+
+#define tve_writel(offset, v)  gm7122_i2c_send(offset, v)
+/*#define tve_readl(offset, *v)        gm7122_i2c_recv(offset, v)*/
+
+#ifdef DEBUG
+#define TVEDBG(format, ...) \
+               dev_info(gm7122_tve->dev,\
+                "GM7122 TVE: " format "\n", ## __VA_ARGS__)
+#else
+#define TVEDBG(format, ...)
+#endif
+
+int gm7122_i2c_send(const u8 reg, const u8 value)
+{
+       char buf[2];
+       int ret;
+
+       buf[0] = reg;
+       buf[1] = value;
+       ret = i2c_master_send(gm7122_tve->client, buf, 2);
+       if (ret != 2) {
+               TVEDBG("gm7122 control i2c write err,ret =%d\n", ret);
+               return -1;
+       }
+       return 0;
+}
+
+int gm7122_i2c_recv(const u8 reg, char *value)
+{
+       int ret;
+
+       ret = i2c_master_send(gm7122_tve->client, &reg, 1);
+       i2c_master_recv(gm7122_tve->client, value, 1);
+       pr_info("%s reg = 0x%x , value = 0x%c\n", __func__, reg, *value);
+       return (ret == 2) ? 0 : -1;
+}
+
+
+static void tve_set_mode(int mode)
+{
+       TVEDBG("%s mode %d\n", __func__, mode);
+       if (cvbsformat >= 0)
+               return;
+
+       if (mode == TVOUT_CVBS_NTSC) {
+               tve_writel(BURST_START, V_D0_BS0(1) | V_D0_BS5(1));
+               tve_writel(BURST_END, V_D0_BE0(1) | V_D0_BE2(1) |
+                       V_D0_BE3(1) | V_D0_BE4(1));
+               tve_writel(INPUT_PORT_CTL, V_SYMP(1) | V_UV2C(1) | V_Y2C(1));
+               tve_writel(COLOR_DIFF_CTL, 0x00);
+               tve_writel(U_GAIN_CTL, V_GAINU0(1) | V_GAINU2(1) |
+                       V_GAINU3(3) | V_GAINU5(1) | V_GAINU6(1));
+               tve_writel(V_GAIN_CTL, V_GAINV0(1) | V_GAINV1(1) |
+                       V_GAINV2(1) | V_GAINV3(1) | V_GAINV4(1) |
+                       V_GAINV7(1));
+               tve_writel(UMSB_BLACK_GAIN,     V_BLACK1(1) | V_BLACK2(1) |
+                       V_BLACK3(1));
+               tve_writel(VMSB_BLNNL_GAIN, V_BLNNL2(1) | V_BLNNL3(1) |
+                       V_BLNNL4(1));
+               tve_writel(STANDARD_CTL, V_PAL(0) | V_BIT0(1));
+               tve_writel(RTCEN_BURST_CTL, V_BSTA0(1) | V_BSTA1(1)|
+                       V_BSTA3(1) | V_BSTA4(1) | V_BSTA5(1));
+               tve_writel(SUBCARRIER0, V_FSC00(1) | V_FSC01(1)|
+                       V_FSC02(1) | V_FSC03(1) | V_FSC04(1));
+               tve_writel(SUBCARRIER1, V_FSC10(1) | V_FSC11(1)|
+                       V_FSC12(1) | V_FSC13(1) | V_FSC14(1));
+               tve_writel(SUBCARRIER2, V_FSC20(1) | V_FSC21(1) |
+                       V_FSC22(1) | V_FSC23(1));
+               tve_writel(SUBCARRIER3, V_FSC29(1) | V_FSC24(1));
+               tve_writel(RCV_PORT_CTL, 0x00);
+               tve_writel(TRIG0_CTL, V_HTRIG0(1) | V_HTRIG2(1) | V_HTRIG4(1) |
+                                      V_HTRIG5(1) | V_HTRIG6(1) | V_HTRIG7(1));
+               tve_writel(TRIG1_CTL, V_VTRIG0(1) | V_VTRIG4(1) | V_HTRIG8(1) |
+                                     V_HTRIG10(1));
+       } else if (mode == TVOUT_CVBS_PAL) {
+               tve_writel(BURST_START, V_D0_BS0(1) | V_D0_BS5(1));
+               tve_writel(BURST_END, V_D0_BE0(1) | V_D0_BE2(1) |
+                       V_D0_BE3(1) | V_D0_BE4(1));
+               tve_writel(INPUT_PORT_CTL, V_SYMP(1) | V_UV2C(1) | V_Y2C(1));
+               /*tve_writel(INPUT_PORT_CTL, 0x93);*//*color bar for debug*/
+               tve_writel(COLOR_DIFF_CTL, V_CHPS0(1));
+               tve_writel(U_GAIN_CTL, V_GAINU1(1) | V_GAINU3(1) |
+                       V_GAINU5(1) | V_GAINU6(1));
+               tve_writel(V_GAIN_CTL, V_GAINV0(1) | V_GAINV1(1) |
+                       V_GAINV2(1) | V_GAINV3(1) | V_GAINV4(1) |
+                       V_GAINV7(1));
+               tve_writel(UMSB_BLACK_GAIN,     V_BLACK1(1) | V_BLACK4(1));
+               tve_writel(VMSB_BLNNL_GAIN, V_BLNNL0(1) | V_BLNNL1(1) |
+                       V_BLNNL2(1) | V_BLNNL3(1) | V_BLNNL4(1));
+               tve_writel(STANDARD_CTL, V_PAL(1) | V_SCBW(1));
+               tve_writel(RTCEN_BURST_CTL, V_BSTA0(1) | V_BSTA1(1)|
+                       V_BSTA3(1) | V_BSTA4(1) | V_BSTA5(1));
+               tve_writel(SUBCARRIER0, V_FSC00(1) | V_FSC01(1)|
+                       V_FSC03(1) | V_FSC06(1) | V_FSC07(1));
+               tve_writel(SUBCARRIER1, V_FSC15(1) | V_FSC11(1)|
+                       V_FSC09(1));
+               tve_writel(SUBCARRIER2, V_FSC19(1) | V_FSC16(1));
+               tve_writel(SUBCARRIER3, V_FSC29(1) | V_FSC27(1) | V_FSC25(1));
+               tve_writel(RCV_PORT_CTL, 0x00);
+               tve_writel(TRIG0_CTL, V_HTRIG0(1) | V_HTRIG2(1) | V_HTRIG4(1) |
+                                      V_HTRIG5(1) | V_HTRIG6(1) | V_HTRIG7(1));
+               tve_writel(TRIG1_CTL, V_VTRIG0(1) | V_VTRIG4(1) | V_HTRIG8(1) |
+                                     V_HTRIG10(1));
+       }
+}
+
+static int tve_switch_fb(const struct fb_videomode *modedb, int enable)
+{
+       struct rk_screen *screen = &gm7122_tve->screen;
+
+       if (modedb == NULL)
+               return -1;
+
+       memset(screen, 0, sizeof(struct rk_screen));
+       /* screen type & face */
+       /*screen->type = SCREEN_TVOUT;*/
+       screen->type = SCREEN_RGB;
+       screen->face = OUT_CCIR656;
+       screen->color_mode = COLOR_YCBCR;
+       screen->mode = *modedb;
+       /*screen->mode.vmode = 0;*/
+
+       /* Pin polarity */
+       if (FB_SYNC_HOR_HIGH_ACT & modedb->sync)
+               screen->pin_hsync = 1;
+       else
+               screen->pin_hsync = 0;
+       if (FB_SYNC_VERT_HIGH_ACT & modedb->sync)
+               screen->pin_vsync = 1;
+       else
+               screen->pin_vsync = 0;
+       screen->pin_den = 0;
+       screen->pin_dclk = 1;
+       /*screen->pixelrepeat = 1;*/
+
+       /* Swap rule */
+       screen->swap_rb = 0;
+       screen->swap_rg = 0;
+       screen->swap_gb = 0;
+       screen->swap_delta = 0;
+       screen->swap_dumy = 0;
+       screen->overscan.left = 100;
+       screen->overscan.top = 100;
+       screen->overscan.right = 100;
+       screen->overscan.bottom = 100;
+       /* Operation function*/
+       screen->init = NULL;
+       screen->standby = NULL;
+       rk_fb_switch_screen(screen, enable, gm7122_tve->lcdcid);
+       if (enable) {
+               if (screen->mode.yres == 480)
+                       tve_set_mode(TVOUT_CVBS_NTSC);
+               else
+                       tve_set_mode(TVOUT_CVBS_PAL);
+       }
+       return 0;
+}
+
+static int cvbs_set_enable(struct rk_display_device *device, int enable)
+{
+       if (gm7122_tve->enable != enable) {
+               gm7122_tve->enable = enable;
+               if (gm7122_tve->suspend)
+                       return 0;
+
+               if (enable == 0) {
+                       /*tve_enable(false);*/
+                       cvbsformat = -1;
+                       tve_switch_fb(gm7122_tve->mode, 0);
+               } else if (enable == 1) {
+                       tve_switch_fb(gm7122_tve->mode, 1);
+                       /*tve_enable(true);*/
+               }
+       }
+       return 0;
+}
+
+static int cvbs_get_enable(struct rk_display_device *device)
+{
+       TVEDBG("%s enable %d\n", __func__, gm7122_tve->enable);
+       return gm7122_tve->enable;
+}
+
+static int cvbs_get_status(struct rk_display_device *device)
+{
+       return 1;
+}
+
+static int
+cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+{
+       *modelist = &(gm7122_tve->modelist);
+       return 0;
+}
+
+static int
+cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(gm7122_cvbs_mode); i++) {
+               if (fb_mode_is_equal(&gm7122_cvbs_mode[i], mode)) {
+                       if (gm7122_tve->mode != &gm7122_cvbs_mode[i]) {
+                               gm7122_tve->mode =
+                               (struct fb_videomode *)&gm7122_cvbs_mode[i];
+                               if (gm7122_tve->enable &&
+                                   !gm7122_tve->suspend) {
+                                       /*tve_enable(false);*/
+                                       if (!fb_mode_is_equal(gm7122_tve->mode,
+                                                             mode)) {
+                                               gpio_set_value(
+                                               gm7122_tve->io_sleep.gpio,
+                                               gm7122_tve->io_sleep.active);
+                                               msleep(20);
+                                               gpio_set_value(
+                                               gm7122_tve->io_sleep.gpio,
+                                               !(gm7122_tve->io_sleep.active));
+                                       }
+                                       tve_switch_fb(gm7122_tve->mode, 1);
+                               }
+                                       /*tve_enable(true);*/
+                       }
+                       return 0;
+               }
+       }
+       TVEDBG("%s\n", __func__);
+       return -1;
+}
+
+static int
+cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+{
+       *mode = *(gm7122_tve->mode);
+       return 0;
+}
+
+static int
+tve_fb_event_notify(struct notifier_block *self,
+                   unsigned long action, void *data)
+{
+       struct fb_event *event = data;
+       int blank_mode = *((int *)event->data);
+
+       if (action == FB_EARLY_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_UNBLANK:
+                       break;
+               default:
+                       TVEDBG("suspend tve\n");
+                       if (!gm7122_tve->suspend) {
+                               gm7122_tve->suspend = 1;
+                               if (gm7122_tve->enable) {
+                                       tve_switch_fb(gm7122_tve->mode, 0);
+                                       /*tve_enable(false);*/
+                               }
+                       }
+                       break;
+               }
+       } else if (action == FB_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_UNBLANK:
+                       TVEDBG("resume tve\n");
+                       if (gm7122_tve->suspend) {
+                               gm7122_tve->suspend = 0;
+                               if (gm7122_tve->enable) {
+                                       tve_switch_fb(gm7122_tve->mode, 1);
+                                       /*tve_enable(true);*/
+                               }
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block tve_fb_notifier = {
+       .notifier_call = tve_fb_event_notify,
+};
+
+static struct rk_display_ops cvbs_display_ops = {
+       .setenable = cvbs_set_enable,
+       .getenable = cvbs_get_enable,
+       .getstatus = cvbs_get_status,
+       .getmodelist = cvbs_get_modelist,
+       .setmode = cvbs_set_mode,
+       .getmode = cvbs_get_mode,
+};
+
+static int
+display_cvbs_probe(struct rk_display_device *device, void *devdata)
+{
+       device->owner = THIS_MODULE;
+       strcpy(device->type, "TV");
+       device->name = "cvbs";
+       device->priority = DISPLAY_PRIORITY_TV;
+       device->property = 0;/*just for test*/
+       device->priv_data = devdata;
+       device->ops = &cvbs_display_ops;
+       return 1;
+}
+
+static struct rk_display_driver display_cvbs = {
+       .probe = display_cvbs_probe,
+};
+
+#if defined(CONFIG_OF)
+static const struct i2c_device_id gm7122_tve_dt_ids[] = {
+       { "gm7122_tve", 0 },
+       {}
+};
+#endif
+
+static int __init bootloader_tve_setup(char *str)
+{
+       if (str) {
+               pr_info("cvbs init tve.format is %s\n", str);
+               if (kstrtoint(str, 0, &cvbsformat) < 0)
+                       cvbsformat = -1;
+       }
+       return 0;
+}
+
+early_param("tve.format", bootloader_tve_setup);
+
+
+static int gm7122_tve_probe(struct i2c_client *client,
+                           const struct i2c_device_id *id)
+{
+       int i;
+       struct device_node *gm7122_np;
+       enum of_gpio_flags flags;
+       int ret;
+
+       gm7122_tve = kmalloc(sizeof(*gm7122_tve), GFP_KERNEL);
+       if (!gm7122_tve) {
+               dev_err(&client->dev, "gm7122 tv encoder device kmalloc fail!\n");
+               return -ENOMEM;
+       }
+       memset(gm7122_tve, 0, sizeof(*gm7122_tve));
+       gm7122_tve->client = client;
+       gm7122_tve->dev = &client->dev;
+       gm7122_np = gm7122_tve->dev->of_node;
+       of_property_read_u32(gm7122_np, "rockchip,source", &(ret));
+       gm7122_tve->lcdcid = ret;
+       of_property_read_u32(gm7122_np, "rockchip,prop", &(ret));
+       gm7122_tve->property = ret;
+       /********Get reset pin***********/
+       gm7122_tve->io_reset.gpio = of_get_named_gpio_flags(gm7122_np, "gpio-reset",
+                                                           0, &flags);
+       if (!gpio_is_valid(gm7122_tve->io_reset.gpio)) {
+               TVEDBG("invalid gm7122_tve->io_reset.gpio: %d\n",
+                      gm7122_tve->io_reset.gpio);
+               goto failout;
+               }
+       ret = gpio_request(gm7122_tve->io_reset.gpio, "gm7122-reset-io");
+       if (ret != 0) {
+               TVEDBG("gpio_request gm7122_tve->io_reset.gpio invalid: %d\n",
+                      gm7122_tve->io_reset.gpio);
+               goto failout;
+               }
+       gm7122_tve->io_reset.active = (flags & OF_GPIO_ACTIVE_LOW);
+       gpio_direction_output(gm7122_tve->io_reset.gpio,
+                             !(gm7122_tve->io_reset.active));
+       gpio_set_value(gm7122_tve->io_reset.gpio,
+                      !(gm7122_tve->io_reset.active));
+       /********Reset pin end***********/
+       /********Get sleep pin***********/
+       gm7122_tve->io_sleep.gpio = of_get_named_gpio_flags(gm7122_np, "gpio-sleep", 0, &flags);
+       if (!gpio_is_valid(gm7122_tve->io_sleep.gpio)) {
+               TVEDBG("invalid gm7122_tve->io_reset.gpio: %d\n",
+                      gm7122_tve->io_sleep.gpio);
+               }
+       ret = gpio_request(gm7122_tve->io_sleep.gpio, "gm7122-sleep-io");
+       if (ret != 0) {
+               TVEDBG("gpio_request gm7122_tve->io_reset.gpio invalid: %d\n",
+                      gm7122_tve->io_sleep.gpio);
+               goto failout;
+               }
+       gm7122_tve->io_sleep.active = !(flags & OF_GPIO_ACTIVE_LOW);
+       gpio_direction_output(gm7122_tve->io_sleep.gpio,
+                             !(gm7122_tve->io_sleep.active));
+       gpio_set_value(gm7122_tve->io_sleep.gpio,
+                      !(gm7122_tve->io_sleep.active));
+       /********Sleep pin end***********/
+       INIT_LIST_HEAD(&(gm7122_tve->modelist));
+       for (i = 0; i < ARRAY_SIZE(gm7122_cvbs_mode); i++)
+               fb_add_videomode(&gm7122_cvbs_mode[i], &(gm7122_tve->modelist));
+       if (cvbsformat >= 0) {
+               gm7122_tve->mode =
+                       (struct fb_videomode *)&gm7122_cvbs_mode[cvbsformat];
+               gm7122_tve->enable = 1;
+               tve_switch_fb(gm7122_tve->mode, 1);
+       } else {
+               gm7122_tve->mode = (struct fb_videomode *)&gm7122_cvbs_mode[1];
+       }
+       gm7122_tve->ddev =
+               rk_display_device_register(&display_cvbs,
+                                          gm7122_tve->dev, NULL);
+       rk_display_device_enable(gm7122_tve->ddev);
+       fb_register_client(&tve_fb_notifier);
+       cvbsformat = -1;
+       pr_info("%s tv encoder probe ok!\n", __func__);
+       return 0;
+
+failout:
+       kfree(gm7122_tve);
+       return -ENODEV;
+}
+
+/*static void gm7122_tve_shutdown(struct platform_device *pdev)
+{
+}*/
+static int gm7122_tve_remove(struct i2c_client *client)
+{
+       return 0;
+}
+
+MODULE_DEVICE_TABLE(i2c, gm7122_tve_dt_ids);
+
+static struct i2c_driver gm7122_tve_driver = {
+       .probe = gm7122_tve_probe,
+       .remove = gm7122_tve_remove,
+       .driver = {
+               .name = "gm7122_tve",
+               .owner = THIS_MODULE,
+       },
+       /*.shutdown = gm7122_tve_shutdown,*/
+       .id_table = gm7122_tve_dt_ids,
+};
+
+static int __init gm7122_tve_init(void)
+{
+       return  i2c_add_driver(&gm7122_tve_driver);
+}
+
+static void __exit gm7122_tve_exit(void)
+{
+       i2c_del_driver(&gm7122_tve_driver);
+}
+
+module_init(gm7122_tve_init);
+module_exit(gm7122_tve_exit);
+
+
+MODULE_DESCRIPTION("ROCKCHIP GM7122 TV Encoder ");
+MODULE_AUTHOR("Rock-chips, <www.rock-chips.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/rockchip/tve/gm7122/gm7122_tve.h b/drivers/video/rockchip/tve/gm7122/gm7122_tve.h
new file mode 100644 (file)
index 0000000..e03ca9e
--- /dev/null
@@ -0,0 +1,355 @@
+#ifndef __GM7122_TVE_H__
+#define __GM7122_TVE_H__
+
+#include<linux/regmap.h>
+#include<linux/io.h>
+
+#define BURST_START                    (0x28)
+       #define M_D5_BS0                (1 << 5)
+       #define M_D4_BS0                (1 << 4)
+       #define M_D3_BS0                (1 << 3)
+       #define M_D2_BS0                (1 << 2)
+       #define M_D1_BS0                (1 << 1)
+       #define M_D0_BS0                (1 << 0)
+
+       #define V_D0_BS5(x)             ((x & 1) << 5)
+       #define V_D0_BS4(x)             ((x & 1) << 4)
+       #define V_D0_BS3(x)             ((x & 1) << 3)
+       #define V_D0_BS2(x)             ((x & 1) << 2)
+       #define V_D0_BS1(x)             ((x & 1) << 1)
+       #define V_D0_BS0(x)             ((x & 1) << 0)
+
+#define BURST_END                      (0x29)
+       #define M_D5_BE0                (1 << 5)
+       #define M_D4_BE0                (1 << 4)
+       #define M_D3_BE0                (1 << 3)
+       #define M_D2_BE0                (1 << 2)
+       #define M_D1_BE0                (1 << 1)
+       #define M_D0_BE0                (1 << 0)
+
+       #define V_D0_BE5(x)             ((x & 1) << 5)
+       #define V_D0_BE4(x)             ((x & 1) << 4)
+       #define V_D0_BE3(x)             ((x & 1) << 3)
+       #define V_D0_BE2(x)             ((x & 1) << 2)
+       #define V_D0_BE1(x)             ((x & 1) << 1)
+       #define V_D0_BE0(x)             ((x & 1) << 0)
+
+#define DA_MODE_CTL                    (0x2F)
+       #define M_DA7                   (1 << 7)
+       #define M_DA3                   (1 << 3)
+       #define M_DA2                   (1 << 2)
+
+       #define V_DA7(x)                ((x & 1) << 7)
+       #define V_DA3(x)                ((x & 1) << 3)
+       #define V_DA2(x)                ((x & 1) << 2)
+
+#define INPUT_PORT_CTL                 (0x3A)
+       #define M_CBENB                 (1 << 7)
+       #define M_SYMP                  (1 << 4)
+       #define M_Y2C                   (1 << 1)
+       #define M_UV2C                  (1 << 0)
+
+       #define V_CBENB(x)              ((x & 1) << 7)
+       #define V_SYMP(x)               ((x & 1) << 4)
+       #define V_Y2C(x)                ((x & 1) << 1)
+       #define V_UV2C(x)               ((x & 1) << 0)
+
+#define COLOR_DIFF_CTL                 (0x5A)
+       #define M_CHPS7                 (1 << 7)
+       #define M_CHPS6                 (1 << 6)
+       #define M_CHPS5                 (1 << 5)
+       #define M_CHPS4                 (1 << 4)
+       #define M_CHPS3                 (1 << 3)
+       #define M_CHPS2                 (1 << 2)
+       #define M_CHPS1                 (1 << 1)
+       #define M_CHPS0                 (1 << 0)
+
+       #define V_CHPS7(x)              ((x & 1) << 7)
+       #define V_CHPS6(x)              ((x & 1) << 6)
+       #define V_CHPS5(x)              ((x & 1) << 5)
+       #define V_CHPS4(x)              ((x & 1) << 4)
+       #define V_CHPS3(x)              ((x & 1) << 3)
+       #define V_CHPS2(x)              ((x & 1) << 2)
+       #define V_CHPS1(x)              ((x & 1) << 1)
+       #define V_CHPS0(x)              ((x & 1) << 0)
+
+#define U_GAIN_CTL                     (0x5B)
+       #define M_GAINU7                (1 << 7)
+       #define M_GAINU6                (1 << 6)
+       #define M_GAINU5                (1 << 5)
+       #define M_GAINU4                (1 << 4)
+       #define M_GAINU3                (1 << 3)
+       #define M_GAINU2                (1 << 2)
+       #define M_GAINU1                (1 << 1)
+       #define M_GAINU0                (1 << 0)
+
+       #define V_GAINU7(x)             ((x & 1) << 7)
+       #define V_GAINU6(x)             ((x & 1) << 6)
+       #define V_GAINU5(x)             ((x & 1) << 5)
+       #define V_GAINU4(x)             ((x & 1) << 4)
+       #define V_GAINU3(x)             ((x & 1) << 3)
+       #define V_GAINU2(x)             ((x & 1) << 2)
+       #define V_GAINU1(x)             ((x & 1) << 1)
+       #define V_GAINU0(x)             ((x & 1) << 0)
+
+#define V_GAIN_CTL                     (0x5C)
+       #define M_GAINV7                (1 << 7)
+       #define M_GAINV6                (1 << 6)
+       #define M_GAINV5                (1 << 5)
+       #define M_GAINV4                (1 << 4)
+       #define M_GAINV3                (1 << 3)
+       #define M_GAINV2                (1 << 2)
+       #define M_GAINV1                (1 << 1)
+       #define M_GAINV0                (1 << 0)
+
+       #define V_GAINV7(x)             ((x & 1) << 7)
+       #define V_GAINV6(x)             ((x & 1) << 6)
+       #define V_GAINV5(x)             ((x & 1) << 5)
+       #define V_GAINV4(x)             ((x & 1) << 4)
+       #define V_GAINV3(x)             ((x & 1) << 3)
+       #define V_GAINV2(x)             ((x & 1) << 2)
+       #define V_GAINV1(x)             ((x & 1) << 1)
+       #define V_GAINV0(x)             ((x & 1) << 0)
+
+#define UMSB_BLACK_GAIN                        (0x5D)
+       #define M_GAINU8                (1 << 7)
+       #define M_BLACK5                (1 << 5)
+       #define M_BLACK4                (1 << 4)
+       #define M_BLACK3                (1 << 3)
+       #define M_BLACK2                (1 << 2)
+       #define M_BLACK1                (1 << 1)
+       #define M_BLACK0                (1 << 0)
+
+       #define V_GAINU8(x)             ((x & 1) << 7)
+       #define V_BLACK5(x)             ((x & 1) << 5)
+       #define V_BLACK4(x)             ((x & 1) << 4)
+       #define V_BLACK3(x)             ((x & 1) << 3)
+       #define V_BLACK2(x)             ((x & 1) << 2)
+       #define V_BLACK1(x)             ((x & 1) << 1)
+       #define V_BLACK0(x)             ((x & 1) << 0)
+
+#define VMSB_BLNNL_GAIN                        (0x5E)
+       #define M_GAINV8                (1 << 7)
+       #define M_BLNNL5                (1 << 5)
+       #define M_BLNNL4                (1 << 4)
+       #define M_BLNNL3                (1 << 3)
+       #define M_BLNNL2                (1 << 2)
+       #define M_BLNNL1                (1 << 1)
+       #define M_BLNNL0                (1 << 0)
+
+       #define V_GAINV8(x)             ((x & 1) << 7)
+       #define V_BLNNL5(x)             ((x & 1) << 5)
+       #define V_BLNNL4(x)             ((x & 1) << 4)
+       #define V_BLNNL3(x)             ((x & 1) << 3)
+       #define V_BLNNL2(x)             ((x & 1) << 2)
+       #define V_BLNNL1(x)             ((x & 1) << 1)
+       #define V_BLNNL0(x)             ((x & 1) << 0)
+
+#define STANDARD_CTL                   (0x61)
+       #define M_SCBW                  (1 << 2)
+       #define M_PAL                   (1 << 1)
+       #define M_BIT0                  (1 << 0)
+
+       #define V_SCBW(x)               ((x & 1) << 2)
+       #define V_PAL(x)                ((x & 1) << 1)
+       #define V_BIT0(x)               ((x & 1) << 0)
+
+#define RTCEN_BURST_CTL                        (0x62)
+       #define M_RTCEN                 (1 << 7)
+       #define M_BSTA6                 (1 << 6)
+       #define M_BSTA5                 (1 << 5)
+       #define M_BSTA4                 (1 << 4)
+       #define M_BSTA3                 (1 << 3)
+       #define M_BSTA2                 (1 << 2)
+       #define M_BSTA1                 (1 << 1)
+       #define M_BSTA0                 (1 << 0)
+
+       #define V_RTCEN(x)              ((x & 1) << 7)
+       #define V_BSTA6(x)              ((x & 1) << 6)
+       #define V_BSTA5(x)              ((x & 1) << 5)
+       #define V_BSTA4(x)              ((x & 1) << 4)
+       #define V_BSTA3(x)              ((x & 1) << 3)
+       #define V_BSTA2(x)              ((x & 1) << 2)
+       #define V_BSTA1(x)              ((x & 1) << 1)
+       #define V_BSTA0(x)              ((x & 1) << 0)
+
+#define SUBCARRIER0                    (0x63)
+       #define M_FSC07                 (1 << 7)
+       #define M_FSC06                 (1 << 6)
+       #define M_FSC05                 (1 << 5)
+       #define M_FSC04                 (1 << 4)
+       #define M_FSC03                 (1 << 3)
+       #define M_FSC02                 (1 << 2)
+       #define M_FSC01                 (1 << 1)
+       #define M_FSC00                 (1 << 0)
+
+       #define V_FSC07(x)              ((x & 1) << 7)
+       #define V_FSC06(x)              ((x & 1) << 6)
+       #define V_FSC05(x)              ((x & 1) << 5)
+       #define V_FSC04(x)              ((x & 1) << 4)
+       #define V_FSC03(x)              ((x & 1) << 3)
+       #define V_FSC02(x)              ((x & 1) << 2)
+       #define V_FSC01(x)              ((x & 1) << 1)
+       #define V_FSC00(x)              ((x & 1) << 0)
+
+#define SUBCARRIER1                    (0x64)
+       #define M_FSC15                 (1 << 7)
+       #define M_FSC14                 (1 << 6)
+       #define M_FSC13                 (1 << 5)
+       #define M_FSC12                 (1 << 4)
+       #define M_FSC11                 (1 << 3)
+       #define M_FSC10                 (1 << 2)
+       #define M_FSC09                 (1 << 1)
+       #define M_FSC08                 (1 << 0)
+
+       #define V_FSC15(x)              ((x & 1) << 7)
+       #define V_FSC14(x)              ((x & 1) << 6)
+       #define V_FSC13(x)              ((x & 1) << 5)
+       #define V_FSC12(x)              ((x & 1) << 4)
+       #define V_FSC11(x)              ((x & 1) << 3)
+       #define V_FSC10(x)              ((x & 1) << 2)
+       #define V_FSC09(x)              ((x & 1) << 1)
+       #define V_FSC08(x)              ((x & 1) << 0)
+
+#define SUBCARRIER2                    (0x65)
+       #define M_FSC23                 (1 << 7)
+       #define M_FSC22                 (1 << 6)
+       #define M_FSC21                 (1 << 5)
+       #define M_FSC20                 (1 << 4)
+       #define M_FSC19                 (1 << 3)
+       #define M_FSC18                 (1 << 2)
+       #define M_FSC17                 (1 << 1)
+       #define M_FSC16                 (1 << 0)
+
+       #define V_FSC23(x)              ((x & 1) << 7)
+       #define V_FSC22(x)              ((x & 1) << 6)
+       #define V_FSC21(x)              ((x & 1) << 5)
+       #define V_FSC20(x)              ((x & 1) << 4)
+       #define V_FSC19(x)              ((x & 1) << 3)
+       #define V_FSC18(x)              ((x & 1) << 2)
+       #define V_FSC17(x)              ((x & 1) << 1)
+       #define V_FSC16(x)              ((x & 1) << 0)
+
+#define SUBCARRIER3                    (0x66)
+       #define M_FSC31                 (1 << 7)
+       #define M_FSC30                 (1 << 6)
+       #define M_FSC29                 (1 << 5)
+       #define M_FSC28                 (1 << 4)
+       #define M_FSC27                 (1 << 3)
+       #define M_FSC26                 (1 << 2)
+       #define M_FSC25                 (1 << 1)
+       #define M_FSC24                 (1 << 0)
+
+       #define V_FSC31(x)              ((x & 1) << 7)
+       #define V_FSC30(x)              ((x & 1) << 6)
+       #define V_FSC29(x)              ((x & 1) << 5)
+       #define V_FSC28(x)              ((x & 1) << 4)
+       #define V_FSC27(x)              ((x & 1) << 3)
+       #define V_FSC26(x)              ((x & 1) << 2)
+       #define V_FSC25(x)              ((x & 1) << 1)
+       #define V_FSC24(x)              ((x & 1) << 0)
+
+#define RCV_PORT_CTL                   (0x6B)
+       #define M_ORCV1                 (1 << 4)
+       #define M_PRCV1                 (1 << 3)
+       #define M_ORCV2                 (1 << 1)
+       #define M_PRCV2                 (1 << 0)
+
+       #define V_ORCV1(x)              ((x & 1) << 4)
+       #define V_PRCV1(x)              ((x & 1) << 3)
+       #define V_ORCV2(x)              ((x & 1) << 1)
+       #define V_PRCV2(x)              ((x & 1) << 0)
+
+
+#define TRIG0_CTL                      (0x6C)
+       #define M_HTRIG7                (1 << 7)
+       #define M_HTRIG6                (1 << 6)
+       #define M_HTRIG5                (1 << 5)
+       #define M_HTRIG4                (1 << 4)
+       #define M_HTRIG3                (1 << 3)
+       #define M_HTRIG2                (1 << 2)
+       #define M_HTRIG1                (1 << 1)
+       #define M_HTRIG0                (1 << 0)
+
+       #define V_HTRIG7(x)             ((x & 1) << 7)
+       #define V_HTRIG6(x)             ((x & 1) << 6)
+       #define V_HTRIG5(x)             ((x & 1) << 5)
+       #define V_HTRIG4(x)             ((x & 1) << 4)
+       #define V_HTRIG3(x)             ((x & 1) << 3)
+       #define V_HTRIG2(x)             ((x & 1) << 2)
+       #define V_HTRIG1(x)             ((x & 1) << 1)
+       #define V_HTRIG0(x)             ((x & 1) << 0)
+
+#define TRIG1_CTL                      (0x6D)
+       #define M_HTRIG10               (1 << 7)
+       #define M_HTRIG9                (1 << 6)
+       #define M_HTRIG8                (1 << 5)
+       #define M_VTRIG4                (1 << 4)
+       #define M_VTRIG3                (1 << 3)
+       #define M_VTRIG2                (1 << 2)
+       #define M_VTRIG1                (1 << 1)
+       #define M_VTRIG0                (1 << 0)
+
+       #define V_HTRIG10(x)            ((x & 1) << 7)
+       #define V_HTRIG9(x)             ((x & 1) << 6)
+       #define V_HTRIG8(x)             ((x & 1) << 5)
+       #define V_VTRIG4(x)             ((x & 1) << 4)
+       #define V_VTRIG3(x)             ((x & 1) << 3)
+       #define V_VTRIG2(x)             ((x & 1) << 2)
+       #define V_VTRIG1(x)             ((x & 1) << 1)
+       #define V_VTRIG0(x)             ((x & 1) << 0)
+
+#define TRIG2_CTL                      (0x75)
+       #define M_VTRIG8                (1 << 7)
+       #define M_VTRIG7                (1 << 6)
+       #define M_VTRIG6                (1 << 5)
+       #define M_VTRIG5                (1 << 4)
+
+       #define V_VTRIG8(x)             ((x & 1) << 7)
+       #define V_VTRIG7(x)             ((x & 1) << 6)
+       #define V_VTRIG6(x)             ((x & 1) << 5)
+       #define V_VTRIG5(x)             ((x & 1) << 4)
+
+enum {
+       TVOUT_CVBS_NTSC = 0,
+       TVOUT_CVBS_PAL,
+};
+
+enum {
+       INPUT_FORMAT_RGB = 0,
+       INPUT_FORMAT_YUV,
+       INPUT_FORMAT_CCIR656
+};
+
+enum {
+       SOC_RK1000 = 0,
+       SOC_GM7122
+};
+
+#define TVOUT_DEAULT TVOUT_CVBS_PAL
+
+struct ioctrl {
+       int gpio;
+       int active;
+};
+
+struct gm7122_tve {
+       struct device                   *dev;
+       u32                             reg_phy_base;
+       u32                             len;
+       unsigned int                    lcdcid;
+       unsigned int                    property;
+       struct rk_display_device        *ddev;
+       unsigned int                    enable;
+       unsigned int                    suspend;
+       struct fb_videomode             *mode;
+       struct list_head                modelist;
+       struct rk_screen                screen;
+       struct i2c_client               *client;
+       struct ioctrl                   io_reset;
+       struct ioctrl                   io_sleep;
+};
+
+#define GM7122_I2C_RATE        (100*1000)
+
+#endif