cs35l45.c (44f37b6ce041c838cb2f49f08998c41f1ab3b08c) cs35l45.c (18050443b9fc4e809c077fbf0967349410e86117)
1// SPDX-License-Identifier: GPL-2.0
2//
3// cs35l45.c - CS35L45 ALSA SoC audio driver
4//
5// Copyright 2019-2022 Cirrus Logic, Inc.
6//
7// Author: James Schulman <james.schulman@cirrus.com>
8

--- 155 unchanged lines hidden (view full) ---

164 CSPL_MBOX_CMD_PAUSE);
165 default:
166 return 0;
167 }
168
169 return 0;
170}
171
1// SPDX-License-Identifier: GPL-2.0
2//
3// cs35l45.c - CS35L45 ALSA SoC audio driver
4//
5// Copyright 2019-2022 Cirrus Logic, Inc.
6//
7// Author: James Schulman <james.schulman@cirrus.com>
8

--- 155 unchanged lines hidden (view full) ---

164 CSPL_MBOX_CMD_PAUSE);
165 default:
166 return 0;
167 }
168
169 return 0;
170}
171
172static int cs35l45_activate_ctl(struct snd_soc_component *component,
173 const char *ctl_name, bool active)
174{
175 struct snd_card *card = component->card->snd_card;
176 struct snd_kcontrol *kcontrol;
177 struct snd_kcontrol_volatile *vd;
178 unsigned int index_offset;
179 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
180
181 if (component->name_prefix)
182 snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s",
183 component->name_prefix, ctl_name);
184 else
185 snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s", ctl_name);
186
187 kcontrol = snd_soc_card_get_kcontrol(component->card, name);
188 if (!kcontrol) {
189 dev_err(component->dev, "Can't find kcontrol %s\n", name);
190 return -EINVAL;
191 }
192
193 index_offset = snd_ctl_get_ioff(kcontrol, &kcontrol->id);
194 vd = &kcontrol->vd[index_offset];
195 if (active)
196 vd->access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
197 else
198 vd->access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE;
199
200 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &kcontrol->id);
201
202 return 0;
203}
204
205static int cs35l45_amplifier_mode_get(struct snd_kcontrol *kcontrol,
206 struct snd_ctl_elem_value *ucontrol)
207{
208 struct snd_soc_component *component =
209 snd_soc_kcontrol_component(kcontrol);
210 struct cs35l45_private *cs35l45 =
211 snd_soc_component_get_drvdata(component);
212
213 ucontrol->value.integer.value[0] = cs35l45->amplifier_mode;
214
215 return 0;
216}
217
218static int cs35l45_amplifier_mode_put(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_value *ucontrol)
220{
221 struct snd_soc_component *component =
222 snd_soc_kcontrol_component(kcontrol);
223 struct cs35l45_private *cs35l45 =
224 snd_soc_component_get_drvdata(component);
225 struct snd_soc_dapm_context *dapm =
226 snd_soc_component_get_dapm(component);
227 unsigned int amp_state;
228 int ret;
229
230 if ((ucontrol->value.integer.value[0] == cs35l45->amplifier_mode) ||
231 (ucontrol->value.integer.value[0] > AMP_MODE_RCV))
232 return 0;
233
234 snd_soc_dapm_mutex_lock(dapm);
235
236 ret = regmap_read(cs35l45->regmap, CS35L45_BLOCK_ENABLES, &amp_state);
237 if (ret < 0) {
238 dev_err(cs35l45->dev, "Failed to read AMP state: %d\n", ret);
239 snd_soc_dapm_mutex_unlock(dapm);
240 return ret;
241 }
242
243 regmap_clear_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
244 CS35L45_AMP_EN_MASK);
245 snd_soc_component_disable_pin_unlocked(component, "SPK");
246 snd_soc_dapm_sync_unlocked(dapm);
247
248 if (ucontrol->value.integer.value[0] == AMP_MODE_SPK) {
249 regmap_clear_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
250 CS35L45_RCV_EN_MASK);
251
252 regmap_update_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
253 CS35L45_BST_EN_MASK,
254 CS35L45_BST_ENABLE << CS35L45_BST_EN_SHIFT);
255
256 regmap_update_bits(cs35l45->regmap, CS35L45_HVLV_CONFIG,
257 CS35L45_HVLV_MODE_MASK,
258 CS35L45_HVLV_OPERATION <<
259 CS35L45_HVLV_MODE_SHIFT);
260
261 ret = cs35l45_activate_ctl(component, "Analog PCM Volume", true);
262 if (ret < 0)
263 dev_err(cs35l45->dev,
264 "Unable to deactivate ctl (%d)\n", ret);
265
266 } else /* AMP_MODE_RCV */ {
267 regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
268 CS35L45_RCV_EN_MASK);
269
270 regmap_update_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
271 CS35L45_BST_EN_MASK,
272 CS35L45_BST_DISABLE_FET_OFF <<
273 CS35L45_BST_EN_SHIFT);
274
275 regmap_update_bits(cs35l45->regmap, CS35L45_HVLV_CONFIG,
276 CS35L45_HVLV_MODE_MASK,
277 CS35L45_FORCE_LV_OPERATION <<
278 CS35L45_HVLV_MODE_SHIFT);
279
280 regmap_clear_bits(cs35l45->regmap,
281 CS35L45_BLOCK_ENABLES2,
282 CS35L45_AMP_DRE_EN_MASK);
283
284 regmap_update_bits(cs35l45->regmap, CS35L45_AMP_GAIN,
285 CS35L45_AMP_GAIN_PCM_MASK,
286 CS35L45_AMP_GAIN_PCM_13DBV <<
287 CS35L45_AMP_GAIN_PCM_SHIFT);
288
289 ret = cs35l45_activate_ctl(component, "Analog PCM Volume", false);
290 if (ret < 0)
291 dev_err(cs35l45->dev,
292 "Unable to deactivate ctl (%d)\n", ret);
293 }
294
295 if (amp_state & CS35L45_AMP_EN_MASK)
296 regmap_set_bits(cs35l45->regmap, CS35L45_BLOCK_ENABLES,
297 CS35L45_AMP_EN_MASK);
298
299 snd_soc_component_enable_pin_unlocked(component, "SPK");
300 snd_soc_dapm_sync_unlocked(dapm);
301 snd_soc_dapm_mutex_unlock(dapm);
302
303 cs35l45->amplifier_mode = ucontrol->value.integer.value[0];
304
305 return 1;
306}
307
172static const char * const cs35l45_asp_tx_txt[] = {
173 "Zero", "ASP_RX1", "ASP_RX2",
174 "VMON", "IMON", "ERR_VOL",
175 "VDD_BATTMON", "VDD_BSTMON",
176 "DSP_TX1", "DSP_TX2",
177 "Interpolator", "IL_TARGET",
178};
179

--- 247 unchanged lines hidden (view full) ---

427 {"DSP1 Preload", NULL, "DSP1 Preloader"},
428 {"DSP1", NULL, "DSP1 Preloader"},
429
430 CS35L45_DAC_MUX_ROUTE("DACPCM"),
431
432 { "SPK", NULL, "AMP"},
433};
434
308static const char * const cs35l45_asp_tx_txt[] = {
309 "Zero", "ASP_RX1", "ASP_RX2",
310 "VMON", "IMON", "ERR_VOL",
311 "VDD_BATTMON", "VDD_BSTMON",
312 "DSP_TX1", "DSP_TX2",
313 "Interpolator", "IL_TARGET",
314};
315

--- 247 unchanged lines hidden (view full) ---

563 {"DSP1 Preload", NULL, "DSP1 Preloader"},
564 {"DSP1", NULL, "DSP1 Preloader"},
565
566 CS35L45_DAC_MUX_ROUTE("DACPCM"),
567
568 { "SPK", NULL, "AMP"},
569};
570
571static const char * const amplifier_mode_texts[] = {"SPK", "RCV"};
572static SOC_ENUM_SINGLE_DECL(amplifier_mode_enum, SND_SOC_NOPM, 0,
573 amplifier_mode_texts);
574static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 1000, 300, 0);
435static const DECLARE_TLV_DB_SCALE(cs35l45_dig_pcm_vol_tlv, -10225, 25, true);
436
437static const struct snd_kcontrol_new cs35l45_controls[] = {
575static const DECLARE_TLV_DB_SCALE(cs35l45_dig_pcm_vol_tlv, -10225, 25, true);
576
577static const struct snd_kcontrol_new cs35l45_controls[] = {
578 SOC_ENUM_EXT("Amplifier Mode", amplifier_mode_enum,
579 cs35l45_amplifier_mode_get, cs35l45_amplifier_mode_put),
580 SOC_SINGLE_TLV("Analog PCM Volume", CS35L45_AMP_GAIN,
581 CS35L45_AMP_GAIN_PCM_SHIFT,
582 CS35L45_AMP_GAIN_PCM_MASK >> CS35L45_AMP_GAIN_PCM_SHIFT,
583 0, amp_gain_tlv),
438 /* Ignore bit 0: it is beyond the resolution of TLV_DB_SCALE */
439 SOC_SINGLE_S_TLV("Digital PCM Volume",
440 CS35L45_AMP_PCM_CONTROL,
441 CS35L45_AMP_VOL_PCM_SHIFT + 1,
442 -409, 48,
443 (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,
444 0, cs35l45_dig_pcm_vol_tlv),
445 WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),

--- 653 unchanged lines hidden (view full) ---

1099 dev_err(dev, "Failed to apply init patch %d\n", ret);
1100 return ret;
1101 }
1102
1103 ret = cs35l45_apply_property_config(cs35l45);
1104 if (ret < 0)
1105 return ret;
1106
584 /* Ignore bit 0: it is beyond the resolution of TLV_DB_SCALE */
585 SOC_SINGLE_S_TLV("Digital PCM Volume",
586 CS35L45_AMP_PCM_CONTROL,
587 CS35L45_AMP_VOL_PCM_SHIFT + 1,
588 -409, 48,
589 (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,
590 0, cs35l45_dig_pcm_vol_tlv),
591 WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),

--- 653 unchanged lines hidden (view full) ---

1245 dev_err(dev, "Failed to apply init patch %d\n", ret);
1246 return ret;
1247 }
1248
1249 ret = cs35l45_apply_property_config(cs35l45);
1250 if (ret < 0)
1251 return ret;
1252
1253 cs35l45->amplifier_mode = AMP_MODE_SPK;
1254
1107 return 0;
1108}
1109
1110static const struct reg_sequence cs35l45_fs_errata_patch[] = {
1111 {0x02B80080, 0x00000001},
1112 {0x02B80088, 0x00000001},
1113 {0x02B80090, 0x00000001},
1114 {0x02B80098, 0x00000001},

--- 189 unchanged lines hidden ---
1255 return 0;
1256}
1257
1258static const struct reg_sequence cs35l45_fs_errata_patch[] = {
1259 {0x02B80080, 0x00000001},
1260 {0x02B80088, 0x00000001},
1261 {0x02B80090, 0x00000001},
1262 {0x02B80098, 0x00000001},

--- 189 unchanged lines hidden ---