7eef7c85106abb2a18e68fe0cc5d0adcf981f330
[cascardo/linux.git] / sound / soc / samsung / hdmi_audio.c
1 /* sound/soc/samsung/hdmi_audio.c
2  *
3  * ALSA SoC Audio Layer - Samsung Hdmi Audio Plugin
4  *
5  * Copyright (c) 2012 Samsung Electronics Co. Ltd.
6  *      Rahul Sharma <rahul.sharma@samsung.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <sound/core.h>
17 #include <sound/pcm.h>
18 #include <sound/pcm_params.h>
19 #include <sound/soc.h>
20 #include <linux/slab.h>
21 #include <linux/irq.h>
22 #include <linux/io.h>
23 #include <linux/of_gpio.h>
24 #include <plat/gpio-cfg.h>
25
26 #include "codec_plugin.h"
27 #include "hdmi_audio.h"
28
29 #define DRV_NAME "exynos-hdmi-audio"
30
31 struct hdmi_audio_params {
32         u32 sample_rate;
33         u32 cts;
34         u32 n;
35         u32 sample_frq;
36 };
37
38 struct hdmi_audio_params audio_params[] = {
39                 { 32000, 27000, 4096, 0x3 },
40                 { 44100, 30000, 6272, 0x0 },
41                 { 88200, 30000, 12544, 0x8 },
42                 { 176400, 30000, 25088, 0xc },
43                 { 48000, 27000, 6144, 0x2 },
44                 { 96000, 27000, 12288, 0xa },
45                 { 192000, 27000, 24576, 0xe },
46 };
47
48 static inline u32 hdmi_reg_read(struct hdmi_audio_context *ctx, u32 reg_id)
49 {
50         return readl(ctx->regs + reg_id);
51 }
52
53 static inline void hdmi_reg_writeb(struct hdmi_audio_context *ctx,
54                                  u32 reg_id, u8 value)
55 {
56         writeb(value, ctx->regs + reg_id);
57 }
58
59 static inline void hdmi_reg_writemask(struct hdmi_audio_context *ctx,
60                                  u32 reg_id, u32 value, u32 mask)
61 {
62         u32 old = readl(ctx->regs + reg_id);
63         value = (value & mask) | (old & ~mask);
64         writel(value, ctx->regs + reg_id);
65 }
66
67 static int hdmi_get_audio_params(u32 freq)
68 {
69         int i;
70
71         for (i = 0; i < ARRAY_SIZE(audio_params); ++i)
72                 if (freq == audio_params[i].sample_rate)
73                         return i;
74
75         return -ENXIO;
76 }
77
78 static void hdmi_set_acr(struct hdmi_audio_context *ctx, u8 *acr)
79 {
80         u32 n, cts;
81
82         n = ctx->params.n;
83         cts = ctx->params.cts;
84
85         acr[1] = cts >> 16;
86         acr[2] = cts >> 8 & 0xff;
87         acr[3] = cts & 0xff;
88
89         acr[4] = n >> 16;
90         acr[5] = n >> 8 & 0xff;
91         acr[6] = n & 0xff;
92 }
93
94 static void hdmi_reg_acr(struct hdmi_audio_context *ctx, u8 *acr)
95 {
96         hdmi_reg_writeb(ctx, HDMI_ACR_N0, acr[6]);
97         hdmi_reg_writeb(ctx, HDMI_ACR_N1, acr[5]);
98         hdmi_reg_writeb(ctx, HDMI_ACR_N2, acr[4]);
99         hdmi_reg_writeb(ctx, HDMI_ACR_MCTS0, acr[3]);
100         hdmi_reg_writeb(ctx, HDMI_ACR_MCTS1, acr[2]);
101         hdmi_reg_writeb(ctx, HDMI_ACR_MCTS2, acr[1]);
102         hdmi_reg_writeb(ctx, HDMI_ACR_CTS0, acr[3]);
103         hdmi_reg_writeb(ctx, HDMI_ACR_CTS1, acr[2]);
104         hdmi_reg_writeb(ctx, HDMI_ACR_CTS2, acr[1]);
105         hdmi_reg_writeb(ctx, HDMI_ACR_CON, 4);
106 }
107
108 static void hdmi_audio_i2s_init(struct hdmi_audio_context *ctx)
109 {
110         u32 sample_rate, bits_per_sample, frame_size_code;
111         u32 data_num, bit_ch, sample_frq;
112         u32 val;
113         u8 acr[7];
114
115         sample_rate = ctx->params.sample_rate;
116         bits_per_sample = ctx->params.bits_per_sample;
117         frame_size_code = 0;
118
119         switch (bits_per_sample) {
120         case 16:
121                 data_num = 1;
122                 bit_ch = 0;
123                 break;
124         case 20:
125                 data_num = 2;
126                 bit_ch  = 1;
127                 break;
128         case 24:
129                 data_num = 3;
130                 bit_ch  = 1;
131                 break;
132         case 32:
133                 data_num = 1;
134                 bit_ch  = 2;
135                 break;
136         default:
137                 data_num = 1;
138                 bit_ch  = 0;
139                 break;
140         }
141
142         hdmi_set_acr(ctx, acr);
143         hdmi_reg_acr(ctx, acr);
144
145         hdmi_reg_writeb(ctx, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
146                                 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
147                                 | HDMI_I2S_MUX_ENABLE);
148
149         hdmi_reg_writeb(ctx, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
150                         | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
151
152         hdmi_reg_writeb(ctx, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
153
154         sample_frq = ctx->params.sample_frq;
155
156         hdmi_reg_writeb(ctx, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
157         hdmi_reg_writeb(ctx, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
158
159         val = hdmi_reg_read(ctx, HDMI_I2S_DSD_CON) | 0x01;
160         hdmi_reg_writeb(ctx, HDMI_I2S_DSD_CON, val);
161
162         /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
163         hdmi_reg_writeb(ctx, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
164                         | HDMI_I2S_SEL_LRCK(6));
165         hdmi_reg_writeb(ctx, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
166                         | HDMI_I2S_SEL_SDATA2(4));
167         hdmi_reg_writeb(ctx, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
168                         | HDMI_I2S_SEL_SDATA2(2));
169         hdmi_reg_writeb(ctx, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
170
171         /* I2S_CON_1 & 2 */
172         hdmi_reg_writeb(ctx, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
173                         | HDMI_I2S_L_CH_LOW_POL);
174         hdmi_reg_writeb(ctx, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
175                         | HDMI_I2S_SET_BIT_CH(bit_ch)
176                         | HDMI_I2S_SET_SDATA_BIT(data_num)
177                         | HDMI_I2S_BASIC_FORMAT);
178
179         /* Configure register related to CUV information */
180         hdmi_reg_writeb(ctx, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
181                         | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
182                         | HDMI_I2S_COPYRIGHT
183                         | HDMI_I2S_LINEAR_PCM
184                         | HDMI_I2S_CONSUMER_FORMAT);
185         hdmi_reg_writeb(ctx, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
186         hdmi_reg_writeb(ctx, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
187         hdmi_reg_writeb(ctx, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
188                         | HDMI_I2S_SET_SMP_FREQ(sample_frq));
189         hdmi_reg_writeb(ctx, HDMI_I2S_CH_ST_4,
190                         HDMI_I2S_ORG_SMP_FREQ_44_1
191                         | HDMI_I2S_WORD_LEN_MAX24_24BITS
192                         | HDMI_I2S_WORD_LEN_MAX_24BITS);
193
194         hdmi_reg_writeb(ctx, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
195 }
196
197 static void hdmi_audio_init(struct hdmi_audio_context *ctx)
198 {
199         hdmi_audio_i2s_init(ctx);
200 }
201
202 static int hdmi_audio_control(struct hdmi_audio_context *ctx,
203         bool onoff)
204 {
205         u32 mod;
206
207         snd_printdd("[%d] %s on %d\n", __LINE__,
208                                 __func__, onoff);
209
210         mod = hdmi_reg_read(ctx, HDMI_MODE_SEL);
211         if (mod & HDMI_DVI_MODE_EN && onoff) {
212                 snd_printdd("dvi mode on\n");
213                 return -EINVAL;
214         }
215
216         hdmi_reg_writeb(ctx, HDMI_AUI_CON, onoff ? 2 : 0);
217         hdmi_reg_writemask(ctx, HDMI_CON_0, onoff ?
218                         HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
219         return 0;
220 }
221
222 static u8 hdmi_chksum(struct hdmi_audio_context *ctx,
223                         u32 start, u8 len, u32 hdr_sum)
224 {
225         int i;
226         /* hdr_sum : header0 + header1 + header2
227         * start : start address of packet byte1
228         * len : packet bytes - 1 */
229         for (i = 0; i < len; ++i)
230                 hdr_sum += 0xff & hdmi_reg_read(ctx, start + i * 4);
231
232         return (u8)(0x100 - (hdr_sum & 0xff));
233 }
234
235 static void hdmi_reg_infoframe(struct hdmi_audio_context *ctx,
236                         struct hdmi_infoframe *infoframe)
237 {
238         u32 hdr_sum;
239         u8 chksum;
240         hdmi_reg_writeb(ctx, HDMI_AUI_CON, 0x02);
241         hdmi_reg_writeb(ctx, HDMI_AUI_HEADER0, infoframe->type);
242         hdmi_reg_writeb(ctx, HDMI_AUI_HEADER1, infoframe->ver);
243         hdmi_reg_writeb(ctx, HDMI_AUI_HEADER2, infoframe->len);
244         hdr_sum = infoframe->type + infoframe->ver + infoframe->len;
245         chksum = hdmi_chksum(ctx, HDMI_AUI_BYTE(1),
246                                 infoframe->len, hdr_sum);
247         hdmi_reg_writeb(ctx, HDMI_AUI_CHECK_SUM, chksum);
248 }
249
250 static void hdmi_conf_init(struct hdmi_audio_context *ctx)
251 {
252         struct hdmi_infoframe infoframe;
253
254         snd_printdd("[%d] %s\n", __LINE__, __func__);
255
256         /* enable AVI packet every vsync, fixes purple line problem */
257         hdmi_reg_writemask(ctx, HDMI_CON_1, 2, 3 << 5);
258
259         infoframe.type = HDMI_PACKET_TYPE_AUI;
260         infoframe.ver = HDMI_AUI_VERSION;
261         infoframe.len = HDMI_AUI_LENGTH;
262         hdmi_reg_infoframe(ctx, &infoframe);
263 }
264
265 static int hdmi_audio_hw_params(struct device *dev,
266                 struct snd_pcm_substream *substream,
267                 struct snd_pcm_hw_params *params,
268                 struct snd_soc_dai *dai)
269 {
270         struct hdmi_audio_context *ctx = NULL;
271         struct audio_codec_plugin *plugin;
272         int ret = 0, index;
273
274         if (!dev) {
275                 dev_err(dev, "invalid device.\n");
276                 ret = -EINVAL;
277                 goto err;
278         }
279
280         snd_printdd("[%d] %s\n", __LINE__, __func__);
281
282         plugin = dev_get_drvdata(dev);
283         ctx = container_of(plugin, struct hdmi_audio_context, plugin);
284
285         switch (params_channels(params)) {
286         case 6:
287         case 4:
288         case 2:
289         case 1:
290                 ctx->params.chan_count = params_channels(params);
291                 break;
292         default:
293                 dev_err(dev, "%d channels not supported\n",
294                                 params_channels(params));
295                 ret = -EINVAL;
296                 goto err;
297         }
298
299         switch (params_format(params)) {
300         case SNDRV_PCM_FORMAT_S8:
301                 ctx->params.bits_per_sample = 8;
302                 break;
303         case SNDRV_PCM_FORMAT_S16_LE:
304                 ctx->params.bits_per_sample = 12;
305                 break;
306         case SNDRV_PCM_FORMAT_S24_LE:
307                 ctx->params.bits_per_sample = 16;
308                 break;
309         default:
310                 dev_err(dev, "Format(%d) not supported\n",
311                                 params_format(params));
312                 ret = -EINVAL;
313                 goto err;
314         }
315
316         index = hdmi_get_audio_params(params_rate(params));
317         if (index >= 0) {
318                 ctx->params.sample_rate = audio_params[index].sample_rate;
319                 ctx->params.sample_frq = audio_params[index].sample_frq;
320                 ctx->params.cts = audio_params[index].cts;
321                 ctx->params.n = audio_params[index].n;
322         } else {
323                 dev_err(dev, "Sampling Rate (%d) not supported\n",
324                                 params_rate(params));
325                 ret = -EINVAL;
326                 goto err;
327         }
328
329         snd_printdd("chan cnt [%d]\n", ctx->params.chan_count);
330         snd_printdd("bps [%d]\n", ctx->params.bits_per_sample);
331         snd_printdd("sample_rate [%d]\n", ctx->params.sample_rate);
332
333         /* checking here to cache audioparms for hpd plug handling */
334         if (!atomic_read(&ctx->plugged))
335                 return -EINVAL;
336
337         hdmi_audio_control(ctx, false);
338         hdmi_conf_init(ctx);
339         hdmi_audio_init(ctx);
340         return ret;
341
342 err:
343         hdmi_audio_control(ctx, false);
344         return ret;
345 }
346
347 static int hdmi_audio_trigger(struct device *dev,
348                                 struct snd_pcm_substream *substream, int cmd,
349                                 struct snd_soc_dai *dai)
350 {
351         struct hdmi_audio_context *ctx = NULL;
352         struct audio_codec_plugin *plugin;
353         int ret = 0;
354
355         if (!dev) {
356                 dev_err(dev, "invalid device.\n");
357                 return -EINVAL;
358         }
359
360         snd_printdd("[%d] %s\n", __LINE__, __func__);
361
362         plugin = dev_get_drvdata(dev);
363         ctx = container_of(plugin, struct hdmi_audio_context, plugin);
364
365         if (!atomic_read(&ctx->plugged))
366                 return -EINVAL;
367
368         switch (cmd) {
369         case SNDRV_PCM_TRIGGER_START:
370                 if (!ctx->enabled)
371                         return -EINVAL;
372                 ret = hdmi_audio_control(ctx, true);
373                 if (ret) {
374                         dev_err(dev, "audio enable failed.\n");
375                         return -EINVAL;
376                 }
377                 break;
378         case SNDRV_PCM_TRIGGER_STOP:
379                 hdmi_audio_control(ctx, false);
380                 break;
381         }
382         return ret;
383 }
384
385 static int hdmi_set_state(struct device *dev, int enable)
386 {
387         struct hdmi_audio_context *ctx = NULL;
388         struct audio_codec_plugin *plugin;
389
390         if (!dev) {
391                 dev_err(dev, "invalid device.\n");
392                 return -EINVAL;
393         }
394
395         snd_printdd("[%d] %s en %d\n", __LINE__, __func__, enable);
396
397         plugin = dev_get_drvdata(dev);
398         ctx = container_of(plugin, struct hdmi_audio_context, plugin);
399         ctx->enabled = !!enable;
400
401         if (!atomic_read(&ctx->plugged))
402                 return -EINVAL;
403
404         hdmi_audio_control(ctx, !!enable);
405
406         return 0;
407 }
408
409 static int hdmi_get_state(struct device *dev, int *is_enabled)
410 {
411         struct hdmi_audio_context *ctx = NULL;
412         struct audio_codec_plugin *plugin;
413
414         if (!dev) {
415                 dev_err(dev, "invalid device.\n");
416                 return -EINVAL;
417         }
418
419         snd_printdd("[%d] %s\n", __LINE__, __func__);
420
421         plugin = dev_get_drvdata(dev);
422         ctx = container_of(plugin, struct hdmi_audio_context, plugin);
423
424         if (is_enabled && ctx)
425                 *is_enabled = ctx->enabled;
426         else
427                 return -EINVAL;
428         return 0;
429 }
430
431 static void hdmi_audio_hotplug_func(struct work_struct *work)
432 {
433         struct hdmi_audio_context *ctx = container_of(work,
434                 struct hdmi_audio_context, hotplug_work.work);
435         int plugged;
436
437         snd_printdd("[%d] %s plugged %d\n",
438                         __LINE__, __func__, atomic_read(&ctx->plugged));
439
440         plugged = atomic_read(&ctx->plugged);
441
442         if (hdmi_reg_read(ctx, HDMI_MODE_SEL) & HDMI_DVI_MODE_EN) {
443                 /* If HDMI operates in DVI mode,
444                  * for audio purposes it is the same as nothing plugged.
445                  * Unfortunately, hotplug interrupt is received multiple times,
446                  * and HDMI_DVI_MODE_EN is set only in the last one.
447                  * So, we have already reported that HDMI audio was plugged.
448                  * So, update ctx, report now that it was unplugged and return.
449                  */
450                 atomic_set(&ctx->plugged, 0);
451                 if (plugged && ctx->plugin.jack_cb)
452                         ctx->plugin.jack_cb(false);
453                 return;
454         }
455
456         if (plugged) {
457                 hdmi_audio_control(ctx, false);
458                 hdmi_conf_init(ctx);
459                 hdmi_audio_init(ctx);
460                 if (ctx->enabled)
461                         hdmi_audio_control(ctx, true);
462         }
463
464         if (ctx->plugin.jack_cb)
465                 ctx->plugin.jack_cb(plugged);
466 }
467
468 static irqreturn_t hdmi_audio_irq_handler(int irq, void *arg)
469 {
470         struct hdmi_audio_context *ctx = arg;
471         u32 val = gpio_get_value(ctx->hpd_gpio);
472
473         atomic_set(&ctx->plugged, !!val);
474         snd_printdd("%s %s\n", __func__,
475                         atomic_read(&ctx->plugged) ? "plugged" : "unplugged");
476
477         /* should set audio regs after ip, phy got stable. 5ms suff */
478         queue_delayed_work(ctx->hpd_wq, &ctx->hotplug_work,
479                         msecs_to_jiffies(5));
480         return IRQ_HANDLED;
481 }
482
483
484 static __devinit int hdmi_audio_probe(struct platform_device *pdev)
485 {
486         int ret = 0;
487         struct hdmi_audio_context *ctx;
488         struct resource *res;
489         struct device_node *parent_node;
490
491         snd_printdd(&pdev->dev, "[%d] %s\n", __LINE__, __func__);
492
493         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
494         if (!ctx) {
495                 dev_err(&pdev->dev, "failed to alloc common hdmi audio context.\n");
496                 ret = -ENOMEM;
497                 goto err;
498         }
499
500         ctx->pdev = pdev;
501         ctx->enabled = true;
502         atomic_set(&ctx->plugged, 0);
503         ctx->plugin.dev = &pdev->dev;
504         ctx->plugin.ops.hw_params = hdmi_audio_hw_params;
505         ctx->plugin.ops.trigger = hdmi_audio_trigger;
506         ctx->plugin.ops.get_state = hdmi_get_state;
507         ctx->plugin.ops.set_state = hdmi_set_state;
508         ctx->params.sample_rate = DEFAULT_RATE;
509         ctx->params.bits_per_sample = DEFAULT_BPS;
510
511         dev_set_drvdata(&pdev->dev, &ctx->plugin);
512
513         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
514         if (!res) {
515                 dev_err(&pdev->dev, "failed to find registers.\n");
516                 ret = -ENOENT;
517                 goto err_mem;
518         }
519
520         ctx->regs = ioremap(res->start, resource_size(res));
521         if (!ctx->regs) {
522                 dev_err(&pdev->dev, "failed to map registers\n");
523                 ret = -ENXIO;
524                 goto err_mem;
525         }
526
527         /* create workqueue and hotplug work */
528         ctx->hpd_wq = alloc_workqueue("exynos-hdmi-audio",
529                         WQ_UNBOUND | WQ_NON_REENTRANT, 1);
530         if (ctx->hpd_wq == NULL) {
531                 dev_err(&pdev->dev, "failed to create workqueue\n");
532                 ret = -ENOMEM;
533                 goto err_unmap;
534         }
535         INIT_DELAYED_WORK(&ctx->hotplug_work, hdmi_audio_hotplug_func);
536
537         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
538         if (res == NULL) {
539                 dev_err(&pdev->dev, "get interrupt res failed.\n");
540                 ret = -ENXIO;
541                 goto err_workq;
542         }
543
544         parent_node = of_get_parent(pdev->dev.of_node);
545         if (!parent_node) {
546                 dev_err(&pdev->dev, "no parent node found.\n");
547                 ret = -EINVAL;
548                 goto err_workq;
549         }
550
551         ctx->hpd_gpio = (int)pdev->dev.platform_data;
552
553         if (!gpio_is_valid(ctx->hpd_gpio)) {
554                 dev_err(&pdev->dev, "failed to get hpd gpio.");
555                 ret = -EINVAL;
556                 goto err_workq;
557         }
558
559         ctx->ext_irq = gpio_to_irq(ctx->hpd_gpio);
560
561         ret = request_irq(res->start, hdmi_audio_irq_handler,
562                         IRQF_SHARED, "int_hdmi_audio", ctx);
563         if (ret) {
564                 dev_err(&pdev->dev, "request interrupt failed.\n");
565                 goto err_workq;
566         }
567         ctx->int_irq = res->start;
568
569         ret = request_irq(ctx->ext_irq, hdmi_audio_irq_handler,
570                 IRQ_TYPE_EDGE_BOTH | IRQF_SHARED, "ext_hdmi_audio", ctx);
571         if (ret) {
572                 dev_err(&pdev->dev, "request interrupt failed.\n");
573                 goto err_irq;
574         }
575
576         return ret;
577
578 err_irq:
579         disable_irq(ctx->int_irq);
580         free_irq(ctx->int_irq, ctx);
581 err_workq:
582         destroy_workqueue(ctx->hpd_wq);
583 err_unmap:
584         iounmap(ctx->regs);
585 err_mem:
586         kfree(ctx);
587 err:
588         return ret;
589 }
590
591 static int __devexit hdmi_audio_remove(struct platform_device *pdev)
592 {
593         struct hdmi_audio_context *ctx = NULL;
594         int ret = 0;
595
596         ctx = dev_get_drvdata(&pdev->dev);
597
598         disable_irq(ctx->int_irq);
599         free_irq(ctx->int_irq, ctx);
600         disable_irq(ctx->ext_irq);
601         free_irq(ctx->ext_irq, ctx);
602         destroy_workqueue(ctx->hpd_wq);
603         iounmap(ctx->regs);
604         kfree(ctx);
605
606         return ret;
607 }
608
609 static struct platform_driver hdmi_audio_driver = {
610         .driver = {
611                 .name = DRV_NAME,
612                 .owner = THIS_MODULE,
613         },
614         .probe = hdmi_audio_probe,
615         .remove = __devexit_p(hdmi_audio_remove),
616 };
617
618 module_platform_driver(hdmi_audio_driver);
619
620 MODULE_AUTHOR("Rahul Sharma <rahul.sharma@samsung.com>");
621 MODULE_DESCRIPTION("HDMI Audio Codec Plugin");
622 MODULE_VERSION("1:1.0");
623 MODULE_LICENSE("GPL");
624 MODULE_ALIAS("platform:" DRV_NAME);