Commit 50ee138f authored by Mark Brown's avatar Mark Brown

TAS2770 fixes

Merge series from Martin Povišer <povik+lin@cutebit.org>:

The first two fixes should be straightforward.

The latter two clean up what looks to me like a mess in the setting of
power levels. However we settle it, we should then do the same changes
to TAS2764, which has the same template (and maybe there are other
drivers).
parents afb176d4 1e5907bc
...@@ -46,34 +46,22 @@ static void tas2770_reset(struct tas2770_priv *tas2770) ...@@ -46,34 +46,22 @@ static void tas2770_reset(struct tas2770_priv *tas2770)
usleep_range(1000, 2000); usleep_range(1000, 2000);
} }
static int tas2770_set_bias_level(struct snd_soc_component *component, static int tas2770_update_pwr_ctrl(struct tas2770_priv *tas2770)
enum snd_soc_bias_level level)
{ {
struct tas2770_priv *tas2770 = struct snd_soc_component *component = tas2770->component;
snd_soc_component_get_drvdata(component); unsigned int val;
int ret;
switch (level) { if (tas2770->dac_powered)
case SND_SOC_BIAS_ON: val = tas2770->unmuted ?
snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, TAS2770_PWR_CTRL_ACTIVE : TAS2770_PWR_CTRL_MUTE;
TAS2770_PWR_CTRL_MASK, else
TAS2770_PWR_CTRL_ACTIVE); val = TAS2770_PWR_CTRL_SHUTDOWN;
break;
case SND_SOC_BIAS_STANDBY:
case SND_SOC_BIAS_PREPARE:
snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_MUTE);
break;
case SND_SOC_BIAS_OFF:
snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_SHUTDOWN);
break;
default: ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
dev_err(tas2770->dev, "wrong power level setting %d\n", level); TAS2770_PWR_CTRL_MASK, val);
return -EINVAL; if (ret < 0)
} return ret;
return 0; return 0;
} }
...@@ -114,9 +102,7 @@ static int tas2770_codec_resume(struct snd_soc_component *component) ...@@ -114,9 +102,7 @@ static int tas2770_codec_resume(struct snd_soc_component *component)
gpiod_set_value_cansleep(tas2770->sdz_gpio, 1); gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
usleep_range(1000, 2000); usleep_range(1000, 2000);
} else { } else {
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, ret = tas2770_update_pwr_ctrl(tas2770);
TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_ACTIVE);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
...@@ -152,24 +138,19 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w, ...@@ -152,24 +138,19 @@ static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, tas2770->dac_powered = 1;
TAS2770_PWR_CTRL_MASK, ret = tas2770_update_pwr_ctrl(tas2770);
TAS2770_PWR_CTRL_MUTE);
break; break;
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL, tas2770->dac_powered = 0;
TAS2770_PWR_CTRL_MASK, ret = tas2770_update_pwr_ctrl(tas2770);
TAS2770_PWR_CTRL_SHUTDOWN);
break; break;
default: default:
dev_err(tas2770->dev, "Not supported evevt\n"); dev_err(tas2770->dev, "Not supported evevt\n");
return -EINVAL; return -EINVAL;
} }
if (ret < 0)
return ret; return ret;
return 0;
} }
static const struct snd_kcontrol_new isense_switch = static const struct snd_kcontrol_new isense_switch =
...@@ -203,21 +184,11 @@ static const struct snd_soc_dapm_route tas2770_audio_map[] = { ...@@ -203,21 +184,11 @@ static const struct snd_soc_dapm_route tas2770_audio_map[] = {
static int tas2770_mute(struct snd_soc_dai *dai, int mute, int direction) static int tas2770_mute(struct snd_soc_dai *dai, int mute, int direction)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
int ret; struct tas2770_priv *tas2770 =
snd_soc_component_get_drvdata(component);
if (mute)
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_MUTE);
else
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
TAS2770_PWR_CTRL_MASK,
TAS2770_PWR_CTRL_ACTIVE);
if (ret < 0)
return ret;
return 0; tas2770->unmuted = !mute;
return tas2770_update_pwr_ctrl(tas2770);
} }
static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth) static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
...@@ -337,7 +308,7 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -337,7 +308,7 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct tas2770_priv *tas2770 = struct tas2770_priv *tas2770 =
snd_soc_component_get_drvdata(component); snd_soc_component_get_drvdata(component);
u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; u8 tdm_rx_start_slot = 0, invert_fpol = 0, fpol_preinv = 0, asi_cfg_1 = 0;
int ret; int ret;
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
...@@ -349,9 +320,15 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -349,9 +320,15 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
} }
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_IF:
invert_fpol = 1;
fallthrough;
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_NB_NF:
asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_RSING; asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_RSING;
break; break;
case SND_SOC_DAIFMT_IB_IF:
invert_fpol = 1;
fallthrough;
case SND_SOC_DAIFMT_IB_NF: case SND_SOC_DAIFMT_IB_NF:
asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_FALING; asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_FALING;
break; break;
...@@ -369,15 +346,19 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -369,15 +346,19 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
tdm_rx_start_slot = 1; tdm_rx_start_slot = 1;
fpol_preinv = 0;
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
tdm_rx_start_slot = 0; tdm_rx_start_slot = 0;
fpol_preinv = 1;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
tdm_rx_start_slot = 1; tdm_rx_start_slot = 1;
fpol_preinv = 1;
break; break;
case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_LEFT_J:
tdm_rx_start_slot = 0; tdm_rx_start_slot = 0;
fpol_preinv = 1;
break; break;
default: default:
dev_err(tas2770->dev, dev_err(tas2770->dev,
...@@ -391,6 +372,14 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -391,6 +372,14 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
TAS2770_TDM_CFG_REG0_FPOL_MASK,
(fpol_preinv ^ invert_fpol)
? TAS2770_TDM_CFG_REG0_FPOL_RSING
: TAS2770_TDM_CFG_REG0_FPOL_FALING);
if (ret < 0)
return ret;
return 0; return 0;
} }
...@@ -489,7 +478,7 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = { ...@@ -489,7 +478,7 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = {
.id = 0, .id = 0,
.playback = { .playback = {
.stream_name = "ASI1 Playback", .stream_name = "ASI1 Playback",
.channels_min = 2, .channels_min = 1,
.channels_max = 2, .channels_max = 2,
.rates = TAS2770_RATES, .rates = TAS2770_RATES,
.formats = TAS2770_FORMATS, .formats = TAS2770_FORMATS,
...@@ -537,7 +526,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2770 = { ...@@ -537,7 +526,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2770 = {
.probe = tas2770_codec_probe, .probe = tas2770_codec_probe,
.suspend = tas2770_codec_suspend, .suspend = tas2770_codec_suspend,
.resume = tas2770_codec_resume, .resume = tas2770_codec_resume,
.set_bias_level = tas2770_set_bias_level,
.controls = tas2770_snd_controls, .controls = tas2770_snd_controls,
.num_controls = ARRAY_SIZE(tas2770_snd_controls), .num_controls = ARRAY_SIZE(tas2770_snd_controls),
.dapm_widgets = tas2770_dapm_widgets, .dapm_widgets = tas2770_dapm_widgets,
......
...@@ -41,6 +41,9 @@ ...@@ -41,6 +41,9 @@
#define TAS2770_TDM_CFG_REG0_31_44_1_48KHZ 0x6 #define TAS2770_TDM_CFG_REG0_31_44_1_48KHZ 0x6
#define TAS2770_TDM_CFG_REG0_31_88_2_96KHZ 0x8 #define TAS2770_TDM_CFG_REG0_31_88_2_96KHZ 0x8
#define TAS2770_TDM_CFG_REG0_31_176_4_192KHZ 0xa #define TAS2770_TDM_CFG_REG0_31_176_4_192KHZ 0xa
#define TAS2770_TDM_CFG_REG0_FPOL_MASK BIT(0)
#define TAS2770_TDM_CFG_REG0_FPOL_RSING 0
#define TAS2770_TDM_CFG_REG0_FPOL_FALING 1
/* TDM Configuration Reg1 */ /* TDM Configuration Reg1 */
#define TAS2770_TDM_CFG_REG1 TAS2770_REG(0X0, 0x0B) #define TAS2770_TDM_CFG_REG1 TAS2770_REG(0X0, 0x0B)
#define TAS2770_TDM_CFG_REG1_MASK GENMASK(5, 1) #define TAS2770_TDM_CFG_REG1_MASK GENMASK(5, 1)
...@@ -135,6 +138,8 @@ struct tas2770_priv { ...@@ -135,6 +138,8 @@ struct tas2770_priv {
struct device *dev; struct device *dev;
int v_sense_slot; int v_sense_slot;
int i_sense_slot; int i_sense_slot;
bool dac_powered;
bool unmuted;
}; };
#endif /* __TAS2770__ */ #endif /* __TAS2770__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment