aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,sai.yaml38
-rw-r--r--Documentation/devicetree/bindings/sound/tas5720.txt2
-rw-r--r--sound/soc/amd/acp/acp-mach-common.c8
-rw-r--r--sound/soc/codecs/sma1303.c4
-rw-r--r--sound/soc/codecs/tas5720.c128
-rw-r--r--sound/soc/codecs/tas5720.h16
6 files changed, 143 insertions, 53 deletions
diff --git a/Documentation/devicetree/bindings/sound/fsl,sai.yaml b/Documentation/devicetree/bindings/sound/fsl,sai.yaml
index 7e56337d8edc..088c26b001cc 100644
--- a/Documentation/devicetree/bindings/sound/fsl,sai.yaml
+++ b/Documentation/devicetree/bindings/sound/fsl,sai.yaml
@@ -76,10 +76,14 @@ properties:
minItems: 4
dmas:
- maxItems: 2
+ items:
+ - description: DMA controller phandle and request line for RX
+ - description: DMA controller phandle and request line for TX
dma-names:
- maxItems: 2
+ items:
+ - const: rx
+ - const: tx
interrupts:
items:
@@ -143,31 +147,6 @@ properties:
allOf:
- $ref: dai-common.yaml#
- if:
- properties:
- compatible:
- contains:
- const: fsl,vf610-sai
- then:
- properties:
- dmas:
- items:
- - description: DMA controller phandle and request line for TX
- - description: DMA controller phandle and request line for RX
- dma-names:
- items:
- - const: tx
- - const: rx
- else:
- properties:
- dmas:
- items:
- - description: DMA controller phandle and request line for RX
- - description: DMA controller phandle and request line for TX
- dma-names:
- items:
- - const: rx
- - const: tx
- - if:
required:
- fsl,sai-asynchronous
then:
@@ -199,9 +178,8 @@ examples:
<&clks VF610_CLK_SAI2>,
<&clks 0>, <&clks 0>;
clock-names = "bus", "mclk1", "mclk2", "mclk3";
- dma-names = "tx", "rx";
- dmas = <&edma0 0 21>,
- <&edma0 0 20>;
+ dma-names = "rx", "tx";
+ dmas = <&edma0 0 20>, <&edma0 0 21>;
big-endian;
lsb-first;
};
diff --git a/Documentation/devicetree/bindings/sound/tas5720.txt b/Documentation/devicetree/bindings/sound/tas5720.txt
index df99ca9451b0..7d851ae2bba2 100644
--- a/Documentation/devicetree/bindings/sound/tas5720.txt
+++ b/Documentation/devicetree/bindings/sound/tas5720.txt
@@ -6,11 +6,13 @@ audio playback. For more product information please see the links below:
https://www.ti.com/product/TAS5720L
https://www.ti.com/product/TAS5720M
+https://www.ti.com/product/TAS5720A-Q1
https://www.ti.com/product/TAS5722L
Required properties:
- compatible : "ti,tas5720",
+ "ti,tas5720a-q1",
"ti,tas5722"
- reg : I2C slave address
- dvdd-supply : phandle to a 3.3-V supply for the digital circuitry
diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c
index b83ae946b3e4..b4dcce4fbae9 100644
--- a/sound/soc/amd/acp/acp-mach-common.c
+++ b/sound/soc/amd/acp/acp-mach-common.c
@@ -186,7 +186,7 @@ static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,
srate = params_rate(params);
ch = params_channels(params);
- format = 8 * params_format(params);
+ format = params_physical_width(params);
if (drvdata->tdm_mode)
fmt = SND_SOC_DAIFMT_DSP_A;
@@ -330,7 +330,7 @@ static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,
srate = params_rate(params);
ch = params_channels(params);
- format = 8 * params_format(params);
+ format = params_physical_width(params);
if (drvdata->tdm_mode)
fmt = SND_SOC_DAIFMT_DSP_A;
@@ -475,7 +475,7 @@ static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
srate = params_rate(params);
ch = params_channels(params);
- format = 8 * params_format(params);
+ format = params_physical_width(params);
if (drvdata->amp_codec_id != RT1019)
return -EINVAL;
@@ -616,7 +616,7 @@ static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream,
srate = params_rate(params);
ch = params_channels(params);
- format = 8 * params_format(params);
+ format = params_physical_width(params);
if (drvdata->tdm_mode)
fmt = SND_SOC_DAIFMT_DSP_A;
diff --git a/sound/soc/codecs/sma1303.c b/sound/soc/codecs/sma1303.c
index d3ee831e88f0..3d8e3900f5c3 100644
--- a/sound/soc/codecs/sma1303.c
+++ b/sound/soc/codecs/sma1303.c
@@ -500,7 +500,7 @@ static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w,
sma1303->amp_mode = SMA1303_STEREO;
break;
default:
- dev_err(sma1303->dev, "%s : Invald value (%d)\n",
+ dev_err(sma1303->dev, "%s : Invalid value (%d)\n",
__func__, mux);
return -EINVAL;
}
@@ -640,7 +640,7 @@ static int sma1303_aif_out_event(struct snd_soc_dapm_widget *w,
change = true;
break;
default:
- dev_err(sma1303->dev, "%s : Invald value (%d)\n",
+ dev_err(sma1303->dev, "%s : Invalid value (%d)\n",
__func__, mux);
return -EINVAL;
}
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c
index 3885c0bf0b01..de6d01c8fdd3 100644
--- a/sound/soc/codecs/tas5720.c
+++ b/sound/soc/codecs/tas5720.c
@@ -30,6 +30,7 @@
enum tas572x_type {
TAS5720,
+ TAS5720A_Q1,
TAS5722,
};
@@ -166,17 +167,26 @@ static int tas5720_set_dai_tdm_slot(struct snd_soc_dai *dai,
return -EINVAL;
}
- /* Enable manual TDM slot selection (instead of I2C ID based) */
- ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
- TAS5720_TDM_CFG_SRC, TAS5720_TDM_CFG_SRC);
- if (ret < 0)
- goto error_snd_soc_component_update_bits;
+ /*
+ * Enable manual TDM slot selection (instead of I2C ID based).
+ * This is not applicable to TAS5720A-Q1.
+ */
+ switch (tas5720->devtype) {
+ case TAS5720A_Q1:
+ break;
+ default:
+ ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL1_REG,
+ TAS5720_TDM_CFG_SRC, TAS5720_TDM_CFG_SRC);
+ if (ret < 0)
+ goto error_snd_soc_component_update_bits;
- /* Configure the TDM slot to process audio from */
- ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
- TAS5720_TDM_SLOT_SEL_MASK, first_slot);
- if (ret < 0)
- goto error_snd_soc_component_update_bits;
+ /* Configure the TDM slot to process audio from */
+ ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
+ TAS5720_TDM_SLOT_SEL_MASK, first_slot);
+ if (ret < 0)
+ goto error_snd_soc_component_update_bits;
+ break;
+ }
/* Configure TDM slot width. This is only applicable to TAS5722. */
switch (tas5720->devtype) {
@@ -199,13 +209,24 @@ error_snd_soc_component_update_bits:
return ret;
}
-static int tas5720_mute(struct snd_soc_dai *dai, int mute, int direction)
+static int tas5720_mute_soc_component(struct snd_soc_component *component, int mute)
{
- struct snd_soc_component *component = dai->component;
+ struct tas5720_data *tas5720 = snd_soc_component_get_drvdata(component);
+ unsigned int reg, mask;
int ret;
- ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
- TAS5720_MUTE, mute ? TAS5720_MUTE : 0);
+ switch (tas5720->devtype) {
+ case TAS5720A_Q1:
+ reg = TAS5720_Q1_VOLUME_CTRL_CFG_REG;
+ mask = TAS5720_Q1_MUTE;
+ break;
+ default:
+ reg = TAS5720_DIGITAL_CTRL2_REG;
+ mask = TAS5720_MUTE;
+ break;
+ }
+
+ ret = snd_soc_component_update_bits(component, reg, mask, mute ? mask : 0);
if (ret < 0) {
dev_err(component->dev, "error (un-)muting device: %d\n", ret);
return ret;
@@ -214,6 +235,11 @@ static int tas5720_mute(struct snd_soc_dai *dai, int mute, int direction)
return 0;
}
+static int tas5720_mute(struct snd_soc_dai *dai, int mute, int direction)
+{
+ return tas5720_mute_soc_component(dai->component, mute);
+}
+
static void tas5720_fault_check_work(struct work_struct *work)
{
struct tas5720_data *tas5720 = container_of(work, struct tas5720_data,
@@ -305,6 +331,9 @@ static int tas5720_codec_probe(struct snd_soc_component *component)
case TAS5720:
expected_device_id = TAS5720_DEVICE_ID;
break;
+ case TAS5720A_Q1:
+ expected_device_id = TAS5720A_Q1_DEVICE_ID;
+ break;
case TAS5722:
expected_device_id = TAS5722_DEVICE_ID;
break;
@@ -318,8 +347,20 @@ static int tas5720_codec_probe(struct snd_soc_component *component)
expected_device_id, device_id);
/* Set device to mute */
- ret = snd_soc_component_update_bits(component, TAS5720_DIGITAL_CTRL2_REG,
- TAS5720_MUTE, TAS5720_MUTE);
+ ret = tas5720_mute_soc_component(component, 1);
+ if (ret < 0)
+ goto error_snd_soc_component_update_bits;
+
+ /* Set Bit 7 in TAS5720_ANALOG_CTRL_REG to 1 for TAS5720A_Q1 */
+ switch (tas5720->devtype) {
+ case TAS5720A_Q1:
+ ret = snd_soc_component_update_bits(component, TAS5720_ANALOG_CTRL_REG,
+ TAS5720_Q1_RESERVED7_BIT,
+ TAS5720_Q1_RESERVED7_BIT);
+ break;
+ default:
+ break;
+ }
if (ret < 0)
goto error_snd_soc_component_update_bits;
@@ -471,6 +512,15 @@ static const struct regmap_config tas5720_regmap_config = {
.volatile_reg = tas5720_is_volatile_reg,
};
+static const struct regmap_config tas5720a_q1_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .max_register = TAS5720_MAX_REG,
+ .cache_type = REGCACHE_RBTREE,
+ .volatile_reg = tas5720_is_volatile_reg,
+};
+
static const struct regmap_config tas5722_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -492,6 +542,16 @@ static const DECLARE_TLV_DB_RANGE(dac_analog_tlv,
);
/*
+ * DAC analog gain for TAS5720A-Q1. There are three discrete values to select from, ranging
+ * from 19.2 dB to 25.0dB.
+ */
+static const DECLARE_TLV_DB_RANGE(dac_analog_tlv_a_q1,
+ 0x0, 0x0, TLV_DB_SCALE_ITEM(1920, 0, 0),
+ 0x1, 0x1, TLV_DB_SCALE_ITEM(2260, 0, 0),
+ 0x2, 0x2, TLV_DB_SCALE_ITEM(2500, 0, 0),
+);
+
+/*
* DAC digital volumes. From -103.5 to 24 dB in 0.5 dB or 0.25 dB steps
* depending on the device. Note that setting the gain below -100 dB
* (register value <0x7) is effectively a MUTE as per device datasheet.
@@ -537,6 +597,15 @@ static const struct snd_kcontrol_new tas5720_snd_controls[] = {
TAS5720_ANALOG_GAIN_SHIFT, 3, 0, dac_analog_tlv),
};
+static const struct snd_kcontrol_new tas5720a_q1_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("Speaker Driver Playback Volume",
+ TAS5720_Q1_VOLUME_CTRL_LEFT_REG,
+ TAS5720_Q1_VOLUME_CTRL_RIGHT_REG,
+ 0, 0xff, 0, tas5720_dac_tlv),
+ SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG,
+ TAS5720_ANALOG_GAIN_SHIFT, 3, 0, dac_analog_tlv_a_q1),
+};
+
static const struct snd_kcontrol_new tas5722_snd_controls[] = {
SOC_SINGLE_EXT_TLV("Speaker Driver Playback Volume",
0, 0, 511, 0,
@@ -574,6 +643,22 @@ static const struct snd_soc_component_driver soc_component_dev_tas5720 = {
.endianness = 1,
};
+static const struct snd_soc_component_driver soc_component_dev_tas5720_a_q1 = {
+ .probe = tas5720_codec_probe,
+ .remove = tas5720_codec_remove,
+ .suspend = tas5720_suspend,
+ .resume = tas5720_resume,
+ .controls = tas5720a_q1_snd_controls,
+ .num_controls = ARRAY_SIZE(tas5720a_q1_snd_controls),
+ .dapm_widgets = tas5720_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tas5720_dapm_widgets),
+ .dapm_routes = tas5720_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(tas5720_audio_map),
+ .idle_bias_on = 1,
+ .use_pmdown_time = 1,
+ .endianness = 1,
+};
+
static const struct snd_soc_component_driver soc_component_dev_tas5722 = {
.probe = tas5720_codec_probe,
.remove = tas5720_codec_remove,
@@ -633,6 +718,7 @@ static struct snd_soc_dai_driver tas5720_dai[] = {
static const struct i2c_device_id tas5720_id[] = {
{ "tas5720", TAS5720 },
+ { "tas5720a-q1", TAS5720A_Q1 },
{ "tas5722", TAS5722 },
{ }
};
@@ -659,6 +745,9 @@ static int tas5720_probe(struct i2c_client *client)
case TAS5720:
regmap_config = &tas5720_regmap_config;
break;
+ case TAS5720A_Q1:
+ regmap_config = &tas5720a_q1_regmap_config;
+ break;
case TAS5722:
regmap_config = &tas5722_regmap_config;
break;
@@ -692,6 +781,12 @@ static int tas5720_probe(struct i2c_client *client)
tas5720_dai,
ARRAY_SIZE(tas5720_dai));
break;
+ case TAS5720A_Q1:
+ ret = devm_snd_soc_register_component(&client->dev,
+ &soc_component_dev_tas5720_a_q1,
+ tas5720_dai,
+ ARRAY_SIZE(tas5720_dai));
+ break;
case TAS5722:
ret = devm_snd_soc_register_component(&client->dev,
&soc_component_dev_tas5722,
@@ -713,6 +808,7 @@ static int tas5720_probe(struct i2c_client *client)
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id tas5720_of_match[] = {
{ .compatible = "ti,tas5720", },
+ { .compatible = "ti,tas5720a-q1", },
{ .compatible = "ti,tas5722", },
{ },
};
diff --git a/sound/soc/codecs/tas5720.h b/sound/soc/codecs/tas5720.h
index 223858f0de71..54b59b05ef0a 100644
--- a/sound/soc/codecs/tas5720.h
+++ b/sound/soc/codecs/tas5720.h
@@ -10,7 +10,7 @@
#ifndef __TAS5720_H__
#define __TAS5720_H__
-/* Register Address Map */
+/* Register Address Map - first 3 regs are common for all variants */
#define TAS5720_DEVICE_ID_REG 0x00
#define TAS5720_POWER_CTRL_REG 0x01
#define TAS5720_DIGITAL_CTRL1_REG 0x02
@@ -27,7 +27,13 @@
#define TAS5722_ANALOG_CTRL2_REG 0x14
#define TAS5722_MAX_REG TAS5722_ANALOG_CTRL2_REG
+/* Register Address Map - volume controls for the TAS5720-Q1 variant */
+#define TAS5720_Q1_VOLUME_CTRL_CFG_REG 0x03
+#define TAS5720_Q1_VOLUME_CTRL_LEFT_REG 0x04
+#define TAS5720_Q1_VOLUME_CTRL_RIGHT_REG 0x05
+
/* TAS5720_DEVICE_ID_REG */
+#define TAS5720A_Q1_DEVICE_ID 0x00
#define TAS5720_DEVICE_ID 0x01
#define TAS5722_DEVICE_ID 0x12
@@ -53,6 +59,10 @@
#define TAS5720_MUTE BIT(4)
#define TAS5720_TDM_SLOT_SEL_MASK GENMASK(2, 0)
+/* TAS5720_Q1_VOLUME_CTRL_CFG_REG */
+#define TAS5720_Q1_FADE BIT(7)
+#define TAS5720_Q1_MUTE GENMASK(1, 0)
+
/* TAS5720_ANALOG_CTRL_REG */
#define TAS5720_PWM_RATE_6_3_FSYNC (0x0 << 4)
#define TAS5720_PWM_RATE_8_4_FSYNC (0x1 << 4)
@@ -70,6 +80,10 @@
#define TAS5720_ANALOG_GAIN_MASK GENMASK(3, 2)
#define TAS5720_ANALOG_GAIN_SHIFT (0x2)
+/* TAS5720_Q1_ANALOG_CTRL_REG */
+#define TAS5720_Q1_RESERVED7_BIT BIT(7)
+#define TAS5720_Q1_CHAN_SEL BIT(1)
+
/* TAS5720_FAULT_REG */
#define TAS5720_OC_THRESH_100PCT (0x0 << 4)
#define TAS5720_OC_THRESH_75PCT (0x1 << 4)