HDMI: Not filter the input 3dmode with EDID information.
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / transmitter / vga.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/delay.h>
4 #include <linux/fb.h>
5 #include <linux/display-sys.h>
6 #include <linux/rk_screen.h>
7 #include <linux/rk_fb.h>
8 #ifdef CONFIG_OF
9 #include <linux/of.h>
10 #include <linux/of_gpio.h>
11 #endif
12
13 #include "../../edid.h"
14
15 #ifdef CONFIG_SWITCH
16 #include <linux/switch.h>
17 #endif
18         
19
20 #define DDC_ADDR                0x50
21 #define DDC_I2C_RATE            100*1000
22 #define INVALID_GPIO            -1
23 #define GPIO_HIGH               1
24 #define GPIO_LOW                0
25 #define DISPLAY_SOURCE_LCDC0    0
26 #define DISPLAY_SOURCE_LCDC1    1
27
28 //static char *vgaenvent[] = {"INTERFACE=VGA", NULL}; 
29
30 static const struct fb_videomode rk29_mode[] = {
31         //name                  refresh         xres    yres    pixclock                        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag(used for vic)
32 {       "1024x768p@60Hz",       60,             1024,   768,    KHZ2PICOS(65000),       160,    24,     29,     3,      136,    6,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },
33 {       "1280x720p@60Hz",       60,             1280,   720,    KHZ2PICOS(74250),       220,    110,    20,     5,      40,     5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },      
34 {       "1280x1024p@60Hz",      60,             1280,   1024,   KHZ2PICOS(108000),      248,    48,     38,     1,      112,    3,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },
35 {       "1366x768p@60Hz",       60,             1366,   768,    KHZ2PICOS(85500),       213,    70,     24,     3,      143,    3,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },
36 {       "1440x900p@60Hz",       60,             1440,   900,    KHZ2PICOS(116500),      232,    80,     25,     3,      152,    6,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },
37 {       "1680x1050p@60Hz",      60,             1680,   1050,   KHZ2PICOS(146250),      280,    104,    30,     3,      176,    6,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },
38 {       "1920x1080p@60Hz",      60,             1920,   1080,   KHZ2PICOS(148500),      148,    88,     36,     4,      44,     5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              0       },
39 };
40
41 struct rockchip_vga {
42         struct device            *dev;  /*i2c device*/
43         struct rk_display_device *ddev; /*display device*/
44         struct i2c_client        *client;
45         struct list_head         modelist;
46         struct fb_monspecs       specs;
47         struct rk_screen         screen;
48         int                      indx;
49         int                      en_pin;
50         int                      en_val;
51         int                      lcdc_id;
52 #ifdef CONFIG_SWITCH
53         struct switch_dev        switch_vga;
54 #endif
55 };
56
57 static int i2c_master_reg8_recv(const struct i2c_client *client,
58                 const char reg, char *buf, int count, int scl_rate)
59 {
60         struct i2c_adapter *adap=client->adapter;
61         struct i2c_msg msgs[2];
62         int ret;
63         char reg_buf = reg;
64
65         msgs[0].addr = client->addr;
66         msgs[0].flags = client->flags;
67         msgs[0].len = 1;
68         msgs[0].buf = &reg_buf;
69         msgs[0].scl_rate = scl_rate;
70
71         msgs[1].addr = client->addr;
72         msgs[1].flags = client->flags | I2C_M_RD;
73         msgs[1].len = count;
74         msgs[1].buf = (char *)buf;
75         msgs[1].scl_rate = scl_rate;
76
77         ret = i2c_transfer(adap, msgs, 2);
78
79         return (ret == 2)? count : ret;
80 }
81
82
83
84 static unsigned char *rk29fb_ddc_read(struct i2c_client *client)
85 {
86         int rc;
87         unsigned char *buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
88         if (!buf) {
89                 dev_err(&client->dev, "unable to allocate memory for EDID\n");
90                 return NULL;
91         }
92         
93         /*Check ddc i2c communication is available or not*/
94         rc = i2c_master_reg8_recv(client, 0, buf, 6, DDC_I2C_RATE);
95         if (rc == 6) {
96                 memset(buf, 0, EDID_LENGTH);
97                 rc = i2c_master_reg8_recv(client, 0, buf, EDID_LENGTH, DDC_I2C_RATE);
98                 if(rc == EDID_LENGTH)
99                         return buf;
100         }
101
102         dev_err(&client->dev, "unable to read EDID block.\n");
103         kfree(buf);
104         return NULL;
105 }
106
107 static int vga_mode2screen(struct fb_videomode *modedb, struct rk_screen *screen)
108 {
109         if(modedb == NULL || screen == NULL)
110                 return -1;
111                 
112         memset(screen, 0, sizeof(struct rk_screen));
113         memcpy(&screen->mode, modedb, sizeof(*modedb));
114         screen->mode.pixclock = PICOS2KHZ(screen->mode.pixclock);
115         screen->mode.pixclock /= 250;
116         screen->mode.pixclock *= 250;
117         screen->mode.pixclock *= 1000;
118         screen->xsize = screen->mode.xres;
119         screen->ysize = screen->mode.yres;
120         screen->overscan.left = 100;
121         screen->overscan.top = 100;
122         screen->overscan.right = 100;
123         screen->overscan.bottom = 100;
124         /* screen type & face */
125         screen->type = SCREEN_RGB;
126         screen->face = OUT_P888;
127
128         screen->pin_vsync = (screen->mode.sync & FB_SYNC_VERT_HIGH_ACT) ? 1:0;
129         screen->pin_hsync = (screen->mode.sync & FB_SYNC_HOR_HIGH_ACT) ? 1:0;
130         screen->pin_den = 0;
131         screen->pin_dclk = 0;
132
133         /* Swap rule */
134         screen->swap_rb = 0;
135         screen->swap_rg = 0;
136         screen->swap_gb = 0;
137         screen->swap_delta = 0;
138         screen->swap_dumy = 0;
139         /* Operation function*/
140         screen->init = NULL;
141         screen->standby = NULL;
142         return 0;
143 }
144
145
146 static int vga_switch_screen(struct rockchip_vga *vga, int indx)
147 {
148         struct fb_videomode *mode = &vga->specs.modedb[indx];
149         struct rk_screen *screen = &vga->screen;
150         vga_mode2screen(mode, screen);
151         rk_fb_switch_screen(screen, 1 ,vga->lcdc_id);
152         vga->indx = indx;
153         return 0;
154         
155         
156 }
157 static int vga_get_screen_info(struct rockchip_vga *vga)
158 {
159         u8 *edid;
160         int i;
161         struct fb_monspecs *specs = &vga->specs;
162         struct list_head *modelist = &vga->modelist;
163         edid = rk29fb_ddc_read(vga->client);
164         if (!edid) {
165                 dev_info(vga->dev, "get edid failed!\n");
166                 return -EINVAL;
167         }
168         fb_edid_to_monspecs(edid,specs);
169         INIT_LIST_HEAD(modelist);
170         for (i = 0; i < specs->modedb_len; i++) {
171                 fb_add_videomode(&specs->modedb[i], modelist);
172                 dev_dbg(vga->dev, "%4dx%4d@%d---dclk:%ld\n",
173                         specs->modedb[i].xres, specs->modedb[i].yres,
174                         specs->modedb[i].refresh,
175                         (PICOS2KHZ(specs->modedb[i].pixclock)/250)*250*1000);
176         }
177         return 0;
178         
179 }
180
181
182
183 static int vga_get_modelist(struct rk_display_device *device,
184                              struct list_head **modelist)
185 {
186         struct rockchip_vga *vga = device->priv_data;
187         *modelist = &vga->modelist;
188         return 0;
189 }
190
191 static int vga_set_mode(struct rk_display_device *device,
192                          struct fb_videomode *mode)
193 {
194         struct rockchip_vga *vga = device->priv_data;
195         struct rk_screen *screen = &vga->screen;
196         vga_mode2screen(mode, screen);
197         rk_fb_switch_screen(screen, 1 ,vga->lcdc_id);
198         return 0;
199 }
200
201 static int vga_get_mode(struct rk_display_device *device,
202                          struct fb_videomode *mode)
203 {
204         //struct vga *vga = device->priv_data;
205         //struct fb_videomode *vmode;
206
207         return 0;
208 }
209
210 struct rk_display_ops vga_display_ops = {
211         .getmodelist = vga_get_modelist,
212         .setmode = vga_set_mode,
213         .getmode = vga_get_mode,
214 };
215
216 static int vga_display_probe(struct rk_display_device *device, void *devdata)
217 {
218         device->owner = THIS_MODULE;
219         strcpy(device->type, "VGA");
220         device->priority = DISPLAY_PRIORITY_VGA;
221         device->priv_data = devdata;
222         device->ops = &vga_display_ops;
223         return 1;
224 }
225
226 static struct rk_display_driver display_vga = {
227         .probe = vga_display_probe,
228 };
229
230
231
232 struct rk_display_device * vga_register_display_sysfs(struct rockchip_vga *vga)
233 {
234         return rk_display_device_register(&display_vga, vga->dev, vga);
235 }
236
237 void vga_unregister_display_sysfs(struct rockchip_vga *vga)
238 {
239         if (vga->ddev)
240                 rk_display_device_unregister(vga->ddev);
241 }
242
243
244 static int vga_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
245 {    
246         int ret;
247         struct rockchip_vga *vga;
248         struct device_node *np = client->dev.of_node;
249         enum of_gpio_flags pwr_flags;
250
251         if (!np) {
252                 dev_err(&client->dev, "no device node found!\n");
253                 return -EINVAL;
254         } 
255
256         vga = devm_kzalloc(&client->dev, sizeof(*vga), GFP_KERNEL);
257         if (!vga) {
258                 dev_err(&client->dev, "allocate for vga failed!\n");
259                 return -ENOMEM;
260         }
261
262         vga->client = client;
263         vga->dev = &client->dev;
264         i2c_set_clientdata(client, vga);
265         vga->ddev = vga_register_display_sysfs(vga);
266         if (IS_ERR(vga->ddev))
267                 dev_warn(vga->dev, "Unable to create device for vga :%ld",
268                         PTR_ERR(vga->ddev));
269         
270         vga->en_pin = of_get_named_gpio_flags(np, "pwr_gpio", 0, &pwr_flags);
271         if (!gpio_is_valid(vga->en_pin)) {
272                 dev_err(vga->dev, "failed to get pwr_gpio!\n");
273                 ret =  -EINVAL;
274                 goto err;
275         }
276
277         vga->en_val = (pwr_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1;
278         vga->lcdc_id = DISPLAY_SOURCE_LCDC1;
279         
280         ret = devm_gpio_request(vga->dev, vga->en_pin, "pwr_pin");
281         if(ret < 0) {
282                 dev_err(vga->dev, "request for pwr_pin failed!\n ");
283                 goto err;
284         }
285         gpio_direction_output(vga->en_pin, vga->en_val);
286         ret = vga_get_screen_info(vga);
287         if (ret < 0)
288                 goto err;
289         vga_switch_screen(vga, 7);
290         
291         printk("VGA probe successful\n");
292         return 0;
293 err:
294         vga_unregister_display_sysfs(vga);
295         return ret;
296         
297 }
298
299
300 static int vga_i2c_remove(struct i2c_client *client)
301 {
302         return 0;
303 }
304
305
306 #if defined(CONFIG_OF)
307 static struct of_device_id vga_dt_ids[] = {
308         {.compatible = "rockchip,vga" },
309         { }
310 };
311 #endif
312
313 static const struct i2c_device_id vga_id[] = {
314         { "vga_i2c", 0 },
315         { }
316 };
317
318 static struct i2c_driver vga_i2c_driver  = {
319         .driver = {
320                 .name  = "vga_i2c",
321                 .owner = THIS_MODULE,
322 #if defined(CONFIG_OF)
323                 .of_match_table = of_match_ptr(vga_dt_ids),
324 #endif
325         },
326         .probe          = &vga_i2c_probe,
327         .remove         = &vga_i2c_remove,
328         .id_table       = vga_id,
329 };
330
331 static int __init rockchip_vga_init(void)
332 {
333     return i2c_add_driver(&vga_i2c_driver);
334 }
335
336 static void __exit rockchip_vga_exit(void)
337 {
338     i2c_del_driver(&vga_i2c_driver);
339 }
340
341 module_init(rockchip_vga_init);
342 module_exit(rockchip_vga_exit);