1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) ST-Ericsson SA 2012
4 *
5 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
6 * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
7 * Sandeep Kaushik <sandeep.kaushik@st.com>
8 * for ST-Ericsson.
9 */
10
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/io.h>
16 #include <linux/of.h>
17
18 #include <sound/soc.h>
19
20 #include "ux500_msp_i2s.h"
21
22 /* Protocol desciptors */
23 static const struct msp_protdesc prot_descs[] = {
24 { /* I2S */
25 MSP_SINGLE_PHASE,
26 MSP_SINGLE_PHASE,
27 MSP_PHASE2_START_MODE_IMEDIATE,
28 MSP_PHASE2_START_MODE_IMEDIATE,
29 MSP_BTF_MS_BIT_FIRST,
30 MSP_BTF_MS_BIT_FIRST,
31 MSP_FRAME_LEN_1,
32 MSP_FRAME_LEN_1,
33 MSP_FRAME_LEN_1,
34 MSP_FRAME_LEN_1,
35 MSP_ELEM_LEN_32,
36 MSP_ELEM_LEN_32,
37 MSP_ELEM_LEN_32,
38 MSP_ELEM_LEN_32,
39 MSP_DELAY_1,
40 MSP_DELAY_1,
41 MSP_RISING_EDGE,
42 MSP_FALLING_EDGE,
43 MSP_FSYNC_POL_ACT_LO,
44 MSP_FSYNC_POL_ACT_LO,
45 MSP_SWAP_NONE,
46 MSP_SWAP_NONE,
47 MSP_COMPRESS_MODE_LINEAR,
48 MSP_EXPAND_MODE_LINEAR,
49 MSP_FSYNC_IGNORE,
50 31,
51 15,
52 32,
53 }, { /* PCM */
54 MSP_DUAL_PHASE,
55 MSP_DUAL_PHASE,
56 MSP_PHASE2_START_MODE_FSYNC,
57 MSP_PHASE2_START_MODE_FSYNC,
58 MSP_BTF_MS_BIT_FIRST,
59 MSP_BTF_MS_BIT_FIRST,
60 MSP_FRAME_LEN_1,
61 MSP_FRAME_LEN_1,
62 MSP_FRAME_LEN_1,
63 MSP_FRAME_LEN_1,
64 MSP_ELEM_LEN_16,
65 MSP_ELEM_LEN_16,
66 MSP_ELEM_LEN_16,
67 MSP_ELEM_LEN_16,
68 MSP_DELAY_0,
69 MSP_DELAY_0,
70 MSP_RISING_EDGE,
71 MSP_FALLING_EDGE,
72 MSP_FSYNC_POL_ACT_HI,
73 MSP_FSYNC_POL_ACT_HI,
74 MSP_SWAP_NONE,
75 MSP_SWAP_NONE,
76 MSP_COMPRESS_MODE_LINEAR,
77 MSP_EXPAND_MODE_LINEAR,
78 MSP_FSYNC_IGNORE,
79 255,
80 0,
81 256,
82 }, { /* Companded PCM */
83 MSP_SINGLE_PHASE,
84 MSP_SINGLE_PHASE,
85 MSP_PHASE2_START_MODE_FSYNC,
86 MSP_PHASE2_START_MODE_FSYNC,
87 MSP_BTF_MS_BIT_FIRST,
88 MSP_BTF_MS_BIT_FIRST,
89 MSP_FRAME_LEN_1,
90 MSP_FRAME_LEN_1,
91 MSP_FRAME_LEN_1,
92 MSP_FRAME_LEN_1,
93 MSP_ELEM_LEN_8,
94 MSP_ELEM_LEN_8,
95 MSP_ELEM_LEN_8,
96 MSP_ELEM_LEN_8,
97 MSP_DELAY_0,
98 MSP_DELAY_0,
99 MSP_RISING_EDGE,
100 MSP_RISING_EDGE,
101 MSP_FSYNC_POL_ACT_HI,
102 MSP_FSYNC_POL_ACT_HI,
103 MSP_SWAP_NONE,
104 MSP_SWAP_NONE,
105 MSP_COMPRESS_MODE_LINEAR,
106 MSP_EXPAND_MODE_LINEAR,
107 MSP_FSYNC_IGNORE,
108 255,
109 0,
110 256,
111 },
112 };
113
set_prot_desc_tx(struct ux500_msp * msp,struct msp_protdesc * protdesc,enum msp_data_size data_size)114 static void set_prot_desc_tx(struct ux500_msp *msp,
115 struct msp_protdesc *protdesc,
116 enum msp_data_size data_size)
117 {
118 u32 temp_reg = 0;
119
120 temp_reg |= MSP_P2_ENABLE_BIT(protdesc->tx_phase_mode);
121 temp_reg |= MSP_P2_START_MODE_BIT(protdesc->tx_phase2_start_mode);
122 temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->tx_frame_len_1);
123 temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->tx_frame_len_2);
124 if (msp->def_elem_len) {
125 temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->tx_elem_len_1);
126 temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->tx_elem_len_2);
127 } else {
128 temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
129 temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
130 }
131 temp_reg |= MSP_DATA_DELAY_BITS(protdesc->tx_data_delay);
132 temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->tx_byte_order);
133 temp_reg |= MSP_FSYNC_POL(protdesc->tx_fsync_pol);
134 temp_reg |= MSP_DATA_WORD_SWAP(protdesc->tx_half_word_swap);
135 temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->compression_mode);
136 temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
137
138 writel(temp_reg, msp->registers + MSP_TCF);
139 }
140
set_prot_desc_rx(struct ux500_msp * msp,struct msp_protdesc * protdesc,enum msp_data_size data_size)141 static void set_prot_desc_rx(struct ux500_msp *msp,
142 struct msp_protdesc *protdesc,
143 enum msp_data_size data_size)
144 {
145 u32 temp_reg = 0;
146
147 temp_reg |= MSP_P2_ENABLE_BIT(protdesc->rx_phase_mode);
148 temp_reg |= MSP_P2_START_MODE_BIT(protdesc->rx_phase2_start_mode);
149 temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->rx_frame_len_1);
150 temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->rx_frame_len_2);
151 if (msp->def_elem_len) {
152 temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->rx_elem_len_1);
153 temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->rx_elem_len_2);
154 } else {
155 temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
156 temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
157 }
158
159 temp_reg |= MSP_DATA_DELAY_BITS(protdesc->rx_data_delay);
160 temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->rx_byte_order);
161 temp_reg |= MSP_FSYNC_POL(protdesc->rx_fsync_pol);
162 temp_reg |= MSP_DATA_WORD_SWAP(protdesc->rx_half_word_swap);
163 temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->expansion_mode);
164 temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
165
166 writel(temp_reg, msp->registers + MSP_RCF);
167 }
168
configure_protocol(struct ux500_msp * msp,struct ux500_msp_config * config)169 static int configure_protocol(struct ux500_msp *msp,
170 struct ux500_msp_config *config)
171 {
172 struct msp_protdesc *protdesc;
173 enum msp_data_size data_size;
174 u32 temp_reg = 0;
175
176 data_size = config->data_size;
177 msp->def_elem_len = config->def_elem_len;
178 if (config->default_protdesc == 1) {
179 if (config->protocol >= MSP_INVALID_PROTOCOL) {
180 dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n",
181 __func__);
182 return -EINVAL;
183 }
184 protdesc =
185 (struct msp_protdesc *)&prot_descs[config->protocol];
186 } else {
187 protdesc = (struct msp_protdesc *)&config->protdesc;
188 }
189
190 if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) {
191 dev_err(msp->dev,
192 "%s: ERROR: Invalid data-size requested (data_size = %d)!\n",
193 __func__, data_size);
194 return -EINVAL;
195 }
196
197 if (config->direction & MSP_DIR_TX)
198 set_prot_desc_tx(msp, protdesc, data_size);
199 if (config->direction & MSP_DIR_RX)
200 set_prot_desc_rx(msp, protdesc, data_size);
201
202 /* The code below should not be separated. */
203 temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
204 temp_reg |= MSP_TX_CLKPOL_BIT(!protdesc->tx_clk_pol ^
205 config->bclk_inverted);
206 writel(temp_reg, msp->registers + MSP_GCR);
207 temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
208 temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol ^
209 config->bclk_inverted);
210 writel(temp_reg, msp->registers + MSP_GCR);
211
212 return 0;
213 }
214
setup_bitclk(struct ux500_msp * msp,struct ux500_msp_config * config)215 static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
216 {
217 struct msp_protdesc *protdesc;
218 u64 desired_bitclk;
219 unsigned int bitclk;
220 u32 reg_val_GCR;
221 u32 sck_div;
222 u32 temp_reg;
223
224 reg_val_GCR = readl(msp->registers + MSP_GCR);
225 writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
226
227 switch (config->protocol) {
228 case MSP_PCM_PROTOCOL:
229 case MSP_PCM_COMPAND_PROTOCOL:
230 case MSP_I2S_PROTOCOL:
231 break;
232 default:
233 dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
234 __func__,
235 config->protocol);
236 return -EINVAL;
237 }
238
239 if (config->default_protdesc)
240 protdesc = (struct msp_protdesc *)&prot_descs[config->protocol];
241 else
242 protdesc = &config->protdesc;
243
244 if (!config->frame_freq || !protdesc->clocks_per_frame)
245 return -EINVAL;
246
247 desired_bitclk = (u64)config->frame_freq * protdesc->clocks_per_frame;
248 if (desired_bitclk > config->f_inputclk)
249 return -EINVAL;
250 bitclk = desired_bitclk;
251 if (config->f_inputclk % bitclk) {
252 dev_err(msp->dev,
253 "Input clock %u cannot generate bit clock %u\n",
254 config->f_inputclk, bitclk);
255 return -EINVAL;
256 }
257
258 sck_div = config->f_inputclk / bitclk;
259 if (!sck_div || sck_div > SCK_DIV_MASK + 1)
260 return -EINVAL;
261
262 temp_reg = (sck_div - 1) & SCK_DIV_MASK;
263 temp_reg |= FRAME_WIDTH_BITS(protdesc->frame_width);
264 temp_reg |= FRAME_PERIOD_BITS(protdesc->frame_period);
265 writel(temp_reg, msp->registers + MSP_SRG);
266
267 msp->f_bitclk = config->f_inputclk / sck_div;
268
269 /* Enable bit-clock */
270 udelay(100);
271 reg_val_GCR = readl(msp->registers + MSP_GCR);
272 writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR);
273 udelay(100);
274
275 return 0;
276 }
277
configure_multichannel(struct ux500_msp * msp,struct ux500_msp_config * config)278 static int configure_multichannel(struct ux500_msp *msp,
279 struct ux500_msp_config *config)
280 {
281 struct msp_protdesc *protdesc;
282 struct msp_multichannel_config *mcfg;
283 u32 reg_val_MCR;
284
285 if (config->default_protdesc == 1) {
286 if (config->protocol >= MSP_INVALID_PROTOCOL) {
287 dev_err(msp->dev,
288 "%s: ERROR: Invalid protocol (%d)!\n",
289 __func__, config->protocol);
290 return -EINVAL;
291 }
292 protdesc = (struct msp_protdesc *)
293 &prot_descs[config->protocol];
294 } else {
295 protdesc = (struct msp_protdesc *)&config->protdesc;
296 }
297
298 mcfg = &config->multichannel_config;
299 if (mcfg->tx_multichannel_enable) {
300 if (protdesc->tx_phase_mode == MSP_SINGLE_PHASE) {
301 reg_val_MCR = readl(msp->registers + MSP_MCR);
302 writel(reg_val_MCR | (mcfg->tx_multichannel_enable ?
303 1 << TMCEN_BIT : 0),
304 msp->registers + MSP_MCR);
305 writel(mcfg->tx_channel_0_enable,
306 msp->registers + MSP_TCE0);
307 writel(mcfg->tx_channel_1_enable,
308 msp->registers + MSP_TCE1);
309 writel(mcfg->tx_channel_2_enable,
310 msp->registers + MSP_TCE2);
311 writel(mcfg->tx_channel_3_enable,
312 msp->registers + MSP_TCE3);
313 } else {
314 dev_err(msp->dev,
315 "%s: ERROR: Only single-phase supported (TX-mode: %d)!\n",
316 __func__, protdesc->tx_phase_mode);
317 return -EINVAL;
318 }
319 }
320 if (mcfg->rx_multichannel_enable) {
321 if (protdesc->rx_phase_mode == MSP_SINGLE_PHASE) {
322 reg_val_MCR = readl(msp->registers + MSP_MCR);
323 writel(reg_val_MCR | (mcfg->rx_multichannel_enable ?
324 1 << RMCEN_BIT : 0),
325 msp->registers + MSP_MCR);
326 writel(mcfg->rx_channel_0_enable,
327 msp->registers + MSP_RCE0);
328 writel(mcfg->rx_channel_1_enable,
329 msp->registers + MSP_RCE1);
330 writel(mcfg->rx_channel_2_enable,
331 msp->registers + MSP_RCE2);
332 writel(mcfg->rx_channel_3_enable,
333 msp->registers + MSP_RCE3);
334 } else {
335 dev_err(msp->dev,
336 "%s: ERROR: Only single-phase supported (RX-mode: %d)!\n",
337 __func__, protdesc->rx_phase_mode);
338 return -EINVAL;
339 }
340 if (mcfg->rx_comparison_enable_mode) {
341 reg_val_MCR = readl(msp->registers + MSP_MCR);
342 writel(reg_val_MCR |
343 (mcfg->rx_comparison_enable_mode << RCMPM_BIT),
344 msp->registers + MSP_MCR);
345
346 writel(mcfg->comparison_mask,
347 msp->registers + MSP_RCM);
348 writel(mcfg->comparison_value,
349 msp->registers + MSP_RCV);
350
351 }
352 }
353
354 return 0;
355 }
356
enable_msp(struct ux500_msp * msp,struct ux500_msp_config * config,bool first)357 static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config,
358 bool first)
359 {
360 int status;
361 u32 reg_val_DMACR;
362
363 /* Configure msp with protocol dependent settings */
364 status = configure_protocol(msp, config);
365 if (status)
366 return status;
367
368 if (first && config->clock_provider) {
369 status = setup_bitclk(msp, config);
370 if (status)
371 return status;
372 }
373
374 if (config->multichannel_configured == 1) {
375 status = configure_multichannel(msp, config);
376 if (status)
377 return status;
378 }
379
380 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
381 if (config->direction & MSP_DIR_RX)
382 reg_val_DMACR |= RX_DMA_ENABLE;
383 if (config->direction & MSP_DIR_TX)
384 reg_val_DMACR |= TX_DMA_ENABLE;
385 writel(reg_val_DMACR, msp->registers + MSP_DMACR);
386
387 writel(config->iodelay, msp->registers + MSP_IODLY);
388
389 return 0;
390 }
391
flush_fifo_rx(struct ux500_msp * msp)392 static void flush_fifo_rx(struct ux500_msp *msp)
393 {
394 u32 reg_val_GCR, reg_val_FLR;
395 u32 limit = 32;
396
397 reg_val_GCR = readl(msp->registers + MSP_GCR);
398 writel(reg_val_GCR | RX_ENABLE, msp->registers + MSP_GCR);
399
400 reg_val_FLR = readl(msp->registers + MSP_FLR);
401 while (!(reg_val_FLR & RX_FIFO_EMPTY) && limit--) {
402 readl(msp->registers + MSP_DR);
403 reg_val_FLR = readl(msp->registers + MSP_FLR);
404 }
405
406 writel(reg_val_GCR, msp->registers + MSP_GCR);
407 }
408
flush_fifo_tx(struct ux500_msp * msp)409 static void flush_fifo_tx(struct ux500_msp *msp)
410 {
411 u32 reg_val_GCR, reg_val_FLR;
412 u32 limit = 32;
413
414 reg_val_GCR = readl(msp->registers + MSP_GCR);
415 writel(reg_val_GCR | TX_ENABLE, msp->registers + MSP_GCR);
416 writel(MSP_ITCR_ITEN | MSP_ITCR_TESTFIFO, msp->registers + MSP_ITCR);
417
418 reg_val_FLR = readl(msp->registers + MSP_FLR);
419 while (!(reg_val_FLR & TX_FIFO_EMPTY) && limit--) {
420 readl(msp->registers + MSP_TSTDR);
421 reg_val_FLR = readl(msp->registers + MSP_FLR);
422 }
423 writel(0x0, msp->registers + MSP_ITCR);
424 writel(reg_val_GCR, msp->registers + MSP_GCR);
425 }
426
ux500_msp_config_compatible(struct ux500_msp * msp,struct ux500_msp_config * config)427 static bool ux500_msp_config_compatible(struct ux500_msp *msp,
428 struct ux500_msp_config *config)
429 {
430 struct ux500_msp_config *active = &msp->config;
431
432 return active->f_inputclk == config->f_inputclk &&
433 active->tx_clk_sel == config->tx_clk_sel &&
434 active->rx_clk_sel == config->rx_clk_sel &&
435 active->srg_clk_sel == config->srg_clk_sel &&
436 active->rx_fsync_pol == config->rx_fsync_pol &&
437 active->tx_fsync_pol == config->tx_fsync_pol &&
438 active->rx_fsync_sel == config->rx_fsync_sel &&
439 active->tx_fsync_sel == config->tx_fsync_sel &&
440 active->default_protdesc == config->default_protdesc &&
441 active->protocol == config->protocol &&
442 active->frame_freq == config->frame_freq &&
443 active->data_size == config->data_size &&
444 active->def_elem_len == config->def_elem_len &&
445 active->clock_provider == config->clock_provider &&
446 active->bclk_inverted == config->bclk_inverted &&
447 !memcmp(&active->protdesc, &config->protdesc,
448 sizeof(active->protdesc));
449 }
450
ux500_msp_i2s_open(struct ux500_msp * msp,struct ux500_msp_config * config)451 int ux500_msp_i2s_open(struct ux500_msp *msp,
452 struct ux500_msp_config *config)
453 {
454 u32 old_reg, new_reg, mask;
455 int res;
456 unsigned int tx_sel, rx_sel, tx_busy, rx_busy;
457 bool first;
458
459 if (in_interrupt()) {
460 dev_err(msp->dev,
461 "%s: ERROR: Open called in interrupt context!\n",
462 __func__);
463 return -1;
464 }
465
466 tx_sel = (config->direction & MSP_DIR_TX) > 0;
467 rx_sel = (config->direction & MSP_DIR_RX) > 0;
468 if (!tx_sel && !rx_sel) {
469 dev_err(msp->dev, "%s: Error: No direction selected!\n",
470 __func__);
471 return -EINVAL;
472 }
473
474 tx_busy = (msp->dir_busy & MSP_DIR_TX) > 0;
475 rx_busy = (msp->dir_busy & MSP_DIR_RX) > 0;
476 if (tx_busy && tx_sel) {
477 dev_err(msp->dev, "%s: Error: TX is in use!\n", __func__);
478 return -EBUSY;
479 }
480 if (rx_busy && rx_sel) {
481 dev_err(msp->dev, "%s: Error: RX is in use!\n", __func__);
482 return -EBUSY;
483 }
484
485 first = !msp->dir_busy;
486 if (!first && !ux500_msp_config_compatible(msp, config)) {
487 dev_err(msp->dev, "%s: Incompatible duplex configuration\n",
488 __func__);
489 return -EBUSY;
490 }
491
492 if (first) {
493 /* First do the global config register */
494 mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
495 TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
496 RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK |
497 SRG_CLK_SEL_MASK | LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
498
499 new_reg = config->tx_clk_sel | config->rx_clk_sel |
500 config->rx_fsync_pol | config->tx_fsync_pol |
501 config->rx_fsync_sel | config->tx_fsync_sel |
502 config->rx_fifo_config | config->tx_fifo_config |
503 config->srg_clk_sel | config->loopback_enable |
504 config->tx_data_enable;
505
506 old_reg = readl(msp->registers + MSP_GCR);
507 old_reg &= ~mask;
508 new_reg |= old_reg;
509 writel(new_reg, msp->registers + MSP_GCR);
510 writel(MSP_WMRK_TX_4_ELEMENTS | MSP_WMRK_RX_4_ELEMENTS,
511 msp->registers + MSP_WMRK);
512 }
513
514 res = enable_msp(msp, config, first);
515 if (res < 0) {
516 dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n",
517 __func__, res);
518 if (tx_sel)
519 writel(0, msp->registers + MSP_TCF);
520 if (rx_sel)
521 writel(0, msp->registers + MSP_RCF);
522 if (first) {
523 writel(0, msp->registers + MSP_GCR);
524 writel(0, msp->registers + MSP_DMACR);
525 writel(0, msp->registers + MSP_SRG);
526 writel(0, msp->registers + MSP_MCR);
527 }
528 return res;
529 }
530
531 msp->dir_busy |= config->direction;
532 if (first) {
533 msp->config = *config;
534 msp->clock_provider = config->clock_provider;
535 }
536 if (config->loopback_enable & 0x80)
537 msp->loopback_enable = 1;
538
539 /* Flush FIFOs */
540 if (tx_sel)
541 flush_fifo_tx(msp);
542 if (rx_sel)
543 flush_fifo_rx(msp);
544
545 if (!msp->dir_running)
546 msp->msp_state = MSP_STATE_CONFIGURED;
547 return 0;
548 }
549
disable_msp_rx(struct ux500_msp * msp)550 static void disable_msp_rx(struct ux500_msp *msp)
551 {
552 u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
553
554 reg_val_GCR = readl(msp->registers + MSP_GCR);
555 writel(reg_val_GCR & ~RX_ENABLE, msp->registers + MSP_GCR);
556 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
557 writel(reg_val_DMACR & ~RX_DMA_ENABLE, msp->registers + MSP_DMACR);
558 reg_val_IMSC = readl(msp->registers + MSP_IMSC);
559 writel(reg_val_IMSC &
560 ~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT),
561 msp->registers + MSP_IMSC);
562
563 }
564
disable_msp_tx(struct ux500_msp * msp)565 static void disable_msp_tx(struct ux500_msp *msp)
566 {
567 u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
568
569 reg_val_GCR = readl(msp->registers + MSP_GCR);
570 writel(reg_val_GCR & ~TX_ENABLE, msp->registers + MSP_GCR);
571 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
572 writel(reg_val_DMACR & ~TX_DMA_ENABLE, msp->registers + MSP_DMACR);
573 reg_val_IMSC = readl(msp->registers + MSP_IMSC);
574 writel(reg_val_IMSC &
575 ~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT),
576 msp->registers + MSP_IMSC);
577
578 }
579
disable_msp(struct ux500_msp * msp,unsigned int dir)580 static int disable_msp(struct ux500_msp *msp, unsigned int dir)
581 {
582 u32 reg_val_GCR;
583 unsigned int disable_tx, disable_rx;
584
585 reg_val_GCR = readl(msp->registers + MSP_GCR);
586 disable_tx = dir & MSP_DIR_TX;
587 disable_rx = dir & MSP_DIR_RX;
588 if (disable_tx && disable_rx) {
589 reg_val_GCR = readl(msp->registers + MSP_GCR);
590 writel(reg_val_GCR | LOOPBACK_MASK,
591 msp->registers + MSP_GCR);
592
593 /* Flush TX-FIFO */
594 flush_fifo_tx(msp);
595
596 /* Disable TX-channel */
597 writel((readl(msp->registers + MSP_GCR) &
598 (~TX_ENABLE)), msp->registers + MSP_GCR);
599
600 /* Flush RX-FIFO */
601 flush_fifo_rx(msp);
602
603 /* Disable Loopback and Receive channel */
604 writel((readl(msp->registers + MSP_GCR) &
605 (~(RX_ENABLE | LOOPBACK_MASK))),
606 msp->registers + MSP_GCR);
607
608 disable_msp_tx(msp);
609 disable_msp_rx(msp);
610 } else if (disable_tx)
611 disable_msp_tx(msp);
612 else if (disable_rx)
613 disable_msp_rx(msp);
614
615 return 0;
616 }
617
ux500_msp_i2s_trigger(struct ux500_msp * msp,int cmd,int direction)618 int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
619 {
620 u32 reg_val_DMACR, reg_val_GCR, dma_enable_bit, enable_bit;
621 unsigned int dir;
622
623 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
624 dir = MSP_DIR_TX;
625 else if (direction == SNDRV_PCM_STREAM_CAPTURE)
626 dir = MSP_DIR_RX;
627 else
628 return -EINVAL;
629
630 if (msp->msp_state == MSP_STATE_IDLE) {
631 dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n",
632 __func__);
633 return -EINVAL;
634 }
635
636 switch (cmd) {
637 case SNDRV_PCM_TRIGGER_START:
638 case SNDRV_PCM_TRIGGER_RESUME:
639 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
640 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
641 enable_bit = TX_ENABLE;
642 dma_enable_bit = TX_DMA_ENABLE;
643 } else {
644 enable_bit = RX_ENABLE;
645 dma_enable_bit = RX_DMA_ENABLE;
646 }
647 if (!(msp->dir_busy & dir))
648 return -EINVAL;
649 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
650 writel(reg_val_DMACR | dma_enable_bit,
651 msp->registers + MSP_DMACR);
652 reg_val_GCR = readl(msp->registers + MSP_GCR);
653 if (msp->clock_provider)
654 enable_bit |= FRAME_GEN_ENABLE;
655 writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR);
656 msp->dir_running |= dir;
657 msp->msp_state = MSP_STATE_RUNNING;
658 break;
659
660 case SNDRV_PCM_TRIGGER_STOP:
661 case SNDRV_PCM_TRIGGER_SUSPEND:
662 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
663 if (!(msp->dir_busy & dir))
664 return -EINVAL;
665 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
666 disable_msp_tx(msp);
667 msp->dir_running &= ~MSP_DIR_TX;
668 } else {
669 disable_msp_rx(msp);
670 msp->dir_running &= ~MSP_DIR_RX;
671 }
672 if (!msp->dir_running) {
673 reg_val_GCR = readl(msp->registers + MSP_GCR);
674 writel(reg_val_GCR & ~FRAME_GEN_ENABLE,
675 msp->registers + MSP_GCR);
676 msp->msp_state = MSP_STATE_CONFIGURED;
677 }
678 break;
679 default:
680 return -EINVAL;
681 }
682
683 return 0;
684 }
685
ux500_msp_i2s_close(struct ux500_msp * msp,unsigned int dir)686 int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
687 {
688 int status = 0;
689
690 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
691
692 if (!dir || dir & ~(MSP_DIR_TX | MSP_DIR_RX) ||
693 (msp->dir_busy & dir) != dir)
694 return -EINVAL;
695
696 status = disable_msp(msp, dir);
697 msp->dir_busy &= ~dir;
698 msp->dir_running &= ~dir;
699 if (msp->dir_busy && !msp->dir_running) {
700 writel(readl(msp->registers + MSP_GCR) & ~FRAME_GEN_ENABLE,
701 msp->registers + MSP_GCR);
702 msp->msp_state = MSP_STATE_CONFIGURED;
703 }
704 if (msp->dir_busy == 0) {
705 /* disable sample rate and frame generators */
706 msp->msp_state = MSP_STATE_IDLE;
707 writel((readl(msp->registers + MSP_GCR) &
708 (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
709 msp->registers + MSP_GCR);
710
711 writel(0, msp->registers + MSP_GCR);
712 writel(0, msp->registers + MSP_TCF);
713 writel(0, msp->registers + MSP_RCF);
714 writel(0, msp->registers + MSP_DMACR);
715 writel(0, msp->registers + MSP_SRG);
716 writel(0, msp->registers + MSP_MCR);
717 writel(0, msp->registers + MSP_RCM);
718 writel(0, msp->registers + MSP_RCV);
719 writel(0, msp->registers + MSP_TCE0);
720 writel(0, msp->registers + MSP_TCE1);
721 writel(0, msp->registers + MSP_TCE2);
722 writel(0, msp->registers + MSP_TCE3);
723 writel(0, msp->registers + MSP_RCE0);
724 writel(0, msp->registers + MSP_RCE1);
725 writel(0, msp->registers + MSP_RCE2);
726 writel(0, msp->registers + MSP_RCE3);
727 memset(&msp->config, 0, sizeof(msp->config));
728 msp->clock_provider = false;
729 }
730
731 return status;
732
733 }
734
ux500_msp_i2s_init_msp(struct platform_device * pdev,struct ux500_msp ** msp_p)735 int ux500_msp_i2s_init_msp(struct platform_device *pdev,
736 struct ux500_msp **msp_p)
737 {
738 struct resource *res;
739 struct ux500_msp *msp;
740
741 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
742 msp = *msp_p;
743 if (!msp)
744 return -ENOMEM;
745
746 msp->dev = &pdev->dev;
747
748 msp->registers = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
749 if (IS_ERR(msp->registers))
750 return PTR_ERR(msp->registers);
751 msp->tx_rx_addr = res->start + MSP_DR;
752
753 msp->msp_state = MSP_STATE_IDLE;
754 msp->loopback_enable = 0;
755
756 return 0;
757 }
758
ux500_msp_i2s_cleanup_msp(struct platform_device * pdev,struct ux500_msp * msp)759 void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
760 struct ux500_msp *msp)
761 {
762 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
763 }
764
765 MODULE_LICENSE("GPL v2");
766