return 0;
}
+static int tas2770_set_dai_tdm_idle(struct snd_soc_dai *dai,
+ unsigned int tx_mask,
+ unsigned int rx_mask,
+ int tx_mode, int rx_mode)
+{
+ struct snd_soc_component *component = dai->component;
+ struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
+ int ret;
+
+ /* We don't support setting anything for SDIN */
+ if (rx_mode)
+ return -EOPNOTSUPP;
+
+ if (tas2770->idle_tx_mode == tx_mode)
+ return 0;
+
+ switch (tx_mode) {
+ case SND_SOC_DAI_TDM_IDLE_PULLDOWN:
+ ret = snd_soc_component_update_bits(component, TAS2770_DIN_PD,
+ TAS2770_DIN_PD_SDOUT,
+ TAS2770_DIN_PD_SDOUT);
+ if (ret)
+ return ret;
+
+ break;
+ case SND_SOC_DAI_TDM_IDLE_ZERO:
+ ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
+ TAS2770_TDM_CFG_REG4_TX_KEEPER,
+ TAS2770_TDM_CFG_REG4_TX_KEEPER);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
+ TAS2770_TDM_CFG_REG4_TX_FILL, 0);
+ if (ret)
+ return ret;
+
+ break;
+ case SND_SOC_DAI_TDM_IDLE_HIZ:
+ ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
+ TAS2770_TDM_CFG_REG4_TX_KEEPER,
+ TAS2770_TDM_CFG_REG4_TX_KEEPER);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
+ TAS2770_TDM_CFG_REG4_TX_FILL,
+ TAS2770_TDM_CFG_REG4_TX_FILL);
+ if (ret)
+ return ret;
+
+ break;
+ case SND_SOC_DAI_TDM_IDLE_OFF:
+ ret = snd_soc_component_update_bits(component, TAS2770_DIN_PD,
+ TAS2770_DIN_PD_SDOUT, 0);
+ if (ret)
+ return ret;
+
+ ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
+ TAS2770_TDM_CFG_REG4_TX_KEEPER, 0);
+ if (ret)
+ return ret;
+
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ tas2770->idle_tx_mode = tx_mode;
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops tas2770_dai_ops = {
.mute_stream = tas2770_mute,
.hw_params = tas2770_hw_params,
.set_fmt = tas2770_set_fmt,
.set_tdm_slot = tas2770_set_dai_tdm_slot,
+ .set_tdm_idle = tas2770_set_dai_tdm_idle,
.no_capture_mute = 1,
};
#define TAS2770_TDM_CFG_REG3_RXS_SHIFT 0x4
#define TAS2770_TDM_CFG_REG3_30_MASK GENMASK(3, 0)
#define TAS2770_TDM_CFG_REG3_30_SHIFT 0
+ /* TDM Configuration Reg4 */
+#define TAS2770_TDM_CFG_REG4 TAS2770_REG(0X0, 0x0E)
+#define TAS2770_TDM_CFG_REG4_TX_LSB_CFG BIT(7)
+#define TAS2770_TDM_CFG_REG4_TX_KEEPER_CFG BIT(6)
+#define TAS2770_TDM_CFG_REG4_TX_KEEPER BIT(5)
+#define TAS2770_TDM_CFG_REG4_TX_FILL BIT(4)
+#define TAS2770_TDM_CFG_REG4_TX_OFFSET_MASK GENMASK(3, 1)
+#define TAS2770_TDM_CFG_REG4_TX_EDGE_FALLING BIT(0)
/* TDM Configuration Reg5 */
#define TAS2770_TDM_CFG_REG5 TAS2770_REG(0X0, 0x0F)
#define TAS2770_TDM_CFG_REG5_VSNS_MASK BIT(6)
#define TAS2770_TEMP_LSB TAS2770_REG(0X0, 0x2A)
/* Interrupt Configuration */
#define TAS2770_INT_CFG TAS2770_REG(0X0, 0x30)
+ /* Data In Pull-Down */
+#define TAS2770_DIN_PD TAS2770_REG(0X0, 0x31)
+#define TAS2770_DIN_PD_SDOUT BIT(7)
/* Misc IRQ */
#define TAS2770_MISC_IRQ TAS2770_REG(0X0, 0x32)
/* Clock Configuration */
int pdm_slot;
bool dac_powered;
bool unmuted;
+ int idle_tx_mode;
};
#endif /* __TAS2770__ */