Commit 0f163546 authored by Stephen Warren's avatar Stephen Warren Committed by Mark Brown

ASoC: tegra: use regmap more directly

Stop open-coding the caching of the ctrl registers; instead, use
regmap_update_bits() to update parts of the register from different
places. The removal of the open-coded cache will allow controls to be
created which touch registers, which will be necessary if any of these
modules are converted to CODECs.

Get rid of tegra*_read/write; just call regmap_read/write directly.
Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent c92a40e3
...@@ -46,18 +46,6 @@ ...@@ -46,18 +46,6 @@
#define DRV_NAME "tegra20-i2s" #define DRV_NAME "tegra20-i2s"
static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
{
regmap_write(i2s->regmap, reg, val);
}
static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
{
u32 val;
regmap_read(i2s->regmap, reg, &val);
return val;
}
static int tegra20_i2s_runtime_suspend(struct device *dev) static int tegra20_i2s_runtime_suspend(struct device *dev)
{ {
struct tegra20_i2s *i2s = dev_get_drvdata(dev); struct tegra20_i2s *i2s = dev_get_drvdata(dev);
...@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, ...@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt) unsigned int fmt)
{ {
struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_NB_NF:
...@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, ...@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
return -EINVAL; return -EINVAL;
} }
i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; mask = TEGRA20_I2S_CTRL_MASTER_ENABLE;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFS:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; val = TEGRA20_I2S_CTRL_MASTER_ENABLE;
break; break;
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
break; break;
...@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, ...@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
return -EINVAL; return -EINVAL;
} }
i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
TEGRA20_I2S_CTRL_LRCK_MASK); TEGRA20_I2S_CTRL_LRCK_MASK;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; val |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
break; break;
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
break; break;
case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_RIGHT_J:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
break; break;
case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_LEFT_J:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
return 0; return 0;
} }
...@@ -140,27 +131,32 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -140,27 +131,32 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
{ {
struct device *dev = dai->dev; struct device *dev = dai->dev;
struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
u32 reg; unsigned int mask, val;
int ret, sample_size, srate, i2sclock, bitcnt; int ret, sample_size, srate, i2sclock, bitcnt;
i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; val = TEGRA20_I2S_CTRL_BIT_SIZE_16;
sample_size = 16; sample_size = 16;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case SNDRV_PCM_FORMAT_S24_LE:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; val = TEGRA20_I2S_CTRL_BIT_SIZE_24;
sample_size = 24; sample_size = 24;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case SNDRV_PCM_FORMAT_S32_LE:
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; val = TEGRA20_I2S_CTRL_BIT_SIZE_32;
sample_size = 32; sample_size = 32;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK;
val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
srate = params_rate(params); srate = params_rate(params);
/* Final "* 2" required by Tegra hardware */ /* Final "* 2" required by Tegra hardware */
...@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
bitcnt = (i2sclock / (2 * srate)) - 1; bitcnt = (i2sclock / (2 * srate)) - 1;
if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
return -EINVAL; return -EINVAL;
reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
if (i2sclock % (2 * srate)) if (i2sclock % (2 * srate))
reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val);
tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR,
TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
return 0; return 0;
} }
static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
{ {
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); TEGRA20_I2S_CTRL_FIFO1_ENABLE,
TEGRA20_I2S_CTRL_FIFO1_ENABLE);
} }
static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
{ {
i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0);
} }
static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
{ {
i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); TEGRA20_I2S_CTRL_FIFO2_ENABLE,
TEGRA20_I2S_CTRL_FIFO2_ENABLE);
} }
static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
{ {
i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0);
} }
static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
...@@ -414,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev) ...@@ -414,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
i2s->playback_dma_data.width = 32; i2s->playback_dma_data.width = 32;
i2s->playback_dma_data.req_sel = dma_ch; i2s->playback_dma_data.req_sel = dma_ch;
i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) { if (!pm_runtime_enabled(&pdev->dev)) {
ret = tegra20_i2s_runtime_resume(&pdev->dev); ret = tegra20_i2s_runtime_resume(&pdev->dev);
......
...@@ -158,7 +158,6 @@ struct tegra20_i2s { ...@@ -158,7 +158,6 @@ struct tegra20_i2s {
struct tegra_pcm_dma_params capture_dma_data; struct tegra_pcm_dma_params capture_dma_data;
struct tegra_pcm_dma_params playback_dma_data; struct tegra_pcm_dma_params playback_dma_data;
struct regmap *regmap; struct regmap *regmap;
u32 reg_ctrl;
}; };
#endif #endif
...@@ -37,19 +37,6 @@ ...@@ -37,19 +37,6 @@
#define DRV_NAME "tegra20-spdif" #define DRV_NAME "tegra20-spdif"
static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
u32 val)
{
regmap_write(spdif->regmap, reg, val);
}
static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
{
u32 val;
regmap_read(spdif->regmap, reg, &val);
return val;
}
static int tegra20_spdif_runtime_suspend(struct device *dev) static int tegra20_spdif_runtime_suspend(struct device *dev)
{ {
struct tegra20_spdif *spdif = dev_get_drvdata(dev); struct tegra20_spdif *spdif = dev_get_drvdata(dev);
...@@ -79,19 +66,22 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, ...@@ -79,19 +66,22 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
{ {
struct device *dev = dai->dev; struct device *dev = dai->dev;
struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
int ret, spdifclock; int ret, spdifclock;
spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; mask = TEGRA20_SPDIF_CTRL_PACK |
spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; val = TEGRA20_SPDIF_CTRL_PACK |
spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val);
switch (params_rate(params)) { switch (params_rate(params)) {
case 32000: case 32000:
spdifclock = 4096000; spdifclock = 4096000;
...@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, ...@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
{ {
spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); TEGRA20_SPDIF_CTRL_TX_EN,
TEGRA20_SPDIF_CTRL_TX_EN);
} }
static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
{ {
spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); TEGRA20_SPDIF_CTRL_TX_EN, 0);
} }
static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
......
...@@ -465,7 +465,6 @@ struct tegra20_spdif { ...@@ -465,7 +465,6 @@ struct tegra20_spdif {
struct tegra_pcm_dma_params capture_dma_data; struct tegra_pcm_dma_params capture_dma_data;
struct tegra_pcm_dma_params playback_dma_data; struct tegra_pcm_dma_params playback_dma_data;
struct regmap *regmap; struct regmap *regmap;
u32 reg_ctrl;
}; };
#endif #endif
...@@ -44,18 +44,6 @@ ...@@ -44,18 +44,6 @@
#define DRV_NAME "tegra30-i2s" #define DRV_NAME "tegra30-i2s"
static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val)
{
regmap_write(i2s->regmap, reg, val);
}
static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg)
{
u32 val;
regmap_read(i2s->regmap, reg, &val);
return val;
}
static int tegra30_i2s_runtime_suspend(struct device *dev) static int tegra30_i2s_runtime_suspend(struct device *dev)
{ {
struct tegra30_i2s *i2s = dev_get_drvdata(dev); struct tegra30_i2s *i2s = dev_get_drvdata(dev);
...@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, ...@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt) unsigned int fmt)
{ {
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
unsigned int mask, val;
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_NB_NF:
...@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, ...@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
return -EINVAL; return -EINVAL;
} }
i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; mask = TEGRA30_I2S_CTRL_MASTER_ENABLE;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFS:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; val = TEGRA30_I2S_CTRL_MASTER_ENABLE;
break; break;
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
break; break;
...@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, ...@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
return -EINVAL; return -EINVAL;
} }
i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK |
TEGRA30_I2S_CTRL_LRCK_MASK); TEGRA30_I2S_CTRL_LRCK_MASK;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; val |= TEGRA30_I2S_CTRL_LRCK_R_LOW;
break; break;
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
break; break;
case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_RIGHT_J:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
break; break;
case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_LEFT_J:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
pm_runtime_get_sync(dai->dev);
regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
pm_runtime_put(dai->dev);
return 0; return 0;
} }
...@@ -183,22 +176,24 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -183,22 +176,24 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
{ {
struct device *dev = dai->dev; struct device *dev = dai->dev;
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
u32 val; unsigned int mask, val, reg;
int ret, sample_size, srate, i2sclock, bitcnt; int ret, sample_size, srate, i2sclock, bitcnt;
if (params_channels(params) != 2) if (params_channels(params) != 2)
return -EINVAL; return -EINVAL;
i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK;
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
sample_size = 16; sample_size = 16;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
srate = params_rate(params); srate = params_rate(params);
/* Final "* 2" required by Tegra hardware */ /* Final "* 2" required by Tegra hardware */
...@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
if (i2sclock % (2 * srate)) if (i2sclock % (2 * srate))
val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE;
tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val);
val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
(1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
...@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); reg = TEGRA30_I2S_CIF_RX_CTRL;
} else { } else {
val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); reg = TEGRA30_I2S_CIF_RX_CTRL;
} }
regmap_write(i2s->regmap, reg, val);
val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
(1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val);
return 0; return 0;
} }
...@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s)
{ {
tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif);
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); TEGRA30_I2S_CTRL_XFER_EN_TX,
TEGRA30_I2S_CTRL_XFER_EN_TX);
} }
static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s)
{ {
tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif);
i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); TEGRA30_I2S_CTRL_XFER_EN_TX, 0);
} }
static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s)
{ {
tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif);
i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); TEGRA30_I2S_CTRL_XFER_EN_RX,
TEGRA30_I2S_CTRL_XFER_EN_RX);
} }
static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s)
{ {
tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif);
i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); TEGRA30_I2S_CTRL_XFER_EN_RX, 0);
} }
static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
......
...@@ -236,7 +236,6 @@ struct tegra30_i2s { ...@@ -236,7 +236,6 @@ struct tegra30_i2s {
enum tegra30_ahub_txcif playback_fifo_cif; enum tegra30_ahub_txcif playback_fifo_cif;
struct tegra_pcm_dma_params playback_dma_data; struct tegra_pcm_dma_params playback_dma_data;
struct regmap *regmap; struct regmap *regmap;
u32 reg_ctrl;
}; };
#endif #endif
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