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 | |
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')
-rw-r--r-- | sound/soc/tegra/tegra20_i2s.c | 90 | ||||
-rw-r--r-- | sound/soc/tegra/tegra20_i2s.h | 1 | ||||
-rw-r--r-- | sound/soc/tegra/tegra20_spdif.c | 33 | ||||
-rw-r--r-- | sound/soc/tegra/tegra20_spdif.h | 1 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.c | 81 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.h | 1 |
6 files changed, 95 insertions, 112 deletions
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 647daf610e4a..c5fc6b1404f6 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c | |||
@@ -46,18 +46,6 @@ | |||
46 | 46 | ||
47 | #define DRV_NAME "tegra20-i2s" | 47 | #define DRV_NAME "tegra20-i2s" |
48 | 48 | ||
49 | static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val) | ||
50 | { | ||
51 | regmap_write(i2s->regmap, reg, val); | ||
52 | } | ||
53 | |||
54 | static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg) | ||
55 | { | ||
56 | u32 val; | ||
57 | regmap_read(i2s->regmap, reg, &val); | ||
58 | return val; | ||
59 | } | ||
60 | |||
61 | static int tegra20_i2s_runtime_suspend(struct device *dev) | 49 | static int tegra20_i2s_runtime_suspend(struct device *dev) |
62 | { | 50 | { |
63 | struct tegra20_i2s *i2s = dev_get_drvdata(dev); | 51 | struct tegra20_i2s *i2s = dev_get_drvdata(dev); |
@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
85 | unsigned int fmt) | 73 | unsigned int fmt) |
86 | { | 74 | { |
87 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 75 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
76 | unsigned int mask, val; | ||
88 | 77 | ||
89 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 78 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
90 | case SND_SOC_DAIFMT_NB_NF: | 79 | case SND_SOC_DAIFMT_NB_NF: |
@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
93 | return -EINVAL; | 82 | return -EINVAL; |
94 | } | 83 | } |
95 | 84 | ||
96 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; | 85 | mask = TEGRA20_I2S_CTRL_MASTER_ENABLE; |
97 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 86 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
98 | case SND_SOC_DAIFMT_CBS_CFS: | 87 | case SND_SOC_DAIFMT_CBS_CFS: |
99 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; | 88 | val = TEGRA20_I2S_CTRL_MASTER_ENABLE; |
100 | break; | 89 | break; |
101 | case SND_SOC_DAIFMT_CBM_CFM: | 90 | case SND_SOC_DAIFMT_CBM_CFM: |
102 | break; | 91 | break; |
@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, | |||
104 | return -EINVAL; | 93 | return -EINVAL; |
105 | } | 94 | } |
106 | 95 | ||
107 | i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | | 96 | mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | |
108 | TEGRA20_I2S_CTRL_LRCK_MASK); | 97 | TEGRA20_I2S_CTRL_LRCK_MASK; |
109 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 98 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
110 | case SND_SOC_DAIFMT_DSP_A: | 99 | case SND_SOC_DAIFMT_DSP_A: |
111 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; | 100 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; |
112 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 101 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
113 | break; | 102 | break; |
114 | case SND_SOC_DAIFMT_DSP_B: | 103 | case SND_SOC_DAIFMT_DSP_B: |
115 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; | 104 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; |
116 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; | 105 | val |= TEGRA20_I2S_CTRL_LRCK_R_LOW; |
117 | break; | 106 | break; |
118 | case SND_SOC_DAIFMT_I2S: | 107 | case SND_SOC_DAIFMT_I2S: |
119 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; | 108 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; |
120 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 109 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
121 | break; | 110 | break; |
122 | case SND_SOC_DAIFMT_RIGHT_J: | 111 | case SND_SOC_DAIFMT_RIGHT_J: |
123 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; | 112 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; |
124 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 113 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
125 | break; | 114 | break; |
126 | case SND_SOC_DAIFMT_LEFT_J: | 115 | case SND_SOC_DAIFMT_LEFT_J: |
127 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; | 116 | val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; |
128 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; | 117 | val |= TEGRA20_I2S_CTRL_LRCK_L_LOW; |
129 | break; | 118 | break; |
130 | default: | 119 | default: |
131 | return -EINVAL; | 120 | return -EINVAL; |
132 | } | 121 | } |
133 | 122 | ||
123 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); | ||
124 | |||
134 | return 0; | 125 | return 0; |
135 | } | 126 | } |
136 | 127 | ||
@@ -140,27 +131,32 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, | |||
140 | { | 131 | { |
141 | struct device *dev = dai->dev; | 132 | struct device *dev = dai->dev; |
142 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 133 | struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
143 | u32 reg; | 134 | unsigned int mask, val; |
144 | int ret, sample_size, srate, i2sclock, bitcnt; | 135 | int ret, sample_size, srate, i2sclock, bitcnt; |
145 | 136 | ||
146 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; | 137 | mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK; |
147 | switch (params_format(params)) { | 138 | switch (params_format(params)) { |
148 | case SNDRV_PCM_FORMAT_S16_LE: | 139 | case SNDRV_PCM_FORMAT_S16_LE: |
149 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; | 140 | val = TEGRA20_I2S_CTRL_BIT_SIZE_16; |
150 | sample_size = 16; | 141 | sample_size = 16; |
151 | break; | 142 | break; |
152 | case SNDRV_PCM_FORMAT_S24_LE: | 143 | case SNDRV_PCM_FORMAT_S24_LE: |
153 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; | 144 | val = TEGRA20_I2S_CTRL_BIT_SIZE_24; |
154 | sample_size = 24; | 145 | sample_size = 24; |
155 | break; | 146 | break; |
156 | case SNDRV_PCM_FORMAT_S32_LE: | 147 | case SNDRV_PCM_FORMAT_S32_LE: |
157 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; | 148 | val = TEGRA20_I2S_CTRL_BIT_SIZE_32; |
158 | sample_size = 32; | 149 | sample_size = 32; |
159 | break; | 150 | break; |
160 | default: | 151 | default: |
161 | return -EINVAL; | 152 | return -EINVAL; |
162 | } | 153 | } |
163 | 154 | ||
155 | mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK; | ||
156 | val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; | ||
157 | |||
158 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val); | ||
159 | |||
164 | srate = params_rate(params); | 160 | srate = params_rate(params); |
165 | 161 | ||
166 | /* Final "* 2" required by Tegra hardware */ | 162 | /* Final "* 2" required by Tegra hardware */ |
@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream, | |||
175 | bitcnt = (i2sclock / (2 * srate)) - 1; | 171 | bitcnt = (i2sclock / (2 * srate)) - 1; |
176 | if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) | 172 | if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) |
177 | return -EINVAL; | 173 | return -EINVAL; |
178 | reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; | 174 | val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; |
179 | 175 | ||
180 | if (i2sclock % (2 * srate)) | 176 | if (i2sclock % (2 * srate)) |
181 | reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; | 177 | val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; |
182 | 178 | ||
183 | tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); | 179 | regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val); |
184 | 180 | ||
185 | tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, | 181 | regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR, |
186 | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | | 182 | TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | |
187 | TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); | 183 | TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); |
188 | 184 | ||
189 | return 0; | 185 | return 0; |
190 | } | 186 | } |
191 | 187 | ||
192 | static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) | 188 | static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) |
193 | { | 189 | { |
194 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; | 190 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
195 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 191 | TEGRA20_I2S_CTRL_FIFO1_ENABLE, |
192 | TEGRA20_I2S_CTRL_FIFO1_ENABLE); | ||
196 | } | 193 | } |
197 | 194 | ||
198 | static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) | 195 | static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) |
199 | { | 196 | { |
200 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; | 197 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
201 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 198 | TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0); |
202 | } | 199 | } |
203 | 200 | ||
204 | static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) | 201 | static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) |
205 | { | 202 | { |
206 | i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; | 203 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
207 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 204 | TEGRA20_I2S_CTRL_FIFO2_ENABLE, |
205 | TEGRA20_I2S_CTRL_FIFO2_ENABLE); | ||
208 | } | 206 | } |
209 | 207 | ||
210 | static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) | 208 | static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) |
211 | { | 209 | { |
212 | i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; | 210 | regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, |
213 | tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); | 211 | TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0); |
214 | } | 212 | } |
215 | 213 | ||
216 | static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | 214 | 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 | i2s->playback_dma_data.width = 32; | 412 | i2s->playback_dma_data.width = 32; |
415 | i2s->playback_dma_data.req_sel = dma_ch; | 413 | i2s->playback_dma_data.req_sel = dma_ch; |
416 | 414 | ||
417 | i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED; | ||
418 | |||
419 | pm_runtime_enable(&pdev->dev); | 415 | pm_runtime_enable(&pdev->dev); |
420 | if (!pm_runtime_enabled(&pdev->dev)) { | 416 | if (!pm_runtime_enabled(&pdev->dev)) { |
421 | ret = tegra20_i2s_runtime_resume(&pdev->dev); | 417 | ret = tegra20_i2s_runtime_resume(&pdev->dev); |
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h index a57efc6a597e..c27069d24d77 100644 --- a/sound/soc/tegra/tegra20_i2s.h +++ b/sound/soc/tegra/tegra20_i2s.h | |||
@@ -158,7 +158,6 @@ struct tegra20_i2s { | |||
158 | struct tegra_pcm_dma_params capture_dma_data; | 158 | struct tegra_pcm_dma_params capture_dma_data; |
159 | struct tegra_pcm_dma_params playback_dma_data; | 159 | struct tegra_pcm_dma_params playback_dma_data; |
160 | struct regmap *regmap; | 160 | struct regmap *regmap; |
161 | u32 reg_ctrl; | ||
162 | }; | 161 | }; |
163 | 162 | ||
164 | #endif | 163 | #endif |
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index f774a2d5e585..5c33c618929d 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c | |||
@@ -37,19 +37,6 @@ | |||
37 | 37 | ||
38 | #define DRV_NAME "tegra20-spdif" | 38 | #define DRV_NAME "tegra20-spdif" |
39 | 39 | ||
40 | static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg, | ||
41 | u32 val) | ||
42 | { | ||
43 | regmap_write(spdif->regmap, reg, val); | ||
44 | } | ||
45 | |||
46 | static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg) | ||
47 | { | ||
48 | u32 val; | ||
49 | regmap_read(spdif->regmap, reg, &val); | ||
50 | return val; | ||
51 | } | ||
52 | |||
53 | static int tegra20_spdif_runtime_suspend(struct device *dev) | 40 | static int tegra20_spdif_runtime_suspend(struct device *dev) |
54 | { | 41 | { |
55 | struct tegra20_spdif *spdif = dev_get_drvdata(dev); | 42 | struct tegra20_spdif *spdif = dev_get_drvdata(dev); |
@@ -79,19 +66,22 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, | |||
79 | { | 66 | { |
80 | struct device *dev = dai->dev; | 67 | struct device *dev = dai->dev; |
81 | struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); | 68 | struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); |
69 | unsigned int mask, val; | ||
82 | int ret, spdifclock; | 70 | int ret, spdifclock; |
83 | 71 | ||
84 | spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; | 72 | mask = TEGRA20_SPDIF_CTRL_PACK | |
85 | spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; | 73 | TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; |
86 | switch (params_format(params)) { | 74 | switch (params_format(params)) { |
87 | case SNDRV_PCM_FORMAT_S16_LE: | 75 | case SNDRV_PCM_FORMAT_S16_LE: |
88 | spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; | 76 | val = TEGRA20_SPDIF_CTRL_PACK | |
89 | spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; | 77 | TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; |
90 | break; | 78 | break; |
91 | default: | 79 | default: |
92 | return -EINVAL; | 80 | return -EINVAL; |
93 | } | 81 | } |
94 | 82 | ||
83 | regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val); | ||
84 | |||
95 | switch (params_rate(params)) { | 85 | switch (params_rate(params)) { |
96 | case 32000: | 86 | case 32000: |
97 | spdifclock = 4096000; | 87 | spdifclock = 4096000; |
@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, | |||
129 | 119 | ||
130 | static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) | 120 | static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) |
131 | { | 121 | { |
132 | spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; | 122 | regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, |
133 | tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); | 123 | TEGRA20_SPDIF_CTRL_TX_EN, |
124 | TEGRA20_SPDIF_CTRL_TX_EN); | ||
134 | } | 125 | } |
135 | 126 | ||
136 | static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) | 127 | static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) |
137 | { | 128 | { |
138 | spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; | 129 | regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, |
139 | tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); | 130 | TEGRA20_SPDIF_CTRL_TX_EN, 0); |
140 | } | 131 | } |
141 | 132 | ||
142 | static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, | 133 | static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, |
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h index ed756527efea..b48d699fd583 100644 --- a/sound/soc/tegra/tegra20_spdif.h +++ b/sound/soc/tegra/tegra20_spdif.h | |||
@@ -465,7 +465,6 @@ struct tegra20_spdif { | |||
465 | struct tegra_pcm_dma_params capture_dma_data; | 465 | struct tegra_pcm_dma_params capture_dma_data; |
466 | struct tegra_pcm_dma_params playback_dma_data; | 466 | struct tegra_pcm_dma_params playback_dma_data; |
467 | struct regmap *regmap; | 467 | struct regmap *regmap; |
468 | u32 reg_ctrl; | ||
469 | }; | 468 | }; |
470 | 469 | ||
471 | #endif | 470 | #endif |
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, |
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index 91adf29c7a87..34dc47b9581c 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h | |||
@@ -236,7 +236,6 @@ struct tegra30_i2s { | |||
236 | enum tegra30_ahub_txcif playback_fifo_cif; | 236 | enum tegra30_ahub_txcif playback_fifo_cif; |
237 | struct tegra_pcm_dma_params playback_dma_data; | 237 | struct tegra_pcm_dma_params playback_dma_data; |
238 | struct regmap *regmap; | 238 | struct regmap *regmap; |
239 | u32 reg_ctrl; | ||
240 | }; | 239 | }; |
241 | 240 | ||
242 | #endif | 241 | #endif |