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_codec
*codec
=rtd
->codec
;
165 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
166 struct snd_pcm_runtime
*master_runtime
;
168 if (uda134x
->master_substream
) {
169 master_runtime
= uda134x
->master_substream
->runtime
;
171 pr_debug("%s constraining to %d bits at %d\n", __func__
,
172 master_runtime
->sample_bits
,
173 master_runtime
->rate
);
175 snd_pcm_hw_constraint_minmax(substream
->runtime
,
176 SNDRV_PCM_HW_PARAM_RATE
,
177 master_runtime
->rate
,
178 master_runtime
->rate
);
180 snd_pcm_hw_constraint_minmax(substream
->runtime
,
181 SNDRV_PCM_HW_PARAM_SAMPLE_BITS
,
182 master_runtime
->sample_bits
,
183 master_runtime
->sample_bits
);
185 uda134x
->slave_substream
= substream
;
187 uda134x
->master_substream
= substream
;
192 static void uda134x_shutdown(struct snd_pcm_substream
*substream
,
193 struct snd_soc_dai
*dai
)
195 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
196 struct snd_soc_codec
*codec
= rtd
->codec
;
197 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
199 if (uda134x
->master_substream
== substream
)
200 uda134x
->master_substream
= uda134x
->slave_substream
;
202 uda134x
->slave_substream
= NULL
;
205 static int uda134x_hw_params(struct snd_pcm_substream
*substream
,
206 struct snd_pcm_hw_params
*params
,
207 struct snd_soc_dai
*dai
)
209 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
210 struct snd_soc_codec
*codec
= rtd
->codec
;
211 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
214 if (substream
== uda134x
->slave_substream
) {
215 pr_debug("%s ignoring hw_params for slave substream\n",
220 hw_params
= uda134x_read_reg_cache(codec
, UDA134X_STATUS0
);
221 hw_params
&= STATUS0_SYSCLK_MASK
;
222 hw_params
&= STATUS0_DAIFMT_MASK
;
224 pr_debug("%s sysclk: %d, rate:%d\n", __func__
,
225 uda134x
->sysclk
, params_rate(params
));
227 /* set SYSCLK / fs ratio */
228 switch (uda134x
->sysclk
/ params_rate(params
)) {
238 printk(KERN_ERR
"%s unsupported fs\n", __func__
);
242 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__
,
243 uda134x
->dai_fmt
, params_format(params
));
245 /* set DAI format and word length */
246 switch (uda134x
->dai_fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
247 case SND_SOC_DAIFMT_I2S
:
249 case SND_SOC_DAIFMT_RIGHT_J
:
250 switch (params_format(params
)) {
251 case SNDRV_PCM_FORMAT_S16_LE
:
254 case SNDRV_PCM_FORMAT_S18_3LE
:
257 case SNDRV_PCM_FORMAT_S20_3LE
:
258 hw_params
|= ((1<<2) | (1<<1));
261 printk(KERN_ERR
"%s unsupported format (right)\n",
266 case SND_SOC_DAIFMT_LEFT_J
:
270 printk(KERN_ERR
"%s unsupported format\n", __func__
);
274 uda134x_write(codec
, UDA134X_STATUS0
, hw_params
);
279 static int uda134x_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
280 int clk_id
, unsigned int freq
, int dir
)
282 struct snd_soc_codec
*codec
= codec_dai
->codec
;
283 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
285 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__
,
288 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
289 because the codec is slave. Of course limitations of the clock
290 master (the IIS controller) apply.
291 We'll error out on set_hw_params if it's not OK */
292 if ((freq
>= (256 * 8000)) && (freq
<= (512 * 48000))) {
293 uda134x
->sysclk
= freq
;
297 printk(KERN_ERR
"%s unsupported sysclk\n", __func__
);
301 static int uda134x_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
304 struct snd_soc_codec
*codec
= codec_dai
->codec
;
305 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
307 pr_debug("%s fmt: %08X\n", __func__
, fmt
);
309 /* codec supports only full slave mode */
310 if ((fmt
& SND_SOC_DAIFMT_MASTER_MASK
) != SND_SOC_DAIFMT_CBS_CFS
) {
311 printk(KERN_ERR
"%s unsupported slave mode\n", __func__
);
315 /* no support for clock inversion */
316 if ((fmt
& SND_SOC_DAIFMT_INV_MASK
) != SND_SOC_DAIFMT_NB_NF
) {
317 printk(KERN_ERR
"%s unsupported clock inversion\n", __func__
);
321 /* We can't setup DAI format here as it depends on the word bit num */
322 /* so let's just store the value for later */
323 uda134x
->dai_fmt
= fmt
;
328 static int uda134x_set_bias_level(struct snd_soc_codec
*codec
,
329 enum snd_soc_bias_level level
)
332 struct uda134x_platform_data
*pd
= codec
->control_data
;
334 u8
*cache
= codec
->reg_cache
;
336 pr_debug("%s bias level %d\n", __func__
, level
);
339 case SND_SOC_BIAS_ON
:
342 case UDA134X_UDA1340
:
343 case UDA134X_UDA1344
:
344 case UDA134X_UDA1345
:
345 reg
= uda134x_read_reg_cache(codec
, UDA134X_DATA011
);
346 uda134x_write(codec
, UDA134X_DATA011
, reg
| 0x03);
348 case UDA134X_UDA1341
:
349 reg
= uda134x_read_reg_cache(codec
, UDA134X_STATUS1
);
350 uda134x_write(codec
, UDA134X_STATUS1
, reg
| 0x03);
353 printk(KERN_ERR
"UDA134X SoC codec: "
354 "unsupported model %d\n", pd
->model
);
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
->driver
->write(codec
, i
, *cache
++);
367 case SND_SOC_BIAS_STANDBY
:
368 /* ADC, DAC power off */
370 case UDA134X_UDA1340
:
371 case UDA134X_UDA1344
:
372 case UDA134X_UDA1345
:
373 reg
= uda134x_read_reg_cache(codec
, UDA134X_DATA011
);
374 uda134x_write(codec
, UDA134X_DATA011
, reg
& ~(0x03));
376 case UDA134X_UDA1341
:
377 reg
= uda134x_read_reg_cache(codec
, UDA134X_STATUS1
);
378 uda134x_write(codec
, UDA134X_STATUS1
, reg
& ~(0x03));
381 printk(KERN_ERR
"UDA134X SoC codec: "
382 "unsupported model %d\n", pd
->model
);
386 case SND_SOC_BIAS_OFF
:
392 codec
->bias_level
= level
;
396 static const char *uda134x_dsp_setting
[] = {"Flat", "Minimum1",
397 "Minimum2", "Maximum"};
398 static const char *uda134x_deemph
[] = {"None", "32Khz", "44.1Khz", "48Khz"};
399 static const char *uda134x_mixmode
[] = {"Differential", "Analog1",
402 static const struct soc_enum uda134x_mixer_enum
[] = {
403 SOC_ENUM_SINGLE(UDA134X_DATA010
, 0, 0x04, uda134x_dsp_setting
),
404 SOC_ENUM_SINGLE(UDA134X_DATA010
, 3, 0x04, uda134x_deemph
),
405 SOC_ENUM_SINGLE(UDA134X_EA010
, 0, 0x04, uda134x_mixmode
),
408 static const struct snd_kcontrol_new uda1341_snd_controls
[] = {
409 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
410 SOC_SINGLE("Capture Volume", UDA134X_EA010
, 2, 0x07, 0),
411 SOC_SINGLE("Analog1 Volume", UDA134X_EA000
, 0, 0x1F, 1),
412 SOC_SINGLE("Analog2 Volume", UDA134X_EA001
, 0, 0x1F, 1),
414 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010
, 2, 7, 0),
415 SOC_SINGLE("Mic Volume", UDA134X_EA101
, 0, 0x1F, 0),
417 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
418 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
420 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
421 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
422 SOC_ENUM("Input Mux", uda134x_mixer_enum
[2]),
424 SOC_SINGLE("AGC Switch", UDA134X_EA100
, 4, 1, 0),
425 SOC_SINGLE("AGC Target Volume", UDA134X_EA110
, 0, 0x03, 1),
426 SOC_SINGLE("AGC Timing", UDA134X_EA110
, 2, 0x07, 0),
428 SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1
, 6, 1, 0),
429 SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1
, 5, 1, 0),
430 SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1
, 4, 1, 0),
431 SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1
, 3, 1, 0),
432 SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1
, 2, 1, 0),
433 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
436 static const struct snd_kcontrol_new uda1340_snd_controls
[] = {
437 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
439 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
440 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
442 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
443 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
445 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
448 static const struct snd_kcontrol_new uda1345_snd_controls
[] = {
449 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
451 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
453 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
456 static struct snd_soc_dai_ops uda134x_dai_ops
= {
457 .startup
= uda134x_startup
,
458 .shutdown
= uda134x_shutdown
,
459 .hw_params
= uda134x_hw_params
,
460 .digital_mute
= uda134x_mute
,
461 .set_sysclk
= uda134x_set_dai_sysclk
,
462 .set_fmt
= uda134x_set_dai_fmt
,
465 static struct snd_soc_dai_driver uda134x_dai
= {
466 .name
= "uda134x-hifi",
467 /* playback capabilities */
469 .stream_name
= "Playback",
472 .rates
= UDA134X_RATES
,
473 .formats
= UDA134X_FORMATS
,
475 /* capture capabilities */
477 .stream_name
= "Capture",
480 .rates
= UDA134X_RATES
,
481 .formats
= UDA134X_FORMATS
,
484 .ops
= &uda134x_dai_ops
,
487 static int uda134x_soc_probe(struct snd_soc_codec
*codec
)
489 struct uda134x_priv
*uda134x
;
490 struct uda134x_platform_data
*pd
= dev_get_drvdata(codec
->card
->dev
);
493 printk(KERN_INFO
"UDA134X SoC Audio Codec\n");
496 printk(KERN_ERR
"UDA134X SoC codec: "
497 "missing L3 bitbang function\n");
502 case UDA134X_UDA1340
:
503 case UDA134X_UDA1341
:
504 case UDA134X_UDA1344
:
505 case UDA134X_UDA1345
:
508 printk(KERN_ERR
"UDA134X SoC codec: "
509 "unsupported model %d\n",
514 uda134x
= kzalloc(sizeof(struct uda134x_priv
), GFP_KERNEL
);
517 snd_soc_codec_set_drvdata(codec
, uda134x
);
519 codec
->control_data
= pd
;
524 uda134x_reset(codec
);
526 if (pd
->is_powered_on_standby
)
527 uda134x_set_bias_level(codec
, SND_SOC_BIAS_ON
);
529 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
532 case UDA134X_UDA1340
:
533 case UDA134X_UDA1344
:
534 ret
= snd_soc_add_controls(codec
, uda1340_snd_controls
,
535 ARRAY_SIZE(uda1340_snd_controls
));
537 case UDA134X_UDA1341
:
538 ret
= snd_soc_add_controls(codec
, uda1341_snd_controls
,
539 ARRAY_SIZE(uda1341_snd_controls
));
541 case UDA134X_UDA1345
:
542 ret
= snd_soc_add_controls(codec
, uda1345_snd_controls
,
543 ARRAY_SIZE(uda1345_snd_controls
));
546 printk(KERN_ERR
"%s unknown codec type: %d",
547 __func__
, pd
->model
);
553 printk(KERN_ERR
"UDA134X: failed to register controls\n");
561 /* power down chip */
562 static int uda134x_soc_remove(struct snd_soc_codec
*codec
)
564 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
566 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
567 uda134x_set_bias_level(codec
, SND_SOC_BIAS_OFF
);
573 #if defined(CONFIG_PM)
574 static int uda134x_soc_suspend(struct snd_soc_codec
*codec
,
577 uda134x_set_bias_level(codec
, SND_SOC_BIAS_STANDBY
);
578 uda134x_set_bias_level(codec
, SND_SOC_BIAS_OFF
);
582 static int uda134x_soc_resume(struct snd_soc_codec
*codec
)
584 uda134x_set_bias_level(codec
, SND_SOC_BIAS_PREPARE
);
585 uda134x_set_bias_level(codec
, SND_SOC_BIAS_ON
);
589 #define uda134x_soc_suspend NULL
590 #define uda134x_soc_resume NULL
591 #endif /* CONFIG_PM */
593 static struct snd_soc_codec_driver soc_codec_dev_uda134x
= {
594 .probe
= uda134x_soc_probe
,
595 .remove
= uda134x_soc_remove
,
596 .suspend
= uda134x_soc_suspend
,
597 .resume
= uda134x_soc_resume
,
598 .reg_cache_size
= sizeof(uda134x_reg
),
599 .reg_word_size
= sizeof(u8
),
601 .read
= uda134x_read_reg_cache
,
602 .write
= uda134x_write
,
603 #ifdef POWER_OFF_ON_STANDBY
604 .set_bias_level
= uda134x_set_bias_level
,
608 static int __devinit
uda134x_codec_probe(struct platform_device
*pdev
)
610 return snd_soc_register_codec(&pdev
->dev
,
611 &soc_codec_dev_uda134x
, &uda134x_dai
, 1);
614 static int __devexit
uda134x_codec_remove(struct platform_device
*pdev
)
616 snd_soc_unregister_codec(&pdev
->dev
);
620 static struct platform_driver uda134x_codec_driver
= {
622 .name
= "uda134x-codec",
623 .owner
= THIS_MODULE
,
625 .probe
= uda134x_codec_probe
,
626 .remove
= __devexit_p(uda134x_codec_remove
),
629 static int __init
uda134x_codec_init(void)
631 return platform_driver_register(&uda134x_codec_driver
);
633 module_init(uda134x_codec_init
);
635 static void __exit
uda134x_codec_exit(void)
637 platform_driver_unregister(&uda134x_codec_driver
);
639 module_exit(uda134x_codec_exit
);
641 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
642 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
643 MODULE_LICENSE("GPL");