hdmi: rk616:
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rk_hdmi_lcdc.c
1 #include <linux/console.h>
2 #include<linux/rk_fb.h>
3 #include "rk_hdmi.h"
4
5 #define OUT_TYPE                SCREEN_HDMI
6 #define OUT_FACE                OUT_P888
7 #define DCLK_POL                1
8 #define SWAP_RB                 0
9 #define LCD_ACLK                800000000
10
11 static const struct fb_videomode hdmi_mode [] = {
12         //name                  refresh         xres    yres    pixclock                h_bp    h_fp    v_bp    v_fp    h_pw    v_pw    polariry        PorI    flag(used for vic)
13 //{     "640x480p@60Hz",                60,             640,    480,    25175000,       48,     16,     33,     10,     96,     2,      0,      0,      1       },
14 //{     "720x480i@60Hz",                60,             720,    480,    27000000,       114,    38,     15,     4,      124,    3,      0,      1,      6       },
15 //{     "720x576i@50Hz",                50,             720,    576,    27000000,       138,    24,     19,     2,      126,    3,      0,      1,      21      },
16 {       "720x480p@60Hz",        60,             720,    480,    27000000,       60,     16,     30,     9,      62,     6,      0,      0,      2       },
17 {       "720x576p@50Hz",        50,             720,    576,    27000000,       68,     12,     39,     5,      64,     5,      0,      0,      17      },
18 //{     "1280x720p@24Hz",       24,             1280,   720,    59400000,       220,    1760,   20,     5,      40,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              60      },
19 //{     "1280x720p@25Hz",       25,             1280,   720,    74250000,       220,    2420,   20,     5,      40,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              61      },
20 //{     "1280x720p@30Hz",       30,             1280,   720,    74250000,       220,    1760,   20,     5,      40,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              62      },
21 {       "1280x720p@50Hz",       50,             1280,   720,    74250000,       220,    440,    20,     5,      40,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              19      },
22 {       "1280x720p@60Hz",       60,             1280,   720,    74250000,       220,    110,    20,     5,      40,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              4       },
23 //{     "1920x1080p@24Hz",      24,             1920,   1080,   74250000,       148,    638,    36,     4,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              32      },
24 //{     "1920x1080p@25Hz",      25,             1920,   1080,   74250000,       148,    528,    36,     4,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              33      },
25 //{     "1920x1080p@30Hz",      30,             1920,   1080,   74250000,       148,    88,     36,     4,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              34      },      
26 //{     "1920x1080i@50Hz_2",    50,             1920,   1080,   72000000,       184,    32,     57,     23,     168,    5,      FB_SYNC_HOR_HIGH_ACT,                   1,              39      },
27 //{     "1920x1080i@50Hz",      50,             1920,   1080,   74250000,       148,    528,    15,     2,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   1,              20      },
28 //{     "1920x1080i@60Hz",      60,             1920,   1080,   74250000,       148,    88,     15,     2,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   1,              5       },
29 {       "1920x1080p@50Hz",      50,             1920,   1080,   148500000,      148,    528,    36,     4,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              31      },
30 {       "1920x1080p@60Hz",      60,             1920,   1080,   148500000,      148,    88,     36,     4,      44,     5,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,                   0,              16      },
31 /*
32 {       "1440x288p@50Hz",       50,             720,    480,    27000000,       138,    24,     19,     2,      126,    3,              0,                      0,              23      },
33 {       "2880x576i@50Hz",       50,             1440,   240,    54000000,       276,    48,     19,     2,      252,    3,              0,                      1,              25      },
34 {       "2880x288p@50Hz",       50,             2880,   480,    54000000,       276,    48,     19,     3,      252,    3,              0,                      0,              27      },
35 {       "1440x576p@50Hz",       50,             2880,   480,    54000000,       136,    24,     39,     5,      128,    5,              0,                      0,              29      },
36 {       "2880x576p@50Hz",       50,             1920,   1080,   108000000,      272,    48,     39,     5,      256,    5,              0,                      0,              37      },
37 {       "1440x240p@60Hz",       60,             1440,   240,    27000000,       114,    38,     15,     4,      124,    3,              0,                      0,              8       },
38 {       "2880x480i@60Hz",       60,             2880,   480,    54000000,       228,    76,     15,     4,      248,    3,              0,                      1,              10      },
39 {       "2880x480p@60Hz",       60,             2880,   480,    54000000,       228,    76,     15,     4,      248,    3,              0,                      0,              12      },
40 {       "1440x480p@60Hz",       60,             1440,   480,    54000000,       120,    32,     30,     9,      124,    6,              0,                      0,              14      },
41 {       "2880x480p@60Hz",       60,             2880,   480,    54000000,       240,    64,     30,     9,      248,    6,              0,                      0,              35      },
42
43 {       "1920x1080i@100Hz",     100,            1920,   1080,   148500000,      148,    528,    15,     2,      44,     5,              1,                      1,              40      },
44 {       "1280x720p@100Hz",      100,            1280,   720,    148500000,      220,    440,    20,     5,      40,     5,              1,                      0,              41      },
45 {       "720x576p@100Hz",       100,            720,    576,    54000000,       68,             12,     39,     5,      64,             5,              0,                      0,              42      },
46 {       "1440x576i@100Hz",      100,            1440,   576,    54000000,       138,    24,     19,     2,      12,     3,              0,                      1,              44      },
47 {       "1920x1080p@100Hz",     100,            1920,   1080,   297000000,      148,    528,    36,     4,      44,     5,              1,                      0,              64      },
48
49 {       "1920x1080i@120Hz",     120,            1920,   1080,   148500000,      148,    88,     15,     2,      44,     5,              1,                      1,              46      },
50 {       "1280x720p@120Hz",      120,            1280,   720,    148500000,      220,    110,    20,     5,      40,     5,              1,                      0,              47      },
51 {       "720x480p@120Hz",       120,            720,    480,    54000000,       60,             16,     30,     9,      62,             6,              0,                      0,              48      },
52 {       "1440x480i@120Hz",      120,            1440,   480,    54000000,       114,    38,     15,     4,      12,     3,              0,                      1,              50      },
53 {       "1920x1080p@120Hz",     120,            1920,   1080,   297000000,      148,    88,     36,     4,      44,     5,              1,                      0,              63      },
54
55 {       "720x576p@200Hz",       200,            720,    576,    108000000,      68,     12,     39,     5,      64,     5,              0,                      0,              52      },
56 {       "1440x576i@200Hz",      200,            1920,   1080,   108000000,      138,    24,     19,     2,      12,     3,              0,                      1,              54      },
57
58 {       "720x480p@240Hz",       240,            720,    480,    108000000,      60,     16,     30,     9,      62,     6,              0,                      0,              56      },
59 {       "1440x480i@240Hz",      240,            1440,   480,    108000000,      114,    38,     15,     4,      12,     3,              0,                      1,              58      },
60 */
61
62 };
63
64 void hdmi_init_lcdc(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info)
65 {
66         hdmi_set_info(screen, HDMI_VIDEO_DEFAULT_MODE);
67 }
68
69 int hdmi_set_info(struct rk29fb_screen *screen, unsigned int vic)
70 {
71     int i;
72     
73     if(screen == NULL)
74         return -1;
75     
76     if(vic == 0)
77         vic = HDMI_VIDEO_DEFAULT_MODE;
78         
79     for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
80     {
81         if(hdmi_mode[i].flag == vic)
82                 break;
83     }
84     if(i == ARRAY_SIZE(hdmi_mode))
85         return -1;
86     
87     memset(screen, 0, sizeof(struct rk29fb_screen));
88     
89     /* screen type & face */
90     screen->type = OUT_TYPE;
91     screen->face = OUT_FACE;
92
93     /* Screen size */
94     screen->x_res = hdmi_mode[i].xres;
95     screen->y_res = hdmi_mode[i].yres;
96     
97     /* Timing */
98     screen->pixclock = hdmi_mode[i].pixclock;
99     screen->fps = hdmi_mode[i].refresh;
100         screen->lcdc_aclk = LCD_ACLK;
101         screen->left_margin = hdmi_mode[i].left_margin;
102         screen->right_margin = hdmi_mode[i].right_margin;
103         screen->hsync_len = hdmi_mode[i].hsync_len;
104         screen->upper_margin = hdmi_mode[i].upper_margin;
105         screen->lower_margin = hdmi_mode[i].lower_margin;
106         screen->vsync_len = hdmi_mode[i].vsync_len;
107         screen->hdmi_resolution = hdmi_mode[i].flag;
108
109         /* Pin polarity */
110 #ifdef CONFIG_HDMI_RK616
111         screen->pin_hsync = 0;
112         screen->pin_vsync = 0;
113 #else 
114         if(FB_SYNC_HOR_HIGH_ACT & hdmi_mode[i].sync)
115                 screen->pin_hsync = 1;
116         else
117                 screen->pin_hsync = 0;
118         if(FB_SYNC_VERT_HIGH_ACT & hdmi_mode[i].sync)
119                 screen->pin_vsync = 1;
120         else
121                 screen->pin_vsync = 0;
122 #endif
123         screen->pin_den = 0;
124         screen->pin_dclk = DCLK_POL;
125
126         /* Swap rule */
127     screen->swap_rb = SWAP_RB;
128     screen->swap_rg = 0;
129     screen->swap_gb = 0;
130     screen->swap_delta = 0;
131     screen->swap_dumy = 0;
132
133     /* Operation function*/
134     screen->init = NULL;
135     screen->standby = NULL;
136     
137     return 0;
138 }
139
140 static void hdmi_show_sink_info(struct hdmi *hdmi)
141 {
142         struct list_head *pos, *head = &hdmi->edid.modelist;
143         struct fb_modelist *modelist;
144         struct fb_videomode *m;
145         int i;
146         struct hdmi_audio *audio;
147
148         hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n");
149         hdmi_dbg(hdmi->dev, "Support video mode: \n");
150         list_for_each(pos, head) {
151                 modelist = list_entry(pos, struct fb_modelist, list);
152                 m = &modelist->mode;
153                 hdmi_dbg(hdmi->dev, "   %s.\n", m->name);
154         }
155         
156         for(i = 0; i < hdmi->edid.audio_num; i++)
157         {
158                 audio = &(hdmi->edid.audio[i]);
159                 switch(audio->type)
160                 {
161                         case HDMI_AUDIO_LPCM:
162                                 hdmi_dbg(hdmi->dev, "Support audio type: LPCM\n");
163                                 break;
164                         case HDMI_AUDIO_AC3:
165                                 hdmi_dbg(hdmi->dev, "Support audio type: AC3\n");
166                                 break;
167                         case HDMI_AUDIO_MPEG1:
168                                 hdmi_dbg(hdmi->dev, "Support audio type: MPEG1\n");
169                                 break;
170                         case HDMI_AUDIO_MP3:
171                                 hdmi_dbg(hdmi->dev, "Support audio type: MP3\n");
172                                 break;
173                         case HDMI_AUDIO_MPEG2:
174                                 hdmi_dbg(hdmi->dev, "Support audio type: MPEG2\n");
175                                 break;
176                         case HDMI_AUDIO_AAC_LC:
177                                 hdmi_dbg(hdmi->dev, "Support audio type: AAC\n");
178                                 break;
179                         case HDMI_AUDIO_DTS:
180                                 hdmi_dbg(hdmi->dev, "Support audio type: DTS\n");
181                                 break;
182                         case HDMI_AUDIO_ATARC:
183                                 hdmi_dbg(hdmi->dev, "Support audio type: ATARC\n");
184                                 break;
185                         case HDMI_AUDIO_DSD:
186                                 hdmi_dbg(hdmi->dev, "Support audio type: DSD\n");
187                                 break;
188                         case HDMI_AUDIO_E_AC3:
189                                 hdmi_dbg(hdmi->dev, "Support audio type: E-AC3\n");
190                                 break;
191                         case HDMI_AUDIO_DTS_HD:
192                                 hdmi_dbg(hdmi->dev, "Support audio type: DTS-HD\n");
193                                 break;
194                         case HDMI_AUDIO_MLP:
195                                 hdmi_dbg(hdmi->dev, "Support audio type: MLP\n");
196                                 break;
197                         case HDMI_AUDIO_DST:
198                                 hdmi_dbg(hdmi->dev, "Support audio type: DST\n");
199                                 break;
200                         case HDMI_AUDIO_WMA_PRO:
201                                 hdmi_dbg(hdmi->dev, "Support audio type: WMP-PRO\n");
202                                 break;
203                         default:
204                                 hdmi_dbg(hdmi->dev, "Support audio type: Unkown\n");
205                                 break;
206                 }
207                 
208                 hdmi_dbg(hdmi->dev, "Support audio sample rate: \n");
209                 if(audio->rate & HDMI_AUDIO_FS_32000)
210                         hdmi_dbg(hdmi->dev, "   32000\n");
211                 if(audio->rate & HDMI_AUDIO_FS_44100)
212                         hdmi_dbg(hdmi->dev, "   44100\n");
213                 if(audio->rate & HDMI_AUDIO_FS_48000)
214                         hdmi_dbg(hdmi->dev, "   48000\n");
215                 if(audio->rate & HDMI_AUDIO_FS_88200)
216                         hdmi_dbg(hdmi->dev, "   88200\n");
217                 if(audio->rate & HDMI_AUDIO_FS_96000)
218                         hdmi_dbg(hdmi->dev, "   96000\n");
219                 if(audio->rate & HDMI_AUDIO_FS_176400)
220                         hdmi_dbg(hdmi->dev, "   176400\n");
221                 if(audio->rate & HDMI_AUDIO_FS_192000)
222                         hdmi_dbg(hdmi->dev, "   192000\n");
223                 
224                 hdmi_dbg(hdmi->dev, "Support audio word lenght: \n");
225                 if(audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit)
226                         hdmi_dbg(hdmi->dev, "   16bit\n");
227                 if(audio->rate & HDMI_AUDIO_WORD_LENGTH_20bit)
228                         hdmi_dbg(hdmi->dev, "   20bit\n");
229                 if(audio->rate & HDMI_AUDIO_WORD_LENGTH_24bit)
230                         hdmi_dbg(hdmi->dev, "   24bit\n");
231         }
232         hdmi_dbg(hdmi->dev, "******** Show Sink Info ********\n");
233 }
234
235 /**
236  * hdmi_ouputmode_select - select hdmi transmitter output mode: hdmi or dvi?
237  * @hdmi: handle of hdmi
238  * @edid_ok: get EDID data success or not, HDMI_ERROR_SUCESS means success.
239  */
240 int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
241 {
242         struct list_head *head = &hdmi->edid.modelist;
243         struct fb_monspecs      *specs = hdmi->edid.specs;
244         struct fb_videomode *modedb = NULL;
245         int i, pixclock;
246         
247         if(edid_ok != HDMI_ERROR_SUCESS) {
248                 dev_err(hdmi->dev, "warning: EDID error, assume sink as HDMI !!!!");
249                 hdmi->edid.sink_hdmi = 1;
250         }
251
252         if(edid_ok != HDMI_ERROR_SUCESS) {
253                 hdmi->edid.ycbcr444 = 0;
254                 hdmi->edid.ycbcr422 = 0;
255                 hdmi->autoconfig = HDMI_DISABLE;
256         }
257         if(head->next == head) {
258                 dev_info(hdmi->dev, "warning: no CEA video mode parsed from EDID !!!!");
259                 // If EDID get error, list all system supported mode.
260                 // If output mode is set to DVI and EDID is ok, check
261                 // the output timing.
262                 
263                 if(hdmi->edid.sink_hdmi == 0 && specs && specs->modedb_len) {
264                         /* Get max resolution timing */
265                         modedb = &specs->modedb[0];
266                         for (i = 0; i < specs->modedb_len; i++) {
267                                 if(specs->modedb[i].xres > modedb->xres)
268                                         modedb = &specs->modedb[i];
269                                 else if(specs->modedb[i].yres > modedb->yres)
270                                         modedb = &specs->modedb[i];
271                         }
272                         // For some monitor, the max pixclock read from EDID is smaller
273                         // than the clock of max resolution mode supported. We fix it.
274                         pixclock = PICOS2KHZ(modedb->pixclock);
275                         pixclock /= 250;
276                         pixclock *= 250;
277                         pixclock *= 1000;
278                         if(pixclock == 148250000)
279                                 pixclock = 148500000;
280                         if(pixclock > specs->dclkmax)
281                                 specs->dclkmax = pixclock;
282                 }
283                 
284                 for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
285                         if(modedb) {
286                                 if( (hdmi_mode[i].pixclock < specs->dclkmin) || 
287                                         (hdmi_mode[i].pixclock > specs->dclkmax) || 
288                                         (hdmi_mode[i].refresh < specs->vfmin) ||
289                                         (hdmi_mode[i].refresh > specs->vfmax) ||
290                                         (hdmi_mode[i].xres > modedb->xres) ||
291                                         (hdmi_mode[i].yres > modedb->yres) )
292                                 continue;
293                         }
294                         hdmi_add_videomode(&hdmi_mode[i], head);
295                 }
296         }
297         
298         #ifdef HDMI_DEBUG
299         hdmi_show_sink_info(hdmi);
300         #endif
301         return HDMI_ERROR_SUCESS;
302 }
303 /**
304  * hdmi_videomode_compare - compare 2 videomodes
305  * @mode1: first videomode
306  * @mode2: second videomode
307  *
308  * RETURNS:
309  * 1 if mode1 > mode2, 0 if mode1 = mode2, -1 mode1 < mode2
310  */
311 static int hdmi_videomode_compare(const struct fb_videomode *mode1,
312                      const struct fb_videomode *mode2)
313 {
314         if(mode1->xres > mode2->xres)
315                 return 1;
316         else if(mode1->xres == mode2->xres)
317         { 
318                 if(mode1->yres > mode2->yres)
319                         return 1;
320                 else if(mode1->yres == mode2->yres)
321                 {
322                         if(mode1->pixclock > mode2->pixclock)   
323                                 return 1;
324                         else if(mode1->pixclock == mode2->pixclock)
325                         {       
326                                 if(mode1->refresh > mode2->refresh)
327                                         return 1;
328                                 else if(mode1->refresh == mode2->refresh) 
329                                         return 0;
330                         }
331                 }
332         }
333         return -1;              
334 }
335 /**
336  * hdmi_add_videomode: adds videomode entry to modelist
337  * @mode: videomode to add
338  * @head: struct list_head of modelist
339  *
340  * NOTES:
341  * Will only add unmatched mode entries
342  */
343 int hdmi_add_videomode(const struct fb_videomode *mode, struct list_head *head)
344 {
345         struct list_head *pos;
346         struct fb_modelist *modelist, *modelist_new;
347         struct fb_videomode *m;
348         int i, found = 0;
349
350         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
351     {
352         m =(struct fb_videomode*) &hdmi_mode[i];
353         if (fb_mode_is_equal(m, mode)) {
354                         found = 1;
355                         break;
356                 }
357     }
358
359         if (found) {
360                 list_for_each(pos, head) {
361                         modelist = list_entry(pos, struct fb_modelist, list);
362                         m = &modelist->mode;
363                         if (fb_mode_is_equal(m, mode)) {
364                         // m == mode    
365                                 return 0;
366                         }
367                         else
368                         { 
369                                 if(hdmi_videomode_compare(m, mode) == -1) {
370                                         break;
371                                 }
372                         }
373                 }
374
375                 modelist_new = kmalloc(sizeof(struct fb_modelist),
376                                   GFP_KERNEL);                                  
377                 if (!modelist_new)
378                         return -ENOMEM; 
379                 modelist_new->mode = hdmi_mode[i];
380                 list_add_tail(&modelist_new->list, pos);
381         }
382         
383         return 0;
384 }
385
386 /**
387  * hdmi_videomode_to_vic: transverse video mode to vic
388  * @vmode: videomode to transverse
389  * 
390  */
391 int hdmi_videomode_to_vic(struct fb_videomode *vmode)
392 {
393         unsigned char vic = 0;
394         int i = 0;
395         
396         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
397         {
398                 if(     vmode->vmode == hdmi_mode[i].vmode &&
399                         vmode->refresh == hdmi_mode[i].refresh &&
400                         vmode->xres == hdmi_mode[i].xres && 
401                         vmode->left_margin == hdmi_mode[i].left_margin &&
402                         vmode->right_margin == hdmi_mode[i].right_margin &&
403                         vmode->upper_margin == hdmi_mode[i].upper_margin &&
404                         vmode->lower_margin == hdmi_mode[i].lower_margin && 
405                         vmode->hsync_len == hdmi_mode[i].hsync_len && 
406                         vmode->vsync_len == hdmi_mode[i].vsync_len)
407                 {
408                         if( (vmode->vmode == FB_VMODE_NONINTERLACED && vmode->yres == hdmi_mode[i].yres) || 
409                                 (vmode->vmode == FB_VMODE_INTERLACED && vmode->yres == hdmi_mode[i].yres/2))
410                         {                                                               
411                                 vic = hdmi_mode[i].flag;
412                                 break;
413                         }
414                 }
415         }
416         return vic;
417 }
418
419 /**
420  * hdmi_vic_to_videomode: transverse vic mode to video mode
421  * @vmode: vic to transverse
422  * 
423  */
424 const struct fb_videomode* hdmi_vic_to_videomode(int vic)
425 {
426         int i;
427         
428         if(vic == 0)
429                 return NULL;
430         
431         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
432         {
433                 if(hdmi_mode[i].flag == vic)
434                         return &hdmi_mode[i];
435         }
436         return NULL;
437 }
438
439 /**
440  * hdmi_find_best_mode: find the video mode nearest to input vic
441  * @hdmi: 
442  * @vic: input vic
443  * 
444  * NOTES:
445  * If vic is zero, return the high resolution video mode vic.
446  */
447 int hdmi_find_best_mode(struct hdmi* hdmi, int vic)
448 {
449         struct list_head *pos, *head = &hdmi->edid.modelist;
450         struct fb_modelist *modelist;
451         struct fb_videomode *m = NULL;
452         int found = 0;
453         
454         if(vic)
455         {
456                 list_for_each(pos, head) {
457                         modelist = list_entry(pos, struct fb_modelist, list);
458                         m = &modelist->mode;
459                         if(m->flag == vic)
460                         {
461                                 found = 1;      
462                                 break;
463                         }
464                 }
465         }
466         if( (vic == 0 || found == 0) && head->next != head)
467         {
468                 modelist = list_entry(head->next, struct fb_modelist, list);
469                 m = &modelist->mode;
470         }
471         if(m != NULL)
472                 return m->flag;
473         else
474                 return 0;
475 }
476
477 const char *hdmi_get_video_mode_name(unsigned char vic)
478 {
479         int i;
480         
481         for(i = 0; i < ARRAY_SIZE(hdmi_mode); i++)
482         {
483                 if(vic == hdmi_mode[i].flag)
484                         break;
485         }
486         if(i == ARRAY_SIZE(hdmi_mode))
487                 return NULL;
488         else
489                 return hdmi_mode[i].name;
490 }
491
492 /**
493  * hdmi_switch_fb: switch lcdc mode to required video mode
494  * @hdmi: 
495  * @type:
496  * 
497  * NOTES:
498  * 
499  */
500 int hdmi_switch_fb(struct hdmi *hdmi, int vic)
501 {
502         int rc = 0;
503         rk_screen *screen;
504         
505         
506         screen =  kzalloc(sizeof(struct rk29fb_screen), GFP_KERNEL);
507         if(screen == NULL)
508                 return -1;
509         
510         if(hdmi->vic == 0)
511                 hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
512                 
513
514         rc = hdmi_set_info(screen, hdmi->vic);
515
516         if(rc == 0) {
517                 if(hdmi->set_vif)
518                         hdmi->set_vif(screen,0); //turn off vif for jettab
519                 rk_fb_switch_screen(screen, 1, hdmi->lcdc->id);
520                 rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id);
521                 if(hdmi->set_vif)
522                         hdmi->set_vif(screen,1);
523
524         }
525         
526         kfree(screen);
527         
528         return rc;
529 }
530
531 /**
532  * hdmi_get_status: get hdmi hotplug status
533  * 
534  * NOTES:
535  * 
536  */
537 int hdmi_get_hotplug(void)
538 {
539         if(hdmi)
540                 return hdmi->hotplug;
541         else
542                 return HDMI_HPD_REMOVED;
543 }