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 <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>
31 #define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
32 #define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
33 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
39 struct snd_pcm_substream
*master_substream
;
40 struct snd_pcm_substream
*slave_substream
;
43 /* In-data addresses are hard-coded into the reg-cache values */
44 static const char uda134x_reg
[UDA134X_REGS_NUM
] = {
45 /* Extended address registers */
46 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
47 /* Status, data regs */
48 0x00, 0x83, 0x00, 0x40, 0x80, 0xC0, 0x00,
52 * The codec has no support for reading its registers except for peak level...
54 static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec
*codec
,
57 u8
*cache
= codec
->reg_cache
;
59 if (reg
>= UDA134X_REGS_NUM
)
65 * Write the register cache
67 static inline void uda134x_write_reg_cache(struct snd_soc_codec
*codec
,
68 u8 reg
, unsigned int value
)
70 u8
*cache
= codec
->reg_cache
;
72 if (reg
>= UDA134X_REGS_NUM
)
78 * Write to the uda134x registers
81 static int uda134x_write(struct snd_soc_codec
*codec
, unsigned int reg
,
87 struct uda134x_platform_data
*pd
= codec
->control_data
;
89 pr_debug("%s reg: %02X, value:%02X\n", __func__
, reg
, value
);
91 if (reg
>= UDA134X_REGS_NUM
) {
92 printk(KERN_ERR
"%s unknown register: reg: %u",
97 uda134x_write_reg_cache(codec
, reg
, value
);
100 case UDA134X_STATUS0
:
101 case UDA134X_STATUS1
:
102 addr
= UDA134X_STATUS_ADDR
;
104 case UDA134X_DATA000
:
105 case UDA134X_DATA001
:
106 case UDA134X_DATA010
:
107 case UDA134X_DATA011
:
108 addr
= UDA134X_DATA0_ADDR
;
111 addr
= UDA134X_DATA1_ADDR
;
114 /* It's an extended address register */
115 addr
= (reg
| UDA134X_EXTADDR_PREFIX
);
117 ret
= l3_write(&pd
->l3
,
118 UDA134X_DATA0_ADDR
, &addr
, 1);
122 addr
= UDA134X_DATA0_ADDR
;
123 data
= (value
| UDA134X_EXTDATA_PREFIX
);
127 ret
= l3_write(&pd
->l3
,
135 static inline void uda134x_reset(struct snd_soc_codec
*codec
)
137 u8 reset_reg
= uda134x_read_reg_cache(codec
, UDA134X_STATUS0
);
138 uda134x_write(codec
, UDA134X_STATUS0
, reset_reg
| (1<<6));
140 uda134x_write(codec
, UDA134X_STATUS0
, reset_reg
& ~(1<<6));
143 static int uda134x_mute(struct snd_soc_dai
*dai
, int mute
)
145 struct snd_soc_codec
*codec
= dai
->codec
;
146 u8 mute_reg
= uda134x_read_reg_cache(codec
, UDA134X_DATA010
);
148 pr_debug("%s mute: %d\n", __func__
, mute
);
155 uda134x_write(codec
, UDA134X_DATA010
, mute_reg
);
160 static int uda134x_startup(struct snd_pcm_substream
*substream
,
161 struct snd_soc_dai
*dai
)
163 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
164 struct snd_soc_device
*socdev
= rtd
->socdev
;
165 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
166 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
167 struct snd_pcm_runtime
*master_runtime
;
169 if (uda134x
->master_substream
) {
170 master_runtime
= uda134x
->master_substream
->runtime
;
172 pr_debug("%s constraining to %d bits at %d\n", __func__
,
173 master_runtime
->sample_bits
,
174 master_runtime
->rate
);
176 snd_pcm_hw_constraint_minmax(substream
->runtime
,
177 SNDRV_PCM_HW_PARAM_RATE
,
178 master_runtime
->rate
,
179 master_runtime
->rate
);
181 snd_pcm_hw_constraint_minmax(substream
->runtime
,
182 SNDRV_PCM_HW_PARAM_SAMPLE_BITS
,
183 master_runtime
->sample_bits
,
184 master_runtime
->sample_bits
);
186 uda134x
->slave_substream
= substream
;
188 uda134x
->master_substream
= substream
;
193 static void uda134x_shutdown(struct snd_pcm_substream
*substream
,
194 struct snd_soc_dai
*dai
)
196 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
197 struct snd_soc_device
*socdev
= rtd
->socdev
;
198 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
199 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
201 if (uda134x
->master_substream
== substream
)
202 uda134x
->master_substream
= uda134x
->slave_substream
;
204 uda134x
->slave_substream
= NULL
;
207 static int uda134x_hw_params(struct snd_pcm_substream
*substream
,
208 struct snd_pcm_hw_params
*params
,
209 struct snd_soc_dai
*dai
)
211 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
212 struct snd_soc_device
*socdev
= rtd
->socdev
;
213 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
214 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
217 if (substream
== uda134x
->slave_substream
) {
218 pr_debug("%s ignoring hw_params for slave substream\n",
223 hw_params
= uda134x_read_reg_cache(codec
, UDA134X_STATUS0
);
224 hw_params
&= STATUS0_SYSCLK_MASK
;
225 hw_params
&= STATUS0_DAIFMT_MASK
;
227 pr_debug("%s sysclk: %d, rate:%d\n", __func__
,
228 uda134x
->sysclk
, params_rate(params
));
230 /* set SYSCLK / fs ratio */
231 switch (uda134x
->sysclk
/ params_rate(params
)) {
241 printk(KERN_ERR
"%s unsupported fs\n", __func__
);
245 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__
,
246 uda134x
->dai_fmt
, params_format(params
));
248 /* set DAI format and word length */
249 switch (uda134x
->dai_fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
250 case SND_SOC_DAIFMT_I2S
:
252 case SND_SOC_DAIFMT_RIGHT_J
:
253 switch (params_format(params
)) {
254 case SNDRV_PCM_FORMAT_S16_LE
:
257 case SNDRV_PCM_FORMAT_S18_3LE
:
260 case SNDRV_PCM_FORMAT_S20_3LE
:
261 hw_params
|= ((1<<2) | (1<<1));
264 printk(KERN_ERR
"%s unsupported format (right)\n",
269 case SND_SOC_DAIFMT_LEFT_J
:
273 printk(KERN_ERR
"%s unsupported format\n", __func__
);
277 uda134x_write(codec
, UDA134X_STATUS0
, hw_params
);
282 static int uda134x_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
283 int clk_id
, unsigned int freq
, int dir
)
285 struct snd_soc_codec
*codec
= codec_dai
->codec
;
286 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
288 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__
,
291 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
292 because the codec is slave. Of course limitations of the clock
293 master (the IIS controller) apply.
294 We'll error out on set_hw_params if it's not OK */
295 if ((freq
>= (256 * 8000)) && (freq
<= (512 * 48000))) {
296 uda134x
->sysclk
= freq
;
300 printk(KERN_ERR
"%s unsupported sysclk\n", __func__
);
304 static int uda134x_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
307 struct snd_soc_codec
*codec
= codec_dai
->codec
;
308 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
310 pr_debug("%s fmt: %08X\n", __func__
, fmt
);
312 /* codec supports only full slave mode */
313 if ((fmt
& SND_SOC_DAIFMT_MASTER_MASK
) != SND_SOC_DAIFMT_CBS_CFS
) {
314 printk(KERN_ERR
"%s unsupported slave mode\n", __func__
);
318 /* no support for clock inversion */
319 if ((fmt
& SND_SOC_DAIFMT_INV_MASK
) != SND_SOC_DAIFMT_NB_NF
) {
320 printk(KERN_ERR
"%s unsupported clock inversion\n", __func__
);
324 /* We can't setup DAI format here as it depends on the word bit num */
325 /* so let's just store the value for later */
326 uda134x
->dai_fmt
= fmt
;
331 static int uda134x_set_bias_level(struct snd_soc_codec
*codec
,
332 enum snd_soc_bias_level level
)
335 struct uda134x_platform_data
*pd
= codec
->control_data
;
337 u8
*cache
= codec
->reg_cache
;
339 pr_debug("%s bias level %d\n", __func__
, level
);
342 case SND_SOC_BIAS_ON
:
345 case UDA134X_UDA1340
:
346 case UDA134X_UDA1344
:
347 case UDA134X_UDA1345
:
348 reg
= uda134x_read_reg_cache(codec
, UDA134X_DATA011
);
349 uda134x_write(codec
, UDA134X_DATA011
, reg
| 0x03);
351 case UDA134X_UDA1341
:
352 reg
= uda134x_read_reg_cache(codec
, UDA134X_STATUS1
);
353 uda134x_write(codec
, UDA134X_STATUS1
, reg
| 0x03);
356 printk(KERN_ERR
"UDA134X SoC codec: "
357 "unsupported model %d\n", pd
->model
);
361 case SND_SOC_BIAS_PREPARE
:
365 /* Sync reg_cache with the hardware */
366 for (i
= 0; i
< ARRAY_SIZE(uda134x_reg
); i
++)
367 codec
->write(codec
, i
, *cache
++);
370 case SND_SOC_BIAS_STANDBY
:
371 /* ADC, DAC power off */
373 case UDA134X_UDA1340
:
374 case UDA134X_UDA1344
:
375 case UDA134X_UDA1345
:
376 reg
= uda134x_read_reg_cache(codec
, UDA134X_DATA011
);
377 uda134x_write(codec
, UDA134X_DATA011
, reg
& ~(0x03));
379 case UDA134X_UDA1341
:
380 reg
= uda134x_read_reg_cache(codec
, UDA134X_STATUS1
);
381 uda134x_write(codec
, UDA134X_STATUS1
, reg
& ~(0x03));
384 printk(KERN_ERR
"UDA134X SoC codec: "
385 "unsupported model %d\n", pd
->model
);
389 case SND_SOC_BIAS_OFF
:
395 codec
->bias_level
= level
;
399 static const char *uda134x_dsp_setting
[] = {"Flat", "Minimum1",
400 "Minimum2", "Maximum"};
401 static const char *uda134x_deemph
[] = {"None", "32Khz", "44.1Khz", "48Khz"};
402 static const char *uda134x_mixmode
[] = {"Differential", "Analog1",
405 static const struct soc_enum uda134x_mixer_enum
[] = {
406 SOC_ENUM_SINGLE(UDA134X_DATA010
, 0, 0x04, uda134x_dsp_setting
),
407 SOC_ENUM_SINGLE(UDA134X_DATA010
, 3, 0x04, uda134x_deemph
),
408 SOC_ENUM_SINGLE(UDA134X_EA010
, 0, 0x04, uda134x_mixmode
),
411 static const struct snd_kcontrol_new uda1341_snd_controls
[] = {
412 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
413 SOC_SINGLE("Capture Volume", UDA134X_EA010
, 2, 0x07, 0),
414 SOC_SINGLE("Analog1 Volume", UDA134X_EA000
, 0, 0x1F, 1),
415 SOC_SINGLE("Analog2 Volume", UDA134X_EA001
, 0, 0x1F, 1),
417 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010
, 2, 7, 0),
418 SOC_SINGLE("Mic Volume", UDA134X_EA101
, 0, 0x1F, 0),
420 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
421 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
423 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
424 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
425 SOC_ENUM("Input Mux", uda134x_mixer_enum
[2]),
427 SOC_SINGLE("AGC Switch", UDA134X_EA100
, 4, 1, 0),
428 SOC_SINGLE("AGC Target Volume", UDA134X_EA110
, 0, 0x03, 1),
429 SOC_SINGLE("AGC Timing", UDA134X_EA110
, 2, 0x07, 0),
431 SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1
, 6, 1, 0),
432 SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1
, 5, 1, 0),
433 SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1
, 4, 1, 0),
434 SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1
, 3, 1, 0),
435 SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1
, 2, 1, 0),
436 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
439 static const struct snd_kcontrol_new uda1340_snd_controls
[] = {
440 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
442 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
443 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
445 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
446 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
448 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
451 static const struct snd_kcontrol_new uda1345_snd_controls
[] = {
452 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
454 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
456 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
459 static struct snd_soc_dai_ops uda134x_dai_ops
= {
460 .startup
= uda134x_startup
,
461 .shutdown
= uda134x_shutdown
,
462 .hw_params
= uda134x_hw_params
,
463 .digital_mute
= uda134x_mute
,
464 .set_sysclk
= uda134x_set_dai_sysclk
,
465 .set_fmt
= uda134x_set_dai_fmt
,
468 struct snd_soc_dai uda134x_dai
= {
470 /* playback capabilities */
472 .stream_name
= "Playback",
475 .rates
= UDA134X_RATES
,
476 .formats
= UDA134X_FORMATS
,
478 /* capture capabilities */
480 .stream_name
= "Capture",
483 .rates
= UDA134X_RATES
,
484 .formats
= UDA134X_FORMATS
,
487 .ops
= &uda134x_dai_ops
,
489 EXPORT_SYMBOL(uda134x_dai
);
492 static int uda134x_soc_probe(struct platform_device
*pdev
)
494 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
495 struct snd_soc_codec
*codec
;
496 struct uda134x_priv
*uda134x
;
497 void *codec_setup_data
= socdev
->codec_data
;
499 struct uda134x_platform_data
*pd
;
501 printk(KERN_INFO
"UDA134X SoC Audio Codec\n");
503 if (!codec_setup_data
) {
504 printk(KERN_ERR
"UDA134X SoC codec: "
505 "missing L3 bitbang function\n");
509 pd
= codec_setup_data
;
511 case UDA134X_UDA1340
:
512 case UDA134X_UDA1341
:
513 case UDA134X_UDA1344
:
514 case UDA134X_UDA1345
:
517 printk(KERN_ERR
"UDA134X SoC codec: "
518 "unsupported model %d\n",
523 socdev
->card
->codec
= kzalloc(sizeof(struct snd_soc_codec
), GFP_KERNEL
);
524 if (socdev
->card
->codec
== NULL
)
527 codec
= socdev
->card
->codec
;
529 uda134x
= kzalloc(sizeof(struct uda134x_priv
), GFP_KERNEL
);
532 snd_soc_codec_set_drvdata(codec
, uda134x
);
534 codec
->reg_cache
= kmemdup(uda134x_reg
, sizeof(uda134x_reg
),
536 if (codec
->reg_cache
== NULL
)
539 mutex_init(&codec
->mutex
);
541 codec
->reg_cache_size
= sizeof(uda134x_reg
);
542 codec
->reg_cache_step
= 1;
544 codec
->name
= "UDA134X";
545 codec
->owner
= THIS_MODULE
;
546 codec
->dai
= &uda134x_dai
;
548 codec
->read
= uda134x_read_reg_cache
;
549 codec
->write
= uda134x_write
;
551 INIT_LIST_HEAD(&codec
->dapm_widgets
);
552 INIT_LIST_HEAD(&codec
->dapm_paths
);
554 codec
->control_data
= codec_setup_data
;
559 uda134x_reset(codec
);
561 if (pd
->is_powered_on_standby
) {
562 codec
->set_bias_level
= NULL
;
563 uda134x_set_bias_level(codec
, SND_SOC_BIAS_ON
);
565 codec
->set_bias_level
= uda134x_set_bias_level
;
566 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
570 ret
= snd_soc_new_pcms(socdev
, SNDRV_DEFAULT_IDX1
, SNDRV_DEFAULT_STR1
);
572 printk(KERN_ERR
"UDA134X: failed to register pcms\n");
577 case UDA134X_UDA1340
:
578 case UDA134X_UDA1344
:
579 ret
= snd_soc_add_controls(codec
, uda1340_snd_controls
,
580 ARRAY_SIZE(uda1340_snd_controls
));
582 case UDA134X_UDA1341
:
583 ret
= snd_soc_add_controls(codec
, uda1341_snd_controls
,
584 ARRAY_SIZE(uda1341_snd_controls
));
586 case UDA134X_UDA1345
:
587 ret
= snd_soc_add_controls(codec
, uda1345_snd_controls
,
588 ARRAY_SIZE(uda1345_snd_controls
));
591 printk(KERN_ERR
"%s unknown codec type: %d",
592 __func__
, pd
->model
);
597 printk(KERN_ERR
"UDA134X: failed to register controls\n");
604 kfree(codec
->reg_cache
);
606 kfree(snd_soc_codec_get_drvdata(codec
));
612 /* power down chip */
613 static int uda134x_soc_remove(struct platform_device
*pdev
)
615 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
616 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
618 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
619 uda134x_set_bias_level(codec
, SND_SOC_BIAS_OFF
);
621 snd_soc_free_pcms(socdev
);
622 snd_soc_dapm_free(socdev
);
624 kfree(snd_soc_codec_get_drvdata(codec
));
625 kfree(codec
->reg_cache
);
631 #if defined(CONFIG_PM)
632 static int uda134x_soc_suspend(struct platform_device
*pdev
,
635 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
636 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
638 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
639 uda134x_set_bias_level(codec
, SND_SOC_BIAS_OFF
);
643 static int uda134x_soc_resume(struct platform_device
*pdev
)
645 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
646 struct snd_soc_codec
*codec
= socdev
->card
->codec
;
648 uda134x_set_bias_level(codec
, SND_SOC_BIAS_PREPARE
);
649 uda134x_set_bias_level(codec
, SND_SOC_BIAS_ON
);
653 #define uda134x_soc_suspend NULL
654 #define uda134x_soc_resume NULL
655 #endif /* CONFIG_PM */
657 struct snd_soc_codec_device soc_codec_dev_uda134x
= {
658 .probe
= uda134x_soc_probe
,
659 .remove
= uda134x_soc_remove
,
660 .suspend
= uda134x_soc_suspend
,
661 .resume
= uda134x_soc_resume
,
663 EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x
);
665 static int __init
uda134x_init(void)
667 return snd_soc_register_dai(&uda134x_dai
);
669 module_init(uda134x_init
);
671 static void __exit
uda134x_exit(void)
673 snd_soc_unregister_dai(&uda134x_dai
);
675 module_exit(uda134x_exit
);
677 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
678 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
679 MODULE_LICENSE("GPL");