]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/soc/codecs/tlv320aic23.c
c2d35e9de335782c178cb295e9a8b61217b8fa1f
[linux-2.6-omap-h63xx.git] / sound / soc / codecs / tlv320aic23.c
1 /*
2  * ALSA SoC TLV320AIC23 codec driver
3  *
4  * Author:      Arun KS, <arunks@mistralsolutions.com>
5  * Copyright:   (C) 2008 Mistral Solutions Pvt Ltd.,
6  *
7  * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  * Notes:
14  *  The AIC23 is a driver for a low power stereo audio
15  *  codec tlv320aic23
16  *
17  *  The machine layer should disable unsupported inputs/outputs by
18  *  snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
19  */
20
21 #include <linux/module.h>
22 #include <linux/moduleparam.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/pm.h>
26 #include <linux/i2c.h>
27 #include <linux/platform_device.h>
28 #include <sound/core.h>
29 #include <sound/pcm.h>
30 #include <sound/pcm_params.h>
31 #include <sound/soc.h>
32 #include <sound/soc-dapm.h>
33 #include <sound/tlv.h>
34 #include <sound/initval.h>
35
36 #include "tlv320aic23.h"
37
38 #define AUDIO_NAME "tlv320aic23"
39 #define AIC23_VERSION "0.1"
40
41 struct tlv320aic23_srate_reg_info {
42         u32 sample_rate;
43         u8 control;             /* SR3, SR2, SR1, SR0 and BOSR */
44         u8 divider;             /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
45 };
46
47 /*
48  * AIC23 register cache
49  */
50 static const u16 tlv320aic23_reg[] = {
51         0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
52         0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
53         0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
54         0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
55 };
56
57 /*
58  * read tlv320aic23 register cache
59  */
60 static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
61                                                       *codec, unsigned int reg)
62 {
63         u16 *cache = codec->reg_cache;
64         if (reg >= ARRAY_SIZE(tlv320aic23_reg))
65                 return -1;
66         return cache[reg];
67 }
68
69 /*
70  * write tlv320aic23 register cache
71  */
72 static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
73                                                u8 reg, u16 value)
74 {
75         u16 *cache = codec->reg_cache;
76         if (reg >= ARRAY_SIZE(tlv320aic23_reg))
77                 return;
78         cache[reg] = value;
79 }
80
81 /*
82  * write to the tlv320aic23 register space
83  */
84 static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
85                              unsigned int value)
86 {
87
88         u8 data;
89
90         /* TLV320AIC23 has 7 bit address and 9 bits of data
91          * so we need to switch one data bit into reg and rest
92          * of data into val
93          */
94
95         if ((reg < 0 || reg > 9) && (reg != 15)) {
96                 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
97                 return -1;
98         }
99
100         data = (reg << 1) | (value >> 8 & 0x01);
101
102         tlv320aic23_write_reg_cache(codec, reg, value);
103
104         if (codec->hw_write(codec->control_data, data,
105                             (value & 0xff)) == 0)
106                 return 0;
107
108         printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
109                value, reg);
110
111         return -EIO;
112 }
113
114 static const char *rec_src_text[] = { "Line", "Mic" };
115 static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
116 static const char *sidetone_text[] = {"-6db", "-9db", "-12db", "-18db", "0db"};
117
118 static const struct soc_enum rec_src_enum =
119         SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
120
121 static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
122 SOC_DAPM_ENUM("Input Select", rec_src_enum);
123
124 static const struct soc_enum tlv320aic23_rec_src =
125         SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
126 static const struct soc_enum tlv320aic23_deemph =
127         SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
128 static const struct soc_enum tlv320aic23_sidetone =
129         SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 6, 5, sidetone_text);
130
131 static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
132 static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
133
134 static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
135         SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
136                          TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
137         SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
138         SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
139                      TLV320AIC23_RINVOL, 7, 1, 0),
140         SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
141                          TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
142         SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
143         SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
144         SOC_ENUM("Sidetone Gain", tlv320aic23_sidetone),
145         SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
146 };
147
148 /* add non dapm controls */
149 static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
150 {
151
152         int err, i;
153
154         for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
155                 err = snd_ctl_add(codec->card,
156                                   snd_soc_cnew(&tlv320aic23_snd_controls[i],
157                                                codec, NULL));
158                 if (err < 0)
159                         return err;
160         }
161
162         return 0;
163
164 }
165
166 /* PGA Mixer controls for Line and Mic switch */
167 static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
168         SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
169         SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
170         SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
171 };
172
173 static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
174         SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
175         SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
176         SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
177                          &tlv320aic23_rec_src_mux_controls),
178         SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
179                            &tlv320aic23_output_mixer_controls[0],
180                            ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
181         SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
182         SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
183
184         SND_SOC_DAPM_OUTPUT("LHPOUT"),
185         SND_SOC_DAPM_OUTPUT("RHPOUT"),
186         SND_SOC_DAPM_OUTPUT("LOUT"),
187         SND_SOC_DAPM_OUTPUT("ROUT"),
188
189         SND_SOC_DAPM_INPUT("LLINEIN"),
190         SND_SOC_DAPM_INPUT("RLINEIN"),
191
192         SND_SOC_DAPM_INPUT("MICIN"),
193 };
194
195 static const struct snd_soc_dapm_route intercon[] = {
196         /* Output Mixer */
197         {"Output Mixer", "Line Bypass Switch", "Line Input"},
198         {"Output Mixer", "Playback Switch", "DAC"},
199         {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
200
201         /* Outputs */
202         {"RHPOUT", NULL, "Output Mixer"},
203         {"LHPOUT", NULL, "Output Mixer"},
204         {"LOUT", NULL, "Output Mixer"},
205         {"ROUT", NULL, "Output Mixer"},
206
207         /* Inputs */
208         {"Line Input", "NULL", "LLINEIN"},
209         {"Line Input", "NULL", "RLINEIN"},
210
211         {"Mic Input", "NULL", "MICIN"},
212
213         /* input mux */
214         {"Capture Source", "Line", "Line Input"},
215         {"Capture Source", "Mic", "Mic Input"},
216         {"ADC", NULL, "Capture Source"},
217
218 };
219
220 /* tlv320aic23 related */
221 static const struct tlv320aic23_srate_reg_info srate_reg_info[] = {
222         {4000, 0x06, 1},        /*  4000 */
223         {8000, 0x06, 0},        /*  8000 */
224         {16000, 0x0C, 1},       /* 16000 */
225         {22050, 0x11, 1},       /* 22050 */
226         {24000, 0x00, 1},       /* 24000 */
227         {32000, 0x0C, 0},       /* 32000 */
228         {44100, 0x11, 0},       /* 44100 */
229         {48000, 0x00, 0},       /* 48000 */
230         {88200, 0x1F, 0},       /* 88200 */
231         {96000, 0x0E, 0},       /* 96000 */
232 };
233
234 static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
235 {
236         snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
237                                   ARRAY_SIZE(tlv320aic23_dapm_widgets));
238
239         /* set up audio path interconnects */
240         snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
241
242         snd_soc_dapm_new_widgets(codec);
243         return 0;
244 }
245
246 static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
247                                  struct snd_pcm_hw_params *params)
248 {
249         struct snd_soc_pcm_runtime *rtd = substream->private_data;
250         struct snd_soc_device *socdev = rtd->socdev;
251         struct snd_soc_codec *codec = socdev->codec;
252         u16 iface_reg, data;
253         u8 count = 0;
254
255         iface_reg =
256             tlv320aic23_read_reg_cache(codec,
257                                        TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
258
259         /* Search for the right sample rate */
260         /* Verify what happens if the rate is not supported
261          * now it goes to 96Khz */
262         while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
263                (count < ARRAY_SIZE(srate_reg_info))) {
264                 count++;
265         }
266
267         data =  (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
268                 (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
269                 TLV320AIC23_USB_CLK_ON;
270
271         tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
272
273         switch (params_format(params)) {
274         case SNDRV_PCM_FORMAT_S16_LE:
275                 break;
276         case SNDRV_PCM_FORMAT_S20_3LE:
277                 iface_reg |= (0x01 << 2);
278                 break;
279         case SNDRV_PCM_FORMAT_S24_LE:
280                 iface_reg |= (0x02 << 2);
281                 break;
282         case SNDRV_PCM_FORMAT_S32_LE:
283                 iface_reg |= (0x03 << 2);
284                 break;
285         }
286         tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
287
288         return 0;
289 }
290
291 static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
292 {
293         struct snd_soc_pcm_runtime *rtd = substream->private_data;
294         struct snd_soc_device *socdev = rtd->socdev;
295         struct snd_soc_codec *codec = socdev->codec;
296
297         /* set active */
298         tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
299
300         return 0;
301 }
302
303 static void tlv320aic23_shutdown(struct snd_pcm_substream *substream)
304 {
305         struct snd_soc_pcm_runtime *rtd = substream->private_data;
306         struct snd_soc_device *socdev = rtd->socdev;
307         struct snd_soc_codec *codec = socdev->codec;
308
309         /* deactivate */
310         if (!codec->active) {
311                 udelay(50);
312                 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
313         }
314 }
315
316 static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
317 {
318         struct snd_soc_codec *codec = dai->codec;
319         u16 reg;
320
321         reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
322         if (mute)
323                 reg |= TLV320AIC23_DACM_MUTE;
324
325         else
326                 reg &= ~TLV320AIC23_DACM_MUTE;
327
328         tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
329
330         return 0;
331 }
332
333 static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
334                                    unsigned int fmt)
335 {
336         struct snd_soc_codec *codec = codec_dai->codec;
337         u16 iface_reg;
338
339         iface_reg =
340             tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
341
342         /* set master/slave audio interface */
343         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344         case SND_SOC_DAIFMT_CBM_CFM:
345                 iface_reg |= TLV320AIC23_MS_MASTER;
346                 break;
347         case SND_SOC_DAIFMT_CBS_CFS:
348                 break;
349         default:
350                 return -EINVAL;
351
352         }
353
354         /* interface format */
355         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
356         case SND_SOC_DAIFMT_I2S:
357                 iface_reg |= TLV320AIC23_FOR_I2S;
358                 break;
359         case SND_SOC_DAIFMT_DSP_A:
360                 iface_reg |= TLV320AIC23_FOR_DSP;
361                 break;
362         case SND_SOC_DAIFMT_RIGHT_J:
363                 break;
364         case SND_SOC_DAIFMT_LEFT_J:
365                 iface_reg |= TLV320AIC23_FOR_LJUST;
366                 break;
367         default:
368                 return -EINVAL;
369
370         }
371
372         tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
373
374         return 0;
375 }
376
377 static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
378                                       int clk_id, unsigned int freq, int dir)
379 {
380         struct snd_soc_codec *codec = codec_dai->codec;
381
382         switch (freq) {
383         case 12000000:
384                 return 0;
385         }
386         return -EINVAL;
387 }
388
389 static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
390                                       enum snd_soc_bias_level level)
391 {
392         u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
393
394         switch (level) {
395         case SND_SOC_BIAS_ON:
396                 /* vref/mid, osc on, dac unmute */
397                 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
398                 break;
399         case SND_SOC_BIAS_PREPARE:
400                 break;
401         case SND_SOC_BIAS_STANDBY:
402                 /* everything off except vref/vmid, */
403                 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040);
404                 break;
405         case SND_SOC_BIAS_OFF:
406                 /* everything off, dac mute, inactive */
407                 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
408                 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
409                 break;
410         }
411         codec->bias_level = level;
412         return 0;
413 }
414
415 #define AIC23_RATES     SNDRV_PCM_RATE_8000_96000
416 #define AIC23_FORMATS   (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
417                          SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
418
419 struct snd_soc_dai tlv320aic23_dai = {
420         .name = "tlv320aic23",
421         .playback = {
422                      .stream_name = "Playback",
423                      .channels_min = 2,
424                      .channels_max = 2,
425                      .rates = AIC23_RATES,
426                      .formats = AIC23_FORMATS,},
427         .capture = {
428                     .stream_name = "Capture",
429                     .channels_min = 2,
430                     .channels_max = 2,
431                     .rates = AIC23_RATES,
432                     .formats = AIC23_FORMATS,},
433         .ops = {
434                 .prepare = tlv320aic23_pcm_prepare,
435                 .hw_params = tlv320aic23_hw_params,
436                 .shutdown = tlv320aic23_shutdown,
437                 },
438         .dai_ops = {
439                     .digital_mute = tlv320aic23_mute,
440                     .set_fmt = tlv320aic23_set_dai_fmt,
441                     .set_sysclk = tlv320aic23_set_dai_sysclk,
442                     }
443 };
444 EXPORT_SYMBOL_GPL(tlv320aic23_dai);
445
446 static int tlv320aic23_suspend(struct platform_device *pdev,
447                                pm_message_t state)
448 {
449         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
450         struct snd_soc_codec *codec = socdev->codec;
451
452         tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
453         tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
454
455         return 0;
456 }
457
458 static int tlv320aic23_resume(struct platform_device *pdev)
459 {
460         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
461         struct snd_soc_codec *codec = socdev->codec;
462         int i;
463         u16 reg;
464
465         /* Sync reg_cache with the hardware */
466         for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
467                 u16 val = tlv320aic23_read_reg_cache(codec, reg);
468                 tlv320aic23_write(codec, reg, val);
469         }
470
471         tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
472         tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
473
474         return 0;
475 }
476
477 /*
478  * initialise the AIC23 driver
479  * register the mixer and dsp interfaces with the kernel
480  */
481 static int tlv320aic23_init(struct snd_soc_device *socdev)
482 {
483         struct snd_soc_codec *codec = socdev->codec;
484         int ret = 0;
485         u16 reg;
486
487         codec->name = "tlv320aic23";
488         codec->owner = THIS_MODULE;
489         codec->read = tlv320aic23_read_reg_cache;
490         codec->write = tlv320aic23_write;
491         codec->set_bias_level = tlv320aic23_set_bias_level;
492         codec->dai = &tlv320aic23_dai;
493         codec->num_dai = 1;
494         codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
495         codec->reg_cache =
496             kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
497         if (codec->reg_cache == NULL)
498                 return -ENOMEM;
499
500         /* Reset codec */
501         tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
502
503         /* register pcms */
504         ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
505         if (ret < 0) {
506                 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
507                 goto pcm_err;
508         }
509
510         /* power on device */
511         tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
512
513         tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
514
515         /* Unmute input */
516         reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
517         tlv320aic23_write(codec, TLV320AIC23_LINVOL,
518                           (reg & (~TLV320AIC23_LIM_MUTED)) |
519                           (TLV320AIC23_LRS_ENABLED));
520
521         reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
522         tlv320aic23_write(codec, TLV320AIC23_RINVOL,
523                           (reg & (~TLV320AIC23_LIM_MUTED)) |
524                           TLV320AIC23_LRS_ENABLED);
525
526         reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
527         tlv320aic23_write(codec, TLV320AIC23_ANLG,
528                          (reg) & (~TLV320AIC23_BYPASS_ON) &
529                          (~TLV320AIC23_MICM_MUTED));
530
531         /* Default output volume */
532         tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
533                           TLV320AIC23_DEFAULT_OUT_VOL &
534                           TLV320AIC23_OUT_VOL_MASK);
535         tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
536                           TLV320AIC23_DEFAULT_OUT_VOL &
537                           TLV320AIC23_OUT_VOL_MASK);
538
539         tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
540
541         tlv320aic23_add_controls(codec);
542         tlv320aic23_add_widgets(codec);
543         ret = snd_soc_register_card(socdev);
544         if (ret < 0) {
545                 printk(KERN_ERR "tlv320aic23: failed to register card\n");
546                 goto card_err;
547         }
548
549         return ret;
550
551 card_err:
552         snd_soc_free_pcms(socdev);
553         snd_soc_dapm_free(socdev);
554 pcm_err:
555         kfree(codec->reg_cache);
556         return ret;
557 }
558 static struct snd_soc_device *tlv320aic23_socdev;
559
560 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
561 /*
562  * If the i2c layer weren't so broken, we could pass this kind of data
563  * around
564  */
565 static int tlv320aic23_codec_probe(struct i2c_client *i2c,
566                                    const struct i2c_device_id *i2c_id)
567 {
568         struct snd_soc_device *socdev = tlv320aic23_socdev;
569         struct snd_soc_codec *codec = socdev->codec;
570         int ret;
571
572         if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
573                 return -EINVAL;
574
575         i2c_set_clientdata(i2c, codec);
576         codec->control_data = i2c;
577
578         ret = tlv320aic23_init(socdev);
579         if (ret < 0) {
580                 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
581                 goto err;
582         }
583         return ret;
584
585 err:
586         kfree(codec);
587         kfree(i2c);
588         return ret;
589 }
590 static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
591 {
592         put_device(&i2c->dev);
593         return 0;
594 }
595
596 static const struct i2c_device_id tlv320aic23_id[] = {
597         {"tlv320aic23", 0},
598         {}
599 };
600
601 MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
602
603 static struct i2c_driver tlv320aic23_i2c_driver = {
604         .driver = {
605                    .name = "tlv320aic23",
606                    },
607         .probe = tlv320aic23_codec_probe,
608         .remove = __exit_p(tlv320aic23_i2c_remove),
609         .id_table = tlv320aic23_id,
610 };
611
612 #endif
613
614 static int tlv320aic23_probe(struct platform_device *pdev)
615 {
616         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
617         struct snd_soc_codec *codec;
618         int ret = 0;
619
620         printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
621
622         codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
623         if (codec == NULL)
624                 return -ENOMEM;
625
626         socdev->codec = codec;
627         mutex_init(&codec->mutex);
628         INIT_LIST_HEAD(&codec->dapm_widgets);
629         INIT_LIST_HEAD(&codec->dapm_paths);
630
631         tlv320aic23_socdev = socdev;
632 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
633         codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data;
634         codec->hw_read = NULL;
635         ret = i2c_add_driver(&tlv320aic23_i2c_driver);
636         if (ret != 0)
637                 printk(KERN_ERR "can't add i2c driver");
638 #endif
639         return ret;
640 }
641
642 static int tlv320aic23_remove(struct platform_device *pdev)
643 {
644         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
645         struct snd_soc_codec *codec = socdev->codec;
646
647         if (codec->control_data)
648                 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
649
650         snd_soc_free_pcms(socdev);
651         snd_soc_dapm_free(socdev);
652 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
653         i2c_del_driver(&tlv320aic23_i2c_driver);
654 #endif
655         kfree(codec->reg_cache);
656         kfree(codec);
657
658         return 0;
659 }
660 struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
661         .probe = tlv320aic23_probe,
662         .remove = tlv320aic23_remove,
663         .suspend = tlv320aic23_suspend,
664         .resume = tlv320aic23_resume,
665 };
666 EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
667
668 MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
669 MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
670 MODULE_LICENSE("GPL");