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