Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[pandora-kernel.git] / sound / soc / codecs / uda134x.c
1 /*
2  * uda134x.c  --  UDA134X ALSA SoC Codec driver
3  *
4  * Modifications by Christian Pellegrin <chripell@evolware.org>
5  *
6  * Copyright 2007 Dension Audio Systems Ltd.
7  * Author: Zoltan Devai
8  *
9  * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15
16 #include <linux/module.h>
17 #include <linux/delay.h>
18 #include <linux/slab.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/initval.h>
24
25 #include <sound/uda134x.h>
26 #include <sound/l3.h>
27
28 #include "uda134x.h"
29
30
31 #define POWER_OFF_ON_STANDBY 1
32 /*
33   ALSA SOC usually puts the device in standby mode when it's not used
34   for sometime. If you define POWER_OFF_ON_STANDBY the driver will
35   turn off the ADC/DAC when this callback is invoked and turn it back
36   on when needed. Unfortunately this will result in a very light bump
37   (it can be audible only with good earphones). If this bothers you
38   just comment this line, you will have slightly higher power
39   consumption . Please note that sending the L3 command for ADC is
40   enough to make the bump, so it doesn't make difference if you
41   completely take off power from the codec.
42  */
43
44 #define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
45 #define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
46                 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
47
48 struct uda134x_priv {
49         int sysclk;
50         int dai_fmt;
51
52         struct snd_pcm_substream *master_substream;
53         struct snd_pcm_substream *slave_substream;
54 };
55
56 /* In-data addresses are hard-coded into the reg-cache values */
57 static const char uda134x_reg[UDA134X_REGS_NUM] = {
58         /* Extended address registers */
59         0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
60         /* Status, data regs */
61         0x00, 0x83, 0x00, 0x40, 0x80, 0x00,
62 };
63
64 /*
65  * The codec has no support for reading its registers except for peak level...
66  */
67 static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
68         unsigned int reg)
69 {
70         u8 *cache = codec->reg_cache;
71
72         if (reg >= UDA134X_REGS_NUM)
73                 return -1;
74         return cache[reg];
75 }
76
77 /*
78  * Write the register cache
79  */
80 static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
81         u8 reg, unsigned int value)
82 {
83         u8 *cache = codec->reg_cache;
84
85         if (reg >= UDA134X_REGS_NUM)
86                 return;
87         cache[reg] = value;
88 }
89
90 /*
91  * Write to the uda134x registers
92  *
93  */
94 static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
95         unsigned int value)
96 {
97         int ret;
98         u8 addr;
99         u8 data = value;
100         struct uda134x_platform_data *pd = codec->control_data;
101
102         pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
103
104         if (reg >= UDA134X_REGS_NUM) {
105                 printk(KERN_ERR "%s unknown register: reg: %u",
106                        __func__, reg);
107                 return -EINVAL;
108         }
109
110         uda134x_write_reg_cache(codec, reg, value);
111
112         switch (reg) {
113         case UDA134X_STATUS0:
114         case UDA134X_STATUS1:
115                 addr = UDA134X_STATUS_ADDR;
116                 break;
117         case UDA134X_DATA000:
118         case UDA134X_DATA001:
119         case UDA134X_DATA010:
120                 addr = UDA134X_DATA0_ADDR;
121                 break;
122         case UDA134X_DATA1:
123                 addr = UDA134X_DATA1_ADDR;
124                 break;
125         default:
126                 /* It's an extended address register */
127                 addr =  (reg | UDA134X_EXTADDR_PREFIX);
128
129                 ret = l3_write(&pd->l3,
130                                UDA134X_DATA0_ADDR, &addr, 1);
131                 if (ret != 1)
132                         return -EIO;
133
134                 addr = UDA134X_DATA0_ADDR;
135                 data = (value | UDA134X_EXTDATA_PREFIX);
136                 break;
137         }
138
139         ret = l3_write(&pd->l3,
140                        addr, &data, 1);
141         if (ret != 1)
142                 return -EIO;
143
144         return 0;
145 }
146
147 static inline void uda134x_reset(struct snd_soc_codec *codec)
148 {
149         u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
150         uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
151         msleep(1);
152         uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
153 }
154
155 static int uda134x_mute(struct snd_soc_dai *dai, int mute)
156 {
157         struct snd_soc_codec *codec = dai->codec;
158         u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
159
160         pr_debug("%s mute: %d\n", __func__, mute);
161
162         if (mute)
163                 mute_reg |= (1<<2);
164         else
165                 mute_reg &= ~(1<<2);
166
167         uda134x_write(codec, UDA134X_DATA010, mute_reg);
168
169         return 0;
170 }
171
172 static int uda134x_startup(struct snd_pcm_substream *substream,
173         struct snd_soc_dai *dai)
174 {
175         struct snd_soc_pcm_runtime *rtd = substream->private_data;
176         struct snd_soc_device *socdev = rtd->socdev;
177         struct snd_soc_codec *codec = socdev->card->codec;
178         struct uda134x_priv *uda134x = codec->private_data;
179         struct snd_pcm_runtime *master_runtime;
180
181         if (uda134x->master_substream) {
182                 master_runtime = uda134x->master_substream->runtime;
183
184                 pr_debug("%s constraining to %d bits at %d\n", __func__,
185                          master_runtime->sample_bits,
186                          master_runtime->rate);
187
188                 snd_pcm_hw_constraint_minmax(substream->runtime,
189                                              SNDRV_PCM_HW_PARAM_RATE,
190                                              master_runtime->rate,
191                                              master_runtime->rate);
192
193                 snd_pcm_hw_constraint_minmax(substream->runtime,
194                                              SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
195                                              master_runtime->sample_bits,
196                                              master_runtime->sample_bits);
197
198                 uda134x->slave_substream = substream;
199         } else
200                 uda134x->master_substream = substream;
201
202         return 0;
203 }
204
205 static void uda134x_shutdown(struct snd_pcm_substream *substream,
206         struct snd_soc_dai *dai)
207 {
208         struct snd_soc_pcm_runtime *rtd = substream->private_data;
209         struct snd_soc_device *socdev = rtd->socdev;
210         struct snd_soc_codec *codec = socdev->card->codec;
211         struct uda134x_priv *uda134x = codec->private_data;
212
213         if (uda134x->master_substream == substream)
214                 uda134x->master_substream = uda134x->slave_substream;
215
216         uda134x->slave_substream = NULL;
217 }
218
219 static int uda134x_hw_params(struct snd_pcm_substream *substream,
220         struct snd_pcm_hw_params *params,
221         struct snd_soc_dai *dai)
222 {
223         struct snd_soc_pcm_runtime *rtd = substream->private_data;
224         struct snd_soc_device *socdev = rtd->socdev;
225         struct snd_soc_codec *codec = socdev->card->codec;
226         struct uda134x_priv *uda134x = codec->private_data;
227         u8 hw_params;
228
229         if (substream == uda134x->slave_substream) {
230                 pr_debug("%s ignoring hw_params for slave substream\n",
231                          __func__);
232                 return 0;
233         }
234
235         hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
236         hw_params &= STATUS0_SYSCLK_MASK;
237         hw_params &= STATUS0_DAIFMT_MASK;
238
239         pr_debug("%s sysclk: %d, rate:%d\n", __func__,
240                  uda134x->sysclk, params_rate(params));
241
242         /* set SYSCLK / fs ratio */
243         switch (uda134x->sysclk / params_rate(params)) {
244         case 512:
245                 break;
246         case 384:
247                 hw_params |= (1<<4);
248                 break;
249         case 256:
250                 hw_params |= (1<<5);
251                 break;
252         default:
253                 printk(KERN_ERR "%s unsupported fs\n", __func__);
254                 return -EINVAL;
255         }
256
257         pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
258                  uda134x->dai_fmt, params_format(params));
259
260         /* set DAI format and word length */
261         switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
262         case SND_SOC_DAIFMT_I2S:
263                 break;
264         case SND_SOC_DAIFMT_RIGHT_J:
265                 switch (params_format(params)) {
266                 case SNDRV_PCM_FORMAT_S16_LE:
267                         hw_params |= (1<<1);
268                         break;
269                 case SNDRV_PCM_FORMAT_S18_3LE:
270                         hw_params |= (1<<2);
271                         break;
272                 case SNDRV_PCM_FORMAT_S20_3LE:
273                         hw_params |= ((1<<2) | (1<<1));
274                         break;
275                 default:
276                         printk(KERN_ERR "%s unsupported format (right)\n",
277                                __func__);
278                         return -EINVAL;
279                 }
280                 break;
281         case SND_SOC_DAIFMT_LEFT_J:
282                 hw_params |= (1<<3);
283                 break;
284         default:
285                 printk(KERN_ERR "%s unsupported format\n", __func__);
286                 return -EINVAL;
287         }
288
289         uda134x_write(codec, UDA134X_STATUS0, hw_params);
290
291         return 0;
292 }
293
294 static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
295                                   int clk_id, unsigned int freq, int dir)
296 {
297         struct snd_soc_codec *codec = codec_dai->codec;
298         struct uda134x_priv *uda134x = codec->private_data;
299
300         pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
301                  clk_id, freq, dir);
302
303         /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
304            because the codec is slave. Of course limitations of the clock
305            master (the IIS controller) apply.
306            We'll error out on set_hw_params if it's not OK */
307         if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
308                 uda134x->sysclk = freq;
309                 return 0;
310         }
311
312         printk(KERN_ERR "%s unsupported sysclk\n", __func__);
313         return -EINVAL;
314 }
315
316 static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
317                                unsigned int fmt)
318 {
319         struct snd_soc_codec *codec = codec_dai->codec;
320         struct uda134x_priv *uda134x = codec->private_data;
321
322         pr_debug("%s fmt: %08X\n", __func__, fmt);
323
324         /* codec supports only full slave mode */
325         if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
326                 printk(KERN_ERR "%s unsupported slave mode\n", __func__);
327                 return -EINVAL;
328         }
329
330         /* no support for clock inversion */
331         if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
332                 printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
333                 return -EINVAL;
334         }
335
336         /* We can't setup DAI format here as it depends on the word bit num */
337         /* so let's just store the value for later */
338         uda134x->dai_fmt = fmt;
339
340         return 0;
341 }
342
343 static int uda134x_set_bias_level(struct snd_soc_codec *codec,
344                                   enum snd_soc_bias_level level)
345 {
346         u8 reg;
347         struct uda134x_platform_data *pd = codec->control_data;
348         int i;
349         u8 *cache = codec->reg_cache;
350
351         pr_debug("%s bias level %d\n", __func__, level);
352
353         switch (level) {
354         case SND_SOC_BIAS_ON:
355                 /* ADC, DAC on */
356                 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
357                 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
358                 break;
359         case SND_SOC_BIAS_PREPARE:
360                 /* power on */
361                 if (pd->power) {
362                         pd->power(1);
363                         /* Sync reg_cache with the hardware */
364                         for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
365                                 codec->write(codec, i, *cache++);
366                 }
367                 break;
368         case SND_SOC_BIAS_STANDBY:
369                 /* ADC, DAC power off */
370                 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
371                 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
372                 break;
373         case SND_SOC_BIAS_OFF:
374                 /* power off */
375                 if (pd->power)
376                         pd->power(0);
377                 break;
378         }
379         codec->bias_level = level;
380         return 0;
381 }
382
383 static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
384                                             "Minimum2", "Maximum"};
385 static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
386 static const char *uda134x_mixmode[] = {"Differential", "Analog1",
387                                         "Analog2", "Both"};
388
389 static const struct soc_enum uda134x_mixer_enum[] = {
390 SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
391 SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
392 SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
393 };
394
395 static const struct snd_kcontrol_new uda1341_snd_controls[] = {
396 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
397 SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
398 SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
399 SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
400
401 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
402 SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
403
404 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
405 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
406
407 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
408 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
409 SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
410
411 SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
412 SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
413 SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
414
415 SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
416 SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
417 SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
418 SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
419 SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
420 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
421 };
422
423 static const struct snd_kcontrol_new uda1340_snd_controls[] = {
424 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
425
426 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
427 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
428
429 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
430 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
431
432 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
433 };
434
435 static struct snd_soc_dai_ops uda134x_dai_ops = {
436         .startup        = uda134x_startup,
437         .shutdown       = uda134x_shutdown,
438         .hw_params      = uda134x_hw_params,
439         .digital_mute   = uda134x_mute,
440         .set_sysclk     = uda134x_set_dai_sysclk,
441         .set_fmt        = uda134x_set_dai_fmt,
442 };
443
444 struct snd_soc_dai uda134x_dai = {
445         .name = "UDA134X",
446         /* playback capabilities */
447         .playback = {
448                 .stream_name = "Playback",
449                 .channels_min = 1,
450                 .channels_max = 2,
451                 .rates = UDA134X_RATES,
452                 .formats = UDA134X_FORMATS,
453         },
454         /* capture capabilities */
455         .capture = {
456                 .stream_name = "Capture",
457                 .channels_min = 1,
458                 .channels_max = 2,
459                 .rates = UDA134X_RATES,
460                 .formats = UDA134X_FORMATS,
461         },
462         /* pcm operations */
463         .ops = &uda134x_dai_ops,
464 };
465 EXPORT_SYMBOL(uda134x_dai);
466
467
468 static int uda134x_soc_probe(struct platform_device *pdev)
469 {
470         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
471         struct snd_soc_codec *codec;
472         struct uda134x_priv *uda134x;
473         void *codec_setup_data = socdev->codec_data;
474         int ret = -ENOMEM;
475         struct uda134x_platform_data *pd;
476
477         printk(KERN_INFO "UDA134X SoC Audio Codec\n");
478
479         if (!codec_setup_data) {
480                 printk(KERN_ERR "UDA134X SoC codec: "
481                        "missing L3 bitbang function\n");
482                 return -ENODEV;
483         }
484
485         pd = codec_setup_data;
486         switch (pd->model) {
487         case UDA134X_UDA1340:
488         case UDA134X_UDA1341:
489         case UDA134X_UDA1344:
490                 break;
491         default:
492                 printk(KERN_ERR "UDA134X SoC codec: "
493                        "unsupported model %d\n",
494                         pd->model);
495                 return -EINVAL;
496         }
497
498         socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
499         if (socdev->card->codec == NULL)
500                 return ret;
501
502         codec = socdev->card->codec;
503
504         uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
505         if (uda134x == NULL)
506                 goto priv_err;
507         codec->private_data = uda134x;
508
509         codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
510                                    GFP_KERNEL);
511         if (codec->reg_cache == NULL)
512                 goto reg_err;
513
514         mutex_init(&codec->mutex);
515
516         codec->reg_cache_size = sizeof(uda134x_reg);
517         codec->reg_cache_step = 1;
518
519         codec->name = "UDA134X";
520         codec->owner = THIS_MODULE;
521         codec->dai = &uda134x_dai;
522         codec->num_dai = 1;
523         codec->read = uda134x_read_reg_cache;
524         codec->write = uda134x_write;
525 #ifdef POWER_OFF_ON_STANDBY
526         codec->set_bias_level = uda134x_set_bias_level;
527 #endif
528         INIT_LIST_HEAD(&codec->dapm_widgets);
529         INIT_LIST_HEAD(&codec->dapm_paths);
530
531         codec->control_data = codec_setup_data;
532
533         if (pd->power)
534                 pd->power(1);
535
536         uda134x_reset(codec);
537
538         /* register pcms */
539         ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
540         if (ret < 0) {
541                 printk(KERN_ERR "UDA134X: failed to register pcms\n");
542                 goto pcm_err;
543         }
544
545         switch (pd->model) {
546         case UDA134X_UDA1340:
547         case UDA134X_UDA1344:
548                 ret = snd_soc_add_controls(codec, uda1340_snd_controls,
549                                         ARRAY_SIZE(uda1340_snd_controls));
550         break;
551         case UDA134X_UDA1341:
552                 ret = snd_soc_add_controls(codec, uda1341_snd_controls,
553                                         ARRAY_SIZE(uda1341_snd_controls));
554         break;
555         default:
556                 printk(KERN_ERR "%s unknown codec type: %d",
557                         __func__, pd->model);
558         return -EINVAL;
559         }
560
561         if (ret < 0) {
562                 printk(KERN_ERR "UDA134X: failed to register controls\n");
563                 goto pcm_err;
564         }
565
566         return 0;
567
568 pcm_err:
569         kfree(codec->reg_cache);
570 reg_err:
571         kfree(codec->private_data);
572 priv_err:
573         kfree(codec);
574         return ret;
575 }
576
577 /* power down chip */
578 static int uda134x_soc_remove(struct platform_device *pdev)
579 {
580         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
581         struct snd_soc_codec *codec = socdev->card->codec;
582
583         uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
584         uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
585
586         snd_soc_free_pcms(socdev);
587         snd_soc_dapm_free(socdev);
588
589         kfree(codec->private_data);
590         kfree(codec->reg_cache);
591         kfree(codec);
592
593         return 0;
594 }
595
596 #if defined(CONFIG_PM)
597 static int uda134x_soc_suspend(struct platform_device *pdev,
598                                                 pm_message_t state)
599 {
600         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
601         struct snd_soc_codec *codec = socdev->card->codec;
602
603         uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
604         uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
605         return 0;
606 }
607
608 static int uda134x_soc_resume(struct platform_device *pdev)
609 {
610         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
611         struct snd_soc_codec *codec = socdev->card->codec;
612
613         uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
614         uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
615         return 0;
616 }
617 #else
618 #define uda134x_soc_suspend NULL
619 #define uda134x_soc_resume NULL
620 #endif /* CONFIG_PM */
621
622 struct snd_soc_codec_device soc_codec_dev_uda134x = {
623         .probe =        uda134x_soc_probe,
624         .remove =       uda134x_soc_remove,
625         .suspend =      uda134x_soc_suspend,
626         .resume =       uda134x_soc_resume,
627 };
628 EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
629
630 static int __init uda134x_init(void)
631 {
632         return snd_soc_register_dai(&uda134x_dai);
633 }
634 module_init(uda134x_init);
635
636 static void __exit uda134x_exit(void)
637 {
638         snd_soc_unregister_dai(&uda134x_dai);
639 }
640 module_exit(uda134x_exit);
641
642 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
643 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
644 MODULE_LICENSE("GPL");