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/initval.h>
24 #include <sound/uda134x.h>
30 #define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
31 #define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
32 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
38 struct snd_pcm_substream
*master_substream
;
39 struct snd_pcm_substream
*slave_substream
;
41 struct regmap
*regmap
;
42 struct uda134x_platform_data
*pd
;
45 static const struct reg_default uda134x_reg_defaults
[] = {
46 { UDA134X_EA000
, 0x04 },
47 { UDA134X_EA001
, 0x04 },
48 { UDA134X_EA010
, 0x04 },
49 { UDA134X_EA011
, 0x00 },
50 { UDA134X_EA100
, 0x00 },
51 { UDA134X_EA101
, 0x00 },
52 { UDA134X_EA110
, 0x00 },
53 { UDA134X_EA111
, 0x00 },
54 { UDA134X_STATUS0
, 0x00 },
55 { UDA134X_STATUS1
, 0x03 },
56 { UDA134X_DATA000
, 0x00 },
57 { UDA134X_DATA001
, 0x00 },
58 { UDA134X_DATA010
, 0x00 },
59 { UDA134X_DATA011
, 0x00 },
60 { UDA134X_DATA1
, 0x00 },
64 * Write to the uda134x registers
67 static int uda134x_regmap_write(void *context
, unsigned int reg
,
70 struct uda134x_platform_data
*pd
= context
;
78 addr
= UDA134X_STATUS_ADDR
;
79 data
|= (reg
- UDA134X_STATUS0
) << 7;
85 addr
= UDA134X_DATA0_ADDR
;
86 data
|= (reg
- UDA134X_DATA000
) << 6;
89 addr
= UDA134X_DATA1_ADDR
;
92 /* It's an extended address register */
93 addr
= (reg
| UDA134X_EXTADDR_PREFIX
);
95 ret
= l3_write(&pd
->l3
,
96 UDA134X_DATA0_ADDR
, &addr
, 1);
100 addr
= UDA134X_DATA0_ADDR
;
101 data
= (value
| UDA134X_EXTDATA_PREFIX
);
105 ret
= l3_write(&pd
->l3
,
113 static inline void uda134x_reset(struct snd_soc_codec
*codec
)
115 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
116 unsigned int mask
= 1<<6;
118 regmap_update_bits(uda134x
->regmap
, UDA134X_STATUS0
, mask
, mask
);
120 regmap_update_bits(uda134x
->regmap
, UDA134X_STATUS0
, mask
, 0);
123 static int uda134x_mute(struct snd_soc_dai
*dai
, int mute
)
125 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(dai
->codec
);
126 unsigned int mask
= 1<<2;
129 pr_debug("%s mute: %d\n", __func__
, mute
);
136 return regmap_update_bits(uda134x
->regmap
, UDA134X_DATA010
, mask
, val
);
139 static int uda134x_startup(struct snd_pcm_substream
*substream
,
140 struct snd_soc_dai
*dai
)
142 struct snd_soc_codec
*codec
= dai
->codec
;
143 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
144 struct snd_pcm_runtime
*master_runtime
;
146 if (uda134x
->master_substream
) {
147 master_runtime
= uda134x
->master_substream
->runtime
;
149 pr_debug("%s constraining to %d bits at %d\n", __func__
,
150 master_runtime
->sample_bits
,
151 master_runtime
->rate
);
153 snd_pcm_hw_constraint_single(substream
->runtime
,
154 SNDRV_PCM_HW_PARAM_RATE
,
155 master_runtime
->rate
);
157 snd_pcm_hw_constraint_single(substream
->runtime
,
158 SNDRV_PCM_HW_PARAM_SAMPLE_BITS
,
159 master_runtime
->sample_bits
);
161 uda134x
->slave_substream
= substream
;
163 uda134x
->master_substream
= substream
;
168 static void uda134x_shutdown(struct snd_pcm_substream
*substream
,
169 struct snd_soc_dai
*dai
)
171 struct snd_soc_codec
*codec
= dai
->codec
;
172 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
174 if (uda134x
->master_substream
== substream
)
175 uda134x
->master_substream
= uda134x
->slave_substream
;
177 uda134x
->slave_substream
= NULL
;
180 static int uda134x_hw_params(struct snd_pcm_substream
*substream
,
181 struct snd_pcm_hw_params
*params
,
182 struct snd_soc_dai
*dai
)
184 struct snd_soc_codec
*codec
= dai
->codec
;
185 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
186 unsigned int hw_params
= 0;
188 if (substream
== uda134x
->slave_substream
) {
189 pr_debug("%s ignoring hw_params for slave substream\n",
194 pr_debug("%s sysclk: %d, rate:%d\n", __func__
,
195 uda134x
->sysclk
, params_rate(params
));
197 /* set SYSCLK / fs ratio */
198 switch (uda134x
->sysclk
/ params_rate(params
)) {
208 printk(KERN_ERR
"%s unsupported fs\n", __func__
);
212 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__
,
213 uda134x
->dai_fmt
, params_format(params
));
215 /* set DAI format and word length */
216 switch (uda134x
->dai_fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
217 case SND_SOC_DAIFMT_I2S
:
219 case SND_SOC_DAIFMT_RIGHT_J
:
220 switch (params_width(params
)) {
228 hw_params
|= ((1<<2) | (1<<1));
231 printk(KERN_ERR
"%s unsupported format (right)\n",
236 case SND_SOC_DAIFMT_LEFT_J
:
240 printk(KERN_ERR
"%s unsupported format\n", __func__
);
244 return regmap_update_bits(uda134x
->regmap
, UDA134X_STATUS0
,
245 STATUS0_SYSCLK_MASK
| STATUS0_DAIFMT_MASK
, hw_params
);
248 static int uda134x_set_dai_sysclk(struct snd_soc_dai
*codec_dai
,
249 int clk_id
, unsigned int freq
, int dir
)
251 struct snd_soc_codec
*codec
= codec_dai
->codec
;
252 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
254 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__
,
257 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
258 because the codec is slave. Of course limitations of the clock
259 master (the IIS controller) apply.
260 We'll error out on set_hw_params if it's not OK */
261 if ((freq
>= (256 * 8000)) && (freq
<= (512 * 48000))) {
262 uda134x
->sysclk
= freq
;
266 printk(KERN_ERR
"%s unsupported sysclk\n", __func__
);
270 static int uda134x_set_dai_fmt(struct snd_soc_dai
*codec_dai
,
273 struct snd_soc_codec
*codec
= codec_dai
->codec
;
274 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
276 pr_debug("%s fmt: %08X\n", __func__
, fmt
);
278 /* codec supports only full slave mode */
279 if ((fmt
& SND_SOC_DAIFMT_MASTER_MASK
) != SND_SOC_DAIFMT_CBS_CFS
) {
280 printk(KERN_ERR
"%s unsupported slave mode\n", __func__
);
284 /* no support for clock inversion */
285 if ((fmt
& SND_SOC_DAIFMT_INV_MASK
) != SND_SOC_DAIFMT_NB_NF
) {
286 printk(KERN_ERR
"%s unsupported clock inversion\n", __func__
);
290 /* We can't setup DAI format here as it depends on the word bit num */
291 /* so let's just store the value for later */
292 uda134x
->dai_fmt
= fmt
;
297 static int uda134x_set_bias_level(struct snd_soc_codec
*codec
,
298 enum snd_soc_bias_level level
)
300 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
301 struct uda134x_platform_data
*pd
= uda134x
->pd
;
302 pr_debug("%s bias level %d\n", __func__
, level
);
305 case SND_SOC_BIAS_ON
:
307 case SND_SOC_BIAS_PREPARE
:
311 regcache_sync(uda134x
->regmap
);
314 case SND_SOC_BIAS_STANDBY
:
316 case SND_SOC_BIAS_OFF
:
320 regcache_mark_dirty(uda134x
->regmap
);
327 static const char *uda134x_dsp_setting
[] = {"Flat", "Minimum1",
328 "Minimum2", "Maximum"};
329 static const char *uda134x_deemph
[] = {"None", "32Khz", "44.1Khz", "48Khz"};
330 static const char *uda134x_mixmode
[] = {"Differential", "Analog1",
333 static const struct soc_enum uda134x_mixer_enum
[] = {
334 SOC_ENUM_SINGLE(UDA134X_DATA010
, 0, 0x04, uda134x_dsp_setting
),
335 SOC_ENUM_SINGLE(UDA134X_DATA010
, 3, 0x04, uda134x_deemph
),
336 SOC_ENUM_SINGLE(UDA134X_EA010
, 0, 0x04, uda134x_mixmode
),
339 static const struct snd_kcontrol_new uda1341_snd_controls
[] = {
340 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
341 SOC_SINGLE("Capture Volume", UDA134X_EA010
, 2, 0x07, 0),
342 SOC_SINGLE("Analog1 Volume", UDA134X_EA000
, 0, 0x1F, 1),
343 SOC_SINGLE("Analog2 Volume", UDA134X_EA001
, 0, 0x1F, 1),
345 SOC_SINGLE("Mic Sensitivity", UDA134X_EA010
, 2, 7, 0),
346 SOC_SINGLE("Mic Volume", UDA134X_EA101
, 0, 0x1F, 0),
348 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
349 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
351 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
352 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
353 SOC_ENUM("Input Mux", uda134x_mixer_enum
[2]),
355 SOC_SINGLE("AGC Switch", UDA134X_EA100
, 4, 1, 0),
356 SOC_SINGLE("AGC Target Volume", UDA134X_EA110
, 0, 0x03, 1),
357 SOC_SINGLE("AGC Timing", UDA134X_EA110
, 2, 0x07, 0),
359 SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1
, 6, 1, 0),
360 SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1
, 5, 1, 0),
361 SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1
, 4, 1, 0),
362 SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1
, 3, 1, 0),
363 SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1
, 2, 1, 0),
364 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
367 static const struct snd_kcontrol_new uda1340_snd_controls
[] = {
368 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
370 SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001
, 2, 0xF, 0),
371 SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001
, 0, 3, 0),
373 SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum
[0]),
374 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
376 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
379 static const struct snd_kcontrol_new uda1345_snd_controls
[] = {
380 SOC_SINGLE("Master Playback Volume", UDA134X_DATA000
, 0, 0x3F, 1),
382 SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum
[1]),
384 SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0
, 0, 1, 0),
387 /* UDA1341 has the DAC/ADC power down in STATUS1 */
388 static const struct snd_soc_dapm_widget uda1341_dapm_widgets
[] = {
389 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_STATUS1
, 0, 0),
390 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_STATUS1
, 1, 0),
393 /* UDA1340/4/5 has the DAC/ADC pwoer down in DATA0 11 */
394 static const struct snd_soc_dapm_widget uda1340_dapm_widgets
[] = {
395 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_DATA011
, 0, 0),
396 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_DATA011
, 1, 0),
399 /* Common DAPM widgets */
400 static const struct snd_soc_dapm_widget uda134x_dapm_widgets
[] = {
401 SND_SOC_DAPM_INPUT("VINL1"),
402 SND_SOC_DAPM_INPUT("VINR1"),
403 SND_SOC_DAPM_INPUT("VINL2"),
404 SND_SOC_DAPM_INPUT("VINR2"),
405 SND_SOC_DAPM_OUTPUT("VOUTL"),
406 SND_SOC_DAPM_OUTPUT("VOUTR"),
409 static const struct snd_soc_dapm_route uda134x_dapm_routes
[] = {
410 { "ADC", NULL
, "VINL1" },
411 { "ADC", NULL
, "VINR1" },
412 { "ADC", NULL
, "VINL2" },
413 { "ADC", NULL
, "VINR2" },
414 { "VOUTL", NULL
, "DAC" },
415 { "VOUTR", NULL
, "DAC" },
418 static const struct snd_soc_dai_ops uda134x_dai_ops
= {
419 .startup
= uda134x_startup
,
420 .shutdown
= uda134x_shutdown
,
421 .hw_params
= uda134x_hw_params
,
422 .digital_mute
= uda134x_mute
,
423 .set_sysclk
= uda134x_set_dai_sysclk
,
424 .set_fmt
= uda134x_set_dai_fmt
,
427 static struct snd_soc_dai_driver uda134x_dai
= {
428 .name
= "uda134x-hifi",
429 /* playback capabilities */
431 .stream_name
= "Playback",
434 .rates
= UDA134X_RATES
,
435 .formats
= UDA134X_FORMATS
,
437 /* capture capabilities */
439 .stream_name
= "Capture",
442 .rates
= UDA134X_RATES
,
443 .formats
= UDA134X_FORMATS
,
446 .ops
= &uda134x_dai_ops
,
449 static int uda134x_soc_probe(struct snd_soc_codec
*codec
)
451 struct snd_soc_dapm_context
*dapm
= snd_soc_codec_get_dapm(codec
);
452 struct uda134x_priv
*uda134x
= snd_soc_codec_get_drvdata(codec
);
453 struct uda134x_platform_data
*pd
= uda134x
->pd
;
454 const struct snd_soc_dapm_widget
*widgets
;
455 unsigned num_widgets
;
458 printk(KERN_INFO
"UDA134X SoC Audio Codec\n");
461 case UDA134X_UDA1340
:
462 case UDA134X_UDA1341
:
463 case UDA134X_UDA1344
:
464 case UDA134X_UDA1345
:
467 printk(KERN_ERR
"UDA134X SoC codec: "
468 "unsupported model %d\n",
476 uda134x_reset(codec
);
478 if (pd
->model
== UDA134X_UDA1341
) {
479 widgets
= uda1341_dapm_widgets
;
480 num_widgets
= ARRAY_SIZE(uda1341_dapm_widgets
);
482 widgets
= uda1340_dapm_widgets
;
483 num_widgets
= ARRAY_SIZE(uda1340_dapm_widgets
);
486 ret
= snd_soc_dapm_new_controls(dapm
, widgets
, num_widgets
);
488 printk(KERN_ERR
"%s failed to register dapm controls: %d",
494 case UDA134X_UDA1340
:
495 case UDA134X_UDA1344
:
496 ret
= snd_soc_add_codec_controls(codec
, uda1340_snd_controls
,
497 ARRAY_SIZE(uda1340_snd_controls
));
499 case UDA134X_UDA1341
:
500 ret
= snd_soc_add_codec_controls(codec
, uda1341_snd_controls
,
501 ARRAY_SIZE(uda1341_snd_controls
));
503 case UDA134X_UDA1345
:
504 ret
= snd_soc_add_codec_controls(codec
, uda1345_snd_controls
,
505 ARRAY_SIZE(uda1345_snd_controls
));
508 printk(KERN_ERR
"%s unknown codec type: %d",
509 __func__
, pd
->model
);
514 printk(KERN_ERR
"UDA134X: failed to register controls\n");
521 static const struct snd_soc_codec_driver soc_codec_dev_uda134x
= {
522 .probe
= uda134x_soc_probe
,
523 .set_bias_level
= uda134x_set_bias_level
,
524 .suspend_bias_off
= true,
526 .component_driver
= {
527 .dapm_widgets
= uda134x_dapm_widgets
,
528 .num_dapm_widgets
= ARRAY_SIZE(uda134x_dapm_widgets
),
529 .dapm_routes
= uda134x_dapm_routes
,
530 .num_dapm_routes
= ARRAY_SIZE(uda134x_dapm_routes
),
534 static const struct regmap_config uda134x_regmap_config
= {
537 .max_register
= UDA134X_DATA1
,
538 .reg_defaults
= uda134x_reg_defaults
,
539 .num_reg_defaults
= ARRAY_SIZE(uda134x_reg_defaults
),
540 .cache_type
= REGCACHE_RBTREE
,
542 .reg_write
= uda134x_regmap_write
,
545 static int uda134x_codec_probe(struct platform_device
*pdev
)
547 struct uda134x_platform_data
*pd
= pdev
->dev
.platform_data
;
548 struct uda134x_priv
*uda134x
;
552 dev_err(&pdev
->dev
, "Missing L3 bitbang function\n");
556 uda134x
= devm_kzalloc(&pdev
->dev
, sizeof(*uda134x
), GFP_KERNEL
);
561 platform_set_drvdata(pdev
, uda134x
);
563 if (pd
->l3
.use_gpios
) {
564 ret
= l3_set_gpio_ops(&pdev
->dev
, &uda134x
->pd
->l3
);
569 uda134x
->regmap
= devm_regmap_init(&pdev
->dev
, NULL
, pd
,
570 &uda134x_regmap_config
);
571 if (IS_ERR(uda134x
->regmap
))
572 return PTR_ERR(uda134x
->regmap
);
574 return snd_soc_register_codec(&pdev
->dev
,
575 &soc_codec_dev_uda134x
, &uda134x_dai
, 1);
578 static int uda134x_codec_remove(struct platform_device
*pdev
)
580 snd_soc_unregister_codec(&pdev
->dev
);
584 static struct platform_driver uda134x_codec_driver
= {
586 .name
= "uda134x-codec",
588 .probe
= uda134x_codec_probe
,
589 .remove
= uda134x_codec_remove
,
592 module_platform_driver(uda134x_codec_driver
);
594 MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
595 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
596 MODULE_LICENSE("GPL");