1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // |
3 | // Driver for Microchip S/PDIF RX Controller |
4 | // |
5 | // Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries |
6 | // |
7 | // Author: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> |
8 | |
9 | #include <linux/clk.h> |
10 | #include <linux/io.h> |
11 | #include <linux/module.h> |
12 | #include <linux/pm_runtime.h> |
13 | #include <linux/regmap.h> |
14 | #include <linux/spinlock.h> |
15 | |
16 | #include <sound/dmaengine_pcm.h> |
17 | #include <sound/pcm_params.h> |
18 | #include <sound/soc.h> |
19 | |
20 | /* |
21 | * ---- S/PDIF Receiver Controller Register map ---- |
22 | */ |
23 | #define SPDIFRX_CR 0x00 /* Control Register */ |
24 | #define SPDIFRX_MR 0x04 /* Mode Register */ |
25 | |
26 | #define SPDIFRX_IER 0x10 /* Interrupt Enable Register */ |
27 | #define SPDIFRX_IDR 0x14 /* Interrupt Disable Register */ |
28 | #define SPDIFRX_IMR 0x18 /* Interrupt Mask Register */ |
29 | #define SPDIFRX_ISR 0x1c /* Interrupt Status Register */ |
30 | #define SPDIFRX_RSR 0x20 /* Status Register */ |
31 | #define SPDIFRX_RHR 0x24 /* Holding Register */ |
32 | |
33 | #define SPDIFRX_CHSR(channel, reg) \ |
34 | (0x30 + (channel) * 0x30 + (reg) * 4) /* Channel x Status Registers */ |
35 | |
36 | #define SPDIFRX_CHUD(channel, reg) \ |
37 | (0x48 + (channel) * 0x30 + (reg) * 4) /* Channel x User Data Registers */ |
38 | |
39 | #define SPDIFRX_WPMR 0xE4 /* Write Protection Mode Register */ |
40 | #define SPDIFRX_WPSR 0xE8 /* Write Protection Status Register */ |
41 | |
42 | #define SPDIFRX_VERSION 0xFC /* Version Register */ |
43 | |
44 | /* |
45 | * ---- Control Register (Write-only) ---- |
46 | */ |
47 | #define SPDIFRX_CR_SWRST BIT(0) /* Software Reset */ |
48 | |
49 | /* |
50 | * ---- Mode Register (Read/Write) ---- |
51 | */ |
52 | /* Receive Enable */ |
53 | #define SPDIFRX_MR_RXEN_MASK GENMASK(0, 0) |
54 | #define SPDIFRX_MR_RXEN_DISABLE (0 << 0) /* SPDIF Receiver Disabled */ |
55 | #define SPDIFRX_MR_RXEN_ENABLE (1 << 0) /* SPDIF Receiver Enabled */ |
56 | |
57 | /* Validity Bit Mode */ |
58 | #define SPDIFRX_MR_VBMODE_MASK GENAMSK(1, 1) |
59 | #define SPDIFRX_MR_VBMODE_ALWAYS_LOAD \ |
60 | (0 << 1) /* Load sample regardless of validity bit value */ |
61 | #define SPDIFRX_MR_VBMODE_DISCARD_IF_VB1 \ |
62 | (1 << 1) /* Load sample only if validity bit is 0 */ |
63 | |
64 | /* Data Word Endian Mode */ |
65 | #define SPDIFRX_MR_ENDIAN_MASK GENMASK(2, 2) |
66 | #define SPDIFRX_MR_ENDIAN_LITTLE (0 << 2) /* Little Endian Mode */ |
67 | #define SPDIFRX_MR_ENDIAN_BIG (1 << 2) /* Big Endian Mode */ |
68 | |
69 | /* Parity Bit Mode */ |
70 | #define SPDIFRX_MR_PBMODE_MASK GENMASK(3, 3) |
71 | #define SPDIFRX_MR_PBMODE_PARCHECK (0 << 3) /* Parity Check Enabled */ |
72 | #define SPDIFRX_MR_PBMODE_NOPARCHECK (1 << 3) /* Parity Check Disabled */ |
73 | |
74 | /* Sample Data Width */ |
75 | #define SPDIFRX_MR_DATAWIDTH_MASK GENMASK(5, 4) |
76 | #define SPDIFRX_MR_DATAWIDTH(width) \ |
77 | (((6 - (width) / 4) << 4) & SPDIFRX_MR_DATAWIDTH_MASK) |
78 | |
79 | /* Packed Data Mode in Receive Holding Register */ |
80 | #define SPDIFRX_MR_PACK_MASK GENMASK(7, 7) |
81 | #define SPDIFRX_MR_PACK_DISABLED (0 << 7) |
82 | #define SPDIFRX_MR_PACK_ENABLED (1 << 7) |
83 | |
84 | /* Start of Block Bit Mode */ |
85 | #define SPDIFRX_MR_SBMODE_MASK GENMASK(8, 8) |
86 | #define SPDIFRX_MR_SBMODE_ALWAYS_LOAD (0 << 8) |
87 | #define SPDIFRX_MR_SBMODE_DISCARD (1 << 8) |
88 | |
89 | /* Consecutive Preamble Error Threshold Automatic Restart */ |
90 | #define SPDIFRX_MR_AUTORST_MASK GENMASK(24, 24) |
91 | #define SPDIFRX_MR_AUTORST_NOACTION (0 << 24) |
92 | #define SPDIFRX_MR_AUTORST_UNLOCK_ON_PRE_ERR (1 << 24) |
93 | |
94 | /* |
95 | * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ---- |
96 | */ |
97 | #define SPDIFRX_IR_RXRDY BIT(0) |
98 | #define SPDIFRX_IR_LOCKED BIT(1) |
99 | #define SPDIFRX_IR_LOSS BIT(2) |
100 | #define SPDIFRX_IR_BLOCKEND BIT(3) |
101 | #define SPDIFRX_IR_SFE BIT(4) |
102 | #define SPDIFRX_IR_PAR_ERR BIT(5) |
103 | #define SPDIFRX_IR_OVERRUN BIT(6) |
104 | #define SPDIFRX_IR_RXFULL BIT(7) |
105 | #define SPDIFRX_IR_CSC(ch) BIT((ch) + 8) |
106 | #define SPDIFRX_IR_SECE BIT(10) |
107 | #define SPDIFRX_IR_BLOCKST BIT(11) |
108 | #define SPDIFRX_IR_NRZ_ERR BIT(12) |
109 | #define SPDIFRX_IR_PRE_ERR BIT(13) |
110 | #define SPDIFRX_IR_CP_ERR BIT(14) |
111 | |
112 | /* |
113 | * ---- Receiver Status Register (Read/Write) ---- |
114 | */ |
115 | /* Enable Status */ |
116 | #define SPDIFRX_RSR_ULOCK BIT(0) |
117 | #define SPDIFRX_RSR_BADF BIT(1) |
118 | #define SPDIFRX_RSR_LOWF BIT(2) |
119 | #define SPDIFRX_RSR_NOSIGNAL BIT(3) |
120 | #define SPDIFRX_RSR_IFS_MASK GENMASK(27, 16) |
121 | #define SPDIFRX_RSR_IFS(reg) \ |
122 | (((reg) & SPDIFRX_RSR_IFS_MASK) >> 16) |
123 | |
124 | /* |
125 | * ---- Version Register (Read-only) ---- |
126 | */ |
127 | #define SPDIFRX_VERSION_MASK GENMASK(11, 0) |
128 | #define SPDIFRX_VERSION_MFN_MASK GENMASK(18, 16) |
129 | #define SPDIFRX_VERSION_MFN(reg) (((reg) & SPDIFRX_VERSION_MFN_MASK) >> 16) |
130 | |
131 | static bool mchp_spdifrx_readable_reg(struct device *dev, unsigned int reg) |
132 | { |
133 | switch (reg) { |
134 | case SPDIFRX_MR: |
135 | case SPDIFRX_IMR: |
136 | case SPDIFRX_ISR: |
137 | case SPDIFRX_RSR: |
138 | case SPDIFRX_CHSR(0, 0): |
139 | case SPDIFRX_CHSR(0, 1): |
140 | case SPDIFRX_CHSR(0, 2): |
141 | case SPDIFRX_CHSR(0, 3): |
142 | case SPDIFRX_CHSR(0, 4): |
143 | case SPDIFRX_CHSR(0, 5): |
144 | case SPDIFRX_CHUD(0, 0): |
145 | case SPDIFRX_CHUD(0, 1): |
146 | case SPDIFRX_CHUD(0, 2): |
147 | case SPDIFRX_CHUD(0, 3): |
148 | case SPDIFRX_CHUD(0, 4): |
149 | case SPDIFRX_CHUD(0, 5): |
150 | case SPDIFRX_CHSR(1, 0): |
151 | case SPDIFRX_CHSR(1, 1): |
152 | case SPDIFRX_CHSR(1, 2): |
153 | case SPDIFRX_CHSR(1, 3): |
154 | case SPDIFRX_CHSR(1, 4): |
155 | case SPDIFRX_CHSR(1, 5): |
156 | case SPDIFRX_CHUD(1, 0): |
157 | case SPDIFRX_CHUD(1, 1): |
158 | case SPDIFRX_CHUD(1, 2): |
159 | case SPDIFRX_CHUD(1, 3): |
160 | case SPDIFRX_CHUD(1, 4): |
161 | case SPDIFRX_CHUD(1, 5): |
162 | case SPDIFRX_WPMR: |
163 | case SPDIFRX_WPSR: |
164 | case SPDIFRX_VERSION: |
165 | return true; |
166 | default: |
167 | return false; |
168 | } |
169 | } |
170 | |
171 | static bool mchp_spdifrx_writeable_reg(struct device *dev, unsigned int reg) |
172 | { |
173 | switch (reg) { |
174 | case SPDIFRX_CR: |
175 | case SPDIFRX_MR: |
176 | case SPDIFRX_IER: |
177 | case SPDIFRX_IDR: |
178 | case SPDIFRX_WPMR: |
179 | return true; |
180 | default: |
181 | return false; |
182 | } |
183 | } |
184 | |
185 | static bool mchp_spdifrx_precious_reg(struct device *dev, unsigned int reg) |
186 | { |
187 | switch (reg) { |
188 | case SPDIFRX_ISR: |
189 | case SPDIFRX_RHR: |
190 | return true; |
191 | default: |
192 | return false; |
193 | } |
194 | } |
195 | |
196 | static bool mchp_spdifrx_volatile_reg(struct device *dev, unsigned int reg) |
197 | { |
198 | switch (reg) { |
199 | case SPDIFRX_IMR: |
200 | case SPDIFRX_ISR: |
201 | case SPDIFRX_RSR: |
202 | case SPDIFRX_CHSR(0, 0): |
203 | case SPDIFRX_CHSR(0, 1): |
204 | case SPDIFRX_CHSR(0, 2): |
205 | case SPDIFRX_CHSR(0, 3): |
206 | case SPDIFRX_CHSR(0, 4): |
207 | case SPDIFRX_CHSR(0, 5): |
208 | case SPDIFRX_CHUD(0, 0): |
209 | case SPDIFRX_CHUD(0, 1): |
210 | case SPDIFRX_CHUD(0, 2): |
211 | case SPDIFRX_CHUD(0, 3): |
212 | case SPDIFRX_CHUD(0, 4): |
213 | case SPDIFRX_CHUD(0, 5): |
214 | case SPDIFRX_CHSR(1, 0): |
215 | case SPDIFRX_CHSR(1, 1): |
216 | case SPDIFRX_CHSR(1, 2): |
217 | case SPDIFRX_CHSR(1, 3): |
218 | case SPDIFRX_CHSR(1, 4): |
219 | case SPDIFRX_CHSR(1, 5): |
220 | case SPDIFRX_CHUD(1, 0): |
221 | case SPDIFRX_CHUD(1, 1): |
222 | case SPDIFRX_CHUD(1, 2): |
223 | case SPDIFRX_CHUD(1, 3): |
224 | case SPDIFRX_CHUD(1, 4): |
225 | case SPDIFRX_CHUD(1, 5): |
226 | case SPDIFRX_VERSION: |
227 | return true; |
228 | default: |
229 | return false; |
230 | } |
231 | } |
232 | |
233 | static const struct regmap_config mchp_spdifrx_regmap_config = { |
234 | .reg_bits = 32, |
235 | .reg_stride = 4, |
236 | .val_bits = 32, |
237 | .max_register = SPDIFRX_VERSION, |
238 | .readable_reg = mchp_spdifrx_readable_reg, |
239 | .writeable_reg = mchp_spdifrx_writeable_reg, |
240 | .precious_reg = mchp_spdifrx_precious_reg, |
241 | .volatile_reg = mchp_spdifrx_volatile_reg, |
242 | .cache_type = REGCACHE_FLAT, |
243 | }; |
244 | |
245 | #define SPDIFRX_GCLK_RATIO_MIN (12 * 64) |
246 | |
247 | #define SPDIFRX_CS_BITS 192 |
248 | #define SPDIFRX_UD_BITS 192 |
249 | |
250 | #define SPDIFRX_CHANNELS 2 |
251 | |
252 | /** |
253 | * struct mchp_spdifrx_ch_stat: MCHP SPDIFRX channel status |
254 | * @data: channel status bits |
255 | * @done: completion to signal channel status bits acquisition done |
256 | */ |
257 | struct mchp_spdifrx_ch_stat { |
258 | unsigned char data[SPDIFRX_CS_BITS / 8]; |
259 | struct completion done; |
260 | }; |
261 | |
262 | /** |
263 | * struct mchp_spdifrx_user_data: MCHP SPDIFRX user data |
264 | * @data: user data bits |
265 | * @done: completion to signal user data bits acquisition done |
266 | */ |
267 | struct mchp_spdifrx_user_data { |
268 | unsigned char data[SPDIFRX_UD_BITS / 8]; |
269 | struct completion done; |
270 | }; |
271 | |
272 | /** |
273 | * struct mchp_spdifrx_mixer_control: MCHP SPDIFRX mixer control data structure |
274 | * @ch_stat: array of channel statuses |
275 | * @user_data: array of user data |
276 | * @ulock: ulock bit status |
277 | * @badf: badf bit status |
278 | * @signal: signal bit status |
279 | */ |
280 | struct mchp_spdifrx_mixer_control { |
281 | struct mchp_spdifrx_ch_stat ch_stat[SPDIFRX_CHANNELS]; |
282 | struct mchp_spdifrx_user_data user_data[SPDIFRX_CHANNELS]; |
283 | bool ulock; |
284 | bool badf; |
285 | bool signal; |
286 | }; |
287 | |
288 | /** |
289 | * struct mchp_spdifrx_dev: MCHP SPDIFRX device data structure |
290 | * @capture: DAI DMA configuration data |
291 | * @control: mixer controls |
292 | * @mlock: mutex to protect concurency b/w configuration and control APIs |
293 | * @dev: struct device |
294 | * @regmap: regmap for this device |
295 | * @pclk: peripheral clock |
296 | * @gclk: generic clock |
297 | * @trigger_enabled: true if enabled though trigger() ops |
298 | */ |
299 | struct mchp_spdifrx_dev { |
300 | struct snd_dmaengine_dai_dma_data capture; |
301 | struct mchp_spdifrx_mixer_control control; |
302 | struct mutex mlock; |
303 | struct device *dev; |
304 | struct regmap *regmap; |
305 | struct clk *pclk; |
306 | struct clk *gclk; |
307 | unsigned int trigger_enabled; |
308 | }; |
309 | |
310 | static void mchp_spdifrx_channel_status_read(struct mchp_spdifrx_dev *dev, |
311 | int channel) |
312 | { |
313 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
314 | u8 *ch_stat = &ctrl->ch_stat[channel].data[0]; |
315 | u32 val; |
316 | int i; |
317 | |
318 | for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat[channel].data) / 4; i++) { |
319 | regmap_read(map: dev->regmap, SPDIFRX_CHSR(channel, i), val: &val); |
320 | *ch_stat++ = val & 0xFF; |
321 | *ch_stat++ = (val >> 8) & 0xFF; |
322 | *ch_stat++ = (val >> 16) & 0xFF; |
323 | *ch_stat++ = (val >> 24) & 0xFF; |
324 | } |
325 | } |
326 | |
327 | static void mchp_spdifrx_channel_user_data_read(struct mchp_spdifrx_dev *dev, |
328 | int channel) |
329 | { |
330 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
331 | u8 *user_data = &ctrl->user_data[channel].data[0]; |
332 | u32 val; |
333 | int i; |
334 | |
335 | for (i = 0; i < ARRAY_SIZE(ctrl->user_data[channel].data) / 4; i++) { |
336 | regmap_read(map: dev->regmap, SPDIFRX_CHUD(channel, i), val: &val); |
337 | *user_data++ = val & 0xFF; |
338 | *user_data++ = (val >> 8) & 0xFF; |
339 | *user_data++ = (val >> 16) & 0xFF; |
340 | *user_data++ = (val >> 24) & 0xFF; |
341 | } |
342 | } |
343 | |
344 | static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id) |
345 | { |
346 | struct mchp_spdifrx_dev *dev = dev_id; |
347 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
348 | u32 sr, imr, pending; |
349 | irqreturn_t ret = IRQ_NONE; |
350 | int ch; |
351 | |
352 | regmap_read(map: dev->regmap, SPDIFRX_ISR, val: &sr); |
353 | regmap_read(map: dev->regmap, SPDIFRX_IMR, val: &imr); |
354 | pending = sr & imr; |
355 | dev_dbg(dev->dev, "ISR: %#x, IMR: %#x, pending: %#x\n" , sr, imr, |
356 | pending); |
357 | |
358 | if (!pending) |
359 | return IRQ_NONE; |
360 | |
361 | if (pending & SPDIFRX_IR_BLOCKEND) { |
362 | for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) { |
363 | mchp_spdifrx_channel_user_data_read(dev, channel: ch); |
364 | complete(&ctrl->user_data[ch].done); |
365 | } |
366 | regmap_write(map: dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); |
367 | ret = IRQ_HANDLED; |
368 | } |
369 | |
370 | for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) { |
371 | if (pending & SPDIFRX_IR_CSC(ch)) { |
372 | mchp_spdifrx_channel_status_read(dev, channel: ch); |
373 | complete(&ctrl->ch_stat[ch].done); |
374 | regmap_write(map: dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(ch)); |
375 | ret = IRQ_HANDLED; |
376 | } |
377 | } |
378 | |
379 | if (pending & SPDIFRX_IR_OVERRUN) { |
380 | dev_warn(dev->dev, "Overrun detected\n" ); |
381 | ret = IRQ_HANDLED; |
382 | } |
383 | |
384 | return ret; |
385 | } |
386 | |
387 | static int mchp_spdifrx_trigger(struct snd_pcm_substream *substream, int cmd, |
388 | struct snd_soc_dai *dai) |
389 | { |
390 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
391 | int ret = 0; |
392 | |
393 | switch (cmd) { |
394 | case SNDRV_PCM_TRIGGER_START: |
395 | case SNDRV_PCM_TRIGGER_RESUME: |
396 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
397 | mutex_lock(&dev->mlock); |
398 | /* Enable overrun interrupts */ |
399 | regmap_write(map: dev->regmap, SPDIFRX_IER, SPDIFRX_IR_OVERRUN); |
400 | |
401 | /* Enable receiver. */ |
402 | regmap_update_bits(map: dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, |
403 | SPDIFRX_MR_RXEN_ENABLE); |
404 | dev->trigger_enabled = true; |
405 | mutex_unlock(lock: &dev->mlock); |
406 | break; |
407 | case SNDRV_PCM_TRIGGER_STOP: |
408 | case SNDRV_PCM_TRIGGER_SUSPEND: |
409 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
410 | mutex_lock(&dev->mlock); |
411 | /* Disable overrun interrupts */ |
412 | regmap_write(map: dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_OVERRUN); |
413 | |
414 | /* Disable receiver. */ |
415 | regmap_update_bits(map: dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, |
416 | SPDIFRX_MR_RXEN_DISABLE); |
417 | dev->trigger_enabled = false; |
418 | mutex_unlock(lock: &dev->mlock); |
419 | break; |
420 | default: |
421 | ret = -EINVAL; |
422 | } |
423 | |
424 | return ret; |
425 | } |
426 | |
427 | static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream, |
428 | struct snd_pcm_hw_params *params, |
429 | struct snd_soc_dai *dai) |
430 | { |
431 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
432 | u32 mr = 0; |
433 | int ret; |
434 | |
435 | dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n" , |
436 | __func__, params_rate(params), params_format(params), |
437 | params_width(params), params_channels(params)); |
438 | |
439 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
440 | dev_err(dev->dev, "Playback is not supported\n" ); |
441 | return -EINVAL; |
442 | } |
443 | |
444 | if (params_channels(p: params) != SPDIFRX_CHANNELS) { |
445 | dev_err(dev->dev, "unsupported number of channels: %d\n" , |
446 | params_channels(params)); |
447 | return -EINVAL; |
448 | } |
449 | |
450 | switch (params_format(p: params)) { |
451 | case SNDRV_PCM_FORMAT_S16_BE: |
452 | case SNDRV_PCM_FORMAT_S20_3BE: |
453 | case SNDRV_PCM_FORMAT_S24_3BE: |
454 | case SNDRV_PCM_FORMAT_S24_BE: |
455 | mr |= SPDIFRX_MR_ENDIAN_BIG; |
456 | fallthrough; |
457 | case SNDRV_PCM_FORMAT_S16_LE: |
458 | case SNDRV_PCM_FORMAT_S20_3LE: |
459 | case SNDRV_PCM_FORMAT_S24_3LE: |
460 | case SNDRV_PCM_FORMAT_S24_LE: |
461 | mr |= SPDIFRX_MR_DATAWIDTH(params_width(params)); |
462 | break; |
463 | default: |
464 | dev_err(dev->dev, "unsupported PCM format: %d\n" , |
465 | params_format(params)); |
466 | return -EINVAL; |
467 | } |
468 | |
469 | mutex_lock(&dev->mlock); |
470 | if (dev->trigger_enabled) { |
471 | dev_err(dev->dev, "PCM already running\n" ); |
472 | ret = -EBUSY; |
473 | goto unlock; |
474 | } |
475 | |
476 | /* GCLK is enabled by runtime PM. */ |
477 | clk_disable_unprepare(clk: dev->gclk); |
478 | |
479 | ret = clk_set_min_rate(clk: dev->gclk, rate: params_rate(p: params) * |
480 | SPDIFRX_GCLK_RATIO_MIN + 1); |
481 | if (ret) { |
482 | dev_err(dev->dev, |
483 | "unable to set gclk min rate: rate %u * ratio %u + 1\n" , |
484 | params_rate(params), SPDIFRX_GCLK_RATIO_MIN); |
485 | /* Restore runtime PM state. */ |
486 | clk_prepare_enable(clk: dev->gclk); |
487 | goto unlock; |
488 | } |
489 | ret = clk_prepare_enable(clk: dev->gclk); |
490 | if (ret) { |
491 | dev_err(dev->dev, "unable to enable gclk: %d\n" , ret); |
492 | goto unlock; |
493 | } |
494 | |
495 | dev_dbg(dev->dev, "GCLK range min set to %d\n" , |
496 | params_rate(params) * SPDIFRX_GCLK_RATIO_MIN + 1); |
497 | |
498 | ret = regmap_write(map: dev->regmap, SPDIFRX_MR, val: mr); |
499 | |
500 | unlock: |
501 | mutex_unlock(lock: &dev->mlock); |
502 | |
503 | return ret; |
504 | } |
505 | |
506 | #define MCHP_SPDIF_RATES SNDRV_PCM_RATE_8000_192000 |
507 | |
508 | #define MCHP_SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
509 | SNDRV_PCM_FMTBIT_U16_BE | \ |
510 | SNDRV_PCM_FMTBIT_S20_3LE | \ |
511 | SNDRV_PCM_FMTBIT_S20_3BE | \ |
512 | SNDRV_PCM_FMTBIT_S24_3LE | \ |
513 | SNDRV_PCM_FMTBIT_S24_3BE | \ |
514 | SNDRV_PCM_FMTBIT_S24_LE | \ |
515 | SNDRV_PCM_FMTBIT_S24_BE \ |
516 | ) |
517 | |
518 | static int mchp_spdifrx_info(struct snd_kcontrol *kcontrol, |
519 | struct snd_ctl_elem_info *uinfo) |
520 | { |
521 | uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; |
522 | uinfo->count = 1; |
523 | |
524 | return 0; |
525 | } |
526 | |
527 | static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev, |
528 | int channel, |
529 | struct snd_ctl_elem_value *uvalue) |
530 | { |
531 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
532 | struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel]; |
533 | int ret = 0; |
534 | |
535 | mutex_lock(&dev->mlock); |
536 | |
537 | ret = pm_runtime_resume_and_get(dev: dev->dev); |
538 | if (ret < 0) |
539 | goto unlock; |
540 | |
541 | /* |
542 | * We may reach this point with both clocks enabled but the receiver |
543 | * still disabled. To void waiting for completion and return with |
544 | * timeout check the dev->trigger_enabled. |
545 | * |
546 | * To retrieve data: |
547 | * - if the receiver is enabled CSC IRQ will update the data in software |
548 | * caches (ch_stat->data) |
549 | * - otherwise we just update it here the software caches with latest |
550 | * available information and return it; in this case we don't need |
551 | * spin locking as the IRQ is disabled and will not be raised from |
552 | * anywhere else. |
553 | */ |
554 | |
555 | if (dev->trigger_enabled) { |
556 | reinit_completion(x: &ch_stat->done); |
557 | regmap_write(map: dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel)); |
558 | /* Check for new data available */ |
559 | ret = wait_for_completion_interruptible_timeout(x: &ch_stat->done, |
560 | timeout: msecs_to_jiffies(m: 100)); |
561 | /* Valid stream might not be present */ |
562 | if (ret <= 0) { |
563 | dev_dbg(dev->dev, "channel status for channel %d timeout\n" , |
564 | channel); |
565 | regmap_write(map: dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(channel)); |
566 | ret = ret ? : -ETIMEDOUT; |
567 | goto pm_runtime_put; |
568 | } else { |
569 | ret = 0; |
570 | } |
571 | } else { |
572 | /* Update software cache with latest channel status. */ |
573 | mchp_spdifrx_channel_status_read(dev, channel); |
574 | } |
575 | |
576 | memcpy(uvalue->value.iec958.status, ch_stat->data, |
577 | sizeof(ch_stat->data)); |
578 | |
579 | pm_runtime_put: |
580 | pm_runtime_mark_last_busy(dev: dev->dev); |
581 | pm_runtime_put_autosuspend(dev: dev->dev); |
582 | unlock: |
583 | mutex_unlock(lock: &dev->mlock); |
584 | return ret; |
585 | } |
586 | |
587 | static int mchp_spdifrx_cs1_get(struct snd_kcontrol *kcontrol, |
588 | struct snd_ctl_elem_value *uvalue) |
589 | { |
590 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
591 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
592 | |
593 | return mchp_spdifrx_cs_get(dev, channel: 0, uvalue); |
594 | } |
595 | |
596 | static int mchp_spdifrx_cs2_get(struct snd_kcontrol *kcontrol, |
597 | struct snd_ctl_elem_value *uvalue) |
598 | { |
599 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
600 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
601 | |
602 | return mchp_spdifrx_cs_get(dev, channel: 1, uvalue); |
603 | } |
604 | |
605 | static int mchp_spdifrx_cs_mask(struct snd_kcontrol *kcontrol, |
606 | struct snd_ctl_elem_value *uvalue) |
607 | { |
608 | memset(uvalue->value.iec958.status, 0xff, |
609 | sizeof(uvalue->value.iec958.status)); |
610 | |
611 | return 0; |
612 | } |
613 | |
614 | static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev, |
615 | int channel, |
616 | struct snd_ctl_elem_value *uvalue) |
617 | { |
618 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
619 | struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel]; |
620 | int ret = 0; |
621 | |
622 | mutex_lock(&dev->mlock); |
623 | |
624 | ret = pm_runtime_resume_and_get(dev: dev->dev); |
625 | if (ret < 0) |
626 | goto unlock; |
627 | |
628 | /* |
629 | * We may reach this point with both clocks enabled but the receiver |
630 | * still disabled. To void waiting for completion to just timeout we |
631 | * check here the dev->trigger_enabled flag. |
632 | * |
633 | * To retrieve data: |
634 | * - if the receiver is enabled we need to wait for blockend IRQ to read |
635 | * data to and update it for us in software caches |
636 | * - otherwise reading the SPDIFRX_CHUD() registers is enough. |
637 | */ |
638 | |
639 | if (dev->trigger_enabled) { |
640 | reinit_completion(x: &user_data->done); |
641 | regmap_write(map: dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND); |
642 | ret = wait_for_completion_interruptible_timeout(x: &user_data->done, |
643 | timeout: msecs_to_jiffies(m: 100)); |
644 | /* Valid stream might not be present. */ |
645 | if (ret <= 0) { |
646 | dev_dbg(dev->dev, "user data for channel %d timeout\n" , |
647 | channel); |
648 | regmap_write(map: dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); |
649 | ret = ret ? : -ETIMEDOUT; |
650 | goto pm_runtime_put; |
651 | } else { |
652 | ret = 0; |
653 | } |
654 | } else { |
655 | /* Update software cache with last available data. */ |
656 | mchp_spdifrx_channel_user_data_read(dev, channel); |
657 | } |
658 | |
659 | memcpy(uvalue->value.iec958.subcode, user_data->data, |
660 | sizeof(user_data->data)); |
661 | |
662 | pm_runtime_put: |
663 | pm_runtime_mark_last_busy(dev: dev->dev); |
664 | pm_runtime_put_autosuspend(dev: dev->dev); |
665 | unlock: |
666 | mutex_unlock(lock: &dev->mlock); |
667 | return ret; |
668 | } |
669 | |
670 | static int mchp_spdifrx_subcode_ch1_get(struct snd_kcontrol *kcontrol, |
671 | struct snd_ctl_elem_value *uvalue) |
672 | { |
673 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
674 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
675 | |
676 | return mchp_spdifrx_subcode_ch_get(dev, channel: 0, uvalue); |
677 | } |
678 | |
679 | static int mchp_spdifrx_subcode_ch2_get(struct snd_kcontrol *kcontrol, |
680 | struct snd_ctl_elem_value *uvalue) |
681 | { |
682 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
683 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
684 | |
685 | return mchp_spdifrx_subcode_ch_get(dev, channel: 1, uvalue); |
686 | } |
687 | |
688 | static int mchp_spdifrx_boolean_info(struct snd_kcontrol *kcontrol, |
689 | struct snd_ctl_elem_info *uinfo) |
690 | { |
691 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
692 | uinfo->count = 1; |
693 | uinfo->value.integer.min = 0; |
694 | uinfo->value.integer.max = 1; |
695 | |
696 | return 0; |
697 | } |
698 | |
699 | static int mchp_spdifrx_ulock_get(struct snd_kcontrol *kcontrol, |
700 | struct snd_ctl_elem_value *uvalue) |
701 | { |
702 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
703 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
704 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
705 | u32 val; |
706 | int ret; |
707 | bool ulock_old = ctrl->ulock; |
708 | |
709 | mutex_lock(&dev->mlock); |
710 | |
711 | ret = pm_runtime_resume_and_get(dev: dev->dev); |
712 | if (ret < 0) |
713 | goto unlock; |
714 | |
715 | /* |
716 | * The RSR.ULOCK has wrong value if both pclk and gclk are enabled |
717 | * and the receiver is disabled. Thus we take into account the |
718 | * dev->trigger_enabled here to return a real status. |
719 | */ |
720 | if (dev->trigger_enabled) { |
721 | regmap_read(map: dev->regmap, SPDIFRX_RSR, val: &val); |
722 | ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK); |
723 | } else { |
724 | ctrl->ulock = 0; |
725 | } |
726 | |
727 | uvalue->value.integer.value[0] = ctrl->ulock; |
728 | |
729 | pm_runtime_mark_last_busy(dev: dev->dev); |
730 | pm_runtime_put_autosuspend(dev: dev->dev); |
731 | unlock: |
732 | mutex_unlock(lock: &dev->mlock); |
733 | |
734 | return ulock_old != ctrl->ulock; |
735 | } |
736 | |
737 | static int mchp_spdifrx_badf_get(struct snd_kcontrol *kcontrol, |
738 | struct snd_ctl_elem_value *uvalue) |
739 | { |
740 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
741 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
742 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
743 | u32 val; |
744 | int ret; |
745 | bool badf_old = ctrl->badf; |
746 | |
747 | mutex_lock(&dev->mlock); |
748 | |
749 | ret = pm_runtime_resume_and_get(dev: dev->dev); |
750 | if (ret < 0) |
751 | goto unlock; |
752 | |
753 | /* |
754 | * The RSR.ULOCK has wrong value if both pclk and gclk are enabled |
755 | * and the receiver is disabled. Thus we take into account the |
756 | * dev->trigger_enabled here to return a real status. |
757 | */ |
758 | if (dev->trigger_enabled) { |
759 | regmap_read(map: dev->regmap, SPDIFRX_RSR, val: &val); |
760 | ctrl->badf = !!(val & SPDIFRX_RSR_BADF); |
761 | } else { |
762 | ctrl->badf = 0; |
763 | } |
764 | |
765 | pm_runtime_mark_last_busy(dev: dev->dev); |
766 | pm_runtime_put_autosuspend(dev: dev->dev); |
767 | unlock: |
768 | mutex_unlock(lock: &dev->mlock); |
769 | |
770 | uvalue->value.integer.value[0] = ctrl->badf; |
771 | |
772 | return badf_old != ctrl->badf; |
773 | } |
774 | |
775 | static int mchp_spdifrx_signal_get(struct snd_kcontrol *kcontrol, |
776 | struct snd_ctl_elem_value *uvalue) |
777 | { |
778 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
779 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
780 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
781 | u32 val = ~0U, loops = 10; |
782 | int ret; |
783 | bool signal_old = ctrl->signal; |
784 | |
785 | mutex_lock(&dev->mlock); |
786 | |
787 | ret = pm_runtime_resume_and_get(dev: dev->dev); |
788 | if (ret < 0) |
789 | goto unlock; |
790 | |
791 | /* |
792 | * To get the signal we need to have receiver enabled. This |
793 | * could be enabled also from trigger() function thus we need to |
794 | * take care of not disabling the receiver when it runs. |
795 | */ |
796 | if (!dev->trigger_enabled) { |
797 | regmap_update_bits(map: dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, |
798 | SPDIFRX_MR_RXEN_ENABLE); |
799 | |
800 | /* Wait for RSR.ULOCK bit. */ |
801 | while (--loops) { |
802 | regmap_read(map: dev->regmap, SPDIFRX_RSR, val: &val); |
803 | if (!(val & SPDIFRX_RSR_ULOCK)) |
804 | break; |
805 | usleep_range(min: 100, max: 150); |
806 | } |
807 | |
808 | regmap_update_bits(map: dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, |
809 | SPDIFRX_MR_RXEN_DISABLE); |
810 | } else { |
811 | regmap_read(map: dev->regmap, SPDIFRX_RSR, val: &val); |
812 | } |
813 | |
814 | pm_runtime_mark_last_busy(dev: dev->dev); |
815 | pm_runtime_put_autosuspend(dev: dev->dev); |
816 | |
817 | unlock: |
818 | mutex_unlock(lock: &dev->mlock); |
819 | |
820 | if (!(val & SPDIFRX_RSR_ULOCK)) |
821 | ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL); |
822 | else |
823 | ctrl->signal = 0; |
824 | uvalue->value.integer.value[0] = ctrl->signal; |
825 | |
826 | return signal_old != ctrl->signal; |
827 | } |
828 | |
829 | static int mchp_spdifrx_rate_info(struct snd_kcontrol *kcontrol, |
830 | struct snd_ctl_elem_info *uinfo) |
831 | { |
832 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
833 | uinfo->count = 1; |
834 | uinfo->value.integer.min = 0; |
835 | uinfo->value.integer.max = 192000; |
836 | |
837 | return 0; |
838 | } |
839 | |
840 | static int mchp_spdifrx_rate_get(struct snd_kcontrol *kcontrol, |
841 | struct snd_ctl_elem_value *ucontrol) |
842 | { |
843 | struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); |
844 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
845 | unsigned long rate; |
846 | u32 val; |
847 | int ret; |
848 | |
849 | mutex_lock(&dev->mlock); |
850 | |
851 | ret = pm_runtime_resume_and_get(dev: dev->dev); |
852 | if (ret < 0) |
853 | goto unlock; |
854 | |
855 | /* |
856 | * The RSR.ULOCK has wrong value if both pclk and gclk are enabled |
857 | * and the receiver is disabled. Thus we take into account the |
858 | * dev->trigger_enabled here to return a real status. |
859 | */ |
860 | if (dev->trigger_enabled) { |
861 | regmap_read(map: dev->regmap, SPDIFRX_RSR, val: &val); |
862 | /* If the receiver is not locked, ISF data is invalid. */ |
863 | if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) { |
864 | ucontrol->value.integer.value[0] = 0; |
865 | goto pm_runtime_put; |
866 | } |
867 | } else { |
868 | /* Reveicer is not locked, IFS data is invalid. */ |
869 | ucontrol->value.integer.value[0] = 0; |
870 | goto pm_runtime_put; |
871 | } |
872 | |
873 | rate = clk_get_rate(clk: dev->gclk); |
874 | |
875 | ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val)); |
876 | |
877 | pm_runtime_put: |
878 | pm_runtime_mark_last_busy(dev: dev->dev); |
879 | pm_runtime_put_autosuspend(dev: dev->dev); |
880 | unlock: |
881 | mutex_unlock(lock: &dev->mlock); |
882 | return ret; |
883 | } |
884 | |
885 | static struct snd_kcontrol_new mchp_spdifrx_ctrls[] = { |
886 | /* Channel status controller */ |
887 | { |
888 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
889 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, DEFAULT) |
890 | " Channel 1" , |
891 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
892 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
893 | .info = mchp_spdifrx_info, |
894 | .get = mchp_spdifrx_cs1_get, |
895 | }, |
896 | { |
897 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
898 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, DEFAULT) |
899 | " Channel 2" , |
900 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
901 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
902 | .info = mchp_spdifrx_info, |
903 | .get = mchp_spdifrx_cs2_get, |
904 | }, |
905 | { |
906 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
907 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, MASK), |
908 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
909 | .info = mchp_spdifrx_info, |
910 | .get = mchp_spdifrx_cs_mask, |
911 | }, |
912 | /* User bits controller */ |
913 | { |
914 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
915 | .name = "IEC958 Subcode Capture Default Channel 1" , |
916 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
917 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
918 | .info = mchp_spdifrx_info, |
919 | .get = mchp_spdifrx_subcode_ch1_get, |
920 | }, |
921 | { |
922 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
923 | .name = "IEC958 Subcode Capture Default Channel 2" , |
924 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
925 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
926 | .info = mchp_spdifrx_info, |
927 | .get = mchp_spdifrx_subcode_ch2_get, |
928 | }, |
929 | /* Lock status */ |
930 | { |
931 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
932 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, NONE) "Unlocked" , |
933 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
934 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
935 | .info = mchp_spdifrx_boolean_info, |
936 | .get = mchp_spdifrx_ulock_get, |
937 | }, |
938 | /* Bad format */ |
939 | { |
940 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
941 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, NONE)"Bad Format" , |
942 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
943 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
944 | .info = mchp_spdifrx_boolean_info, |
945 | .get = mchp_spdifrx_badf_get, |
946 | }, |
947 | /* Signal */ |
948 | { |
949 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
950 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, NONE) "Signal" , |
951 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
952 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
953 | .info = mchp_spdifrx_boolean_info, |
954 | .get = mchp_spdifrx_signal_get, |
955 | }, |
956 | /* Sampling rate */ |
957 | { |
958 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
959 | .name = SNDRV_CTL_NAME_IEC958("" , CAPTURE, NONE) "Rate" , |
960 | .access = SNDRV_CTL_ELEM_ACCESS_READ | |
961 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
962 | .info = mchp_spdifrx_rate_info, |
963 | .get = mchp_spdifrx_rate_get, |
964 | }, |
965 | }; |
966 | |
967 | static int mchp_spdifrx_dai_probe(struct snd_soc_dai *dai) |
968 | { |
969 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
970 | struct mchp_spdifrx_mixer_control *ctrl = &dev->control; |
971 | int ch; |
972 | |
973 | snd_soc_dai_init_dma_data(dai, NULL, capture: &dev->capture); |
974 | |
975 | /* Software reset the IP */ |
976 | regmap_write(map: dev->regmap, SPDIFRX_CR, SPDIFRX_CR_SWRST); |
977 | |
978 | /* Default configuration */ |
979 | regmap_write(map: dev->regmap, SPDIFRX_MR, |
980 | SPDIFRX_MR_VBMODE_DISCARD_IF_VB1 | |
981 | SPDIFRX_MR_SBMODE_DISCARD | |
982 | SPDIFRX_MR_AUTORST_NOACTION | |
983 | SPDIFRX_MR_PACK_DISABLED); |
984 | |
985 | for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) { |
986 | init_completion(x: &ctrl->ch_stat[ch].done); |
987 | init_completion(x: &ctrl->user_data[ch].done); |
988 | } |
989 | |
990 | /* Add controls */ |
991 | snd_soc_add_dai_controls(dai, controls: mchp_spdifrx_ctrls, |
992 | ARRAY_SIZE(mchp_spdifrx_ctrls)); |
993 | |
994 | return 0; |
995 | } |
996 | |
997 | static int mchp_spdifrx_dai_remove(struct snd_soc_dai *dai) |
998 | { |
999 | struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai); |
1000 | |
1001 | /* Disable interrupts */ |
1002 | regmap_write(map: dev->regmap, SPDIFRX_IDR, GENMASK(14, 0)); |
1003 | |
1004 | return 0; |
1005 | } |
1006 | |
1007 | static const struct snd_soc_dai_ops mchp_spdifrx_dai_ops = { |
1008 | .probe = mchp_spdifrx_dai_probe, |
1009 | .remove = mchp_spdifrx_dai_remove, |
1010 | .trigger = mchp_spdifrx_trigger, |
1011 | .hw_params = mchp_spdifrx_hw_params, |
1012 | }; |
1013 | |
1014 | static struct snd_soc_dai_driver mchp_spdifrx_dai = { |
1015 | .name = "mchp-spdifrx" , |
1016 | .capture = { |
1017 | .stream_name = "S/PDIF Capture" , |
1018 | .channels_min = SPDIFRX_CHANNELS, |
1019 | .channels_max = SPDIFRX_CHANNELS, |
1020 | .rates = MCHP_SPDIF_RATES, |
1021 | .formats = MCHP_SPDIF_FORMATS, |
1022 | }, |
1023 | .ops = &mchp_spdifrx_dai_ops, |
1024 | }; |
1025 | |
1026 | static const struct snd_soc_component_driver mchp_spdifrx_component = { |
1027 | .name = "mchp-spdifrx" , |
1028 | .legacy_dai_naming = 1, |
1029 | }; |
1030 | |
1031 | static const struct of_device_id mchp_spdifrx_dt_ids[] = { |
1032 | { |
1033 | .compatible = "microchip,sama7g5-spdifrx" , |
1034 | }, |
1035 | { /* sentinel */ } |
1036 | }; |
1037 | MODULE_DEVICE_TABLE(of, mchp_spdifrx_dt_ids); |
1038 | |
1039 | static int mchp_spdifrx_runtime_suspend(struct device *dev) |
1040 | { |
1041 | struct mchp_spdifrx_dev *spdifrx = dev_get_drvdata(dev); |
1042 | |
1043 | regcache_cache_only(map: spdifrx->regmap, enable: true); |
1044 | clk_disable_unprepare(clk: spdifrx->gclk); |
1045 | clk_disable_unprepare(clk: spdifrx->pclk); |
1046 | |
1047 | return 0; |
1048 | } |
1049 | |
1050 | static int mchp_spdifrx_runtime_resume(struct device *dev) |
1051 | { |
1052 | struct mchp_spdifrx_dev *spdifrx = dev_get_drvdata(dev); |
1053 | int ret; |
1054 | |
1055 | ret = clk_prepare_enable(clk: spdifrx->pclk); |
1056 | if (ret) |
1057 | return ret; |
1058 | |
1059 | ret = clk_prepare_enable(clk: spdifrx->gclk); |
1060 | if (ret) |
1061 | goto disable_pclk; |
1062 | |
1063 | regcache_cache_only(map: spdifrx->regmap, enable: false); |
1064 | regcache_mark_dirty(map: spdifrx->regmap); |
1065 | ret = regcache_sync(map: spdifrx->regmap); |
1066 | if (ret) { |
1067 | regcache_cache_only(map: spdifrx->regmap, enable: true); |
1068 | clk_disable_unprepare(clk: spdifrx->gclk); |
1069 | disable_pclk: |
1070 | clk_disable_unprepare(clk: spdifrx->pclk); |
1071 | } |
1072 | |
1073 | return ret; |
1074 | } |
1075 | |
1076 | static const struct dev_pm_ops mchp_spdifrx_pm_ops = { |
1077 | RUNTIME_PM_OPS(mchp_spdifrx_runtime_suspend, mchp_spdifrx_runtime_resume, |
1078 | NULL) |
1079 | }; |
1080 | |
1081 | static int mchp_spdifrx_probe(struct platform_device *pdev) |
1082 | { |
1083 | struct mchp_spdifrx_dev *dev; |
1084 | struct resource *mem; |
1085 | struct regmap *regmap; |
1086 | void __iomem *base; |
1087 | int irq; |
1088 | int err; |
1089 | u32 vers; |
1090 | |
1091 | /* Get memory for driver data. */ |
1092 | dev = devm_kzalloc(dev: &pdev->dev, size: sizeof(*dev), GFP_KERNEL); |
1093 | if (!dev) |
1094 | return -ENOMEM; |
1095 | |
1096 | /* Map I/O registers. */ |
1097 | base = devm_platform_get_and_ioremap_resource(pdev, index: 0, res: &mem); |
1098 | if (IS_ERR(ptr: base)) |
1099 | return PTR_ERR(ptr: base); |
1100 | |
1101 | regmap = devm_regmap_init_mmio(&pdev->dev, base, |
1102 | &mchp_spdifrx_regmap_config); |
1103 | if (IS_ERR(ptr: regmap)) |
1104 | return PTR_ERR(ptr: regmap); |
1105 | |
1106 | /* Request IRQ. */ |
1107 | irq = platform_get_irq(pdev, 0); |
1108 | if (irq < 0) |
1109 | return irq; |
1110 | |
1111 | err = devm_request_irq(dev: &pdev->dev, irq, handler: mchp_spdif_interrupt, irqflags: 0, |
1112 | devname: dev_name(dev: &pdev->dev), dev_id: dev); |
1113 | if (err) |
1114 | return err; |
1115 | |
1116 | /* Get the peripheral clock */ |
1117 | dev->pclk = devm_clk_get(dev: &pdev->dev, id: "pclk" ); |
1118 | if (IS_ERR(ptr: dev->pclk)) { |
1119 | err = PTR_ERR(ptr: dev->pclk); |
1120 | dev_err(&pdev->dev, "failed to get the peripheral clock: %d\n" , |
1121 | err); |
1122 | return err; |
1123 | } |
1124 | |
1125 | /* Get the generated clock */ |
1126 | dev->gclk = devm_clk_get(dev: &pdev->dev, id: "gclk" ); |
1127 | if (IS_ERR(ptr: dev->gclk)) { |
1128 | err = PTR_ERR(ptr: dev->gclk); |
1129 | dev_err(&pdev->dev, |
1130 | "failed to get the PMC generated clock: %d\n" , err); |
1131 | return err; |
1132 | } |
1133 | |
1134 | /* |
1135 | * Signal control need a valid rate on gclk. hw_params() configures |
1136 | * it propertly but requesting signal before any hw_params() has been |
1137 | * called lead to invalid value returned for signal. Thus, configure |
1138 | * gclk at a valid rate, here, in initialization, to simplify the |
1139 | * control path. |
1140 | */ |
1141 | clk_set_min_rate(clk: dev->gclk, rate: 48000 * SPDIFRX_GCLK_RATIO_MIN + 1); |
1142 | |
1143 | mutex_init(&dev->mlock); |
1144 | |
1145 | dev->dev = &pdev->dev; |
1146 | dev->regmap = regmap; |
1147 | platform_set_drvdata(pdev, data: dev); |
1148 | |
1149 | pm_runtime_enable(dev: dev->dev); |
1150 | if (!pm_runtime_enabled(dev: dev->dev)) { |
1151 | err = mchp_spdifrx_runtime_resume(dev: dev->dev); |
1152 | if (err) |
1153 | goto pm_runtime_disable; |
1154 | } |
1155 | |
1156 | dev->capture.addr = (dma_addr_t)mem->start + SPDIFRX_RHR; |
1157 | dev->capture.maxburst = 1; |
1158 | |
1159 | err = devm_snd_dmaengine_pcm_register(dev: &pdev->dev, NULL, flags: 0); |
1160 | if (err) { |
1161 | dev_err(&pdev->dev, "failed to register PCM: %d\n" , err); |
1162 | goto pm_runtime_suspend; |
1163 | } |
1164 | |
1165 | err = devm_snd_soc_register_component(dev: &pdev->dev, |
1166 | component_driver: &mchp_spdifrx_component, |
1167 | dai_drv: &mchp_spdifrx_dai, num_dai: 1); |
1168 | if (err) { |
1169 | dev_err(&pdev->dev, "fail to register dai\n" ); |
1170 | goto pm_runtime_suspend; |
1171 | } |
1172 | |
1173 | regmap_read(map: regmap, SPDIFRX_VERSION, val: &vers); |
1174 | dev_info(&pdev->dev, "hw version: %#lx\n" , vers & SPDIFRX_VERSION_MASK); |
1175 | |
1176 | return 0; |
1177 | |
1178 | pm_runtime_suspend: |
1179 | if (!pm_runtime_status_suspended(dev: dev->dev)) |
1180 | mchp_spdifrx_runtime_suspend(dev: dev->dev); |
1181 | pm_runtime_disable: |
1182 | pm_runtime_disable(dev: dev->dev); |
1183 | return err; |
1184 | } |
1185 | |
1186 | static void mchp_spdifrx_remove(struct platform_device *pdev) |
1187 | { |
1188 | struct mchp_spdifrx_dev *dev = platform_get_drvdata(pdev); |
1189 | |
1190 | pm_runtime_disable(dev: dev->dev); |
1191 | if (!pm_runtime_status_suspended(dev: dev->dev)) |
1192 | mchp_spdifrx_runtime_suspend(dev: dev->dev); |
1193 | } |
1194 | |
1195 | static struct platform_driver mchp_spdifrx_driver = { |
1196 | .probe = mchp_spdifrx_probe, |
1197 | .remove_new = mchp_spdifrx_remove, |
1198 | .driver = { |
1199 | .name = "mchp_spdifrx" , |
1200 | .of_match_table = mchp_spdifrx_dt_ids, |
1201 | .pm = pm_ptr(&mchp_spdifrx_pm_ops), |
1202 | }, |
1203 | }; |
1204 | |
1205 | module_platform_driver(mchp_spdifrx_driver); |
1206 | |
1207 | MODULE_AUTHOR("Codrin Ciubotariu <codrin.ciubotariu@microchip.com>" ); |
1208 | MODULE_DESCRIPTION("Microchip S/PDIF RX Controller Driver" ); |
1209 | MODULE_LICENSE("GPL v2" ); |
1210 | |