1 // SPDX-License-Identifier: GPL-2.0
3 // MAX9867 ALSA SoC codec driver
5 // Copyright 2013-2015 Maxim Integrated Products
6 // Copyright 2018 Ladislav Michl <ladis@linux-mips.org>
9 #include <linux/delay.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc.h>
15 #include <sound/tlv.h>
18 static const char *const max9867_spmode[] = {
19 "Stereo Diff", "Mono Diff",
20 "Stereo Cap", "Mono Cap",
21 "Stereo Single", "Mono Single",
22 "Stereo Single Fast", "Mono Single Fast"
24 static const char *const max9867_filter_text[] = {"IIR", "FIR"};
26 static const char *const max9867_adc_dac_filter_text[] = {
35 static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
37 static SOC_ENUM_SINGLE_DECL(max9867_dac_filter, MAX9867_CODECFLTR, 0,
38 max9867_adc_dac_filter_text);
39 static SOC_ENUM_SINGLE_DECL(max9867_adc_filter, MAX9867_CODECFLTR, 4,
40 max9867_adc_dac_filter_text);
41 static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
43 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv,
44 0, 2, TLV_DB_SCALE_ITEM(-8600, 200, 1),
45 3, 17, TLV_DB_SCALE_ITEM(-7800, 400, 0),
46 18, 25, TLV_DB_SCALE_ITEM(-2000, 200, 0),
47 26, 34, TLV_DB_SCALE_ITEM( -500, 100, 0),
48 35, 40, TLV_DB_SCALE_ITEM( 350, 50, 0),
50 static DECLARE_TLV_DB_SCALE(max9867_mic_tlv, 0, 100, 0);
51 static DECLARE_TLV_DB_SCALE(max9867_line_tlv, -600, 200, 0);
52 static DECLARE_TLV_DB_SCALE(max9867_adc_tlv, -1200, 100, 0);
53 static DECLARE_TLV_DB_SCALE(max9867_dac_tlv, -1500, 100, 0);
54 static DECLARE_TLV_DB_SCALE(max9867_dacboost_tlv, 0, 600, 0);
55 static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_micboost_tlv,
56 0, 2, TLV_DB_SCALE_ITEM(-2000, 2000, 1),
57 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
60 static const struct snd_kcontrol_new max9867_snd_controls[] = {
61 SOC_DOUBLE_R_TLV("Master Playback Volume", MAX9867_LEFTVOL,
62 MAX9867_RIGHTVOL, 0, 40, 1, max9867_master_tlv),
63 SOC_DOUBLE_R_TLV("Line Capture Volume", MAX9867_LEFTLINELVL,
64 MAX9867_RIGHTLINELVL, 0, 15, 1, max9867_line_tlv),
65 SOC_DOUBLE_R_TLV("Mic Capture Volume", MAX9867_LEFTMICGAIN,
66 MAX9867_RIGHTMICGAIN, 0, 20, 1, max9867_mic_tlv),
67 SOC_DOUBLE_R_TLV("Mic Boost Capture Volume", MAX9867_LEFTMICGAIN,
68 MAX9867_RIGHTMICGAIN, 5, 3, 0, max9867_micboost_tlv),
69 SOC_SINGLE("Digital Sidetone Volume", MAX9867_SIDETONE, 0, 31, 1),
70 SOC_SINGLE_TLV("Digital Playback Volume", MAX9867_DACLEVEL, 0, 15, 1,
72 SOC_SINGLE_TLV("Digital Boost Playback Volume", MAX9867_DACLEVEL, 4, 3, 0,
73 max9867_dacboost_tlv),
74 SOC_DOUBLE_TLV("Digital Capture Volume", MAX9867_ADCLEVEL, 4, 0, 15, 1,
76 SOC_ENUM("Speaker Mode", max9867_spkmode),
77 SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
78 SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
79 SOC_ENUM("DSP Filter", max9867_filter),
80 SOC_ENUM("ADC Filter", max9867_adc_filter),
81 SOC_ENUM("DAC Filter", max9867_dac_filter),
82 SOC_SINGLE("Mono Playback Switch", MAX9867_IFC1B, 3, 1, 0),
86 static const struct snd_kcontrol_new max9867_input_mixer_controls[] = {
87 SOC_DAPM_DOUBLE("Line Capture Switch", MAX9867_INPUTCONFIG, 7, 5, 1, 0),
88 SOC_DAPM_DOUBLE("Mic Capture Switch", MAX9867_INPUTCONFIG, 6, 4, 1, 0),
92 static const struct snd_kcontrol_new max9867_output_mixer_controls[] = {
93 SOC_DAPM_DOUBLE_R("Line Bypass Switch",
94 MAX9867_LEFTLINELVL, MAX9867_RIGHTLINELVL, 6, 1, 1),
98 static const struct snd_kcontrol_new max9867_sidetone_mixer_controls[] = {
99 SOC_DAPM_DOUBLE("Sidetone Switch", MAX9867_SIDETONE, 6, 7, 1, 0),
102 /* Line out switch */
103 static const struct snd_kcontrol_new max9867_line_out_control =
104 SOC_DAPM_DOUBLE_R("Switch",
105 MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1);
108 static const char *const dmic_mux_text[] = {
111 static SOC_ENUM_SINGLE_DECL(left_dmic_mux_enum,
112 MAX9867_MICCONFIG, 5, dmic_mux_text);
113 static SOC_ENUM_SINGLE_DECL(right_dmic_mux_enum,
114 MAX9867_MICCONFIG, 4, dmic_mux_text);
115 static const struct snd_kcontrol_new max9867_left_dmic_mux =
116 SOC_DAPM_ENUM("DMICL Mux", left_dmic_mux_enum);
117 static const struct snd_kcontrol_new max9867_right_dmic_mux =
118 SOC_DAPM_ENUM("DMICR Mux", right_dmic_mux_enum);
120 static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
121 SND_SOC_DAPM_INPUT("MICL"),
122 SND_SOC_DAPM_INPUT("MICR"),
123 SND_SOC_DAPM_INPUT("DMICL"),
124 SND_SOC_DAPM_INPUT("DMICR"),
125 SND_SOC_DAPM_INPUT("LINL"),
126 SND_SOC_DAPM_INPUT("LINR"),
128 SND_SOC_DAPM_PGA("Left Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
129 SND_SOC_DAPM_PGA("Right Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
130 SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
131 max9867_input_mixer_controls,
132 ARRAY_SIZE(max9867_input_mixer_controls)),
133 SND_SOC_DAPM_MUX("DMICL Mux", SND_SOC_NOPM, 0, 0,
134 &max9867_left_dmic_mux),
135 SND_SOC_DAPM_MUX("DMICR Mux", SND_SOC_NOPM, 0, 0,
136 &max9867_right_dmic_mux),
137 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", SND_SOC_NOPM, 0, 0),
138 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", SND_SOC_NOPM, 0, 0),
140 SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
141 max9867_sidetone_mixer_controls,
142 ARRAY_SIZE(max9867_sidetone_mixer_controls)),
143 SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
144 max9867_output_mixer_controls,
145 ARRAY_SIZE(max9867_output_mixer_controls)),
146 SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SND_SOC_NOPM, 0, 0),
147 SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SND_SOC_NOPM, 0, 0),
148 SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
149 &max9867_line_out_control),
150 SND_SOC_DAPM_OUTPUT("LOUT"),
151 SND_SOC_DAPM_OUTPUT("ROUT"),
154 static const struct snd_soc_dapm_route max9867_audio_map[] = {
155 {"Left Line Input", NULL, "LINL"},
156 {"Right Line Input", NULL, "LINR"},
157 {"Input Mixer", "Mic Capture Switch", "MICL"},
158 {"Input Mixer", "Mic Capture Switch", "MICR"},
159 {"Input Mixer", "Line Capture Switch", "Left Line Input"},
160 {"Input Mixer", "Line Capture Switch", "Right Line Input"},
161 {"DMICL Mux", "DMIC", "DMICL"},
162 {"DMICR Mux", "DMIC", "DMICR"},
163 {"DMICL Mux", "ADC", "Input Mixer"},
164 {"DMICR Mux", "ADC", "Input Mixer"},
165 {"ADCL", NULL, "DMICL Mux"},
166 {"ADCR", NULL, "DMICR Mux"},
168 {"Digital", "Sidetone Switch", "ADCL"},
169 {"Digital", "Sidetone Switch", "ADCR"},
170 {"DACL", NULL, "Digital"},
171 {"DACR", NULL, "Digital"},
173 {"Output Mixer", "Line Bypass Switch", "Left Line Input"},
174 {"Output Mixer", "Line Bypass Switch", "Right Line Input"},
175 {"Output Mixer", NULL, "DACL"},
176 {"Output Mixer", NULL, "DACR"},
177 {"Master Playback", "Switch", "Output Mixer"},
178 {"LOUT", NULL, "Master Playback"},
179 {"ROUT", NULL, "Master Playback"},
182 static const unsigned int max9867_rates_44k1[] = {
186 static const struct snd_pcm_hw_constraint_list max9867_constraints_44k1 = {
187 .list = max9867_rates_44k1,
188 .count = ARRAY_SIZE(max9867_rates_44k1),
191 static const unsigned int max9867_rates_48k[] = {
192 8000, 16000, 32000, 48000,
195 static const struct snd_pcm_hw_constraint_list max9867_constraints_48k = {
196 .list = max9867_rates_48k,
197 .count = ARRAY_SIZE(max9867_rates_48k),
200 struct max9867_priv {
201 struct regmap *regmap;
202 const struct snd_pcm_hw_constraint_list *constraints;
203 unsigned int sysclk, pclk;
207 static int max9867_startup(struct snd_pcm_substream *substream,
208 struct snd_soc_dai *dai)
210 struct max9867_priv *max9867 =
211 snd_soc_component_get_drvdata(dai->component);
213 if (max9867->constraints)
214 snd_pcm_hw_constraint_list(substream->runtime, 0,
215 SNDRV_PCM_HW_PARAM_RATE, max9867->constraints);
220 static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
221 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
224 unsigned long int rate, ratio;
225 struct snd_soc_component *component = dai->component;
226 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
227 unsigned int ni = DIV_ROUND_CLOSEST_ULL(96ULL * 0x10000 * params_rate(params),
230 /* set up the ni value */
231 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
232 MAX9867_NI_HIGH_MASK, (0xFF00 & ni) >> 8);
233 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
234 MAX9867_NI_LOW_MASK, 0x00FF & ni);
235 if (max9867->master) {
236 if (max9867->dsp_a) {
237 value = MAX9867_IFC1B_48X;
239 rate = params_rate(params) * 2 * params_width(params);
240 ratio = max9867->pclk / rate;
241 switch (params_width(params)) {
246 value = MAX9867_IFC1B_PCLK_2;
249 value = MAX9867_IFC1B_PCLK_4;
252 value = MAX9867_IFC1B_PCLK_8;
255 value = MAX9867_IFC1B_PCLK_16;
262 value = MAX9867_IFC1B_48X;
265 value = MAX9867_IFC1B_64X;
271 regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
272 MAX9867_IFC1B_BCLK_MASK, value);
275 * digital pll locks on to any externally supplied LRCLK signal
276 * and also enable rapid lock mode.
278 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
279 MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK);
280 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
281 MAX9867_PLL, MAX9867_PLL);
286 static int max9867_mute(struct snd_soc_dai *dai, int mute, int direction)
288 struct snd_soc_component *component = dai->component;
289 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
291 return regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
292 1 << 6, !!mute << 6);
295 static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
296 int clk_id, unsigned int freq, int dir)
298 struct snd_soc_component *component = codec_dai->component;
299 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
302 /* Set the prescaler based on the master clock frequency*/
303 if (freq >= 10000000 && freq <= 20000000) {
304 value |= MAX9867_PSCLK_10_20;
305 max9867->pclk = freq;
306 } else if (freq >= 20000000 && freq <= 40000000) {
307 value |= MAX9867_PSCLK_20_40;
308 max9867->pclk = freq / 2;
309 } else if (freq >= 40000000 && freq <= 60000000) {
310 value |= MAX9867_PSCLK_40_60;
311 max9867->pclk = freq / 4;
313 dev_err(component->dev,
314 "Invalid clock frequency %uHz (required 10-60MHz)\n",
318 if (freq % 48000 == 0)
319 max9867->constraints = &max9867_constraints_48k;
320 else if (freq % 44100 == 0)
321 max9867->constraints = &max9867_constraints_44k1;
323 dev_warn(component->dev,
324 "Unable to set exact rate with %uHz clock frequency\n",
326 max9867->sysclk = freq;
327 value = value << MAX9867_PSCLK_SHIFT;
328 /* exact integer mode is not supported */
329 value &= ~MAX9867_FREQ_MASK;
330 regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
331 MAX9867_PSCLK_MASK, value);
335 static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
338 struct snd_soc_component *component = codec_dai->component;
339 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
342 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
343 case SND_SOC_DAIFMT_CBM_CFM:
344 max9867->master = true;
345 iface1A = MAX9867_MASTER;
346 iface1B = MAX9867_IFC1B_48X;
348 case SND_SOC_DAIFMT_CBS_CFS:
349 max9867->master = false;
350 iface1A = iface1B = 0;
356 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
357 case SND_SOC_DAIFMT_I2S:
358 max9867->dsp_a = false;
359 iface1A |= MAX9867_I2S_DLY;
361 case SND_SOC_DAIFMT_DSP_A:
362 max9867->dsp_a = true;
363 iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ;
369 /* Clock inversion bits, BCI and WCI */
370 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
371 case SND_SOC_DAIFMT_NB_NF:
373 case SND_SOC_DAIFMT_IB_IF:
374 iface1A |= MAX9867_WCI_MODE | MAX9867_BCI_MODE;
376 case SND_SOC_DAIFMT_IB_NF:
377 iface1A |= MAX9867_BCI_MODE;
379 case SND_SOC_DAIFMT_NB_IF:
380 iface1A |= MAX9867_WCI_MODE;
386 regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
387 regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
388 MAX9867_IFC1B_BCLK_MASK, iface1B);
393 static const struct snd_soc_dai_ops max9867_dai_ops = {
394 .set_sysclk = max9867_set_dai_sysclk,
395 .set_fmt = max9867_dai_set_fmt,
396 .mute_stream = max9867_mute,
397 .startup = max9867_startup,
398 .hw_params = max9867_dai_hw_params,
399 .no_capture_mute = 1,
402 static struct snd_soc_dai_driver max9867_dai[] = {
404 .name = "max9867-aif1",
406 .stream_name = "HiFi Playback",
409 .rates = SNDRV_PCM_RATE_8000_48000,
410 .formats = SNDRV_PCM_FMTBIT_S16_LE,
413 .stream_name = "HiFi Capture",
416 .rates = SNDRV_PCM_RATE_8000_48000,
417 .formats = SNDRV_PCM_FMTBIT_S16_LE,
419 .ops = &max9867_dai_ops,
420 .symmetric_rates = 1,
425 static int max9867_suspend(struct snd_soc_component *component)
427 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
432 static int max9867_resume(struct snd_soc_component *component)
434 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
439 #define max9867_suspend NULL
440 #define max9867_resume NULL
443 static int max9867_set_bias_level(struct snd_soc_component *component,
444 enum snd_soc_bias_level level)
447 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
450 case SND_SOC_BIAS_STANDBY:
451 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
452 err = regcache_sync(max9867->regmap);
456 err = regmap_write(max9867->regmap,
457 MAX9867_PWRMAN, 0xff);
462 case SND_SOC_BIAS_OFF:
463 err = regmap_write(max9867->regmap, MAX9867_PWRMAN, 0);
467 regcache_mark_dirty(max9867->regmap);
476 static const struct snd_soc_component_driver max9867_component = {
477 .controls = max9867_snd_controls,
478 .num_controls = ARRAY_SIZE(max9867_snd_controls),
479 .dapm_routes = max9867_audio_map,
480 .num_dapm_routes = ARRAY_SIZE(max9867_audio_map),
481 .dapm_widgets = max9867_dapm_widgets,
482 .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets),
483 .suspend = max9867_suspend,
484 .resume = max9867_resume,
485 .set_bias_level = max9867_set_bias_level,
487 .use_pmdown_time = 1,
489 .non_legacy_dai_naming = 1,
492 static bool max9867_volatile_register(struct device *dev, unsigned int reg)
496 case MAX9867_JACKSTATUS:
497 case MAX9867_AUXHIGH:
505 static const struct regmap_config max9867_regmap = {
508 .max_register = MAX9867_REVISION,
509 .volatile_reg = max9867_volatile_register,
510 .cache_type = REGCACHE_RBTREE,
513 static int max9867_i2c_probe(struct i2c_client *i2c,
514 const struct i2c_device_id *id)
516 struct max9867_priv *max9867;
519 max9867 = devm_kzalloc(&i2c->dev, sizeof(*max9867), GFP_KERNEL);
523 i2c_set_clientdata(i2c, max9867);
524 max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
525 if (IS_ERR(max9867->regmap)) {
526 ret = PTR_ERR(max9867->regmap);
527 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
530 ret = regmap_read(max9867->regmap, MAX9867_REVISION, ®);
532 dev_err(&i2c->dev, "Failed to read: %d\n", ret);
535 dev_info(&i2c->dev, "device revision: %x\n", reg);
536 ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component,
537 max9867_dai, ARRAY_SIZE(max9867_dai));
539 dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
543 static const struct i2c_device_id max9867_i2c_id[] = {
547 MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
549 static const struct of_device_id max9867_of_match[] = {
550 { .compatible = "maxim,max9867", },
553 MODULE_DEVICE_TABLE(of, max9867_of_match);
555 static struct i2c_driver max9867_i2c_driver = {
558 .of_match_table = of_match_ptr(max9867_of_match),
560 .probe = max9867_i2c_probe,
561 .id_table = max9867_i2c_id,
564 module_i2c_driver(max9867_i2c_driver);
566 MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
567 MODULE_DESCRIPTION("ASoC MAX9867 driver");
568 MODULE_LICENSE("GPL");