forked from luck/tmp_suning_uos_patched
ASoC: sun4i-i2s: Add support for DSP formats
In addition to the I2S format, the controller also supports the DSP_* formats. This requires some extra care on the LRCK period calculation, since the controller, with the PCM formats, require that the value set is no longer the periods of LRCK for a single channel, but for all of them. Let's add the code to deal with this, and support the DSP_A and DSP_B formats. Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://lore.kernel.org/r/5562db1ac8759f12b1b87c3258223eed629ef771.1566392800.git-series.maxime.ripard@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
84884c7ad5
commit
7ae7834ec4
|
@ -130,7 +130,6 @@ struct sun4i_i2s;
|
|||
* struct sun4i_i2s_quirks - Differences between SoC variants.
|
||||
*
|
||||
* @has_reset: SoC needs reset deasserted.
|
||||
* @has_fmt_set_lrck_period: SoC requires lrclk period to be set.
|
||||
* @reg_offset_txdata: offset of the tx fifo.
|
||||
* @sun4i_i2s_regmap: regmap config to use.
|
||||
* @field_clkdiv_mclk_en: regmap field to enable mclk output.
|
||||
|
@ -139,7 +138,6 @@ struct sun4i_i2s;
|
|||
*/
|
||||
struct sun4i_i2s_quirks {
|
||||
bool has_reset;
|
||||
bool has_fmt_set_lrck_period;
|
||||
unsigned int reg_offset_txdata; /* TX FIFO */
|
||||
const struct regmap_config *sun4i_i2s_regmap;
|
||||
|
||||
|
@ -167,6 +165,7 @@ struct sun4i_i2s {
|
|||
struct regmap *regmap;
|
||||
struct reset_control *rst;
|
||||
|
||||
unsigned int format;
|
||||
unsigned int mclk_freq;
|
||||
unsigned int slots;
|
||||
unsigned int slot_width;
|
||||
|
@ -355,12 +354,6 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
|
|||
|
||||
regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
|
||||
|
||||
/* Set sync period */
|
||||
if (i2s->variant->has_fmt_set_lrck_period)
|
||||
regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
|
||||
SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
|
||||
SUN8I_I2S_FMT0_LRCK_PERIOD(slot_width));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -422,6 +415,7 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
|||
{
|
||||
unsigned int channels = params_channels(params);
|
||||
unsigned int slots = channels;
|
||||
unsigned int lrck_period;
|
||||
|
||||
if (i2s->slots)
|
||||
slots = i2s->slots;
|
||||
|
@ -445,6 +439,26 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
|||
SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
|
||||
SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
|
||||
|
||||
switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
lrck_period = params_physical_width(params) * slots;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
lrck_period = params_physical_width(params);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
|
||||
SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
|
||||
SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period));
|
||||
|
||||
regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
|
||||
SUN8I_I2S_TX_CHAN_EN_MASK,
|
||||
SUN8I_I2S_TX_CHAN_EN(channels));
|
||||
|
@ -616,6 +630,16 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
|||
|
||||
/* DAI Mode */
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
mode = SUN8I_I2S_CTRL_MODE_PCM;
|
||||
offset = 1;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
mode = SUN8I_I2S_CTRL_MODE_PCM;
|
||||
offset = 0;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
mode = SUN8I_I2S_CTRL_MODE_LEFT;
|
||||
offset = 1;
|
||||
|
@ -684,6 +708,9 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
|||
SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
|
||||
SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
|
||||
SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
|
||||
|
||||
i2s->format = fmt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1074,7 +1101,6 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
|
|||
.has_reset = true,
|
||||
.reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
|
||||
.sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
|
||||
.has_fmt_set_lrck_period = true,
|
||||
.field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
|
||||
.field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
|
||||
.field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
|
||||
|
|
Loading…
Reference in New Issue
Block a user