diff options
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 0eed9b1b24e1..ea3ad747d092 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -154,9 +154,9 @@ static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp) | |||
154 | 154 | ||
155 | static void mcasp_start_rx(struct davinci_mcasp *mcasp) | 155 | static void mcasp_start_rx(struct davinci_mcasp *mcasp) |
156 | { | 156 | { |
157 | /* Start clocks */ | ||
157 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); | 158 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); |
158 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); | 159 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); |
159 | |||
160 | /* | 160 | /* |
161 | * When ASYNC == 0 the transmit and receive sections operate | 161 | * When ASYNC == 0 the transmit and receive sections operate |
162 | * synchronously from the transmit clock and frame sync. We need to make | 162 | * synchronously from the transmit clock and frame sync. We need to make |
@@ -167,47 +167,36 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp) | |||
167 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); | 167 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); |
168 | } | 168 | } |
169 | 169 | ||
170 | /* Activate serializer(s) */ | ||
170 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); | 171 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); |
171 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXBUF_REG, 0); | 172 | /* Release RX state machine */ |
172 | |||
173 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); | ||
174 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); | ||
175 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXBUF_REG, 0); | ||
176 | |||
177 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); | 173 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); |
174 | /* Release Frame Sync generator */ | ||
178 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); | 175 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); |
179 | |||
180 | if (mcasp_is_synchronous(mcasp)) | 176 | if (mcasp_is_synchronous(mcasp)) |
181 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); | 177 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); |
182 | } | 178 | } |
183 | 179 | ||
184 | static void mcasp_start_tx(struct davinci_mcasp *mcasp) | 180 | static void mcasp_start_tx(struct davinci_mcasp *mcasp) |
185 | { | 181 | { |
186 | u8 offset = 0, i; | ||
187 | u32 cnt; | 182 | u32 cnt; |
188 | 183 | ||
184 | /* Start clocks */ | ||
189 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); | 185 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); |
190 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); | 186 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); |
187 | /* Activate serializer(s) */ | ||
191 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); | 188 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); |
192 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); | ||
193 | 189 | ||
194 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); | 190 | /* wait for XDATA to be cleared */ |
195 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); | ||
196 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); | ||
197 | for (i = 0; i < mcasp->num_serializer; i++) { | ||
198 | if (mcasp->serial_dir[i] == TX_MODE) { | ||
199 | offset = i; | ||
200 | break; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /* wait for TX ready */ | ||
205 | cnt = 0; | 191 | cnt = 0; |
206 | while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(offset)) & | 192 | while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) & |
207 | TXSTATE) && (cnt < 100000)) | 193 | ~XRDATA) && (cnt < 100000)) |
208 | cnt++; | 194 | cnt++; |
209 | 195 | ||
210 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); | 196 | /* Release TX state machine */ |
197 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); | ||
198 | /* Release Frame Sync generator */ | ||
199 | mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); | ||
211 | } | 200 | } |
212 | 201 | ||
213 | static void davinci_mcasp_start(struct davinci_mcasp *mcasp, int stream) | 202 | static void davinci_mcasp_start(struct davinci_mcasp *mcasp, int stream) |
@@ -244,6 +233,12 @@ static void mcasp_stop_rx(struct davinci_mcasp *mcasp) | |||
244 | 233 | ||
245 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0); | 234 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0); |
246 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); | 235 | mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); |
236 | |||
237 | if (mcasp->rxnumevt) { /* disable FIFO */ | ||
238 | u32 reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; | ||
239 | |||
240 | mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); | ||
241 | } | ||
247 | } | 242 | } |
248 | 243 | ||
249 | static void mcasp_stop_tx(struct davinci_mcasp *mcasp) | 244 | static void mcasp_stop_tx(struct davinci_mcasp *mcasp) |
@@ -259,27 +254,22 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp) | |||
259 | 254 | ||
260 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); | 255 | mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); |
261 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); | 256 | mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); |
257 | |||
258 | if (mcasp->txnumevt) { /* disable FIFO */ | ||
259 | u32 reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; | ||
260 | |||
261 | mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); | ||
262 | } | ||
262 | } | 263 | } |
263 | 264 | ||
264 | static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream) | 265 | static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream) |
265 | { | 266 | { |
266 | u32 reg; | ||
267 | |||
268 | mcasp->streams--; | 267 | mcasp->streams--; |
269 | 268 | ||
270 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 269 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
271 | if (mcasp->txnumevt) { /* disable FIFO */ | ||
272 | reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; | ||
273 | mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); | ||
274 | } | ||
275 | mcasp_stop_tx(mcasp); | 270 | mcasp_stop_tx(mcasp); |
276 | } else { | 271 | else |
277 | if (mcasp->rxnumevt) { /* disable FIFO */ | ||
278 | reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; | ||
279 | mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); | ||
280 | } | ||
281 | mcasp_stop_rx(mcasp); | 272 | mcasp_stop_rx(mcasp); |
282 | } | ||
283 | } | 273 | } |
284 | 274 | ||
285 | static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | 275 | static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, |
@@ -500,8 +490,17 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | |||
500 | * both left and right channels), so it has to be divided by number of | 490 | * both left and right channels), so it has to be divided by number of |
501 | * tdm-slots (for I2S - divided by 2). | 491 | * tdm-slots (for I2S - divided by 2). |
502 | */ | 492 | */ |
503 | if (mcasp->bclk_lrclk_ratio) | 493 | if (mcasp->bclk_lrclk_ratio) { |
504 | word_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots; | 494 | u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots; |
495 | |||
496 | /* | ||
497 | * When we have more bclk then it is needed for the data, we | ||
498 | * need to use the rotation to move the received samples to have | ||
499 | * correct alignment. | ||
500 | */ | ||
501 | rx_rotate = (slot_length - word_length) / 4; | ||
502 | word_length = slot_length; | ||
503 | } | ||
505 | 504 | ||
506 | /* mapping of the XSSZ bit-field as described in the datasheet */ | 505 | /* mapping of the XSSZ bit-field as described in the datasheet */ |
507 | fmt = (word_length >> 1) - 1; | 506 | fmt = (word_length >> 1) - 1; |
@@ -971,6 +970,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
971 | }, | 970 | }, |
972 | .ops = &davinci_mcasp_dai_ops, | 971 | .ops = &davinci_mcasp_dai_ops, |
973 | 972 | ||
973 | .symmetric_samplebits = 1, | ||
974 | }, | 974 | }, |
975 | { | 975 | { |
976 | .name = "davinci-mcasp.1", | 976 | .name = "davinci-mcasp.1", |
@@ -1235,6 +1235,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1235 | ret = pm_runtime_get_sync(&pdev->dev); | 1235 | ret = pm_runtime_get_sync(&pdev->dev); |
1236 | if (IS_ERR_VALUE(ret)) { | 1236 | if (IS_ERR_VALUE(ret)) { |
1237 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); | 1237 | dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); |
1238 | pm_runtime_disable(&pdev->dev); | ||
1238 | return ret; | 1239 | return ret; |
1239 | } | 1240 | } |
1240 | 1241 | ||