Commit | Line | Data |
---|---|---|
a2388a49 NC |
1 | /* |
2 | * Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver | |
3 | * | |
4 | * Copyright (C) 2013 Freescale Semiconductor, Inc. | |
5 | * | |
6 | * Based on stmp3xxx_spdif_dai.c | |
7 | * Vladimir Barinov <vbarinov@embeddedalley.com> | |
8 | * Copyright 2008 SigmaTel, Inc | |
9 | * Copyright 2008 Embedded Alley Solutions, Inc | |
10 | * | |
11 | * This file is licensed under the terms of the GNU General Public License | |
12 | * version 2. This program is licensed "as is" without any warranty of any | |
13 | * kind, whether express or implied. | |
14 | */ | |
15 | ||
16 | #include <linux/module.h> | |
17 | #include <linux/clk.h> | |
18 | #include <linux/clk-private.h> | |
19 | #include <linux/bitrev.h> | |
20 | #include <linux/regmap.h> | |
21 | #include <linux/of_address.h> | |
22 | #include <linux/of_device.h> | |
23 | #include <linux/of_irq.h> | |
24 | ||
25 | #include <sound/asoundef.h> | |
26 | #include <sound/soc.h> | |
27 | #include <sound/dmaengine_pcm.h> | |
28 | ||
29 | #include "fsl_spdif.h" | |
30 | #include "imx-pcm.h" | |
31 | ||
32 | #define FSL_SPDIF_TXFIFO_WML 0x8 | |
33 | #define FSL_SPDIF_RXFIFO_WML 0x8 | |
34 | ||
35 | #define INTR_FOR_PLAYBACK (INT_TXFIFO_RESYNC) | |
36 | #define INTR_FOR_CAPTURE (INT_SYM_ERR | INT_BIT_ERR | INT_URX_FUL | INT_URX_OV|\ | |
37 | INT_QRX_FUL | INT_QRX_OV | INT_UQ_SYNC | INT_UQ_ERR |\ | |
38 | INT_RXFIFO_RESYNC | INT_LOSS_LOCK | INT_DPLL_LOCKED) | |
39 | ||
40 | /* Index list for the values that has if (DPLL Locked) condition */ | |
41 | static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb }; | |
42 | #define SRPC_NODPLL_START1 0x5 | |
43 | #define SRPC_NODPLL_START2 0xc | |
44 | ||
45 | #define DEFAULT_RXCLK_SRC 1 | |
46 | ||
47 | /* | |
48 | * SPDIF control structure | |
49 | * Defines channel status, subcode and Q sub | |
50 | */ | |
51 | struct spdif_mixer_control { | |
52 | /* spinlock to access control data */ | |
53 | spinlock_t ctl_lock; | |
54 | ||
55 | /* IEC958 channel tx status bit */ | |
56 | unsigned char ch_status[4]; | |
57 | ||
58 | /* User bits */ | |
59 | unsigned char subcode[2 * SPDIF_UBITS_SIZE]; | |
60 | ||
61 | /* Q subcode part of user bits */ | |
62 | unsigned char qsub[2 * SPDIF_QSUB_SIZE]; | |
63 | ||
64 | /* Buffer offset for U/Q */ | |
65 | u32 upos; | |
66 | u32 qpos; | |
67 | ||
68 | /* Ready buffer index of the two buffers */ | |
69 | u32 ready_buf; | |
70 | }; | |
71 | ||
72 | struct fsl_spdif_priv { | |
73 | struct spdif_mixer_control fsl_spdif_control; | |
74 | struct snd_soc_dai_driver cpu_dai_drv; | |
75 | struct platform_device *pdev; | |
76 | struct regmap *regmap; | |
77 | bool dpll_locked; | |
78 | u8 txclk_div[SPDIF_TXRATE_MAX]; | |
79 | u8 txclk_src[SPDIF_TXRATE_MAX]; | |
80 | u8 rxclk_src; | |
81 | struct clk *txclk[SPDIF_TXRATE_MAX]; | |
82 | struct clk *rxclk; | |
83 | struct snd_dmaengine_dai_dma_data dma_params_tx; | |
84 | struct snd_dmaengine_dai_dma_data dma_params_rx; | |
85 | ||
86 | /* The name space will be allocated dynamically */ | |
87 | char name[0]; | |
88 | }; | |
89 | ||
90 | ||
91 | /* DPLL locked and lock loss interrupt handler */ | |
92 | static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv) | |
93 | { | |
94 | struct regmap *regmap = spdif_priv->regmap; | |
95 | struct platform_device *pdev = spdif_priv->pdev; | |
96 | u32 locked; | |
97 | ||
98 | regmap_read(regmap, REG_SPDIF_SRPC, &locked); | |
99 | locked &= SRPC_DPLL_LOCKED; | |
100 | ||
101 | dev_dbg(&pdev->dev, "isr: Rx dpll %s \n", | |
102 | locked ? "locked" : "loss lock"); | |
103 | ||
104 | spdif_priv->dpll_locked = locked ? true : false; | |
105 | } | |
106 | ||
107 | /* Receiver found illegal symbol interrupt handler */ | |
108 | static void spdif_irq_sym_error(struct fsl_spdif_priv *spdif_priv) | |
109 | { | |
110 | struct regmap *regmap = spdif_priv->regmap; | |
111 | struct platform_device *pdev = spdif_priv->pdev; | |
112 | ||
113 | dev_dbg(&pdev->dev, "isr: receiver found illegal symbol\n"); | |
114 | ||
115 | if (!spdif_priv->dpll_locked) { | |
116 | /* DPLL unlocked seems no audio stream */ | |
117 | regmap_update_bits(regmap, REG_SPDIF_SIE, INT_SYM_ERR, 0); | |
118 | } | |
119 | } | |
120 | ||
121 | /* U/Q Channel receive register full */ | |
122 | static void spdif_irq_uqrx_full(struct fsl_spdif_priv *spdif_priv, char name) | |
123 | { | |
124 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
125 | struct regmap *regmap = spdif_priv->regmap; | |
126 | struct platform_device *pdev = spdif_priv->pdev; | |
127 | u32 *pos, size, val, reg; | |
128 | ||
129 | switch (name) { | |
130 | case 'U': | |
131 | pos = &ctrl->upos; | |
132 | size = SPDIF_UBITS_SIZE; | |
133 | reg = REG_SPDIF_SRU; | |
134 | break; | |
135 | case 'Q': | |
136 | pos = &ctrl->qpos; | |
137 | size = SPDIF_QSUB_SIZE; | |
138 | reg = REG_SPDIF_SRQ; | |
139 | break; | |
140 | default: | |
141 | dev_err(&pdev->dev, "unsupported channel name\n"); | |
142 | return; | |
143 | } | |
144 | ||
145 | dev_dbg(&pdev->dev, "isr: %c Channel receive register full\n", name); | |
146 | ||
147 | if (*pos >= size * 2) { | |
148 | *pos = 0; | |
149 | } else if (unlikely((*pos % size) + 3 > size)) { | |
150 | dev_err(&pdev->dev, "User bit receivce buffer overflow\n"); | |
151 | return; | |
152 | } | |
153 | ||
154 | regmap_read(regmap, reg, &val); | |
155 | ctrl->subcode[*pos++] = val >> 16; | |
156 | ctrl->subcode[*pos++] = val >> 8; | |
157 | ctrl->subcode[*pos++] = val; | |
158 | } | |
159 | ||
160 | /* U/Q Channel sync found */ | |
161 | static void spdif_irq_uq_sync(struct fsl_spdif_priv *spdif_priv) | |
162 | { | |
163 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
164 | struct platform_device *pdev = spdif_priv->pdev; | |
165 | ||
166 | dev_dbg(&pdev->dev, "isr: U/Q Channel sync found\n"); | |
167 | ||
168 | /* U/Q buffer reset */ | |
169 | if (ctrl->qpos == 0) | |
170 | return; | |
171 | ||
172 | /* Set ready to this buffer */ | |
173 | ctrl->ready_buf = (ctrl->qpos - 1) / SPDIF_QSUB_SIZE + 1; | |
174 | } | |
175 | ||
176 | /* U/Q Channel framing error */ | |
177 | static void spdif_irq_uq_err(struct fsl_spdif_priv *spdif_priv) | |
178 | { | |
179 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
180 | struct regmap *regmap = spdif_priv->regmap; | |
181 | struct platform_device *pdev = spdif_priv->pdev; | |
182 | u32 val; | |
183 | ||
184 | dev_dbg(&pdev->dev, "isr: U/Q Channel framing error\n"); | |
185 | ||
186 | /* Read U/Q data to clear the irq and do buffer reset */ | |
187 | regmap_read(regmap, REG_SPDIF_SRU, &val); | |
188 | regmap_read(regmap, REG_SPDIF_SRQ, &val); | |
189 | ||
190 | /* Drop this U/Q buffer */ | |
191 | ctrl->ready_buf = 0; | |
192 | ctrl->upos = 0; | |
193 | ctrl->qpos = 0; | |
194 | } | |
195 | ||
196 | /* Get spdif interrupt status and clear the interrupt */ | |
197 | static u32 spdif_intr_status_clear(struct fsl_spdif_priv *spdif_priv) | |
198 | { | |
199 | struct regmap *regmap = spdif_priv->regmap; | |
200 | u32 val, val2; | |
201 | ||
202 | regmap_read(regmap, REG_SPDIF_SIS, &val); | |
203 | regmap_read(regmap, REG_SPDIF_SIE, &val2); | |
204 | ||
205 | regmap_write(regmap, REG_SPDIF_SIC, val & val2); | |
206 | ||
207 | return val; | |
208 | } | |
209 | ||
210 | static irqreturn_t spdif_isr(int irq, void *devid) | |
211 | { | |
212 | struct fsl_spdif_priv *spdif_priv = (struct fsl_spdif_priv *)devid; | |
213 | struct platform_device *pdev = spdif_priv->pdev; | |
214 | u32 sis; | |
215 | ||
216 | sis = spdif_intr_status_clear(spdif_priv); | |
217 | ||
218 | if (sis & INT_DPLL_LOCKED) | |
219 | spdif_irq_dpll_lock(spdif_priv); | |
220 | ||
221 | if (sis & INT_TXFIFO_UNOV) | |
222 | dev_dbg(&pdev->dev, "isr: Tx FIFO under/overrun\n"); | |
223 | ||
224 | if (sis & INT_TXFIFO_RESYNC) | |
225 | dev_dbg(&pdev->dev, "isr: Tx FIFO resync\n"); | |
226 | ||
227 | if (sis & INT_CNEW) | |
228 | dev_dbg(&pdev->dev, "isr: cstatus new\n"); | |
229 | ||
230 | if (sis & INT_VAL_NOGOOD) | |
231 | dev_dbg(&pdev->dev, "isr: validity flag no good\n"); | |
232 | ||
233 | if (sis & INT_SYM_ERR) | |
234 | spdif_irq_sym_error(spdif_priv); | |
235 | ||
236 | if (sis & INT_BIT_ERR) | |
237 | dev_dbg(&pdev->dev, "isr: receiver found parity bit error\n"); | |
238 | ||
239 | if (sis & INT_URX_FUL) | |
240 | spdif_irq_uqrx_full(spdif_priv, 'U'); | |
241 | ||
242 | if (sis & INT_URX_OV) | |
243 | dev_dbg(&pdev->dev, "isr: U Channel receive register overrun\n"); | |
244 | ||
245 | if (sis & INT_QRX_FUL) | |
246 | spdif_irq_uqrx_full(spdif_priv, 'Q'); | |
247 | ||
248 | if (sis & INT_QRX_OV) | |
249 | dev_dbg(&pdev->dev, "isr: Q Channel receive register overrun\n"); | |
250 | ||
251 | if (sis & INT_UQ_SYNC) | |
252 | spdif_irq_uq_sync(spdif_priv); | |
253 | ||
254 | if (sis & INT_UQ_ERR) | |
255 | spdif_irq_uq_err(spdif_priv); | |
256 | ||
257 | if (sis & INT_RXFIFO_UNOV) | |
258 | dev_dbg(&pdev->dev, "isr: Rx FIFO under/overrun\n"); | |
259 | ||
260 | if (sis & INT_RXFIFO_RESYNC) | |
261 | dev_dbg(&pdev->dev, "isr: Rx FIFO resync\n"); | |
262 | ||
263 | if (sis & INT_LOSS_LOCK) | |
264 | spdif_irq_dpll_lock(spdif_priv); | |
265 | ||
266 | /* FIXME: Write Tx FIFO to clear TxEm */ | |
267 | if (sis & INT_TX_EM) | |
268 | dev_dbg(&pdev->dev, "isr: Tx FIFO empty\n"); | |
269 | ||
270 | /* FIXME: Read Rx FIFO to clear RxFIFOFul */ | |
271 | if (sis & INT_RXFIFO_FUL) | |
272 | dev_dbg(&pdev->dev, "isr: Rx FIFO full\n"); | |
273 | ||
274 | return IRQ_HANDLED; | |
275 | } | |
276 | ||
277 | static int spdif_softreset(struct fsl_spdif_priv *spdif_priv) | |
278 | { | |
279 | struct regmap *regmap = spdif_priv->regmap; | |
280 | u32 val, cycle = 1000; | |
281 | ||
282 | regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); | |
283 | ||
284 | /* | |
285 | * RESET bit would be cleared after finishing its reset procedure, | |
286 | * which typically lasts 8 cycles. 1000 cycles will keep it safe. | |
287 | */ | |
288 | do { | |
289 | regmap_read(regmap, REG_SPDIF_SCR, &val); | |
290 | } while ((val & SCR_SOFT_RESET) && cycle--); | |
291 | ||
292 | if (cycle) | |
293 | return 0; | |
294 | else | |
295 | return -EBUSY; | |
296 | } | |
297 | ||
298 | static void spdif_set_cstatus(struct spdif_mixer_control *ctrl, | |
299 | u8 mask, u8 cstatus) | |
300 | { | |
301 | ctrl->ch_status[3] &= ~mask; | |
302 | ctrl->ch_status[3] |= cstatus & mask; | |
303 | } | |
304 | ||
305 | static void spdif_write_channel_status(struct fsl_spdif_priv *spdif_priv) | |
306 | { | |
307 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
308 | struct regmap *regmap = spdif_priv->regmap; | |
309 | struct platform_device *pdev = spdif_priv->pdev; | |
310 | u32 ch_status; | |
311 | ||
312 | ch_status = (bitrev8(ctrl->ch_status[0]) << 16) | | |
313 | (bitrev8(ctrl->ch_status[1]) << 8) | | |
314 | bitrev8(ctrl->ch_status[2]); | |
315 | regmap_write(regmap, REG_SPDIF_STCSCH, ch_status); | |
316 | ||
317 | dev_dbg(&pdev->dev, "STCSCH: 0x%06x\n", ch_status); | |
318 | ||
319 | ch_status = bitrev8(ctrl->ch_status[3]) << 16; | |
320 | regmap_write(regmap, REG_SPDIF_STCSCL, ch_status); | |
321 | ||
322 | dev_dbg(&pdev->dev, "STCSCL: 0x%06x\n", ch_status); | |
323 | } | |
324 | ||
325 | /* Set SPDIF PhaseConfig register for rx clock */ | |
326 | static int spdif_set_rx_clksrc(struct fsl_spdif_priv *spdif_priv, | |
327 | enum spdif_gainsel gainsel, int dpll_locked) | |
328 | { | |
329 | struct regmap *regmap = spdif_priv->regmap; | |
330 | u8 clksrc = spdif_priv->rxclk_src; | |
331 | ||
332 | if (clksrc >= SRPC_CLKSRC_MAX || gainsel >= GAINSEL_MULTI_MAX) | |
333 | return -EINVAL; | |
334 | ||
335 | regmap_update_bits(regmap, REG_SPDIF_SRPC, | |
336 | SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK, | |
337 | SRPC_CLKSRC_SEL_SET(clksrc) | SRPC_GAINSEL_SET(gainsel)); | |
338 | ||
339 | return 0; | |
340 | } | |
341 | ||
342 | static int spdif_set_sample_rate(struct snd_pcm_substream *substream, | |
343 | int sample_rate) | |
344 | { | |
345 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
346 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | |
347 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
348 | struct regmap *regmap = spdif_priv->regmap; | |
349 | struct platform_device *pdev = spdif_priv->pdev; | |
350 | unsigned long csfs = 0; | |
351 | u32 stc, mask, rate; | |
352 | u8 clk, div; | |
353 | int ret; | |
354 | ||
355 | switch (sample_rate) { | |
356 | case 32000: | |
357 | rate = SPDIF_TXRATE_32000; | |
358 | csfs = IEC958_AES3_CON_FS_32000; | |
359 | break; | |
360 | case 44100: | |
361 | rate = SPDIF_TXRATE_44100; | |
362 | csfs = IEC958_AES3_CON_FS_44100; | |
363 | break; | |
364 | case 48000: | |
365 | rate = SPDIF_TXRATE_48000; | |
366 | csfs = IEC958_AES3_CON_FS_48000; | |
367 | break; | |
368 | default: | |
369 | dev_err(&pdev->dev, "unsupported sample rate %d\n", sample_rate); | |
370 | return -EINVAL; | |
371 | } | |
372 | ||
373 | clk = spdif_priv->txclk_src[rate]; | |
374 | if (clk >= STC_TXCLK_SRC_MAX) { | |
375 | dev_err(&pdev->dev, "tx clock source is out of range\n"); | |
376 | return -EINVAL; | |
377 | } | |
378 | ||
379 | div = spdif_priv->txclk_div[rate]; | |
380 | if (div == 0) { | |
381 | dev_err(&pdev->dev, "the divisor can't be zero\n"); | |
382 | return -EINVAL; | |
383 | } | |
384 | ||
385 | /* | |
386 | * The S/PDIF block needs a clock of 64 * fs * div. The S/PDIF block | |
387 | * will divide by (div). So request 64 * fs * (div+1) which will | |
388 | * get rounded. | |
389 | */ | |
390 | ret = clk_set_rate(spdif_priv->txclk[rate], 64 * sample_rate * (div + 1)); | |
391 | if (ret) { | |
392 | dev_err(&pdev->dev, "failed to set tx clock rate\n"); | |
393 | return ret; | |
394 | } | |
395 | ||
396 | dev_dbg(&pdev->dev, "expected clock rate = %d\n", | |
397 | (64 * sample_rate * div)); | |
398 | dev_dbg(&pdev->dev, "actual clock rate = %ld\n", | |
399 | clk_get_rate(spdif_priv->txclk[rate])); | |
400 | ||
401 | /* set fs field in consumer channel status */ | |
402 | spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs); | |
403 | ||
404 | /* select clock source and divisor */ | |
405 | stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DIV(div); | |
406 | mask = STC_TXCLK_ALL_EN_MASK | STC_TXCLK_SRC_MASK | STC_TXCLK_DIV_MASK; | |
407 | regmap_update_bits(regmap, REG_SPDIF_STC, mask, stc); | |
408 | ||
409 | dev_dbg(&pdev->dev, "set sample rate to %d\n", sample_rate); | |
410 | ||
411 | return 0; | |
412 | } | |
413 | ||
6b4c80f9 MB |
414 | static int fsl_spdif_startup(struct snd_pcm_substream *substream, |
415 | struct snd_soc_dai *cpu_dai) | |
a2388a49 NC |
416 | { |
417 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
418 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | |
419 | struct platform_device *pdev = spdif_priv->pdev; | |
420 | struct regmap *regmap = spdif_priv->regmap; | |
421 | u32 scr, mask, i; | |
422 | int ret; | |
423 | ||
424 | /* Reset module and interrupts only for first initialization */ | |
425 | if (!cpu_dai->active) { | |
426 | ret = spdif_softreset(spdif_priv); | |
427 | if (ret) { | |
428 | dev_err(&pdev->dev, "failed to soft reset\n"); | |
429 | return ret; | |
430 | } | |
431 | ||
432 | /* Disable all the interrupts */ | |
433 | regmap_update_bits(regmap, REG_SPDIF_SIE, 0xffffff, 0); | |
434 | } | |
435 | ||
436 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
437 | scr = SCR_TXFIFO_AUTOSYNC | SCR_TXFIFO_CTRL_NORMAL | | |
438 | SCR_TXSEL_NORMAL | SCR_USRC_SEL_CHIP | | |
439 | SCR_TXFIFO_FSEL_IF8; | |
440 | mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK | | |
441 | SCR_TXSEL_MASK | SCR_USRC_SEL_MASK | | |
442 | SCR_TXFIFO_FSEL_MASK; | |
443 | for (i = 0; i < SPDIF_TXRATE_MAX; i++) | |
444 | clk_prepare_enable(spdif_priv->txclk[i]); | |
445 | } else { | |
446 | scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC; | |
447 | mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK| | |
448 | SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK; | |
449 | clk_prepare_enable(spdif_priv->rxclk); | |
450 | } | |
451 | regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr); | |
452 | ||
453 | /* Power up SPDIF module */ | |
454 | regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0); | |
455 | ||
456 | return 0; | |
457 | } | |
458 | ||
459 | static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, | |
460 | struct snd_soc_dai *cpu_dai) | |
461 | { | |
462 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
463 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | |
464 | struct regmap *regmap = spdif_priv->regmap; | |
465 | u32 scr, mask, i; | |
466 | ||
467 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
468 | scr = 0; | |
469 | mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK | | |
470 | SCR_TXSEL_MASK | SCR_USRC_SEL_MASK | | |
471 | SCR_TXFIFO_FSEL_MASK; | |
472 | for (i = 0; i < SPDIF_TXRATE_MAX; i++) | |
473 | clk_disable_unprepare(spdif_priv->txclk[i]); | |
474 | } else { | |
475 | scr = SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO; | |
476 | mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK| | |
477 | SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK; | |
478 | clk_disable_unprepare(spdif_priv->rxclk); | |
479 | } | |
480 | regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr); | |
481 | ||
482 | /* Power down SPDIF module only if tx&rx are both inactive */ | |
483 | if (!cpu_dai->active) { | |
484 | spdif_intr_status_clear(spdif_priv); | |
485 | regmap_update_bits(regmap, REG_SPDIF_SCR, | |
486 | SCR_LOW_POWER, SCR_LOW_POWER); | |
487 | } | |
488 | } | |
489 | ||
490 | static int fsl_spdif_hw_params(struct snd_pcm_substream *substream, | |
491 | struct snd_pcm_hw_params *params, | |
492 | struct snd_soc_dai *dai) | |
493 | { | |
494 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
495 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | |
496 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
497 | struct platform_device *pdev = spdif_priv->pdev; | |
498 | u32 sample_rate = params_rate(params); | |
499 | int ret = 0; | |
500 | ||
501 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | |
502 | ret = spdif_set_sample_rate(substream, sample_rate); | |
503 | if (ret) { | |
504 | dev_err(&pdev->dev, "%s: set sample rate failed: %d\n", | |
505 | __func__, sample_rate); | |
506 | return ret; | |
507 | } | |
508 | spdif_set_cstatus(ctrl, IEC958_AES3_CON_CLOCK, | |
509 | IEC958_AES3_CON_CLOCK_1000PPM); | |
510 | spdif_write_channel_status(spdif_priv); | |
511 | } else { | |
512 | /* Setup rx clock source */ | |
513 | ret = spdif_set_rx_clksrc(spdif_priv, SPDIF_DEFAULT_GAINSEL, 1); | |
514 | } | |
515 | ||
516 | return ret; | |
517 | } | |
518 | ||
519 | static int fsl_spdif_trigger(struct snd_pcm_substream *substream, | |
520 | int cmd, struct snd_soc_dai *dai) | |
521 | { | |
522 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
523 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | |
524 | struct regmap *regmap = spdif_priv->regmap; | |
525 | int is_playack = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | |
526 | u32 intr = is_playack ? INTR_FOR_PLAYBACK : INTR_FOR_CAPTURE; | |
527 | u32 dmaen = is_playack ? SCR_DMA_TX_EN : SCR_DMA_RX_EN;; | |
528 | ||
529 | switch (cmd) { | |
530 | case SNDRV_PCM_TRIGGER_START: | |
531 | case SNDRV_PCM_TRIGGER_RESUME: | |
532 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | |
533 | regmap_update_bits(regmap, REG_SPDIF_SIE, intr, intr); | |
534 | regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, dmaen); | |
535 | break; | |
536 | case SNDRV_PCM_TRIGGER_STOP: | |
537 | case SNDRV_PCM_TRIGGER_SUSPEND: | |
538 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | |
539 | regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, 0); | |
540 | regmap_update_bits(regmap, REG_SPDIF_SIE, intr, 0); | |
541 | break; | |
542 | default: | |
543 | return -EINVAL; | |
544 | } | |
545 | ||
546 | return 0; | |
547 | } | |
548 | ||
6b4c80f9 | 549 | static struct snd_soc_dai_ops fsl_spdif_dai_ops = { |
a2388a49 NC |
550 | .startup = fsl_spdif_startup, |
551 | .hw_params = fsl_spdif_hw_params, | |
552 | .trigger = fsl_spdif_trigger, | |
553 | .shutdown = fsl_spdif_shutdown, | |
554 | }; | |
555 | ||
556 | ||
557 | /* | |
a2388a49 NC |
558 | * FSL SPDIF IEC958 controller(mixer) functions |
559 | * | |
560 | * Channel status get/put control | |
561 | * User bit value get/put control | |
562 | * Valid bit value get control | |
563 | * DPLL lock status get control | |
564 | * User bit sync mode selection control | |
a2388a49 NC |
565 | */ |
566 | ||
567 | static int fsl_spdif_info(struct snd_kcontrol *kcontrol, | |
568 | struct snd_ctl_elem_info *uinfo) | |
569 | { | |
570 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; | |
571 | uinfo->count = 1; | |
572 | ||
573 | return 0; | |
574 | } | |
575 | ||
576 | static int fsl_spdif_pb_get(struct snd_kcontrol *kcontrol, | |
577 | struct snd_ctl_elem_value *uvalue) | |
578 | { | |
579 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
580 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
581 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
582 | ||
583 | uvalue->value.iec958.status[0] = ctrl->ch_status[0]; | |
584 | uvalue->value.iec958.status[1] = ctrl->ch_status[1]; | |
585 | uvalue->value.iec958.status[2] = ctrl->ch_status[2]; | |
586 | uvalue->value.iec958.status[3] = ctrl->ch_status[3]; | |
587 | ||
588 | return 0; | |
589 | } | |
590 | ||
591 | static int fsl_spdif_pb_put(struct snd_kcontrol *kcontrol, | |
592 | struct snd_ctl_elem_value *uvalue) | |
593 | { | |
594 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
595 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
596 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
597 | ||
598 | ctrl->ch_status[0] = uvalue->value.iec958.status[0]; | |
599 | ctrl->ch_status[1] = uvalue->value.iec958.status[1]; | |
600 | ctrl->ch_status[2] = uvalue->value.iec958.status[2]; | |
601 | ctrl->ch_status[3] = uvalue->value.iec958.status[3]; | |
602 | ||
603 | spdif_write_channel_status(spdif_priv); | |
604 | ||
605 | return 0; | |
606 | } | |
607 | ||
608 | /* Get channel status from SPDIF_RX_CCHAN register */ | |
609 | static int fsl_spdif_capture_get(struct snd_kcontrol *kcontrol, | |
610 | struct snd_ctl_elem_value *ucontrol) | |
611 | { | |
612 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
613 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
614 | struct regmap *regmap = spdif_priv->regmap; | |
615 | u32 cstatus, val; | |
616 | ||
617 | regmap_read(regmap, REG_SPDIF_SIS, &val); | |
618 | if (!(val & INT_CNEW)) { | |
619 | return -EAGAIN; | |
620 | } | |
621 | ||
622 | regmap_read(regmap, REG_SPDIF_SRCSH, &cstatus); | |
623 | ucontrol->value.iec958.status[0] = (cstatus >> 16) & 0xFF; | |
624 | ucontrol->value.iec958.status[1] = (cstatus >> 8) & 0xFF; | |
625 | ucontrol->value.iec958.status[2] = cstatus & 0xFF; | |
626 | ||
627 | regmap_read(regmap, REG_SPDIF_SRCSL, &cstatus); | |
628 | ucontrol->value.iec958.status[3] = (cstatus >> 16) & 0xFF; | |
629 | ucontrol->value.iec958.status[4] = (cstatus >> 8) & 0xFF; | |
630 | ucontrol->value.iec958.status[5] = cstatus & 0xFF; | |
631 | ||
632 | /* Clear intr */ | |
633 | regmap_write(regmap, REG_SPDIF_SIC, INT_CNEW); | |
634 | ||
635 | return 0; | |
636 | } | |
637 | ||
638 | /* | |
639 | * Get User bits (subcode) from chip value which readed out | |
640 | * in UChannel register. | |
641 | */ | |
642 | static int fsl_spdif_subcode_get(struct snd_kcontrol *kcontrol, | |
643 | struct snd_ctl_elem_value *ucontrol) | |
644 | { | |
645 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
646 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
647 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
648 | unsigned long flags; | |
649 | int ret = 0; | |
650 | ||
651 | spin_lock_irqsave(&ctrl->ctl_lock, flags); | |
652 | if (ctrl->ready_buf) { | |
653 | int idx = (ctrl->ready_buf - 1) * SPDIF_UBITS_SIZE; | |
654 | memcpy(&ucontrol->value.iec958.subcode[0], | |
655 | &ctrl->subcode[idx], SPDIF_UBITS_SIZE); | |
656 | } else { | |
657 | ret = -EAGAIN; | |
658 | } | |
659 | spin_unlock_irqrestore(&ctrl->ctl_lock, flags); | |
660 | ||
661 | return ret; | |
662 | } | |
663 | ||
664 | /* Q-subcode infomation. The byte size is SPDIF_UBITS_SIZE/8 */ | |
665 | static int fsl_spdif_qinfo(struct snd_kcontrol *kcontrol, | |
666 | struct snd_ctl_elem_info *uinfo) | |
667 | { | |
668 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | |
669 | uinfo->count = SPDIF_QSUB_SIZE; | |
670 | ||
671 | return 0; | |
672 | } | |
673 | ||
674 | /* Get Q subcode from chip value which readed out in QChannel register */ | |
675 | static int fsl_spdif_qget(struct snd_kcontrol *kcontrol, | |
676 | struct snd_ctl_elem_value *ucontrol) | |
677 | { | |
678 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
679 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
680 | struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control; | |
681 | unsigned long flags; | |
682 | int ret = 0; | |
683 | ||
684 | spin_lock_irqsave(&ctrl->ctl_lock, flags); | |
685 | if (ctrl->ready_buf) { | |
686 | int idx = (ctrl->ready_buf - 1) * SPDIF_QSUB_SIZE; | |
687 | memcpy(&ucontrol->value.bytes.data[0], | |
688 | &ctrl->qsub[idx], SPDIF_QSUB_SIZE); | |
689 | } else { | |
690 | ret = -EAGAIN; | |
691 | } | |
692 | spin_unlock_irqrestore(&ctrl->ctl_lock, flags); | |
693 | ||
694 | return ret; | |
695 | } | |
696 | ||
697 | /* Valid bit infomation */ | |
698 | static int fsl_spdif_vbit_info(struct snd_kcontrol *kcontrol, | |
699 | struct snd_ctl_elem_info *uinfo) | |
700 | { | |
701 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | |
702 | uinfo->count = 1; | |
703 | uinfo->value.integer.min = 0; | |
704 | uinfo->value.integer.max = 1; | |
705 | ||
706 | return 0; | |
707 | } | |
708 | ||
709 | /* Get valid good bit from interrupt status register */ | |
710 | static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol, | |
711 | struct snd_ctl_elem_value *ucontrol) | |
712 | { | |
713 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
714 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
715 | struct regmap *regmap = spdif_priv->regmap; | |
716 | u32 val; | |
717 | ||
718 | val = regmap_read(regmap, REG_SPDIF_SIS, &val); | |
719 | ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0; | |
720 | regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD); | |
721 | ||
722 | return 0; | |
723 | } | |
724 | ||
725 | /* DPLL lock infomation */ | |
726 | static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol, | |
727 | struct snd_ctl_elem_info *uinfo) | |
728 | { | |
729 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | |
730 | uinfo->count = 1; | |
731 | uinfo->value.integer.min = 16000; | |
732 | uinfo->value.integer.max = 96000; | |
733 | ||
734 | return 0; | |
735 | } | |
736 | ||
737 | static u32 gainsel_multi[GAINSEL_MULTI_MAX] = { | |
738 | 24, 16, 12, 8, 6, 4, 3, | |
739 | }; | |
740 | ||
741 | /* Get RX data clock rate given the SPDIF bus_clk */ | |
742 | static int spdif_get_rxclk_rate(struct fsl_spdif_priv *spdif_priv, | |
743 | enum spdif_gainsel gainsel) | |
744 | { | |
745 | struct regmap *regmap = spdif_priv->regmap; | |
746 | struct platform_device *pdev = spdif_priv->pdev; | |
747 | u64 tmpval64, busclk_freq = 0; | |
748 | u32 freqmeas, phaseconf; | |
749 | u8 clksrc; | |
750 | ||
751 | regmap_read(regmap, REG_SPDIF_SRFM, &freqmeas); | |
752 | regmap_read(regmap, REG_SPDIF_SRPC, &phaseconf); | |
753 | ||
754 | clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf; | |
755 | if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) { | |
756 | /* Get bus clock from system */ | |
757 | busclk_freq = clk_get_rate(spdif_priv->rxclk); | |
758 | } | |
759 | ||
760 | /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */ | |
761 | tmpval64 = (u64) busclk_freq * freqmeas; | |
762 | do_div(tmpval64, gainsel_multi[gainsel] * 1024); | |
763 | do_div(tmpval64, 128 * 1024); | |
764 | ||
765 | dev_dbg(&pdev->dev, "FreqMeas: %d\n", freqmeas); | |
766 | dev_dbg(&pdev->dev, "BusclkFreq: %lld\n", busclk_freq); | |
767 | dev_dbg(&pdev->dev, "RxRate: %lld\n", tmpval64); | |
768 | ||
769 | return (int)tmpval64; | |
770 | } | |
771 | ||
772 | /* | |
773 | * Get DPLL lock or not info from stable interrupt status register. | |
774 | * User application must use this control to get locked, | |
775 | * then can do next PCM operation | |
776 | */ | |
777 | static int fsl_spdif_rxrate_get(struct snd_kcontrol *kcontrol, | |
778 | struct snd_ctl_elem_value *ucontrol) | |
779 | { | |
780 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
781 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
782 | int rate = spdif_get_rxclk_rate(spdif_priv, SPDIF_DEFAULT_GAINSEL); | |
783 | ||
784 | if (spdif_priv->dpll_locked) | |
785 | ucontrol->value.integer.value[0] = rate; | |
786 | else | |
787 | ucontrol->value.integer.value[0] = 0; | |
788 | ||
789 | return 0; | |
790 | } | |
791 | ||
792 | /* User bit sync mode info */ | |
793 | static int fsl_spdif_usync_info(struct snd_kcontrol *kcontrol, | |
794 | struct snd_ctl_elem_info *uinfo) | |
795 | { | |
796 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | |
797 | uinfo->count = 1; | |
798 | uinfo->value.integer.min = 0; | |
799 | uinfo->value.integer.max = 1; | |
800 | ||
801 | return 0; | |
802 | } | |
803 | ||
804 | /* | |
805 | * User bit sync mode: | |
806 | * 1 CD User channel subcode | |
807 | * 0 Non-CD data | |
808 | */ | |
809 | static int fsl_spdif_usync_get(struct snd_kcontrol *kcontrol, | |
810 | struct snd_ctl_elem_value *ucontrol) | |
811 | { | |
812 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
813 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
814 | struct regmap *regmap = spdif_priv->regmap; | |
815 | u32 val; | |
816 | ||
817 | regmap_read(regmap, REG_SPDIF_SRCD, &val); | |
818 | ucontrol->value.integer.value[0] = (val & SRCD_CD_USER) != 0; | |
819 | ||
820 | return 0; | |
821 | } | |
822 | ||
823 | /* | |
824 | * User bit sync mode: | |
825 | * 1 CD User channel subcode | |
826 | * 0 Non-CD data | |
827 | */ | |
828 | static int fsl_spdif_usync_put(struct snd_kcontrol *kcontrol, | |
829 | struct snd_ctl_elem_value *ucontrol) | |
830 | { | |
831 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); | |
832 | struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai); | |
833 | struct regmap *regmap = spdif_priv->regmap; | |
834 | u32 val = ucontrol->value.integer.value[0] << SRCD_CD_USER_OFFSET; | |
835 | ||
836 | regmap_update_bits(regmap, REG_SPDIF_SRCD, SRCD_CD_USER, val); | |
837 | ||
838 | return 0; | |
839 | } | |
840 | ||
841 | /* FSL SPDIF IEC958 controller defines */ | |
842 | static struct snd_kcontrol_new fsl_spdif_ctrls[] = { | |
843 | /* Status cchanel controller */ | |
844 | { | |
845 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | |
846 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), | |
847 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
848 | SNDRV_CTL_ELEM_ACCESS_WRITE | | |
849 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
850 | .info = fsl_spdif_info, | |
851 | .get = fsl_spdif_pb_get, | |
852 | .put = fsl_spdif_pb_put, | |
853 | }, | |
854 | { | |
855 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
856 | .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT), | |
857 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
858 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
859 | .info = fsl_spdif_info, | |
860 | .get = fsl_spdif_capture_get, | |
861 | }, | |
862 | /* User bits controller */ | |
863 | { | |
864 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
865 | .name = "IEC958 Subcode Capture Default", | |
866 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
867 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
868 | .info = fsl_spdif_info, | |
869 | .get = fsl_spdif_subcode_get, | |
870 | }, | |
871 | { | |
872 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
873 | .name = "IEC958 Q-subcode Capture Default", | |
874 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
875 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
876 | .info = fsl_spdif_qinfo, | |
877 | .get = fsl_spdif_qget, | |
878 | }, | |
879 | /* Valid bit error controller */ | |
880 | { | |
881 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
882 | .name = "IEC958 V-Bit Errors", | |
883 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
884 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
885 | .info = fsl_spdif_vbit_info, | |
886 | .get = fsl_spdif_vbit_get, | |
887 | }, | |
888 | /* DPLL lock info get controller */ | |
889 | { | |
890 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
891 | .name = "RX Sample Rate", | |
892 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
893 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
894 | .info = fsl_spdif_rxrate_info, | |
895 | .get = fsl_spdif_rxrate_get, | |
896 | }, | |
897 | /* User bit sync mode set/get controller */ | |
898 | { | |
899 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | |
900 | .name = "IEC958 USyncMode CDText", | |
901 | .access = SNDRV_CTL_ELEM_ACCESS_READ | | |
902 | SNDRV_CTL_ELEM_ACCESS_WRITE | | |
903 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | |
904 | .info = fsl_spdif_usync_info, | |
905 | .get = fsl_spdif_usync_get, | |
906 | .put = fsl_spdif_usync_put, | |
907 | }, | |
908 | }; | |
909 | ||
910 | static int fsl_spdif_dai_probe(struct snd_soc_dai *dai) | |
911 | { | |
912 | struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai); | |
913 | ||
914 | dai->playback_dma_data = &spdif_private->dma_params_tx; | |
915 | dai->capture_dma_data = &spdif_private->dma_params_rx; | |
916 | ||
917 | snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls)); | |
918 | ||
919 | return 0; | |
920 | } | |
921 | ||
6b4c80f9 | 922 | static struct snd_soc_dai_driver fsl_spdif_dai = { |
a2388a49 NC |
923 | .probe = &fsl_spdif_dai_probe, |
924 | .playback = { | |
925 | .channels_min = 2, | |
926 | .channels_max = 2, | |
927 | .rates = FSL_SPDIF_RATES_PLAYBACK, | |
928 | .formats = FSL_SPDIF_FORMATS_PLAYBACK, | |
929 | }, | |
930 | .capture = { | |
931 | .channels_min = 2, | |
932 | .channels_max = 2, | |
933 | .rates = FSL_SPDIF_RATES_CAPTURE, | |
934 | .formats = FSL_SPDIF_FORMATS_CAPTURE, | |
935 | }, | |
936 | .ops = &fsl_spdif_dai_ops, | |
937 | }; | |
938 | ||
939 | static const struct snd_soc_component_driver fsl_spdif_component = { | |
940 | .name = "fsl-spdif", | |
941 | }; | |
942 | ||
6d22db43 | 943 | /* FSL SPDIF REGMAP */ |
a2388a49 NC |
944 | |
945 | static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) | |
946 | { | |
947 | switch (reg) { | |
948 | case REG_SPDIF_SCR: | |
949 | case REG_SPDIF_SRCD: | |
950 | case REG_SPDIF_SRPC: | |
951 | case REG_SPDIF_SIE: | |
952 | case REG_SPDIF_SIS: | |
953 | case REG_SPDIF_SRL: | |
954 | case REG_SPDIF_SRR: | |
955 | case REG_SPDIF_SRCSH: | |
956 | case REG_SPDIF_SRCSL: | |
957 | case REG_SPDIF_SRU: | |
958 | case REG_SPDIF_SRQ: | |
959 | case REG_SPDIF_STCSCH: | |
960 | case REG_SPDIF_STCSCL: | |
961 | case REG_SPDIF_SRFM: | |
962 | case REG_SPDIF_STC: | |
963 | return true; | |
964 | default: | |
965 | return false; | |
966 | }; | |
967 | } | |
968 | ||
969 | static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) | |
970 | { | |
971 | switch (reg) { | |
972 | case REG_SPDIF_SCR: | |
973 | case REG_SPDIF_SRCD: | |
974 | case REG_SPDIF_SRPC: | |
975 | case REG_SPDIF_SIE: | |
976 | case REG_SPDIF_SIC: | |
977 | case REG_SPDIF_STL: | |
978 | case REG_SPDIF_STR: | |
979 | case REG_SPDIF_STCSCH: | |
980 | case REG_SPDIF_STCSCL: | |
981 | case REG_SPDIF_STC: | |
982 | return true; | |
983 | default: | |
984 | return false; | |
985 | }; | |
986 | } | |
987 | ||
988 | static const struct regmap_config fsl_spdif_regmap_config = { | |
989 | .reg_bits = 32, | |
990 | .reg_stride = 4, | |
991 | .val_bits = 32, | |
992 | ||
993 | .max_register = REG_SPDIF_STC, | |
994 | .readable_reg = fsl_spdif_readable_reg, | |
995 | .writeable_reg = fsl_spdif_writeable_reg, | |
996 | }; | |
997 | ||
998 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | |
999 | struct clk *clk, u64 savesub, | |
1000 | enum spdif_txrate index) | |
1001 | { | |
1002 | const u32 rate[] = { 32000, 44100, 48000 }; | |
1003 | u64 rate_ideal, rate_actual, sub; | |
1004 | u32 div, arate; | |
1005 | ||
1006 | for (div = 1; div <= 128; div++) { | |
1007 | rate_ideal = rate[index] * (div + 1) * 64; | |
1008 | rate_actual = clk_round_rate(clk, rate_ideal); | |
1009 | ||
1010 | arate = rate_actual / 64; | |
1011 | arate /= div; | |
1012 | ||
1013 | if (arate == rate[index]) { | |
1014 | /* We are lucky */ | |
1015 | savesub = 0; | |
1016 | spdif_priv->txclk_div[index] = div; | |
1017 | break; | |
1018 | } else if (arate / rate[index] == 1) { | |
1019 | /* A little bigger than expect */ | |
1020 | sub = (arate - rate[index]) * 100000; | |
1021 | do_div(sub, rate[index]); | |
1022 | if (sub < savesub) { | |
1023 | savesub = sub; | |
1024 | spdif_priv->txclk_div[index] = div; | |
1025 | } | |
1026 | } else if (rate[index] / arate == 1) { | |
1027 | /* A little smaller than expect */ | |
1028 | sub = (rate[index] - arate) * 100000; | |
1029 | do_div(sub, rate[index]); | |
1030 | if (sub < savesub) { | |
1031 | savesub = sub; | |
1032 | spdif_priv->txclk_div[index] = div; | |
1033 | } | |
1034 | } | |
1035 | } | |
1036 | ||
1037 | return savesub; | |
1038 | } | |
1039 | ||
1040 | static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, | |
1041 | enum spdif_txrate index) | |
1042 | { | |
1043 | const u32 rate[] = { 32000, 44100, 48000 }; | |
1044 | struct platform_device *pdev = spdif_priv->pdev; | |
1045 | struct device *dev = &pdev->dev; | |
1046 | u64 savesub = 100000, ret; | |
1047 | struct clk *clk; | |
1048 | char tmp[16]; | |
1049 | int i; | |
1050 | ||
1051 | for (i = 0; i < STC_TXCLK_SRC_MAX; i++) { | |
1052 | sprintf(tmp, "rxtx%d", i); | |
1053 | clk = devm_clk_get(&pdev->dev, tmp); | |
1054 | if (IS_ERR(clk)) { | |
1055 | dev_err(dev, "no rxtx%d clock in devicetree\n", i); | |
1056 | return PTR_ERR(clk); | |
1057 | } | |
1058 | if (!clk_get_rate(clk)) | |
1059 | continue; | |
1060 | ||
1061 | ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index); | |
1062 | if (savesub == ret) | |
1063 | continue; | |
1064 | ||
1065 | savesub = ret; | |
1066 | spdif_priv->txclk[index] = clk; | |
1067 | spdif_priv->txclk_src[index] = i; | |
1068 | ||
1069 | /* To quick catch a divisor, we allow a 0.1% deviation */ | |
1070 | if (savesub < 100) | |
1071 | break; | |
1072 | } | |
1073 | ||
8a309d71 | 1074 | dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", |
a2388a49 | 1075 | spdif_priv->txclk_src[index], rate[index]); |
8a309d71 | 1076 | dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate\n", |
a2388a49 NC |
1077 | spdif_priv->txclk_div[index], rate[index]); |
1078 | ||
1079 | return 0; | |
1080 | } | |
1081 | ||
1082 | static int fsl_spdif_probe(struct platform_device *pdev) | |
1083 | { | |
1084 | struct device_node *np = pdev->dev.of_node; | |
1085 | struct fsl_spdif_priv *spdif_priv; | |
1086 | struct spdif_mixer_control *ctrl; | |
1087 | struct resource *res; | |
1088 | void __iomem *regs; | |
1089 | int irq, ret, i; | |
1090 | ||
1091 | if (!np) | |
1092 | return -ENODEV; | |
1093 | ||
1094 | spdif_priv = devm_kzalloc(&pdev->dev, | |
1095 | sizeof(struct fsl_spdif_priv) + strlen(np->name) + 1, | |
1096 | GFP_KERNEL); | |
1097 | if (!spdif_priv) | |
1098 | return -ENOMEM; | |
1099 | ||
1100 | strcpy(spdif_priv->name, np->name); | |
1101 | ||
1102 | spdif_priv->pdev = pdev; | |
1103 | ||
1104 | /* Initialize this copy of the CPU DAI driver structure */ | |
1105 | memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai)); | |
1106 | spdif_priv->cpu_dai_drv.name = spdif_priv->name; | |
1107 | ||
1108 | /* Get the addresses and IRQ */ | |
1109 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
1110 | if (IS_ERR(res)) { | |
1111 | dev_err(&pdev->dev, "could not determine device resources\n"); | |
1112 | return PTR_ERR(res); | |
1113 | } | |
1114 | ||
1115 | regs = devm_ioremap_resource(&pdev->dev, res); | |
bfd7d1aa | 1116 | if (IS_ERR(regs)) |
a2388a49 | 1117 | return PTR_ERR(regs); |
a2388a49 NC |
1118 | |
1119 | spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, | |
1120 | "core", regs, &fsl_spdif_regmap_config); | |
1121 | if (IS_ERR(spdif_priv->regmap)) { | |
1122 | dev_err(&pdev->dev, "regmap init failed\n"); | |
1123 | return PTR_ERR(spdif_priv->regmap); | |
1124 | } | |
1125 | ||
1126 | irq = platform_get_irq(pdev, 0); | |
1127 | if (irq < 0) { | |
1128 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | |
1129 | return irq; | |
1130 | } | |
1131 | ||
1132 | ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, | |
1133 | spdif_priv->name, spdif_priv); | |
1134 | if (ret) { | |
1135 | dev_err(&pdev->dev, "could not claim irq %u\n", irq); | |
1136 | return ret; | |
1137 | } | |
1138 | ||
1139 | /* Select clock source for rx/tx clock */ | |
1140 | spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); | |
1141 | if (IS_ERR(spdif_priv->rxclk)) { | |
1142 | dev_err(&pdev->dev, "no rxtx1 clock in devicetree\n"); | |
1143 | return PTR_ERR(spdif_priv->rxclk); | |
1144 | } | |
1145 | spdif_priv->rxclk_src = DEFAULT_RXCLK_SRC; | |
1146 | ||
1147 | for (i = 0; i < SPDIF_TXRATE_MAX; i++) { | |
1148 | ret = fsl_spdif_probe_txclk(spdif_priv, i); | |
1149 | if (ret) | |
1150 | return ret; | |
1151 | } | |
1152 | ||
1153 | /* Initial spinlock for control data */ | |
1154 | ctrl = &spdif_priv->fsl_spdif_control; | |
1155 | spin_lock_init(&ctrl->ctl_lock); | |
1156 | ||
1157 | /* Init tx channel status default value */ | |
1158 | ctrl->ch_status[0] = | |
1159 | IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_5015; | |
1160 | ctrl->ch_status[1] = IEC958_AES1_CON_DIGDIGCONV_ID; | |
1161 | ctrl->ch_status[2] = 0x00; | |
1162 | ctrl->ch_status[3] = | |
1163 | IEC958_AES3_CON_FS_44100 | IEC958_AES3_CON_CLOCK_1000PPM; | |
1164 | ||
1165 | spdif_priv->dpll_locked = false; | |
1166 | ||
1167 | spdif_priv->dma_params_tx.maxburst = FSL_SPDIF_TXFIFO_WML; | |
1168 | spdif_priv->dma_params_rx.maxburst = FSL_SPDIF_RXFIFO_WML; | |
1169 | spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL; | |
1170 | spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL; | |
1171 | ||
1172 | /* Register with ASoC */ | |
1173 | dev_set_drvdata(&pdev->dev, spdif_priv); | |
1174 | ||
1175 | ret = snd_soc_register_component(&pdev->dev, &fsl_spdif_component, | |
1176 | &spdif_priv->cpu_dai_drv, 1); | |
1177 | if (ret) { | |
1178 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | |
5af407cd | 1179 | return ret; |
a2388a49 NC |
1180 | } |
1181 | ||
1182 | ret = imx_pcm_dma_init(pdev); | |
1183 | if (ret) { | |
1184 | dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret); | |
1185 | goto error_component; | |
1186 | } | |
1187 | ||
1188 | return ret; | |
1189 | ||
1190 | error_component: | |
1191 | snd_soc_unregister_component(&pdev->dev); | |
a2388a49 NC |
1192 | |
1193 | return ret; | |
1194 | } | |
1195 | ||
1196 | static int fsl_spdif_remove(struct platform_device *pdev) | |
1197 | { | |
1198 | imx_pcm_dma_exit(pdev); | |
1199 | snd_soc_unregister_component(&pdev->dev); | |
a2388a49 NC |
1200 | |
1201 | return 0; | |
1202 | } | |
1203 | ||
1204 | static const struct of_device_id fsl_spdif_dt_ids[] = { | |
1205 | { .compatible = "fsl,imx35-spdif", }, | |
1206 | {} | |
1207 | }; | |
1208 | MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids); | |
1209 | ||
1210 | static struct platform_driver fsl_spdif_driver = { | |
1211 | .driver = { | |
1212 | .name = "fsl-spdif-dai", | |
1213 | .owner = THIS_MODULE, | |
1214 | .of_match_table = fsl_spdif_dt_ids, | |
1215 | }, | |
1216 | .probe = fsl_spdif_probe, | |
1217 | .remove = fsl_spdif_remove, | |
1218 | }; | |
1219 | ||
1220 | module_platform_driver(fsl_spdif_driver); | |
1221 | ||
1222 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | |
1223 | MODULE_DESCRIPTION("Freescale S/PDIF CPU DAI Driver"); | |
1224 | MODULE_LICENSE("GPL v2"); | |
1225 | MODULE_ALIAS("platform:fsl-spdif-dai"); |