2 * uda134x.c -- UDA134X ALSA SoC Codec driver
4 * Modifications by Christian Pellegrin <chripell@evolware.org>
6 * Copyright 2007 Dension Audio Systems Ltd.
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 <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>
24 #include <sound/uda134x.h>
27 #include "uda134x_codec.h"
30 #define POWER_OFF_ON_STANDBY 1
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.
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)
51 struct snd_pcm_substream *master_substream;
52 struct snd_pcm_substream *slave_substream;
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,
64 * The codec has no support for reading its registers except for peak level...
66 static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
69 u8 *cache = codec->reg_cache;
71 if (reg >= UDA134X_REGS_NUM)
77 * Write the register cache
79 static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
80 u8 reg, unsigned int value)
82 u8 *cache = codec->reg_cache;
84 if (reg >= UDA134X_REGS_NUM)
90 * Write to the uda134x registers
93 static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
99 struct uda134x_platform_data *pd = codec->control_data;
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %d",
109 uda134x_write_reg_cache(codec, reg, value);
112 case UDA134X_STATUS0:
113 case UDA134X_STATUS1:
114 addr = UDA134X_STATUS_ADDR;
116 case UDA134X_DATA000:
117 case UDA134X_DATA001:
118 case UDA134X_DATA010:
119 addr = UDA134X_DATA0_ADDR;
122 addr = UDA134X_DATA1_ADDR;
125 /* It's an extended address register */
126 addr = (reg | UDA134X_EXTADDR_PREFIX);
128 ret = l3_write(&pd->l3,
129 UDA134X_DATA0_ADDR, &addr, 1);
133 addr = UDA134X_DATA0_ADDR;
134 data = (value | UDA134X_EXTDATA_PREFIX);
138 ret = l3_write(&pd->l3,
146 static inline void uda134x_reset(struct snd_soc_codec *codec)
148 u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
149 uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
151 uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
154 static int uda134x_mute(struct snd_soc_dai *dai, int mute)
156 struct snd_soc_codec *codec = dai->codec;
157 u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
159 pr_debug("%s mute: %d\n", __func__, mute);
166 uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
171 static int uda134x_startup(struct snd_pcm_substream *substream)
173 struct snd_soc_pcm_runtime *rtd = substream->private_data;
174 struct snd_soc_device *socdev = rtd->socdev;
175 struct snd_soc_codec *codec = socdev->codec;
176 struct uda134x_priv *uda134x = codec->private_data;
177 struct snd_pcm_runtime *master_runtime;
179 if (uda134x->master_substream) {
180 master_runtime = uda134x->master_substream->runtime;
182 pr_debug("%s constraining to %d bits at %d\n", __func__,
183 master_runtime->sample_bits,
184 master_runtime->rate);
186 snd_pcm_hw_constraint_minmax(substream->runtime,
187 SNDRV_PCM_HW_PARAM_RATE,
188 master_runtime->rate,
189 master_runtime->rate);
191 snd_pcm_hw_constraint_minmax(substream->runtime,
192 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
193 master_runtime->sample_bits,
194 master_runtime->sample_bits);
196 uda134x->slave_substream = substream;
198 uda134x->master_substream = substream;
203 static void uda134x_shutdown(struct snd_pcm_substream *substream)
205 struct snd_soc_pcm_runtime *rtd = substream->private_data;
206 struct snd_soc_device *socdev = rtd->socdev;
207 struct snd_soc_codec *codec = socdev->codec;
208 struct uda134x_priv *uda134x = codec->private_data;
210 if (uda134x->master_substream == substream)
211 uda134x->master_substream = uda134x->slave_substream;
213 uda134x->slave_substream = NULL;
216 static int uda134x_hw_params(struct snd_pcm_substream *substream,
217 struct snd_pcm_hw_params *params)
219 struct snd_soc_pcm_runtime *rtd = substream->private_data;
220 struct snd_soc_device *socdev = rtd->socdev;
221 struct snd_soc_codec *codec = socdev->codec;
222 struct uda134x_priv *uda134x = codec->private_data;
225 if (substream == uda134x->slave_substream) {
226 pr_debug("%s ignoring hw_params for slave substream\n",
231 hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
232 hw_params &= STATUS0_SYSCLK_MASK;
233 hw_params &= STATUS0_DAIFMT_MASK;
235 pr_debug("%s sysclk: %d, rate:%d\n", __func__,
236 uda134x->sysclk, params_rate(params));
238 /* set SYSCLK / fs ratio */
239 switch (uda134x->sysclk / params_rate(params)) {
249 printk(KERN_ERR "%s unsupported fs\n", __func__);
253 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
254 uda134x->dai_fmt, params_format(params));
256 /* set DAI format and word length */
257 switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
258 case SND_SOC_DAIFMT_I2S:
260 case SND_SOC_DAIFMT_RIGHT_J:
261 switch (params_format(params)) {
262 case SNDRV_PCM_FORMAT_S16_LE:
265 case SNDRV_PCM_FORMAT_S18_3LE:
268 case SNDRV_PCM_FORMAT_S20_3LE:
269 hw_params |= ((1<<2) | (1<<1));
272 printk(KERN_ERR "%s unsupported format (right)\n",
277 case SND_SOC_DAIFMT_LEFT_J:
281 printk(KERN_ERR "%s unsupported format\n", __func__);
285 uda134x_write(codec, UDA134X_STATUS0, hw_params);
290 static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
291 int clk_id, unsigned int freq, int dir)
293 struct snd_soc_codec *codec = codec_dai->codec;
294 struct uda134x_priv *uda134x = codec->private_data;
296 pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
299 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
300 because the codec is slave. Of course limitations of the clock
301 master (the IIS controller) apply.
302 We'll error out on set_hw_params if it's not OK */
303 if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
304 uda134x->sysclk = freq;
308 printk(KERN_ERR "%s unsupported sysclk\n", __func__);
312 static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
315 struct snd_soc_codec *codec = codec_dai->codec;
316 struct uda134x_priv *uda134x = codec->private_data;
318 pr_debug("%s fmt: %08X\n", __func__, fmt);
320 /* codec supports only full slave mode */
321 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
322 printk(KERN_ERR "%s unsupported slave mode\n", __func__);
326 /* no support for clock inversion */
327 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
328 printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
332 /* We can't setup DAI format here as it depends on the word bit num */
333 /* so let's just store the value for later */
334 uda134x->dai_fmt = fmt;
339 static int uda134x_set_bias_level(struct snd_soc_codec *codec,
340 enum snd_soc_bias_level level)
343 struct uda134x_platform_data *pd = codec->control_data;
345 u8 *cache = codec->reg_cache;
347 pr_debug("%s bias level %d\n", __func__, level);
350 case SND_SOC_BIAS_ON:
352 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
353 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
355 case SND_SOC_BIAS_PREPARE:
359 /* Sync reg_cache with the hardware */
360 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
361 codec->write(codec, i, *cache++);
364 case SND_SOC_BIAS_STANDBY:
365 /* ADC, DAC power off */
366 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
367 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
369 case SND_SOC_BIAS_OFF:
375 codec->bias_level = level;
379 static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
380 "Minimum2", "Maximum"};
381 static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
382 static const char *uda134x_mixmode[] = {"Differential", "Analog1",
385 static const struct soc_enum uda134x_mixer_enum[] = {
386 SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
387 SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
388 SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
391 static const struct snd_kcontrol_new uda1341_snd_controls[] = {
392 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
393 SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
394 SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
395 SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
397 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
398 SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
400 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
401 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
403 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
404 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
405 SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
407 SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
408 SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
409 SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
411 SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
412 SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
413 SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
414 SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
415 SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
416 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
419 static const struct snd_kcontrol_new uda1340_snd_controls[] = {
420 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
422 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
423 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
425 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
426 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
428 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
431 static int uda134x_add_controls(struct snd_soc_codec *codec)
434 const struct snd_kcontrol_new *ctrls;
435 struct uda134x_platform_data *pd = codec->control_data;
438 case UDA134X_UDA1340:
439 case UDA134X_UDA1344:
440 n = ARRAY_SIZE(uda1340_snd_controls);
441 ctrls = uda1340_snd_controls;
443 case UDA134X_UDA1341:
444 n = ARRAY_SIZE(uda1341_snd_controls);
445 ctrls = uda1341_snd_controls;
448 printk(KERN_ERR "%s unkown codec type: %d",
449 __func__, pd->model);
453 for (i = 0; i < n; i++) {
454 err = snd_ctl_add(codec->card,
455 snd_soc_cnew(&ctrls[i],
464 struct snd_soc_dai uda134x_dai = {
466 /* playback capabilities */
468 .stream_name = "Playback",
471 .rates = UDA134X_RATES,
472 .formats = UDA134X_FORMATS,
474 /* capture capabilities */
476 .stream_name = "Capture",
479 .rates = UDA134X_RATES,
480 .formats = UDA134X_FORMATS,
484 .startup = uda134x_startup,
485 .shutdown = uda134x_shutdown,
486 .hw_params = uda134x_hw_params,
490 .digital_mute = uda134x_mute,
491 .set_sysclk = uda134x_set_dai_sysclk,
492 .set_fmt = uda134x_set_dai_fmt,
495 EXPORT_SYMBOL(uda134x_dai);
498 static int uda134x_soc_probe(struct platform_device *pdev)
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;
505 struct uda134x_platform_data *pd;
507 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
509 if (!codec_setup_data) {
510 printk(KERN_ERR "UDA134X SoC codec: "
511 "missing L3 bitbang function\n");
515 pd = codec_setup_data;
517 case UDA134X_UDA1340:
518 case UDA134X_UDA1341:
519 case UDA134X_UDA1344:
522 printk(KERN_ERR "UDA134X SoC codec: "
523 "unsupported model %d\n",
528 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
529 if (socdev->codec == NULL)
532 codec = socdev->codec;
534 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
537 codec->private_data = uda134x;
539 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
541 if (codec->reg_cache == NULL)
544 mutex_init(&codec->mutex);
546 codec->reg_cache_size = sizeof(uda134x_reg);
547 codec->reg_cache_step = 1;
549 codec->name = "UDA134X";
550 codec->owner = THIS_MODULE;
551 codec->dai = &uda134x_dai;
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;
558 INIT_LIST_HEAD(&codec->dapm_widgets);
559 INIT_LIST_HEAD(&codec->dapm_paths);
561 codec->control_data = codec_setup_data;
566 uda134x_reset(codec);
569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
571 printk(KERN_ERR "UDA134X: failed to register pcms\n");
575 ret = uda134x_add_controls(codec);
577 printk(KERN_ERR "UDA134X: failed to register controls\n");
581 ret = snd_soc_register_card(socdev);
583 printk(KERN_ERR "UDA134X: failed to register card\n");
590 snd_soc_free_pcms(socdev);
591 snd_soc_dapm_free(socdev);
593 kfree(codec->reg_cache);
595 kfree(codec->private_data);
601 /* power down chip */
602 static int uda134x_soc_remove(struct platform_device *pdev)
604 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
605 struct snd_soc_codec *codec = socdev->codec;
607 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
608 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
610 snd_soc_free_pcms(socdev);
611 snd_soc_dapm_free(socdev);
613 kfree(codec->private_data);
614 kfree(codec->reg_cache);
620 #if defined(CONFIG_PM)
621 static int uda134x_soc_suspend(struct platform_device *pdev,
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_codec *codec = socdev->codec;
627 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
628 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
632 static int uda134x_soc_resume(struct platform_device *pdev)
634 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
635 struct snd_soc_codec *codec = socdev->codec;
637 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
642 #define uda134x_soc_suspend NULL
643 #define uda134x_soc_resume NULL
644 #endif /* CONFIG_PM */
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,
652 EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
654 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
655 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
656 MODULE_LICENSE("GPL");