1 #include <linux/ctype.h>
2 #include <linux/string.h>
3 #include <linux/display-sys.h>
7 #ifdef CONFIG_DISPLAY_KEY_LED_CONTROL
8 #define RK610_LED_CVBS_PIN RK29_PIN4_PD3
10 #define RK610_LED_CVBS_PIN INVALID_GPIO
14 static const struct fb_videomode rk610_cvbs_mode [] = {
15 //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag
16 { "NTSC", 60, 720, 480, 27000000, 116, 16, 25, 14, 6, 6, 0, 1, OUT_P888 },
17 { "PAL", 50, 720, 576, 27000000, 126, 12, 37, 6, 6, 6, 0, 1, OUT_P888 },
20 static const struct fb_videomode rk610_cvbs_mode [] = {
21 //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag
22 { "NTSC", 60, 720, 480, 27000000, 116, 16, 16, 3, 6, 3, 0, 1, OUT_CCIR656 },
23 { "PAL", 50, 720, 576, 27000000, 126, 12, 19, 2, 6, 3, 0, 1, OUT_CCIR656 },
27 struct rk610_monspecs rk610_cvbs_monspecs;
30 int rk610_tv_cvbs_init(void)
32 unsigned char TVE_Regs[9];
33 unsigned char TVE_CON_Reg;
36 rk610_tv_wirte_reg(TVE_HDTVCR, TVE_RESET);
38 memset(TVE_Regs, 0, 9);
39 TVE_CON_Reg = TVE_CONTROL_CVBS_3_CHANNEL_ENALBE;
40 TVE_Regs[TVE_VINCR] = TVE_VINCR_PIX_DATA_DELAY(0) | TVE_VINCR_H_SYNC_POLARITY_NEGTIVE | TVE_VINCR_V_SYNC_POLARITY_NEGTIVE | TVE_VINCR_VSYNC_FUNCTION_VSYNC;
41 TVE_Regs[TVE_POWERCR] = TVE_DAC_Y_ENABLE | TVE_DAC_U_ENABLE | TVE_DAC_V_ENABLE;
42 TVE_Regs[TVE_VOUTCR] = TVE_VOUTCR_OUTPUT_CVBS;
43 TVE_Regs[TVE_YADJCR] = 0x17;
44 TVE_Regs[TVE_YCBADJCR] = 0x10;
45 TVE_Regs[TVE_YCRADJCR] = 0x10;
47 switch(rk610_tv_output_status) {
49 TVE_Regs[TVE_VFCR] = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_7_5_IRE | TVE_VFCR_NTSC;
51 TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
52 TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
53 TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_NTSC | RGB2CCIR_ENABLE;
55 TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
56 TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
60 TVE_Regs[TVE_VFCR] = TVE_VFCR_ENABLE_SUBCARRIER_RESET | TVE_VFCR_VIN_RANGE_16_235 | TVE_VFCR_BLACK_0_IRE | TVE_VFCR_PAL_B_N;
62 TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT601_SLAVE);
63 TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_COLOR_CONVERT_REC601 | TVE_INPUT_DATA_RGB | TVE_OUTPUT_MODE_PAL_NTSC;
64 TVE_CON_Reg |= RGB2CCIR_INPUT_DATA_FORMAT(0) | RGB2CCIR_RGB_SWAP_DISABLE | RGB2CCIR_INPUT_PROGRESSIVE | RGB2CCIR_CVBS_PAL | RGB2CCIR_ENABLE;
66 TVE_Regs[TVE_VINCR] |= TVE_VINCR_INPUT_FORMAT(INPUT_FORMAT_BT656);
67 TVE_Regs[TVE_HDTVCR] = TVE_FILTER(0) | TVE_INPUT_DATA_YUV | TVE_OUTPUT_MODE_PAL_NTSC;
74 for(i = 0; i < sizeof(TVE_Regs); i++){
75 // printk(KERN_ERR "reg[%d] = 0x%02x\n", i, TVE_Regs[i]);
76 ret = rk610_tv_wirte_reg(i, TVE_Regs[i]);
78 printk(KERN_ERR "rk610_tv_wirte_reg %d err!\n", i);
82 // printk(KERN_ERR "TVE_CON_Reg = 0x%02x\n", TVE_CON_Reg);
83 rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, TVE_CON_Reg);
85 rk610_control_send_byte(RK610_CONTROL_REG_CCIR_RESET, 0x01);
90 static int rk610_cvbs_set_enable(struct rk_display_device *device, int enable)
92 if(rk610_cvbs_monspecs.enable != enable || rk610_cvbs_monspecs.mode_set != rk610_tv_output_status)
96 rk610_tv_standby(RK610_TVOUT_CVBS);
97 rk610_cvbs_monspecs.enable = 0;
98 if(RK610_LED_CVBS_PIN != INVALID_GPIO)
99 gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);
103 rk610_switch_fb(rk610_cvbs_monspecs.mode, rk610_cvbs_monspecs.mode_set);
104 rk610_cvbs_monspecs.enable = 1;
105 if(RK610_LED_CVBS_PIN != INVALID_GPIO)
106 gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_LOW);
112 static int rk610_cvbs_get_enable(struct rk_display_device *device)
114 return rk610_cvbs_monspecs.enable;
117 static int rk610_cvbs_get_status(struct rk_display_device *device)
119 if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
125 static int rk610_cvbs_get_modelist(struct rk_display_device *device, struct list_head **modelist)
127 *modelist = &(rk610_cvbs_monspecs.modelist);
131 static int rk610_cvbs_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
135 for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
137 if(fb_mode_is_equal(&rk610_cvbs_mode[i], mode))
139 if( ((i + 1) != rk610_tv_output_status) )
141 rk610_cvbs_monspecs.mode_set = i + 1;
142 rk610_cvbs_monspecs.mode = (struct fb_videomode *)&rk610_cvbs_mode[i];
151 static int rk610_cvbs_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
153 *mode = *(rk610_cvbs_monspecs.mode);
157 static struct rk_display_ops rk610_cvbs_display_ops = {
158 .setenable = rk610_cvbs_set_enable,
159 .getenable = rk610_cvbs_get_enable,
160 .getstatus = rk610_cvbs_get_status,
161 .getmodelist = rk610_cvbs_get_modelist,
162 .setmode = rk610_cvbs_set_mode,
163 .getmode = rk610_cvbs_get_mode,
166 static int rk610_display_cvbs_probe(struct rk_display_device *device, void *devdata)
168 device->owner = THIS_MODULE;
169 strcpy(device->type, "TV");
170 device->priority = DISPLAY_PRIORITY_TV;
171 device->priv_data = devdata;
172 device->ops = &rk610_cvbs_display_ops;
176 static struct rk_display_driver display_rk610_cvbs = {
177 .probe = rk610_display_cvbs_probe,
180 int rk610_register_display_cvbs(struct device *parent)
184 memset(&rk610_cvbs_monspecs, 0, sizeof(struct rk610_monspecs));
185 INIT_LIST_HEAD(&rk610_cvbs_monspecs.modelist);
186 for(i = 0; i < ARRAY_SIZE(rk610_cvbs_mode); i++)
187 fb_add_videomode(&rk610_cvbs_mode[i], &rk610_cvbs_monspecs.modelist);
188 if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60) {
189 rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[rk610_tv_output_status - 1]);
190 rk610_cvbs_monspecs.mode_set = rk610_tv_output_status;
193 rk610_cvbs_monspecs.mode = (struct fb_videomode *)&(rk610_cvbs_mode[0]);
194 rk610_cvbs_monspecs.mode_set = TVOUT_CVBS_NTSC;
196 rk610_cvbs_monspecs.ddev = rk_display_device_register(&display_rk610_cvbs, parent, NULL);
197 if(RK610_LED_CVBS_PIN != INVALID_GPIO)
199 if(gpio_request(RK610_LED_CVBS_PIN, NULL) != 0)
201 gpio_free(RK610_LED_CVBS_PIN);
202 dev_err(rk610_cvbs_monspecs.ddev->dev, ">>>>>> RK610_LED_CVBS_PIN gpio_request err \n ");
205 gpio_pull_updown(RK610_LED_CVBS_PIN,GPIOPullUp);
206 gpio_direction_output(RK610_LED_CVBS_PIN, GPIO_HIGH);