xref: /openbmc/linux/sound/soc/codecs/tlv320aic23.c (revision c1f27190)
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");
671