1844372c25145872336d38af170058e11965846d
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmi-core.c
1 #include <linux/delay.h>
2 #include "rockchip-hdmi.h"
3 #include "rockchip-hdmi-cec.h"
4
5 struct hdmi_delayed_work {
6         struct delayed_work work;
7         struct hdmi *hdmi;
8         int event;
9         void *data;
10 };
11
12 struct hdmi_id_ref_info {
13         struct hdmi *hdmi;
14         int id;
15         int ref;
16 } ref_info[HDMI_MAX_ID];
17
18 static int uboot_vic;
19 static void hdmi_work_queue(struct work_struct *work);
20
21 struct delayed_work *hdmi_submit_work(struct hdmi *hdmi,
22                                       int event, int delay, void *data)
23 {
24         struct hdmi_delayed_work *work;
25
26         DBG("%s event %04x delay %d", __func__, event, delay);
27
28         work = kmalloc(sizeof(*work), GFP_ATOMIC);
29
30         if (work) {
31                 INIT_DELAYED_WORK(&work->work, hdmi_work_queue);
32                 work->hdmi = hdmi;
33                 work->event = event;
34                 work->data = data;
35                 queue_delayed_work(hdmi->workqueue,
36                                    &work->work,
37                                    msecs_to_jiffies(delay));
38         } else {
39                 pr_warn("HDMI: Cannot allocate memory to create work\n");
40                 return 0;
41         }
42
43         return &work->work;
44 }
45
46 static void hdmi_send_uevent(struct hdmi *hdmi, int uevent)
47 {
48         char *envp[3];
49
50         envp[0] = "INTERFACE=HDMI";
51         envp[1] = kmalloc(32, GFP_KERNEL);
52         if (envp[1] == NULL)
53                 return;
54         sprintf(envp[1], "SCREEN=%d", hdmi->ddev->property);
55         envp[2] = NULL;
56         kobject_uevent_env(&hdmi->ddev->dev->kobj, uevent, envp);
57         kfree(envp[1]);
58 }
59
60 static inline void hdmi_wq_set_output(struct hdmi *hdmi, int mute)
61 {
62         DBG("%s mute %d", __func__, mute);
63         if (hdmi->ops->setmute)
64                 hdmi->ops->setmute(hdmi, mute);
65 }
66
67 static inline void hdmi_wq_set_audio(struct hdmi *hdmi)
68 {
69         DBG("%s", __func__);
70         if (hdmi->ops->setaudio)
71                 hdmi->ops->setaudio(hdmi, &hdmi->audio);
72 }
73
74 static void hdmi_wq_set_video(struct hdmi *hdmi)
75 {
76         struct hdmi_video       video;
77         int     deepcolor;
78
79         DBG("%s", __func__);
80
81         video.vic = hdmi->vic & HDMI_VIC_MASK;
82         video.sink_hdmi = hdmi->edid.sink_hdmi;
83         video.format_3d = hdmi->mode_3d;
84
85         /* For DVI, output RGB */
86         if (hdmi->edid.sink_hdmi == 0) {
87                 video.color_output = HDMI_COLOR_RGB_0_255;
88         } else {
89                 if (hdmi->colormode == HDMI_COLOR_AUTO) {
90                         if (hdmi->edid.ycbcr444)
91                                 video.color_output = HDMI_COLOR_YCBCR444;
92                         else if (hdmi->edid.ycbcr422)
93                                 video.color_output = HDMI_COLOR_YCBCR422;
94                         else
95                                 video.color_output = HDMI_COLOR_RGB_16_235;
96                 } else {
97                         video.color_output = hdmi->colormode;
98                 }
99         }
100         if (hdmi->vic & HDMI_VIDEO_YUV420) {
101                 video.color_output = HDMI_COLOR_YCBCR420;
102                 deepcolor = hdmi->edid.deepcolor_420;
103         } else {
104                 deepcolor = hdmi->edid.deepcolor;
105         }
106         if ((hdmi->property->feature & SUPPORT_DEEP_10BIT) &&
107             (deepcolor & HDMI_DEEP_COLOR_30BITS)) {
108                 if (hdmi->colordepth == HDMI_DEPP_COLOR_AUTO ||
109                     hdmi->colordepth == 10)
110                         video.color_output_depth = 10;
111         } else {
112                 video.color_output_depth = 8;
113         }
114
115         pr_info("hdmi output corlor mode is %d\n", video.color_output);
116         video.color_input = HDMI_COLOR_RGB_0_255;
117         if (hdmi->property->feature & SUPPORT_YCBCR_INPUT) {
118                 if (video.color_output == HDMI_COLOR_YCBCR444 ||
119                     video.color_output == HDMI_COLOR_YCBCR422)
120                         video.color_input = HDMI_COLOR_YCBCR444;
121                 else if (video.color_output == HDMI_COLOR_YCBCR420)
122                         video.color_input = HDMI_COLOR_YCBCR420;
123         }
124         hdmi->colormode_input = video.color_input;
125         hdmi_set_lcdc(hdmi);
126         if (hdmi->ops->setvideo)
127                 hdmi->ops->setvideo(hdmi, &video);
128 }
129
130 static void hdmi_wq_parse_edid(struct hdmi *hdmi)
131 {
132         struct hdmi_edid *pedid;
133
134         int rc = HDMI_ERROR_SUCESS, extendblock = 0, i, trytimes;
135
136         if (hdmi == NULL)
137                 return;
138
139         DBG("%s", __func__);
140
141         pedid = &(hdmi->edid);
142         fb_destroy_modelist(&pedid->modelist);
143         memset(pedid, 0, sizeof(struct hdmi_edid));
144         INIT_LIST_HEAD(&pedid->modelist);
145
146         pedid->raw[0] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
147         if (pedid->raw[0] == NULL) {
148                 dev_err(hdmi->dev,
149                         "[%s] can not allocate memory for edid buff.\n",
150                         __func__);
151                 rc = HDMI_ERROR_FALSE;
152                 goto out;
153         }
154
155         if (hdmi->ops->getedid == NULL) {
156                 rc = HDMI_ERROR_FALSE;
157                 goto out;
158         }
159
160         /* Read base block edid.*/
161         for (trytimes = 0; trytimes < 3; trytimes++) {
162                 if (trytimes)
163                         msleep(50);
164                 memset(pedid->raw[0], 0 , HDMI_EDID_BLOCK_SIZE);
165                 rc = hdmi->ops->getedid(hdmi, 0, pedid->raw[0]);
166                 if (rc) {
167                         dev_err(hdmi->dev,
168                                 "[HDMI] read edid base block error\n");
169                         continue;
170                 }
171
172                 rc = hdmi_edid_parse_base(pedid->raw[0], &extendblock, pedid);
173                 if (rc) {
174                         dev_err(hdmi->dev,
175                                 "[HDMI] parse edid base block error\n");
176                         continue;
177                 }
178                 if (!rc)
179                         break;
180         }
181         if (rc)
182                 goto out;
183
184         for (i = 1; (i < extendblock + 1) && (i < HDMI_MAX_EDID_BLOCK); i++) {
185                 pedid->raw[i] = kmalloc(HDMI_EDID_BLOCK_SIZE, GFP_KERNEL);
186                 if (pedid->raw[i] == NULL) {
187                         dev_err(hdmi->dev,
188                                 "[%s] can not allocate memory for edid buff.\n",
189                                 __func__);
190                         rc = HDMI_ERROR_FALSE;
191                         goto out;
192                 }
193                 for (trytimes = 0; trytimes < 3; trytimes++) {
194                         if (trytimes)
195                                 msleep(20);
196                         memset(pedid->raw[i], 0 , HDMI_EDID_BLOCK_SIZE);
197                         rc = hdmi->ops->getedid(hdmi, i, pedid->raw[i]);
198                         if (rc) {
199                                 dev_err(hdmi->dev,
200                                         "[HDMI] read edid block %d error\n",
201                                         i);
202                                 continue;
203                         }
204
205                         rc = hdmi_edid_parse_extensions(pedid->raw[i], pedid);
206                         if (rc) {
207                                 dev_err(hdmi->dev,
208                                         "[HDMI] parse edid block %d error\n",
209                                         i);
210                                 continue;
211                         }
212
213                         if (!rc)
214                                 break;
215                 }
216         }
217 out:
218         rc = hdmi_ouputmode_select(hdmi, rc);
219 }
220
221 static void hdmi_wq_insert(struct hdmi *hdmi)
222 {
223         DBG("%s", __func__);
224         if (hdmi->ops->insert)
225                 hdmi->ops->insert(hdmi);
226         hdmi_wq_parse_edid(hdmi);
227         if (hdmi->property->feature & SUPPORT_CEC)
228                 rockchip_hdmi_cec_set_pa(hdmi->edid.cecaddress);
229         hdmi_send_uevent(hdmi, KOBJ_ADD);
230         if (hdmi->enable) {
231                 /*hdmi->autoset = 0;*/
232                 hdmi_wq_set_video(hdmi);
233                 #ifdef CONFIG_SWITCH
234                 switch_set_state(&(hdmi->switchdev), 1);
235                 #endif
236                 hdmi_wq_set_audio(hdmi);
237                 hdmi_wq_set_output(hdmi, hdmi->mute);
238                 hdmi_submit_work(hdmi, HDMI_ENABLE_HDCP, 100, NULL);
239                 if (hdmi->ops->setcec)
240                         hdmi->ops->setcec(hdmi);
241         }
242         if (hdmi->uboot)
243                 hdmi->uboot = 0;
244 }
245
246 static void hdmi_wq_remove(struct hdmi *hdmi)
247 {
248         struct list_head *pos, *n;
249         struct rk_screen screen;
250         int i;
251
252         DBG("%s", __func__);
253         if (hdmi->ops->remove)
254                 hdmi->ops->remove(hdmi);
255         if (hdmi->hotplug == HDMI_HPD_ACTIVED) {
256                 screen.type = SCREEN_HDMI;
257                 rk_fb_switch_screen(&screen, 0, hdmi->lcdc->id);
258         }
259         #ifdef CONFIG_SWITCH
260         switch_set_state(&(hdmi->switchdev), 0);
261         #endif
262         mutex_lock(&hdmi->ddev->lock);
263         list_for_each_safe(pos, n, &hdmi->edid.modelist) {
264                 list_del(pos);
265                 kfree(pos);
266         }
267         mutex_unlock(&hdmi->ddev->lock);
268         for (i = 0; i < HDMI_MAX_EDID_BLOCK; i++)
269                 kfree(hdmi->edid.raw[i]);
270         kfree(hdmi->edid.audio);
271         if (hdmi->edid.specs) {
272                 kfree(hdmi->edid.specs->modedb);
273                 kfree(hdmi->edid.specs);
274         }
275         memset(&hdmi->edid, 0, sizeof(struct hdmi_edid));
276         hdmi_init_modelist(hdmi);
277         hdmi->mute      = HDMI_AV_UNMUTE;
278         hdmi->mode_3d = HDMI_3D_NONE;
279         hdmi->uboot = 0;
280         hdmi->hotplug = HDMI_HPD_REMOVED;
281         hdmi_send_uevent(hdmi, KOBJ_REMOVE);
282 }
283
284 static void hdmi_work_queue(struct work_struct *work)
285 {
286         struct hdmi_delayed_work *hdmi_w =
287                 container_of(work, struct hdmi_delayed_work, work.work);
288         struct hdmi *hdmi = hdmi_w->hdmi;
289         int event = hdmi_w->event;
290         int hpd = HDMI_HPD_REMOVED;
291
292         mutex_lock(&hdmi->lock);
293
294         DBG("\nhdmi_work_queue() - evt= %x %d\n",
295             (event & 0xFF00) >> 8,
296             event & 0xFF);
297
298         switch (event) {
299         case HDMI_ENABLE_CTL:
300                 if (!hdmi->enable) {
301                         hdmi->enable = 1;
302                         if (!hdmi->sleep) {
303                                 if (hdmi->ops->enable)
304                                         hdmi->ops->enable(hdmi);
305                                 if (hdmi->hotplug == HDMI_HPD_ACTIVED)
306                                         hdmi_wq_insert(hdmi);
307                         }
308                 }
309                 break;
310         case HDMI_RESUME_CTL:
311                 if (hdmi->sleep) {
312                         if (hdmi->ops->enable)
313                                 hdmi->ops->enable(hdmi);
314                         hdmi->sleep = 0;
315                 }
316                 break;
317         case HDMI_DISABLE_CTL:
318                 if (hdmi->enable) {
319                         if (!hdmi->sleep) {
320                                 if (hdmi->ops->disable)
321                                         hdmi->ops->disable(hdmi);
322                                 hdmi_wq_remove(hdmi);
323                         }
324                         hdmi->enable = 0;
325                 }
326                 break;
327         case HDMI_SUSPEND_CTL:
328                 if (!hdmi->sleep) {
329                         hdmi_wq_set_output(hdmi,
330                                            HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE);
331                         if (hdmi->ops->disable)
332                                 hdmi->ops->disable(hdmi);
333                         if (hdmi->enable)
334                                 hdmi_wq_remove(hdmi);
335                         hdmi->sleep = 1;
336                 }
337                 break;
338         case HDMI_HPD_CHANGE:
339                 if (hdmi->ops->getstatus)
340                         hpd = hdmi->ops->getstatus(hdmi);
341                 DBG("hdmi_work_queue() - hpd is %d hotplug is %d",
342                     hpd, hdmi->hotplug);
343                 if (hpd != hdmi->hotplug) {
344                         if (hpd == HDMI_HPD_ACTIVED) {
345                                 hdmi->hotplug = hpd;
346                                 hdmi_wq_insert(hdmi);
347                         } else if (hdmi->hotplug == HDMI_HPD_ACTIVED) {
348                                 hdmi_wq_remove(hdmi);
349                         }
350                         hdmi->hotplug = hpd;
351                 }
352                 break;
353         case HDMI_SET_VIDEO:
354                 if (hdmi->enable && !hdmi->sleep) {
355                         hdmi_wq_set_output(hdmi,
356                                            HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE);
357                         if (rk_fb_get_display_policy() == DISPLAY_POLICY_BOX)
358                                 msleep(2000);
359                         else
360                                 msleep(1000);
361                         hdmi_wq_set_video(hdmi);
362                         hdmi_send_uevent(hdmi, KOBJ_CHANGE);
363                         hdmi_wq_set_audio(hdmi);
364                         hdmi_wq_set_output(hdmi, hdmi->mute);
365                         if (hdmi->ops->hdcp_cb)
366                                 hdmi->ops->hdcp_cb(hdmi);
367                 }
368                 break;
369         case HDMI_SET_AUDIO:
370                 if ((hdmi->mute & HDMI_AUDIO_MUTE) == 0 &&
371                     hdmi->enable && !hdmi->sleep) {
372                         hdmi_wq_set_output(hdmi, HDMI_AUDIO_MUTE);
373                         hdmi_wq_set_audio(hdmi);
374                         hdmi_wq_set_output(hdmi, hdmi->mute);
375                 }
376                 break;
377         case HDMI_MUTE_AUDIO:
378         case HDMI_UNMUTE_AUDIO:
379                 if (hdmi->mute & HDMI_AUDIO_MUTE ||
380                     !hdmi->enable || hdmi->sleep ||
381                     hdmi->hotplug != HDMI_HPD_ACTIVED)
382                         break;
383                 if (event == HDMI_MUTE_AUDIO)
384                         hdmi_wq_set_output(hdmi, hdmi->mute |
385                                            HDMI_AUDIO_MUTE);
386                 else
387                         hdmi_wq_set_output(hdmi,
388                                            hdmi->mute & (~HDMI_AUDIO_MUTE));
389                 break;
390         case HDMI_SET_3D:
391                 if (hdmi->ops->setvsi) {
392                         if (hdmi->mode_3d != HDMI_3D_NONE)
393                                 hdmi->ops->setvsi(hdmi, hdmi->mode_3d,
394                                                   HDMI_VIDEO_FORMAT_3D);
395                         else if ((hdmi->vic & HDMI_TYPE_MASK) == 0)
396                                 hdmi->ops->setvsi(hdmi, hdmi->vic,
397                                                   HDMI_VIDEO_FORMAT_NORMAL);
398                 }
399                 break;
400         case HDMI_SET_COLOR:
401                 hdmi_wq_set_output(hdmi,
402                                    HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE);
403                 msleep(100);
404                 hdmi_wq_set_video(hdmi);
405                 hdmi_wq_set_output(hdmi, hdmi->mute);
406                 break;
407         case HDMI_ENABLE_HDCP:
408                 if (hdmi->hotplug == HDMI_HPD_ACTIVED && hdmi->ops->hdcp_cb)
409                         hdmi->ops->hdcp_cb(hdmi);
410                 break;
411         case HDMI_HDCP_AUTH_2ND:
412                 if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
413                     hdmi->ops->hdcp_auth2nd)
414                         hdmi->ops->hdcp_auth2nd(hdmi);
415                 break;
416         default:
417                 pr_err("HDMI: hdmi_work_queue() unkown event\n");
418                 break;
419         }
420
421         kfree(hdmi_w->data);
422         kfree(hdmi_w);
423
424         DBG("\nhdmi_work_queue() - exit evt= %x %d\n",
425             (event & 0xFF00) >> 8,
426             event & 0xFF);
427         mutex_unlock(&hdmi->lock);
428 }
429
430 struct hdmi *rockchip_hdmi_register(struct hdmi_property *property,
431                                     struct hdmi_ops *ops)
432 {
433         struct hdmi *hdmi;
434         char name[32];
435         int i;
436
437         if (property == NULL || ops == NULL) {
438                 pr_err("HDMI: %s invalid parameter\n", __func__);
439                 return NULL;
440         }
441
442         for (i = 0; i < HDMI_MAX_ID; i++) {
443                 if (ref_info[i].ref == 0)
444                         break;
445         }
446         if (i == HDMI_MAX_ID)
447                 return NULL;
448
449         DBG("hdmi_register() - video source %d display %d",
450             property->videosrc,  property->display);
451
452         hdmi = kmalloc(sizeof(*hdmi), GFP_KERNEL);
453         if (!hdmi) {
454                 pr_err("HDMI: no memory to allocate hdmi device.\n");
455                 return NULL;
456         }
457         memset(hdmi, 0, sizeof(struct hdmi));
458         mutex_init(&hdmi->lock);
459
460         hdmi->property = property;
461         hdmi->ops = ops;
462         hdmi->enable = false;
463         hdmi->mute = HDMI_AV_UNMUTE;
464         hdmi->hotplug = HDMI_HPD_REMOVED;
465         hdmi->autoset = HDMI_AUTO_CONFIG;
466         if (uboot_vic > 0) {
467                 hdmi->vic = uboot_vic;
468                 hdmi->uboot = 1;
469                 hdmi->autoset = 0;
470         } else if (hdmi->autoset) {
471                 hdmi->vic = 0;
472         } else {
473                 hdmi->vic = hdmi->property->defaultmode;
474         }
475         hdmi->colormode = HDMI_VIDEO_DEFAULT_COLORMODE;
476         hdmi->colordepth = HDMI_DEPP_COLOR_AUTO;
477         hdmi->mode_3d = HDMI_3D_NONE;
478         hdmi->audio.type = HDMI_AUDIO_DEFAULT_TYPE;
479         hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL;
480         hdmi->audio.rate = HDMI_AUDIO_DEFAULT_RATE;
481         hdmi->audio.word_length = HDMI_AUDIO_DEFAULT_WORDLENGTH;
482         hdmi->xscale = 100;
483         hdmi->yscale = 100;
484         hdmi_init_modelist(hdmi);
485
486         if (hdmi->property->videosrc == DISPLAY_SOURCE_LCDC0)
487                 hdmi->lcdc = rk_get_lcdc_drv("lcdc0");
488         else
489                 hdmi->lcdc = rk_get_lcdc_drv("lcdc1");
490
491         if (hdmi->lcdc->prop == EXTEND)
492                 hdmi->property->display = DISPLAY_AUX;
493         else
494                 hdmi->property->display = DISPLAY_MAIN;
495         memset(name, 0, 32);
496         sprintf(name, "hdmi-%s", hdmi->property->name);
497         hdmi->workqueue = create_singlethread_workqueue(name);
498         if (hdmi->workqueue == NULL) {
499                 pr_err("HDMI,: create workqueue failed.\n");
500                 goto err_create_wq;
501         }
502         hdmi->ddev = hdmi_register_display_sysfs(hdmi, NULL);
503         if (hdmi->ddev == NULL) {
504                 pr_err("HDMI : register display sysfs failed.\n");
505                 goto err_register_display;
506         }
507         hdmi->id = i;
508         #ifdef CONFIG_SWITCH
509         if (hdmi->id == 0) {
510                 hdmi->switchdev.name = "hdmi";
511         } else {
512                 hdmi->switchdev.name = kzalloc(32, GFP_KERNEL);
513                 memset((char *)hdmi->switchdev.name, 0, 32);
514                 sprintf((char *)hdmi->switchdev.name, "hdmi%d", hdmi->id);
515         }
516         switch_dev_register(&(hdmi->switchdev));
517         #endif
518
519         ref_info[i].hdmi = hdmi;
520         ref_info[i].ref = 1;
521         return hdmi;
522
523 err_register_display:
524         destroy_workqueue(hdmi->workqueue);
525 err_create_wq:
526         kfree(hdmi);
527         return NULL;
528 }
529
530 void rockchip_hdmi_unregister(struct hdmi *hdmi)
531 {
532         if (hdmi) {
533                 flush_workqueue(hdmi->workqueue);
534                 destroy_workqueue(hdmi->workqueue);
535                 #ifdef CONFIG_SWITCH
536                 switch_dev_unregister(&(hdmi->switchdev));
537                 #endif
538                 hdmi_unregister_display_sysfs(hdmi);
539                 fb_destroy_modelist(&hdmi->edid.modelist);
540                 kfree(hdmi->edid.audio);
541                 if (hdmi->edid.specs) {
542                         kfree(hdmi->edid.specs->modedb);
543                         kfree(hdmi->edid.specs);
544                 }
545                 kfree(hdmi);
546
547                 ref_info[hdmi->id].ref = 0;
548                 ref_info[hdmi->id].hdmi = NULL;
549
550                 hdmi = NULL;
551         }
552 }
553
554 int hdmi_get_hotplug(void)
555 {
556         if (ref_info[0].hdmi)
557                 return ref_info[0].hdmi->hotplug;
558         else
559                 return HDMI_HPD_REMOVED;
560 }
561
562 int hdmi_config_audio(struct hdmi_audio *audio)
563 {
564         int i;
565         struct hdmi *hdmi;
566
567         if (audio == NULL)
568                 return HDMI_ERROR_FALSE;
569
570         for (i = 0; i < HDMI_MAX_ID; i++) {
571                 if (ref_info[i].ref == 0)
572                         continue;
573                 hdmi = ref_info[i].hdmi;
574
575                 /*
576                 if (memcmp(audio, &hdmi->audio, sizeof(struct hdmi_audio)) == 0)
577                         continue;
578                 */
579                 /*for (j = 0; j < hdmi->edid.audio_num; j++) {
580                         if (audio->type == hdmi->edid.audio_num)
581                                 break;
582                 }*/
583
584                 /*if ( (j == hdmi->edid.audio_num) ||
585                         (audio->channel > hdmi->edid.audio[j].channel) ||
586                         ((audio->rate & hdmi->edid.audio[j].rate) == 0)||
587                         ((audio->type == HDMI_AUDIO_LPCM) &&
588                         ((audio->word_length &
589                           hdmi->edid.audio[j].word_length) == 0)) ) {
590                         pr_warn("[%s] warning : input audio type
591                                 not supported in hdmi sink\n", __func__);
592                         continue;
593                 }*/
594                 memcpy(&hdmi->audio, audio, sizeof(struct hdmi_audio));
595                 if (hdmi->hotplug == HDMI_HPD_ACTIVED)
596                         hdmi_submit_work(hdmi, HDMI_SET_AUDIO, 0, NULL);
597         }
598         return 0;
599 }
600
601 void hdmi_audio_mute(int mute)
602 {
603         int i;
604         struct hdmi *hdmi;
605
606         for (i = 0; i < HDMI_MAX_ID; i++) {
607                 if (ref_info[i].ref == 0)
608                         continue;
609                 hdmi = ref_info[i].hdmi;
610
611                 if (mute)
612                         hdmi_submit_work(hdmi, HDMI_MUTE_AUDIO, 0, NULL);
613                 else
614                         hdmi_submit_work(hdmi, HDMI_UNMUTE_AUDIO, 0, NULL);
615         }
616 }
617
618 static int __init bootloader_setup(char *str)
619 {
620         if (str) {
621                 pr_info("hdmi init vic is %s\n", str);
622                 if (kstrtoint(str, 0, &uboot_vic) < 0)
623                         uboot_vic = 0;
624         }
625         return 0;
626 }
627
628 early_param("hdmi.vic", bootloader_setup);
629
630 static int __init hdmi_class_init(void)
631 {
632         int i;
633
634         for (i = 0; i < HDMI_MAX_ID; i++) {
635                 ref_info[i].id = i;
636                 ref_info[i].ref = 0;
637                 ref_info[i].hdmi = NULL;
638         }
639         pr_info("Rockchip hdmi driver version 2.0\n.");
640         return 0;
641 }
642
643 subsys_initcall(hdmi_class_init);