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>
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: %u",
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
);
171 static int uda134x_startup(struct snd_pcm_substream
*substream
,
172 struct snd_soc_dai
*dai
)
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
->card
->codec
;
177 struct uda134x_priv
*uda134x
= codec
->private_data
;
178 struct snd_pcm_runtime
*master_runtime
;
180 if (uda134x
->master_substream
) {
181 master_runtime
= uda134x
->master_substream
->runtime
;
183 pr_debug("%s constraining to %d bits at %d\n", __func__
,
184 master_runtime
->sample_bits
,
185 master_runtime
->rate
);
187 snd_pcm_hw_constraint_minmax(substream
->runtime
,
188 SNDRV_PCM_HW_PARAM_RATE
,
189 master_runtime
->rate
,
190 master_runtime
->rate
);
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
);
197 uda134x
->slave_substream
= substream
;
199 uda134x
->master_substream
= substream
;
204 static void uda134x_shutdown(struct snd_pcm_substream
*substream
,
205 struct snd_soc_dai
*dai
)
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
->card
->codec
;
210 struct uda134x_priv
*uda134x
= codec
->private_data
;
212 if (uda134x
->master_substream
== substream
)
213 uda134x
->master_substream
= uda134x
->slave_substream
;
215 uda134x
->slave_substream
= NULL
;
218 static int uda134x_hw_params(struct snd_pcm_substream
*substream
,
219 struct snd_pcm_hw_params
*params
,
220 struct snd_soc_dai
*dai
)
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
->card
->codec
;
225 struct uda134x_priv
*uda134x
= codec
->private_data
;
228 if (substream
== uda134x
->slave_substream
) {
229 pr_debug("%s ignoring hw_params for slave substream\n",
234 hw_params
= uda134x_read_reg_cache(codec
, UDA134X_STATUS0
);
235 hw_params
&= STATUS0_SYSCLK_MASK
;
236 hw_params
&= STATUS0_DAIFMT_MASK
;
238 pr_debug("%s sysclk: %d, rate:%d\n", __func__
,
239 uda134x
->sysclk
, params_rate(params
));
241 /* set SYSCLK / fs ratio */
242 switch (uda134x
->sysclk
/ params_rate(params
)) {
252 printk(KERN_ERR
"%s unsupported fs\n", __func__
);
256 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__
,
257 uda134x
->dai_fmt
, params_format(params
));
259 /* set DAI format and word length */
260 switch (uda134x
->dai_fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
261 case SND_SOC_DAIFMT_I2S
:
263 case SND_SOC_DAIFMT_RIGHT_J
:
264 switch (params_format(params
)) {
265 case SNDRV_PCM_FORMAT_S16_LE
:
268 case SNDRV_PCM_FORMAT_S18_3LE
:
271 case SNDRV_PCM_FORMAT_S20_3LE
:
272 hw_params
|= ((1<<2) | (1<<1));
275 printk(KERN_ERR
"%s unsupported format (right)\n",
280 case SND_SOC_DAIFMT_LEFT_J
:
284 printk(KERN_ERR
"%s unsupported format\n", __func__
);
288 uda134x_write(codec
, UDA134X_STATUS0
, hw_params
);
293 static int uda134x_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
294 int clk_id
, unsigned int freq
, int dir
)
296 struct snd_soc_codec
*codec
= codec_dai
->codec
;
297 struct uda134x_priv
*uda134x
= codec
->private_data
;
299 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__
,
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
;
311 printk(KERN_ERR
"%s unsupported sysclk\n", __func__
);
315 static int uda134x_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
318 struct snd_soc_codec
*codec
= codec_dai
->codec
;
319 struct uda134x_priv
*uda134x
= codec
->private_data
;
321 pr_debug("%s fmt: %08X\n", __func__
, fmt
);
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__
);
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__
);
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
;
342 static int uda134x_set_bias_level(struct snd_soc_codec
*codec
,
343 enum snd_soc_bias_level level
)
346 struct uda134x_platform_data
*pd
= codec
->control_data
;
348 u8
*cache
= codec
->reg_cache
;
350 pr_debug("%s bias level %d\n", __func__
, level
);
353 case SND_SOC_BIAS_ON
:
355 reg
= uda134x_read_reg_cache(codec
, UDA134X_STATUS1
);
356 uda134x_write(codec
, UDA134X_STATUS1
, reg
| 0x03);
358 case SND_SOC_BIAS_PREPARE
:
362 /* Sync reg_cache with the hardware */
363 for (i
= 0; i
< ARRAY_SIZE(uda134x_reg
); i
++)
364 codec
->write(codec
, i
, *cache
++);
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));
372 case SND_SOC_BIAS_OFF
:
378 codec
->bias_level
= level
;
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",
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
),
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),
400 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010
, 2, 7, 0),
401 SOC_SINGLE("Mic Volume", UDA134X_EA101
, 0, 0x1F, 0),
403 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
404 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
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]),
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),
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),
422 static const struct snd_kcontrol_new uda1340_snd_controls
[] = {
423 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
425 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
426 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
428 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
429 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
431 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
434 static struct snd_soc_dai_ops uda134x_dai_ops
= {
435 .startup
= uda134x_startup
,
436 .shutdown
= uda134x_shutdown
,
437 .hw_params
= uda134x_hw_params
,
438 .digital_mute
= uda134x_mute
,
439 .set_sysclk
= uda134x_set_dai_sysclk
,
440 .set_fmt
= uda134x_set_dai_fmt
,
443 struct snd_soc_dai uda134x_dai
= {
445 /* playback capabilities */
447 .stream_name
= "Playback",
450 .rates
= UDA134X_RATES
,
451 .formats
= UDA134X_FORMATS
,
453 /* capture capabilities */
455 .stream_name
= "Capture",
458 .rates
= UDA134X_RATES
,
459 .formats
= UDA134X_FORMATS
,
462 .ops
= &uda134x_dai_ops
,
464 EXPORT_SYMBOL(uda134x_dai
);
467 static int uda134x_soc_probe(struct platform_device
*pdev
)
469 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
470 struct snd_soc_codec
*codec
;
471 struct uda134x_priv
*uda134x
;
472 void *codec_setup_data
= socdev
->codec_data
;
474 struct uda134x_platform_data
*pd
;
476 printk(KERN_INFO
"UDA134X SoC Audio Codec\n");
478 if (!codec_setup_data
) {
479 printk(KERN_ERR
"UDA134X SoC codec: "
480 "missing L3 bitbang function\n");
484 pd
= codec_setup_data
;
486 case UDA134X_UDA1340
:
487 case UDA134X_UDA1341
:
488 case UDA134X_UDA1344
:
491 printk(KERN_ERR
"UDA134X SoC codec: "
492 "unsupported model %d\n",
497 socdev
->card
->codec
= kzalloc(sizeof(struct snd_soc_codec
), GFP_KERNEL
);
498 if (socdev
->card
->codec
== NULL
)
501 codec
= socdev
->card
->codec
;
503 uda134x
= kzalloc(sizeof(struct uda134x_priv
), GFP_KERNEL
);
506 codec
->private_data
= uda134x
;
508 codec
->reg_cache
= kmemdup(uda134x_reg
, sizeof(uda134x_reg
),
510 if (codec
->reg_cache
== NULL
)
513 mutex_init(&codec
->mutex
);
515 codec
->reg_cache_size
= sizeof(uda134x_reg
);
516 codec
->reg_cache_step
= 1;
518 codec
->name
= "UDA134X";
519 codec
->owner
= THIS_MODULE
;
520 codec
->dai
= &uda134x_dai
;
522 codec
->read
= uda134x_read_reg_cache
;
523 codec
->write
= uda134x_write
;
524 #ifdef POWER_OFF_ON_STANDBY
525 codec
->set_bias_level
= uda134x_set_bias_level
;
527 INIT_LIST_HEAD(&codec
->dapm_widgets
);
528 INIT_LIST_HEAD(&codec
->dapm_paths
);
530 codec
->control_data
= codec_setup_data
;
535 uda134x_reset(codec
);
538 ret
= snd_soc_new_pcms(socdev
, SNDRV_DEFAULT_IDX1
, SNDRV_DEFAULT_STR1
);
540 printk(KERN_ERR
"UDA134X: failed to register pcms\n");
545 case UDA134X_UDA1340
:
546 case UDA134X_UDA1344
:
547 ret
= snd_soc_add_controls(codec
, uda1340_snd_controls
,
548 ARRAY_SIZE(uda1340_snd_controls
));
550 case UDA134X_UDA1341
:
551 ret
= snd_soc_add_controls(codec
, uda1341_snd_controls
,
552 ARRAY_SIZE(uda1341_snd_controls
));
555 printk(KERN_ERR
"%s unkown codec type: %d",
556 __func__
, pd
->model
);
561 printk(KERN_ERR
"UDA134X: failed to register controls\n");
565 ret
= snd_soc_init_card(socdev
);
567 printk(KERN_ERR
"UDA134X: failed to register card\n");
574 snd_soc_free_pcms(socdev
);
575 snd_soc_dapm_free(socdev
);
577 kfree(codec
->reg_cache
);
579 kfree(codec
->private_data
);
585 /* power down chip */
586 static int uda134x_soc_remove(struct platform_device
*pdev
)
588 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
589 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
591 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
592 uda134x_set_bias_level(codec
, SND_SOC_BIAS_OFF
);
594 snd_soc_free_pcms(socdev
);
595 snd_soc_dapm_free(socdev
);
597 kfree(codec
->private_data
);
598 kfree(codec
->reg_cache
);
604 #if defined(CONFIG_PM)
605 static int uda134x_soc_suspend(struct platform_device
*pdev
,
608 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
609 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
611 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
612 uda134x_set_bias_level(codec
, SND_SOC_BIAS_OFF
);
616 static int uda134x_soc_resume(struct platform_device
*pdev
)
618 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
619 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
621 uda134x_set_bias_level(codec
, SND_SOC_BIAS_PREPARE
);
622 uda134x_set_bias_level(codec
, SND_SOC_BIAS_ON
);
626 #define uda134x_soc_suspend NULL
627 #define uda134x_soc_resume NULL
628 #endif /* CONFIG_PM */
630 struct snd_soc_codec_device soc_codec_dev_uda134x
= {
631 .probe
= uda134x_soc_probe
,
632 .remove
= uda134x_soc_remove
,
633 .suspend
= uda134x_soc_suspend
,
634 .resume
= uda134x_soc_resume
,
636 EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x
);
638 static int __init
uda134x_init(void)
640 return snd_soc_register_dai(&uda134x_dai
);
642 module_init(uda134x_init
);
644 static void __exit
uda134x_exit(void)
646 snd_soc_unregister_dai(&uda134x_dai
);
648 module_exit(uda134x_exit
);
650 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
651 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
652 MODULE_LICENSE("GPL");