From 8d7ad5d55f2c132c5612b2c1a13b7332766986b1 Mon Sep 17 00:00:00 2001 From: Tracy Yi Date: Fri, 9 Feb 2018 17:51:35 +0800 Subject: [PATCH 1/1] Add support for channel selection. Signed-off-by: Tracy Yi --- dts.readme | 2 ++ tas2770-codec.c | 42 ++++++++++++++++++++++++++++++------------ tas2770-regmap.c | 18 ++++++++++++++++++ tas2770.h | 4 ++++ 4 files changed, 54 insertions(+), 12 deletions(-) diff --git a/dts.readme b/dts.readme index 2991fb6..0c38f90 100644 --- a/dts.readme +++ b/dts.readme @@ -6,5 +6,7 @@ example for dts: ti,irq-gpio = <&msmgpio 59 0>; ti,asi-format = <0>; /* 0, i2S; 1, DSP; */ ti,ppg = <0>; /* 0, 0dB default; 1, enable -2dB */ + ti,left-slot = <0>; /* */ + ti,right-slot = <1>; /* */ status = "ok"; }; \ No newline at end of file diff --git a/tas2770-codec.c b/tas2770-codec.c index 6efab7a..e47a024 100644 --- a/tas2770-codec.c +++ b/tas2770-codec.c @@ -106,7 +106,9 @@ static int tas2770_codec_suspend(struct snd_soc_codec *codec) mutex_lock(&pTAS2770->codec_lock); dev_dbg(pTAS2770->dev, "%s\n", __func__); - + snd_soc_update_bits(codec, TAS2770_PowerControl, + TAS2770_PowerControl_OperationalMode10_Mask, + TAS2770_PowerControl_OperationalMode10_Shutdown); mutex_unlock(&pTAS2770->codec_lock); return ret; } @@ -119,20 +121,25 @@ static int tas2770_codec_resume(struct snd_soc_codec *codec) mutex_lock(&pTAS2770->codec_lock); dev_dbg(pTAS2770->dev, "%s\n", __func__); + snd_soc_update_bits(codec, TAS2770_PowerControl, + TAS2770_PowerControl_OperationalMode10_Mask, + TAS2770_PowerControl_OperationalMode10_Active); mutex_unlock(&pTAS2770->codec_lock); return ret; } -static const struct snd_kcontrol_new tas2770_asi_controls[] = { - SOC_DAPM_SINGLE("Left", TAS2770_TDMConfigurationReg2, - 4, 1, 0), - SOC_DAPM_SINGLE("Right", TAS2770_TDMConfigurationReg2, - 4, 2, 0), - SOC_DAPM_SINGLE("LeftRightDiv2", TAS2770_TDMConfigurationReg2, - 4, 3, 0), +static const char * const tas2770_ASI1_src[] = { + "I2C offset", "Left", "Right", "LeftRightDiv2", }; +static SOC_ENUM_SINGLE_DECL( + tas2770_ASI1_src_enum, TAS2770_TDMConfigurationReg2, + 4, tas2770_ASI1_src); + +static const struct snd_kcontrol_new tas2770_asi1_mux = + SOC_DAPM_ENUM("ASI1 Source", tas2770_ASI1_src_enum); + static int tas2770_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -163,10 +170,8 @@ static const struct snd_kcontrol_new vsense_switch = static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_MIXER("ASI1 Sel", - TAS2770_TDMConfigurationReg2, 4, 0, - &tas2770_asi_controls[0], - ARRAY_SIZE(tas2770_asi_controls)), + SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, + &tas2770_asi1_mux), SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PowerControl, 3, 1, &isense_switch), SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PowerControl, 2, 1, @@ -179,6 +184,7 @@ static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = { }; static const struct snd_soc_dapm_route tas2770_audio_map[] = { + {"ASI1 Sel", "I2C offset", "ASI1"}, {"ASI1 Sel", "Left", "ASI1"}, {"ASI1 Sel", "Right", "ASI1"}, {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, @@ -320,6 +326,7 @@ static int tas2770_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct snd_soc_codec *codec = dai->codec; struct tas2770_priv *pTAS2770 = snd_soc_codec_get_drvdata(codec); int ret = 0; + int value = 0; dev_dbg(pTAS2770->dev, "%s, format=0x%x\n", __func__, fmt); @@ -370,6 +377,17 @@ static int tas2770_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg1, TAS2770_TDMConfigurationReg1_RXOFFSET51_Mask, (tdm_rx_start_slot << TAS2770_TDMConfigurationReg1_RXOFFSET51_Shift)); + + snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg3, + TAS2770_TDMConfigurationReg3_RXSLOTLeft30_Mask, + (pTAS2770->mnLeftSlot << TAS2770_TDMConfigurationReg3_RXSLOTLeft30_Shift)); + snd_soc_update_bits(codec, TAS2770_TDMConfigurationReg3, + TAS2770_TDMConfigurationReg3_RXSLOTRight74_Mask, + (pTAS2770->mnRightSlot << TAS2770_TDMConfigurationReg3_RXSLOTRight74_Shift)); + + value = snd_soc_read(codec, TAS2770_TDMConfigurationReg3); + dev_dbg(pTAS2770->dev, "slot value: 0x%x", value); + return ret; } diff --git a/tas2770-regmap.c b/tas2770-regmap.c index bee8128..9afbbd0 100644 --- a/tas2770-regmap.c +++ b/tas2770-regmap.c @@ -260,6 +260,24 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *pTAS2770) dev_dbg(pTAS2770->dev, "ti,irq-gpio=%d", pTAS2770->mnIRQGPIO); } + of_property_read_u32(np, "ti,left-slot", &pTAS2770->mnLeftSlot); + if (rc) { + dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n", + "ti,left-slot", np->full_name, rc); + } else { + dev_dbg(pTAS2770->dev, "ti,left-slot=%d", + pTAS2770->mnLeftSlot); + } + + of_property_read_u32(np, "ti,right-slot", &pTAS2770->mnRightSlot); + if (rc) { + dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n", + "ti,right-slot", np->full_name, rc); + } else { + dev_dbg(pTAS2770->dev, "ti,right-slot=%d", + pTAS2770->mnRightSlot); + } + return ret; } diff --git a/tas2770.h b/tas2770.h index 197faec..b6b7e65 100644 --- a/tas2770.h +++ b/tas2770.h @@ -179,7 +179,9 @@ /* TDM Configuration Reg3 */ #define TAS2770_TDMConfigurationReg3 TAS2770_REG(0X0, 0x0D) #define TAS2770_TDMConfigurationReg3_RXSLOTRight74_Mask (0xf << 4) +#define TAS2770_TDMConfigurationReg3_RXSLOTRight74_Shift 4 #define TAS2770_TDMConfigurationReg3_RXSLOTLeft30_Mask (0xf << 0) +#define TAS2770_TDMConfigurationReg3_RXSLOTLeft30_Shift 0 /* TDM Configuration Reg4 */ #define TAS2770_TDMConfigurationReg4 TAS2770_REG(0X0, 0x0E) @@ -725,6 +727,8 @@ struct tas2770_priv { int mnFrameSize; int mnPLL; int mnPPG; + int mnLeftSlot; + int mnRightSlot; int ch_size; void (*hw_reset)(struct tas2770_priv *pTAS2770); void (*clearIRQ)(struct tas2770_priv *pTAS2770); -- 2.39.2