diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-06-06 19:15:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-06-07 19:03:14 -0400 |
commit | 0f163546a772d62250f59bad6a9338a0e3a2605c (patch) | |
tree | 3005bdac3443c38efd57908f74cbbad55a37e870 /sound/soc/tegra/tegra30_i2s.c | |
parent | c92a40e3a163b6708e0dd82ba4612f79df846912 (diff) |
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: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/tegra/tegra30_i2s.c')
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.c | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 2327f62e8a8c..b68e27a14608 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c | |||
@@ -44,18 +44,6 @@ | |||
44 | 44 | ||
45 | #define DRV_NAME "tegra30-i2s" | 45 | #define DRV_NAME "tegra30-i2s" |
46 | 46 | ||
47 | static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val) | ||
48 | { | ||
49 | regmap_write(i2s->regmap, reg, val); | ||
50 | } | ||
51 | |||
52 | static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg) | ||
53 | { | ||
54 | u32 val; | ||
55 | regmap_read(i2s->regmap, reg, &val); | ||
56 | return val; | ||
57 | } | ||
58 | |||
59 | static int tegra30_i2s_runtime_suspend(struct device *dev) | 47 | static int tegra30_i2s_runtime_suspend(struct device *dev) |
60 | { | 48 | { |
61 | struct tegra30_i2s *i2s = dev_get_drvdata(dev); | 49 | struct tegra30_i2s *i2s = dev_get_drvdata(dev); |
@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, | |||
128 | unsigned int fmt) | 116 | unsigned int fmt) |
129 | { | 117 | { |
130 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 118 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
119 | unsigned int mask, val; | ||
131 | 120 | ||
132 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 121 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
133 | case SND_SOC_DAIFMT_NB_NF: | 122 | case SND_SOC_DAIFMT_NB_NF: |
@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, | |||
136 | return -EINVAL; | 125 | return -EINVAL; |
137 | } | 126 | } |
138 | 127 | ||
139 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; | 128 | mask = TEGRA30_I2S_CTRL_MASTER_ENABLE; |
140 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 129 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
141 | case SND_SOC_DAIFMT_CBS_CFS: | 130 | case SND_SOC_DAIFMT_CBS_CFS: |
142 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; | 131 | val = TEGRA30_I2S_CTRL_MASTER_ENABLE; |
143 | break; | 132 | break; |
144 | case SND_SOC_DAIFMT_CBM_CFM: | 133 | case SND_SOC_DAIFMT_CBM_CFM: |
145 | break; | 134 | break; |
@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, | |||
147 | return -EINVAL; | 136 | return -EINVAL; |
148 | } | 137 | } |
149 | 138 | ||
150 | i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | | 139 | mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | |
151 | TEGRA30_I2S_CTRL_LRCK_MASK); | 140 | TEGRA30_I2S_CTRL_LRCK_MASK; |
152 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 141 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
153 | case SND_SOC_DAIFMT_DSP_A: | 142 | case SND_SOC_DAIFMT_DSP_A: |
154 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; | 143 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; |
155 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 144 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
156 | break; | 145 | break; |
157 | case SND_SOC_DAIFMT_DSP_B: | 146 | case SND_SOC_DAIFMT_DSP_B: |
158 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; | 147 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; |
159 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; | 148 | val |= TEGRA30_I2S_CTRL_LRCK_R_LOW; |
160 | break; | 149 | break; |
161 | case SND_SOC_DAIFMT_I2S: | 150 | case SND_SOC_DAIFMT_I2S: |
162 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; | 151 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; |
163 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 152 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
164 | break; | 153 | break; |
165 | case SND_SOC_DAIFMT_RIGHT_J: | 154 | case SND_SOC_DAIFMT_RIGHT_J: |
166 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; | 155 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; |
167 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 156 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
168 | break; | 157 | break; |
169 | case SND_SOC_DAIFMT_LEFT_J: | 158 | case SND_SOC_DAIFMT_LEFT_J: |
170 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; | 159 | val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; |
171 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; | 160 | val |= TEGRA30_I2S_CTRL_LRCK_L_LOW; |
172 | break; | 161 | break; |
173 | default: | 162 | default: |
174 | return -EINVAL; | 163 | return -EINVAL; |
175 | } | 164 | } |
176 | 165 | ||
166 | pm_runtime_get_sync(dai->dev); | ||
167 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); | ||
168 | pm_runtime_put(dai->dev); | ||
169 | |||
177 | return 0; | 170 | return 0; |
178 | } | 171 | } |
179 | 172 | ||
@@ -183,22 +176,24 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
183 | { | 176 | { |
184 | struct device *dev = dai->dev; | 177 | struct device *dev = dai->dev; |
185 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 178 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
186 | u32 val; | 179 | unsigned int mask, val, reg; |
187 | int ret, sample_size, srate, i2sclock, bitcnt; | 180 | int ret, sample_size, srate, i2sclock, bitcnt; |
188 | 181 | ||
189 | if (params_channels(params) != 2) | 182 | if (params_channels(params) != 2) |
190 | return -EINVAL; | 183 | return -EINVAL; |
191 | 184 | ||
192 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; | 185 | mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK; |
193 | switch (params_format(params)) { | 186 | switch (params_format(params)) { |
194 | case SNDRV_PCM_FORMAT_S16_LE: | 187 | case SNDRV_PCM_FORMAT_S16_LE: |
195 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; | 188 | val = TEGRA30_I2S_CTRL_BIT_SIZE_16; |
196 | sample_size = 16; | 189 | sample_size = 16; |
197 | break; | 190 | break; |
198 | default: | 191 | default: |
199 | return -EINVAL; | 192 | return -EINVAL; |
200 | } | 193 | } |
201 | 194 | ||
195 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); | ||
196 | |||
202 | srate = params_rate(params); | 197 | srate = params_rate(params); |
203 | 198 | ||
204 | /* Final "* 2" required by Tegra hardware */ | 199 | /* Final "* 2" required by Tegra hardware */ |
@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
219 | if (i2sclock % (2 * srate)) | 214 | if (i2sclock % (2 * srate)) |
220 | val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; | 215 | val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; |
221 | 216 | ||
222 | tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); | 217 | regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val); |
223 | 218 | ||
224 | val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | | 219 | val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | |
225 | (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | | 220 | (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | |
@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
229 | 224 | ||
230 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 225 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
231 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; | 226 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; |
232 | tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); | 227 | reg = TEGRA30_I2S_CIF_RX_CTRL; |
233 | } else { | 228 | } else { |
234 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; | 229 | val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; |
235 | tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); | 230 | reg = TEGRA30_I2S_CIF_RX_CTRL; |
236 | } | 231 | } |
237 | 232 | ||
233 | regmap_write(i2s->regmap, reg, val); | ||
234 | |||
238 | val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | | 235 | val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | |
239 | (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); | 236 | (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); |
240 | tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); | 237 | regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val); |
241 | 238 | ||
242 | return 0; | 239 | return 0; |
243 | } | 240 | } |
@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, | |||
245 | static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) | 242 | static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) |
246 | { | 243 | { |
247 | tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); | 244 | tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); |
248 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; | 245 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
249 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 246 | TEGRA30_I2S_CTRL_XFER_EN_TX, |
247 | TEGRA30_I2S_CTRL_XFER_EN_TX); | ||
250 | } | 248 | } |
251 | 249 | ||
252 | static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) | 250 | static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) |
253 | { | 251 | { |
254 | tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); | 252 | tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); |
255 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; | 253 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
256 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 254 | TEGRA30_I2S_CTRL_XFER_EN_TX, 0); |
257 | } | 255 | } |
258 | 256 | ||
259 | static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) | 257 | static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) |
260 | { | 258 | { |
261 | tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); | 259 | tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); |
262 | i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; | 260 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
263 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 261 | TEGRA30_I2S_CTRL_XFER_EN_RX, |
262 | TEGRA30_I2S_CTRL_XFER_EN_RX); | ||
264 | } | 263 | } |
265 | 264 | ||
266 | static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) | 265 | static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) |
267 | { | 266 | { |
268 | tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); | 267 | tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); |
269 | i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; | 268 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
270 | tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); | 269 | TEGRA30_I2S_CTRL_XFER_EN_RX, 0); |
271 | } | 270 | } |
272 | 271 | ||
273 | static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | 272 | static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |