4 * Driver for rockchip rk610 tv control
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/i2c.h>
17 #include <linux/delay.h>
18 #include <linux/fcntl.h>
21 #include <linux/console.h>
22 #include <asm/uaccess.h>
24 #include "../../rk29_fb.h"
26 #define DRV_NAME "rk610_tvout"
27 #define RK610_I2C_RATE 100*1000
29 volatile int rk610_tv_output_status = RK610_TVOUT_DEAULT;
30 static struct i2c_client *rk610_tv_i2c_client = NULL;
32 int rk610_tv_wirte_reg(u8 reg, u8 data)
35 if(rk610_tv_i2c_client == NULL)
37 ret = i2c_master_reg8_send(rk610_tv_i2c_client, reg, &data, 1, RK610_I2C_RATE);
43 int rk610_switch_fb(const struct fb_videomode *modedb, int tv_mode)
45 struct rk_screen *screen;
49 screen = kzalloc(sizeof(struct rk_screen), GFP_KERNEL);
53 memset(screen, 0, sizeof(struct rk_screen));
54 /* screen type & face */
55 screen->type = SCREEN_HDMI;
56 screen->mode = modedb->vmode;
57 screen->face = modedb->flag;
59 screen->x_res = modedb->xres;
60 screen->y_res = modedb->yres;
63 screen->pixclock = modedb->pixclock;
65 screen->lcdc_aclk = 500000000;
66 screen->left_margin = modedb->left_margin;
67 screen->right_margin = modedb->right_margin;
68 screen->hsync_len = modedb->hsync_len;
69 screen->upper_margin = modedb->upper_margin;
70 screen->lower_margin = modedb->lower_margin;
71 screen->vsync_len = modedb->vsync_len;
74 if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
75 screen->pin_hsync = 1;
77 screen->pin_hsync = 0;
78 if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
79 screen->pin_vsync = 1;
81 screen->pin_vsync = 0;
89 screen->swap_delta = 0;
90 screen->swap_dumy = 0;
92 /* Operation function*/
94 screen->standby = NULL;
98 #ifdef CONFIG_RK610_TVOUT_CVBS
101 screen->init = rk610_tv_cvbs_init;;
105 #ifdef CONFIG_RK610_TVOUT_YPbPr
106 case TVOUT_YPbPr_720x480p_60:
107 case TVOUT_YPbPr_720x576p_50:
108 case TVOUT_YPbPr_1280x720p_50:
109 case TVOUT_YPbPr_1280x720p_60:
110 //case TVOUT_YPbPr_1920x1080i_50:
111 case TVOUT_YPbPr_1920x1080i_60:
112 case TVOUT_YPbPr_1920x1080p_50:
113 case TVOUT_YPbPr_1920x1080p_60:
114 screen->init = rk610_tv_ypbpr_init;
123 rk610_tv_output_status = tv_mode;
124 FB_Switch_Screen(screen, 1);
129 int rk610_tv_standby(int type)
135 #ifdef CONFIG_RK610_TVOUT_CVBS
136 case RK610_TVOUT_CVBS:
137 if(rk610_cvbs_monspecs.enable == 0)
139 #ifdef CONFIG_RK610_TVOUT_YPbPr
140 if(rk610_ypbpr_monspecs.enable == 1)
145 #ifdef CONFIG_RK610_TVOUT_YPbPr
146 case RK610_TVOUT_YPBPR:
147 if(rk610_ypbpr_monspecs.enable == 0)
149 #ifdef CONFIG_RK610_TVOUT_CVBS
150 if(rk610_cvbs_monspecs.enable == 1)
159 ret = rk610_tv_wirte_reg(TVE_POWERCR, 0);
161 printk("[%s] rk610_tv_wirte_reg err!\n", __FUNCTION__);
165 ret = rk610_control_send_byte(RK610_CONTROL_REG_TVE_CON, 0);
167 printk("[%s] rk610_control_send_byte err!\n", __FUNCTION__);
173 static int rk610_tv_probe(struct i2c_client *client,const struct i2c_device_id *id)
177 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
181 rk610_tv_i2c_client = client;
183 #ifdef CONFIG_RK610_TVOUT_YPbPr
184 rk610_register_display_ypbpr(&client->dev);
185 if(rk610_tv_output_status > TVOUT_CVBS_PAL)
186 rk_display_device_enable(rk610_ypbpr_monspecs.ddev);
189 #ifdef CONFIG_RK610_TVOUT_CVBS
190 rk610_register_display_cvbs(&client->dev);
191 if(rk610_tv_output_status < TVOUT_YPbPr_720x480p_60)
192 rk_display_device_enable(rk610_cvbs_monspecs.ddev);
195 printk(KERN_INFO "rk610_tv ver 1.0 probe ok\n");
202 static int rk610_tv_remove(struct i2c_client *client)
208 static const struct i2c_device_id rk610_tv_id[] = {
212 MODULE_DEVICE_TABLE(i2c, rk610_tv_id);
214 static struct i2c_driver rk610_tv_driver = {
218 .id_table = rk610_tv_id,
219 .probe = rk610_tv_probe,
220 .remove = rk610_tv_remove,
223 static int __init rk610_tv_init(void)
226 ret = i2c_add_driver(&rk610_tv_driver);
228 printk("i2c_add_driver err, ret = %d\n", ret);
233 static void __exit rk610_tv_exit(void)
235 i2c_del_driver(&rk610_tv_driver);
238 module_init(rk610_tv_init);
239 //late_initcall(rk610_tv_init);
240 module_exit(rk610_tv_exit);
242 /* Module information */
243 MODULE_DESCRIPTION("ROCKCHIP RK610 TV Output");
244 MODULE_LICENSE("GPL");