forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/codecs/tlv320aic3x.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ALSA SoC TLV320AIC3X codec driver
34 *
....@@ -5,10 +6,6 @@
56 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
67 *
78 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
129 *
1310 * Notes:
1411 * The AIC3X is a driver for a low power stereo audio
....@@ -324,6 +321,9 @@
324321 */
325322 static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
326323
324
+/* Output volumes. From 0 to 9 dB in 1 dB steps */
325
+static const DECLARE_TLV_DB_SCALE(out_tlv, 0, 100, 0);
326
+
327327 static const struct snd_kcontrol_new aic3x_snd_controls[] = {
328328 /* Output */
329329 SOC_DOUBLE_R_TLV("PCM Playback Volume",
....@@ -386,11 +386,17 @@
386386 DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
387387 0, 118, 1, output_stage_tlv),
388388
389
- /* Output pin mute controls */
389
+ /* Output pin controls */
390
+ SOC_DOUBLE_R_TLV("Line Playback Volume", LLOPM_CTRL, RLOPM_CTRL, 4,
391
+ 9, 0, out_tlv),
390392 SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
391393 0x01, 0),
394
+ SOC_DOUBLE_R_TLV("HP Playback Volume", HPLOUT_CTRL, HPROUT_CTRL, 4,
395
+ 9, 0, out_tlv),
392396 SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
393397 0x01, 0),
398
+ SOC_DOUBLE_R_TLV("HPCOM Playback Volume", HPLCOM_CTRL, HPRCOM_CTRL,
399
+ 4, 9, 0, out_tlv),
394400 SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
395401 0x01, 0),
396402
....@@ -472,6 +478,9 @@
472478 0, 118, 1, output_stage_tlv),
473479
474480 SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
481
+ SOC_SINGLE_TLV("Mono Playback Volume", MONOLOPM_CTRL, 4, 9, 0,
482
+ out_tlv),
483
+
475484 };
476485
477486 /*
....@@ -1047,7 +1056,7 @@
10471056 width = params_width(params);
10481057
10491058 /* select data word length */
1050
- data = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
1059
+ data = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
10511060 switch (width) {
10521061 case 16:
10531062 break;
....@@ -1207,11 +1216,11 @@
12071216 return 0;
12081217 }
12091218
1210
-static int aic3x_mute(struct snd_soc_dai *dai, int mute)
1219
+static int aic3x_mute(struct snd_soc_dai *dai, int mute, int direction)
12111220 {
12121221 struct snd_soc_component *component = dai->component;
1213
- u8 ldac_reg = snd_soc_component_read32(component, LDAC_VOL) & ~MUTE_ON;
1214
- u8 rdac_reg = snd_soc_component_read32(component, RDAC_VOL) & ~MUTE_ON;
1222
+ u8 ldac_reg = snd_soc_component_read(component, LDAC_VOL) & ~MUTE_ON;
1223
+ u8 rdac_reg = snd_soc_component_read(component, RDAC_VOL) & ~MUTE_ON;
12151224
12161225 if (mute) {
12171226 snd_soc_component_write(component, LDAC_VOL, ldac_reg | MUTE_ON);
....@@ -1247,8 +1256,8 @@
12471256 struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
12481257 u8 iface_areg, iface_breg;
12491258
1250
- iface_areg = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLA) & 0x3f;
1251
- iface_breg = snd_soc_component_read32(component, AIC3X_ASD_INTF_CTRLB) & 0x3f;
1259
+ iface_areg = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLA) & 0x3f;
1260
+ iface_breg = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLB) & 0x3f;
12521261
12531262 /* set master/slave audio interface */
12541263 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
....@@ -1259,6 +1268,16 @@
12591268 case SND_SOC_DAIFMT_CBS_CFS:
12601269 aic3x->master = 0;
12611270 iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
1271
+ break;
1272
+ case SND_SOC_DAIFMT_CBM_CFS:
1273
+ aic3x->master = 1;
1274
+ iface_areg |= BIT_CLK_MASTER;
1275
+ iface_areg &= ~WORD_CLK_MASTER;
1276
+ break;
1277
+ case SND_SOC_DAIFMT_CBS_CFM:
1278
+ aic3x->master = 1;
1279
+ iface_areg |= WORD_CLK_MASTER;
1280
+ iface_areg &= ~BIT_CLK_MASTER;
12621281 break;
12631282 default:
12641283 return -EINVAL;
....@@ -1388,8 +1407,8 @@
13881407 * writing one of them and thus caused other one also not
13891408 * being written
13901409 */
1391
- pll_c = snd_soc_component_read32(component, AIC3X_PLL_PROGC_REG);
1392
- pll_d = snd_soc_component_read32(component, AIC3X_PLL_PROGD_REG);
1410
+ pll_c = snd_soc_component_read(component, AIC3X_PLL_PROGC_REG);
1411
+ pll_d = snd_soc_component_read(component, AIC3X_PLL_PROGD_REG);
13931412 if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def ||
13941413 pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) {
13951414 snd_soc_component_write(component, AIC3X_PLL_PROGC_REG, pll_c);
....@@ -1462,10 +1481,11 @@
14621481 static const struct snd_soc_dai_ops aic3x_dai_ops = {
14631482 .hw_params = aic3x_hw_params,
14641483 .prepare = aic3x_prepare,
1465
- .digital_mute = aic3x_mute,
1484
+ .mute_stream = aic3x_mute,
14661485 .set_sysclk = aic3x_set_dai_sysclk,
14671486 .set_fmt = aic3x_set_dai_fmt,
14681487 .set_tdm_slot = aic3x_set_dai_tdm_slot,
1488
+ .no_capture_mute = 1,
14691489 };
14701490
14711491 static struct snd_soc_dai_driver aic3x_dai = {
....@@ -1604,13 +1624,14 @@
16041624 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
16051625 aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
16061626 aic3x->disable_nb[i].aic3x = aic3x;
1607
- ret = regulator_register_notifier(aic3x->supplies[i].consumer,
1608
- &aic3x->disable_nb[i].nb);
1627
+ ret = devm_regulator_register_notifier(
1628
+ aic3x->supplies[i].consumer,
1629
+ &aic3x->disable_nb[i].nb);
16091630 if (ret) {
16101631 dev_err(component->dev,
16111632 "Failed to request regulator notifier: %d\n",
16121633 ret);
1613
- goto err_notif;
1634
+ return ret;
16141635 }
16151636 }
16161637
....@@ -1668,28 +1689,11 @@
16681689 aic3x_add_widgets(component);
16691690
16701691 return 0;
1671
-
1672
-err_notif:
1673
- while (i--)
1674
- regulator_unregister_notifier(aic3x->supplies[i].consumer,
1675
- &aic3x->disable_nb[i].nb);
1676
- return ret;
1677
-}
1678
-
1679
-static void aic3x_remove(struct snd_soc_component *component)
1680
-{
1681
- struct aic3x_priv *aic3x = snd_soc_component_get_drvdata(component);
1682
- int i;
1683
-
1684
- for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1685
- regulator_unregister_notifier(aic3x->supplies[i].consumer,
1686
- &aic3x->disable_nb[i].nb);
16871692 }
16881693
16891694 static const struct snd_soc_component_driver soc_component_dev_aic3x = {
16901695 .set_bias_level = aic3x_set_bias_level,
16911696 .probe = aic3x_probe,
1692
- .remove = aic3x_remove,
16931697 .controls = aic3x_snd_controls,
16941698 .num_controls = ARRAY_SIZE(aic3x_snd_controls),
16951699 .dapm_widgets = aic3x_dapm_widgets,