Merge tag 'v3.10.92'
[firefly-linux-kernel-4.4.55.git] / drivers / misc / scaler / scaler-edid.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/delay.h>
4 #include <linux/fb.h>
5 #include <mach/gpio.h>
6 #include <mach/iomux.h>
7
8 //#include <linux/rk_screen.h>
9 #include <linux/rk_fb.h>
10 #include "../../video/edid.h"
11
12 #define DDC_ADDR                        0x50  //read 0xa0 write 0xa1
13 #define DDC_I2C_RATE            100*1000
14 #define DEFAULT_MODE   3
15
16 #undef SDEBUG
17
18 #ifdef SDEBUG
19 #define SPRINTK(fmt, args...) printk(fmt,## args)
20 #else
21 #define SPRINTK(fmt, args...)
22 #endif
23
24 static struct scaler_ddc_dev
25 {
26         unsigned char        *edid;
27         struct i2c_client    *client;
28         struct fb_monspecs   specs;
29         struct list_head     modelist;
30         struct fb_videomode  *mode;
31 }*ddev = NULL;
32
33 static const struct fb_videomode default_modedb[] = {
34         //name                          refresh         xres    yres    pixclock                        h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag(used for vic)
35 #if defined(CONFIG_CLK_RK30_BOX)
36 {       "1024x768p@60Hz",       60,                     1024,   768,    KHZ2PICOS(65000),       160,    24,             29,             3,              136,    6,              0,                      0,              0       },
37 {       "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       },      
38 {       "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       },
39 {       "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       },
40 {       "1440x900p@60Hz",       60,                     1440,   900,    KHZ2PICOS(106500),      232,    80,             25,             3,              152,    6,              FB_SYNC_VERT_HIGH_ACT,                  0,              0       },
41 {       "1680x1050p@60Hz",      60,                     1680,   1050,   KHZ2PICOS(146250),      280,    104,    30,             3,              176,    6,              FB_SYNC_VERT_HIGH_ACT,                  0,              0       },
42 {       "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       },
43 #else
44 //{     "640x480p@60Hz",        60,                     640,    480,    KHZ2PICOS(25175),       48,             16,             33,             10,             96,             2,              0,                      0,              1       },
45 {       "720x480p@60Hz",        60,                     720,    480,    KHZ2PICOS(27000),       60,             16,             30,             9,              62,             6,              0,                      0,              2       },
46 {       "720x576p@50Hz",        50,                     720,    576,    KHZ2PICOS(27000),       68,             12,             39,             5,              64,             5,              0,                      0,              17      },
47 {       "1280x720p@50Hz",       50,                     1280,   720,    KHZ2PICOS(74250),       220,    440,    20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              19      },
48 {       "1280x720p@60Hz",       60,                     1280,   720,    KHZ2PICOS(74250),       220,    110,    20,             5,              40,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              4       },      
49 {       "1920x1080p@50Hz",      50,                     1920,   1080,   KHZ2PICOS(148500),      148,    528,    36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              31      },
50 {       "1920x1080p@60Hz",      60,                     1920,   1080,   KHZ2PICOS(148500),      148,    88,             36,             4,              44,             5,              FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              16      },
51 #endif
52 };
53
54 static int scaler_mode2screen(const struct fb_videomode *modedb, struct rk29fb_screen *screen)
55 {
56         if(modedb == NULL || screen == NULL)
57                 return -1;
58                 
59         memset(screen, 0, sizeof(struct rk29fb_screen));
60         /* screen type & face */
61     screen->type = SCREEN_RGB;
62     screen->face = OUT_P888;
63         //screen->lvds_format = LVDS_8BIT_1;  //lvds data format
64         
65         /* Screen size */
66         screen->x_res = modedb->xres;
67     screen->y_res = modedb->yres;
68
69     /* Timing */
70     screen->pixclock = PICOS2KHZ(modedb->pixclock);
71     screen->pixclock /= 250;
72     screen->pixclock *= 250;
73     screen->pixclock *= 1000;
74     printk("  pixclock is %d\n", screen->pixclock);
75         screen->lcdc_aclk = 300000000;
76
77         screen->left_margin = modedb->left_margin ;
78         screen->right_margin = modedb->right_margin;
79         screen->hsync_len = modedb->hsync_len;
80         screen->upper_margin = modedb->upper_margin ;
81         screen->lower_margin = modedb->lower_margin;
82         screen->vsync_len = modedb->vsync_len;
83         /* Pin polarity */
84         if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
85                 screen->pin_hsync = 1;
86         else
87                 screen->pin_hsync = 0;
88
89         if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
90                 screen->pin_vsync = 1;
91         else
92                 screen->pin_vsync = 0;  
93
94         screen->pin_den = 0;
95         screen->pin_dclk = 1;
96
97         /* Swap rule */
98     screen->swap_rb = 0;
99     screen->swap_rg = 0;
100     screen->swap_gb = 0;
101     screen->swap_delta = 0;
102     screen->swap_dumy = 0;
103
104     /* Operation function*/
105     screen->init = NULL;
106     screen->standby = NULL;     
107         return 0;
108 }
109
110 void set_vga_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info)
111 {
112         scaler_mode2screen(&default_modedb[DEFAULT_MODE], screen);
113 }
114
115 static int scaler_edid_read(char *buf, int len)
116 {
117         int rc;
118
119         if (ddev == NULL || ddev->client == NULL)
120                 return -ENODEV;
121
122         if (buf == NULL)
123                 return -ENOMEM;
124
125         // Check ddc i2c communication is available or not.
126         rc = i2c_master_reg8_recv(ddev->client, 0, buf, 6, DDC_I2C_RATE);
127         if(rc == 6) {
128                 /************DEBUG*************/        
129                 SPRINTK("EDID HEAD: ");
130                 for (rc = 0; rc < 6; rc++)
131                         SPRINTK(" %#X", buf[rc]);
132                 SPRINTK("\n");
133                 /************DEBUG*************/        
134
135                 memset(buf, 0, len);
136                 // Read EDID.
137                 rc = i2c_master_reg8_recv(ddev->client, 0, buf, len, DDC_I2C_RATE);
138                 if(rc == len)
139                         return 0;
140         }
141
142         printk("unable to read EDID block.\n");
143         return -EIO;
144 }
145
146 /*
147  *read edid of monitor and parse it 
148  */
149 static int scaler_parse_vga_edid(void)
150 {
151         int i ;
152         struct fb_monspecs *specs = NULL;
153         if (ddev == NULL) {
154                 return -ENODEV;
155         }else {
156                 specs = &ddev->specs;
157                 //free old edid
158                 if (ddev->edid) {
159                         kfree(ddev->edid);
160                         ddev->edid = NULL;
161                 }
162                 ddev->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
163                 if (!ddev->edid)
164                         return -ENOMEM;
165
166                 //read edid
167                 if (!scaler_edid_read(ddev->edid, EDID_LENGTH)) {
168                         //free old fb_monspecs
169                         if(specs->modedb)
170                                 kfree(specs->modedb);
171                         memset(specs, 0, sizeof(struct fb_monspecs));
172                         //parse edid to fb_monspecs
173                         fb_edid_to_monspecs(ddev->edid, specs);
174
175                         /********** DEBUG ***********/
176                         SPRINTK("========================================\n");
177                         SPRINTK("Display Information (EDID)\n");
178                         SPRINTK("========================================\n");
179                         SPRINTK("   EDID Version %d.%d\n", (int) specs->version, (int) specs->revision);
180                         SPRINTK("   Serial Number: %s\n", specs->serial_no);
181                         SPRINTK("   ASCII Block: %s\n", specs->ascii);
182                         SPRINTK("   Monitor Name: %s\n", specs->monitor);
183                         SPRINTK("   Display Characteristics:\n");
184                         for (i = 0; i < specs->modedb_len; i++)
185                                 SPRINTK("       %4d x %4d @%d [clk: %ldKHZ]\n", specs->modedb[i].xres, specs->modedb[i].yres,
186                                                                 specs->modedb[i].refresh, PICOS2KHZ(specs->modedb[i].pixclock));
187                         SPRINTK("========================================\n");
188                         /********** DEBUG ***********/
189                 }else {
190                         return -EIO;
191                 }
192         }
193         printk("scaler-ddc: read and parse vga edid success.\n");
194         return 0;
195 }
196
197 static void scaler_set_default_modelist(void)
198 {
199         int i;
200         struct fb_videomode *mode = NULL;
201         struct list_head        *modelist  = &ddev->modelist;
202
203         fb_destroy_modelist(modelist);
204
205         for(i = 0; i < ARRAY_SIZE(default_modedb); i++)
206         {
207                 mode = (struct fb_videomode *)&default_modedb[i];       
208                 fb_add_videomode(mode, modelist);
209         }
210 }
211
212 /*
213  * Check mode 1920x1080p@60Hz is in modedb or not.  
214  * If exist, set it as output moe.
215  * If not exist, try mode 1280x720p@60Hz.
216  * If both mode not exist, try 720x480p@60Hz.
217  */
218 static int scaler_check_mode(struct fb_videomode *mode)
219 {
220         struct fb_monspecs      *specs = NULL;
221         struct list_head        *modelist = NULL;
222         struct fb_videomode *tmp_mode = NULL;
223         unsigned int pixclock;
224         int i;
225
226         if (ddev == NULL)
227                 return -ENODEV;
228         specs = &ddev->specs;
229         modelist = &ddev->modelist;
230
231         fb_destroy_modelist(modelist);
232
233         if (mode) {
234
235                 for(i = 0; i < ARRAY_SIZE(default_modedb); i++) {
236                         tmp_mode = (struct fb_videomode *)&default_modedb[i];   
237                         pixclock = PICOS2KHZ(tmp_mode->pixclock);
238                         pixclock /= 250;
239                         pixclock *= 250;
240                         pixclock *= 1000;
241                         if( (pixclock <= specs->dclkmax) &&     
242                                 (tmp_mode->xres <= mode->xres) && (tmp_mode->yres <= mode->yres) &&
243                                 (tmp_mode->refresh <= specs->vfmax) && (tmp_mode->refresh >= specs->vfmin)
244                           ) {
245                                 fb_add_videomode(tmp_mode, modelist);
246                         }
247                 }
248         }
249
250         return 0;
251 }
252
253 /*
254  * Find monitor prefered video mode. If not find, 
255  * @specs init info of monitor
256  */
257 struct fb_videomode *scaler_find_max_mode(void)
258 {
259         struct fb_videomode *mode = NULL/*, *nearest_mode = NULL*/;
260         struct fb_monspecs *specs = NULL;
261         int i, pixclock;
262         
263         if (ddev == NULL)
264                 return NULL;
265         specs = &ddev->specs;
266         if(specs->modedb_len) {
267
268
269                 /* Get max resolution timing */
270                 mode = &specs->modedb[0];
271                 for (i = 0; i < specs->modedb_len; i++) {
272                         if(specs->modedb[i].xres > mode->xres)
273                                 mode = &specs->modedb[i];
274                         else if( (specs->modedb[i].xres == mode->xres) && (specs->modedb[i].yres > mode->yres) )
275                                 mode = &specs->modedb[i];
276                 }
277
278                 // For some monitor, the max pixclock read from EDID is smaller
279                 // than the clock of max resolution mode supported. We fix it.
280                 pixclock = PICOS2KHZ(mode->pixclock);
281                 pixclock /= 250;
282                 pixclock *= 250;
283                 pixclock *= 1000;
284                 if(pixclock == 148250000)
285                         pixclock = 148500000;
286                 if(pixclock > specs->dclkmax)
287                         specs->dclkmax = pixclock;
288
289                 printk("scaler-ddc: max mode %dx%d@%d[pixclock-%ld KHZ]\n", mode->xres, mode->yres,
290                                 mode->refresh, PICOS2KHZ(mode->pixclock));
291         }
292         
293         return mode;
294 }
295
296 static struct fb_videomode *scaler_find_best_mode(void)
297 {
298         int res = -1;
299         struct fb_videomode *mode = NULL, *best = NULL;
300
301         res = scaler_parse_vga_edid();
302         if (res == 0) {
303                 mode = scaler_find_max_mode();
304                 if (mode) {
305                          scaler_check_mode(mode);
306                          best = (struct fb_videomode *)fb_find_nearest_mode(mode, &ddev->modelist);
307                 }
308         } else {
309                 printk("scaler-ddc: read and parse edid failed errno:%d.\n", res);
310         }
311
312         return best;
313 }
314
315 int scaler_switch_screen(struct fb_videomode *mode)
316 {
317         struct rk29fb_screen screen;
318
319         if (mode) {
320                 scaler_mode2screen(mode, &screen);
321 #ifdef CONFIG_ARCH_RK29
322                 return FB_Switch_Screen(&screen, 1);
323 #else
324                 return rk_fb_switch_screen(&screen, 1, 0);
325 #endif
326         }
327         printk("scaler-ddc:  fb_videomode is null\n");
328         return -1;
329 }
330
331 int scaler_switch_default_screen(void)
332 {
333         int res;
334         struct fb_videomode *mode = NULL;
335         
336         if (ddev == NULL) {
337                 printk("scaler-ddc: No DDC Dev.\n");
338                 return -ENODEV;
339         }
340
341         mode = scaler_find_best_mode();
342         if (mode) {
343                 printk("scaler-ddc: best mode %dx%d@%d[pixclock-%ld KHZ]\n", mode->xres, mode->yres,
344                                 mode->refresh, PICOS2KHZ(mode->pixclock));
345                 ddev->mode = mode;
346                 res = scaler_switch_screen(mode);
347         }else {
348                 res = -1;
349                 printk("scaler-ddc: Don't find best mode\n");
350         }
351
352         return res;
353 }
354 EXPORT_SYMBOL(scaler_switch_default_screen);
355
356 struct fb_videomode *scaler_get_cmode(void)
357 {
358         struct fb_videomode *mode = NULL;
359         if (ddev != NULL)
360                 mode = ddev->mode;
361         return mode;
362 }
363 EXPORT_SYMBOL(scaler_get_cmode);
364
365
366 static int scaler_ddc_probe(struct i2c_client *client,const struct i2c_device_id *id)
367 {    
368
369         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
370                 return -ENODEV;
371
372         ddev = kzalloc(sizeof(struct scaler_ddc_dev), GFP_KERNEL);
373         if (ddev == NULL) 
374                 return -ENOMEM;
375         
376     INIT_LIST_HEAD(&ddev->modelist);
377         ddev->client = client;
378         ddev->mode = &default_modedb[DEFAULT_MODE];
379         scaler_set_default_modelist();
380
381         printk("%s:      success.\n", __func__);
382
383         return 0;
384 }
385
386 static int __devexit scaler_ddc_remove(struct i2c_client *client)
387 {
388         if(ddev->edid)
389                 kfree(ddev->edid);
390         if (ddev->specs.modedb)
391                 kfree(ddev->specs.modedb);
392         kfree(ddev);
393         return 0;
394 }
395
396 static const struct i2c_device_id scaler_ddc_id[] = {
397         { "scaler_ddc", 0 },
398         { }
399 };
400
401 static struct i2c_driver scaler_ddc_driver  = {
402     .driver = {
403         .name  = "scaler_ddc",
404         .owner = THIS_MODULE,
405     },
406     .probe     = scaler_ddc_probe,
407     .remove    = scaler_ddc_remove,
408     .id_table  = scaler_ddc_id,
409 };
410
411 static int __init scaler_ddc_init(void)
412 {
413     return i2c_add_driver(&scaler_ddc_driver);
414 }
415
416 static void __exit scaler_ddc_exit(void)
417 {
418     i2c_del_driver(&scaler_ddc_driver);
419 }
420
421 subsys_initcall(scaler_ddc_init);
422 module_exit(scaler_ddc_exit);
423
424
425 /************SYSFS  DEBUG  ***********/
426 void scaler_ddc_is_ok(void)
427 {
428         int rc = -1;
429         char buf[8];
430         if (ddev != NULL) {
431                 rc = i2c_master_reg8_recv(ddev->client, 0, buf, 8, DDC_I2C_RATE);
432                 if(rc == 8) {
433                         if (buf[0] == 0x00 && buf[1] == 0xff && buf[2] == 0xff && buf[3] == 0xff &&
434                                         buf[4] == 0xff && buf[5] == 0xff && buf[6] == 0xff && buf[7] == 0x00)
435                                 printk("scaler-ddc:  is ok\n");
436                         else
437                                 printk("scaler-ddc: io error");
438                 }else
439                         printk("scaler-ddc: i2c  error\n");
440         }else
441                 printk("scaler-ddc:  unknown error\n");
442 }
443
444 void scaler_current_mode(void)
445 {
446         if (ddev != NULL && ddev->mode != NULL) 
447                 printk("scaler-ddc: cmode %dx%d@%d\n", ddev->mode->xres, ddev->mode->yres,
448                                 ddev->mode->refresh);
449         else
450                 printk("scaler-ddc: unknown mode\n");
451 }
452
453 void scaler_test_read_vga_edid(void)
454 {
455         int i = 0, res;
456         struct fb_monspecs *specs = NULL;
457
458         res = scaler_parse_vga_edid();
459         if (res == 0) {
460                 specs = &ddev->specs;
461
462                 printk("========================================\n");
463                 printk("Display Information (EDID)\n");
464                 printk("========================================\n");
465                 printk("   EDID Version %d.%d\n", (int) specs->version, (int) specs->revision);
466                 printk("   Serial Number: %s\n", specs->serial_no);
467                 printk("   ASCII Block: %s\n", specs->ascii);
468                 printk("   Monitor Name: %s\n", specs->monitor);
469                 printk("   Display Characteristics:\n");
470                 for (i = 0; i < specs->modedb_len; i++)
471                         printk("       %4d x %4d @%d [clk: %ldKHZ]\n", specs->modedb[i].xres, specs->modedb[i].yres,
472                                                         specs->modedb[i].refresh, PICOS2KHZ(specs->modedb[i].pixclock));
473                 printk("========================================\n");
474
475         }else{
476                 printk("scaler-ddc: read and parse failed errno %d\n", res);
477         }
478 }