asm-generic: remove ARCH_HAS_SG_CHAIN in scatterlist.h
[linux-2.6/kvm.git] / sound / soc / codecs / uda134x.c
blob28aac53c97bb799e1b8b731fd75053a15799d4c9
1 /*
2 * uda134x.c -- UDA134X ALSA SoC Codec driver
4 * Modifications by Christian Pellegrin <chripell@evolware.org>
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
9 * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
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.
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>
25 #include <sound/uda134x.h>
26 #include <sound/l3.h>
28 #include "uda134x.h"
31 #define POWER_OFF_ON_STANDBY 1
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.
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)
48 struct uda134x_priv {
49 int sysclk;
50 int dai_fmt;
52 struct snd_pcm_substream *master_substream;
53 struct snd_pcm_substream *slave_substream;
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,
65 * The codec has no support for reading its registers except for peak level...
67 static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
68 unsigned int reg)
70 u8 *cache = codec->reg_cache;
72 if (reg >= UDA134X_REGS_NUM)
73 return -1;
74 return cache[reg];
78 * Write the register cache
80 static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
81 u8 reg, unsigned int value)
83 u8 *cache = codec->reg_cache;
85 if (reg >= UDA134X_REGS_NUM)
86 return;
87 cache[reg] = value;
91 * Write to the uda134x registers
94 static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
95 unsigned int value)
97 int ret;
98 u8 addr;
99 u8 data = value;
100 struct uda134x_platform_data *pd = codec->control_data;
102 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
104 if (reg >= UDA134X_REGS_NUM) {
105 printk(KERN_ERR "%s unknown register: reg: %u",
106 __func__, reg);
107 return -EINVAL;
110 uda134x_write_reg_cache(codec, reg, value);
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);
129 ret = l3_write(&pd->l3,
130 UDA134X_DATA0_ADDR, &addr, 1);
131 if (ret != 1)
132 return -EIO;
134 addr = UDA134X_DATA0_ADDR;
135 data = (value | UDA134X_EXTDATA_PREFIX);
136 break;
139 ret = l3_write(&pd->l3,
140 addr, &data, 1);
141 if (ret != 1)
142 return -EIO;
144 return 0;
147 static inline void uda134x_reset(struct snd_soc_codec *codec)
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));
155 static int uda134x_mute(struct snd_soc_dai *dai, int mute)
157 struct snd_soc_codec *codec = dai->codec;
158 u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
160 pr_debug("%s mute: %d\n", __func__, mute);
162 if (mute)
163 mute_reg |= (1<<2);
164 else
165 mute_reg &= ~(1<<2);
167 uda134x_write(codec, UDA134X_DATA010, mute_reg);
169 return 0;
172 static int uda134x_startup(struct snd_pcm_substream *substream,
173 struct snd_soc_dai *dai)
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 = snd_soc_codec_get_drvdata(codec);
179 struct snd_pcm_runtime *master_runtime;
181 if (uda134x->master_substream) {
182 master_runtime = uda134x->master_substream->runtime;
184 pr_debug("%s constraining to %d bits at %d\n", __func__,
185 master_runtime->sample_bits,
186 master_runtime->rate);
188 snd_pcm_hw_constraint_minmax(substream->runtime,
189 SNDRV_PCM_HW_PARAM_RATE,
190 master_runtime->rate,
191 master_runtime->rate);
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);
198 uda134x->slave_substream = substream;
199 } else
200 uda134x->master_substream = substream;
202 return 0;
205 static void uda134x_shutdown(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
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 = snd_soc_codec_get_drvdata(codec);
213 if (uda134x->master_substream == substream)
214 uda134x->master_substream = uda134x->slave_substream;
216 uda134x->slave_substream = NULL;
219 static int uda134x_hw_params(struct snd_pcm_substream *substream,
220 struct snd_pcm_hw_params *params,
221 struct snd_soc_dai *dai)
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 = snd_soc_codec_get_drvdata(codec);
227 u8 hw_params;
229 if (substream == uda134x->slave_substream) {
230 pr_debug("%s ignoring hw_params for slave substream\n",
231 __func__);
232 return 0;
235 hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
236 hw_params &= STATUS0_SYSCLK_MASK;
237 hw_params &= STATUS0_DAIFMT_MASK;
239 pr_debug("%s sysclk: %d, rate:%d\n", __func__,
240 uda134x->sysclk, params_rate(params));
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;
257 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
258 uda134x->dai_fmt, params_format(params));
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;
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;
289 uda134x_write(codec, UDA134X_STATUS0, hw_params);
291 return 0;
294 static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
295 int clk_id, unsigned int freq, int dir)
297 struct snd_soc_codec *codec = codec_dai->codec;
298 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
300 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
301 clk_id, freq, dir);
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;
312 printk(KERN_ERR "%s unsupported sysclk\n", __func__);
313 return -EINVAL;
316 static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
317 unsigned int fmt)
319 struct snd_soc_codec *codec = codec_dai->codec;
320 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
322 pr_debug("%s fmt: %08X\n", __func__, fmt);
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;
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;
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;
340 return 0;
343 static int uda134x_set_bias_level(struct snd_soc_codec *codec,
344 enum snd_soc_bias_level level)
346 u8 reg;
347 struct uda134x_platform_data *pd = codec->control_data;
348 int i;
349 u8 *cache = codec->reg_cache;
351 pr_debug("%s bias level %d\n", __func__, level);
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++);
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;
379 codec->bias_level = level;
380 return 0;
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"};
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),
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),
401 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
402 SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
404 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
405 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
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]),
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),
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),
423 static const struct snd_kcontrol_new uda1340_snd_controls[] = {
424 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
426 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
427 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
429 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
430 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
432 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
435 static const struct snd_kcontrol_new uda1345_snd_controls[] = {
436 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
438 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
440 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
443 static struct snd_soc_dai_ops uda134x_dai_ops = {
444 .startup = uda134x_startup,
445 .shutdown = uda134x_shutdown,
446 .hw_params = uda134x_hw_params,
447 .digital_mute = uda134x_mute,
448 .set_sysclk = uda134x_set_dai_sysclk,
449 .set_fmt = uda134x_set_dai_fmt,
452 struct snd_soc_dai uda134x_dai = {
453 .name = "UDA134X",
454 /* playback capabilities */
455 .playback = {
456 .stream_name = "Playback",
457 .channels_min = 1,
458 .channels_max = 2,
459 .rates = UDA134X_RATES,
460 .formats = UDA134X_FORMATS,
462 /* capture capabilities */
463 .capture = {
464 .stream_name = "Capture",
465 .channels_min = 1,
466 .channels_max = 2,
467 .rates = UDA134X_RATES,
468 .formats = UDA134X_FORMATS,
470 /* pcm operations */
471 .ops = &uda134x_dai_ops,
473 EXPORT_SYMBOL(uda134x_dai);
476 static int uda134x_soc_probe(struct platform_device *pdev)
478 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
479 struct snd_soc_codec *codec;
480 struct uda134x_priv *uda134x;
481 void *codec_setup_data = socdev->codec_data;
482 int ret = -ENOMEM;
483 struct uda134x_platform_data *pd;
485 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
487 if (!codec_setup_data) {
488 printk(KERN_ERR "UDA134X SoC codec: "
489 "missing L3 bitbang function\n");
490 return -ENODEV;
493 pd = codec_setup_data;
494 switch (pd->model) {
495 case UDA134X_UDA1340:
496 case UDA134X_UDA1341:
497 case UDA134X_UDA1344:
498 case UDA134X_UDA1345:
499 break;
500 default:
501 printk(KERN_ERR "UDA134X SoC codec: "
502 "unsupported model %d\n",
503 pd->model);
504 return -EINVAL;
507 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
508 if (socdev->card->codec == NULL)
509 return ret;
511 codec = socdev->card->codec;
513 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
514 if (uda134x == NULL)
515 goto priv_err;
516 snd_soc_codec_set_drvdata(codec, uda134x);
518 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
519 GFP_KERNEL);
520 if (codec->reg_cache == NULL)
521 goto reg_err;
523 mutex_init(&codec->mutex);
525 codec->reg_cache_size = sizeof(uda134x_reg);
526 codec->reg_cache_step = 1;
528 codec->name = "UDA134X";
529 codec->owner = THIS_MODULE;
530 codec->dai = &uda134x_dai;
531 codec->num_dai = 1;
532 codec->read = uda134x_read_reg_cache;
533 codec->write = uda134x_write;
534 #ifdef POWER_OFF_ON_STANDBY
535 codec->set_bias_level = uda134x_set_bias_level;
536 #endif
537 INIT_LIST_HEAD(&codec->dapm_widgets);
538 INIT_LIST_HEAD(&codec->dapm_paths);
540 codec->control_data = codec_setup_data;
542 if (pd->power)
543 pd->power(1);
545 uda134x_reset(codec);
547 /* register pcms */
548 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
549 if (ret < 0) {
550 printk(KERN_ERR "UDA134X: failed to register pcms\n");
551 goto pcm_err;
554 switch (pd->model) {
555 case UDA134X_UDA1340:
556 case UDA134X_UDA1344:
557 ret = snd_soc_add_controls(codec, uda1340_snd_controls,
558 ARRAY_SIZE(uda1340_snd_controls));
559 break;
560 case UDA134X_UDA1341:
561 ret = snd_soc_add_controls(codec, uda1341_snd_controls,
562 ARRAY_SIZE(uda1341_snd_controls));
563 break;
564 case UDA134X_UDA1345:
565 ret = snd_soc_add_controls(codec, uda1345_snd_controls,
566 ARRAY_SIZE(uda1345_snd_controls));
567 break;
568 default:
569 printk(KERN_ERR "%s unknown codec type: %d",
570 __func__, pd->model);
571 return -EINVAL;
574 if (ret < 0) {
575 printk(KERN_ERR "UDA134X: failed to register controls\n");
576 goto pcm_err;
579 return 0;
581 pcm_err:
582 kfree(codec->reg_cache);
583 reg_err:
584 kfree(snd_soc_codec_get_drvdata(codec));
585 priv_err:
586 kfree(codec);
587 return ret;
590 /* power down chip */
591 static int uda134x_soc_remove(struct platform_device *pdev)
593 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
594 struct snd_soc_codec *codec = socdev->card->codec;
596 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
599 snd_soc_free_pcms(socdev);
600 snd_soc_dapm_free(socdev);
602 kfree(snd_soc_codec_get_drvdata(codec));
603 kfree(codec->reg_cache);
604 kfree(codec);
606 return 0;
609 #if defined(CONFIG_PM)
610 static int uda134x_soc_suspend(struct platform_device *pdev,
611 pm_message_t state)
613 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
614 struct snd_soc_codec *codec = socdev->card->codec;
616 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
617 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
618 return 0;
621 static int uda134x_soc_resume(struct platform_device *pdev)
623 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
624 struct snd_soc_codec *codec = socdev->card->codec;
626 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
627 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
628 return 0;
630 #else
631 #define uda134x_soc_suspend NULL
632 #define uda134x_soc_resume NULL
633 #endif /* CONFIG_PM */
635 struct snd_soc_codec_device soc_codec_dev_uda134x = {
636 .probe = uda134x_soc_probe,
637 .remove = uda134x_soc_remove,
638 .suspend = uda134x_soc_suspend,
639 .resume = uda134x_soc_resume,
641 EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
643 static int __init uda134x_init(void)
645 return snd_soc_register_dai(&uda134x_dai);
647 module_init(uda134x_init);
649 static void __exit uda134x_exit(void)
651 snd_soc_unregister_dai(&uda134x_dai);
653 module_exit(uda134x_exit);
655 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
656 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
657 MODULE_LICENSE("GPL");