Commit | Line | Data |
---|---|---|
c6aeb7de FM |
1 | /* |
2 | * ALSA SoC I2S Audio Layer for Broadcom BCM2835 SoC | |
3 | * | |
4 | * Author: Florian Meier <florian.meier@koalo.de> | |
5 | * Copyright 2013 | |
6 | * | |
7 | * Based on | |
8 | * Raspberry Pi PCM I2S ALSA Driver | |
9 | * Copyright (c) by Phil Poole 2013 | |
10 | * | |
11 | * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor | |
12 | * Vladimir Barinov, <vbarinov@embeddedalley.com> | |
13 | * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com> | |
14 | * | |
15 | * OMAP ALSA SoC DAI driver using McBSP port | |
16 | * Copyright (C) 2008 Nokia Corporation | |
17 | * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com> | |
18 | * Peter Ujfalusi <peter.ujfalusi@ti.com> | |
19 | * | |
20 | * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver | |
21 | * Author: Timur Tabi <timur@freescale.com> | |
22 | * Copyright 2007-2010 Freescale Semiconductor, Inc. | |
23 | * | |
24 | * This program is free software; you can redistribute it and/or | |
25 | * modify it under the terms of the GNU General Public License | |
26 | * version 2 as published by the Free Software Foundation. | |
27 | * | |
28 | * This program is distributed in the hope that it will be useful, but | |
29 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
30 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31 | * General Public License for more details. | |
32 | */ | |
33 | ||
9448572d | 34 | #include <linux/bitops.h> |
7905f082 MS |
35 | #include <linux/clk.h> |
36 | #include <linux/delay.h> | |
37 | #include <linux/device.h> | |
c6aeb7de | 38 | #include <linux/init.h> |
7905f082 | 39 | #include <linux/io.h> |
c6aeb7de | 40 | #include <linux/module.h> |
517e7a15 | 41 | #include <linux/of_address.h> |
c6aeb7de | 42 | #include <linux/slab.h> |
c6aeb7de FM |
43 | |
44 | #include <sound/core.h> | |
7905f082 MS |
45 | #include <sound/dmaengine_pcm.h> |
46 | #include <sound/initval.h> | |
c6aeb7de FM |
47 | #include <sound/pcm.h> |
48 | #include <sound/pcm_params.h> | |
c6aeb7de | 49 | #include <sound/soc.h> |
c6aeb7de | 50 | |
c6aeb7de FM |
51 | /* I2S registers */ |
52 | #define BCM2835_I2S_CS_A_REG 0x00 | |
53 | #define BCM2835_I2S_FIFO_A_REG 0x04 | |
54 | #define BCM2835_I2S_MODE_A_REG 0x08 | |
55 | #define BCM2835_I2S_RXC_A_REG 0x0c | |
56 | #define BCM2835_I2S_TXC_A_REG 0x10 | |
57 | #define BCM2835_I2S_DREQ_A_REG 0x14 | |
58 | #define BCM2835_I2S_INTEN_A_REG 0x18 | |
59 | #define BCM2835_I2S_INTSTC_A_REG 0x1c | |
60 | #define BCM2835_I2S_GRAY_REG 0x20 | |
61 | ||
62 | /* I2S register settings */ | |
63 | #define BCM2835_I2S_STBY BIT(25) | |
64 | #define BCM2835_I2S_SYNC BIT(24) | |
65 | #define BCM2835_I2S_RXSEX BIT(23) | |
66 | #define BCM2835_I2S_RXF BIT(22) | |
67 | #define BCM2835_I2S_TXE BIT(21) | |
68 | #define BCM2835_I2S_RXD BIT(20) | |
69 | #define BCM2835_I2S_TXD BIT(19) | |
70 | #define BCM2835_I2S_RXR BIT(18) | |
71 | #define BCM2835_I2S_TXW BIT(17) | |
72 | #define BCM2835_I2S_CS_RXERR BIT(16) | |
73 | #define BCM2835_I2S_CS_TXERR BIT(15) | |
74 | #define BCM2835_I2S_RXSYNC BIT(14) | |
75 | #define BCM2835_I2S_TXSYNC BIT(13) | |
76 | #define BCM2835_I2S_DMAEN BIT(9) | |
77 | #define BCM2835_I2S_RXTHR(v) ((v) << 7) | |
78 | #define BCM2835_I2S_TXTHR(v) ((v) << 5) | |
79 | #define BCM2835_I2S_RXCLR BIT(4) | |
80 | #define BCM2835_I2S_TXCLR BIT(3) | |
81 | #define BCM2835_I2S_TXON BIT(2) | |
82 | #define BCM2835_I2S_RXON BIT(1) | |
83 | #define BCM2835_I2S_EN (1) | |
84 | ||
85 | #define BCM2835_I2S_CLKDIS BIT(28) | |
86 | #define BCM2835_I2S_PDMN BIT(27) | |
87 | #define BCM2835_I2S_PDME BIT(26) | |
88 | #define BCM2835_I2S_FRXP BIT(25) | |
89 | #define BCM2835_I2S_FTXP BIT(24) | |
90 | #define BCM2835_I2S_CLKM BIT(23) | |
91 | #define BCM2835_I2S_CLKI BIT(22) | |
92 | #define BCM2835_I2S_FSM BIT(21) | |
93 | #define BCM2835_I2S_FSI BIT(20) | |
94 | #define BCM2835_I2S_FLEN(v) ((v) << 10) | |
95 | #define BCM2835_I2S_FSLEN(v) (v) | |
96 | ||
97 | #define BCM2835_I2S_CHWEX BIT(15) | |
98 | #define BCM2835_I2S_CHEN BIT(14) | |
99 | #define BCM2835_I2S_CHPOS(v) ((v) << 4) | |
100 | #define BCM2835_I2S_CHWID(v) (v) | |
101 | #define BCM2835_I2S_CH1(v) ((v) << 16) | |
102 | #define BCM2835_I2S_CH2(v) (v) | |
9448572d MR |
103 | #define BCM2835_I2S_CH1_POS(v) BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(v)) |
104 | #define BCM2835_I2S_CH2_POS(v) BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(v)) | |
c6aeb7de FM |
105 | |
106 | #define BCM2835_I2S_TX_PANIC(v) ((v) << 24) | |
107 | #define BCM2835_I2S_RX_PANIC(v) ((v) << 16) | |
108 | #define BCM2835_I2S_TX(v) ((v) << 8) | |
109 | #define BCM2835_I2S_RX(v) (v) | |
110 | ||
111 | #define BCM2835_I2S_INT_RXERR BIT(3) | |
112 | #define BCM2835_I2S_INT_TXERR BIT(2) | |
113 | #define BCM2835_I2S_INT_RXR BIT(1) | |
114 | #define BCM2835_I2S_INT_TXW BIT(0) | |
115 | ||
9448572d MR |
116 | /* Frame length register is 10 bit, maximum length 1024 */ |
117 | #define BCM2835_I2S_MAX_FRAME_LENGTH 1024 | |
118 | ||
c6aeb7de FM |
119 | /* General device struct */ |
120 | struct bcm2835_i2s_dev { | |
121 | struct device *dev; | |
122 | struct snd_dmaengine_dai_dma_data dma_data[2]; | |
123 | unsigned int fmt; | |
9448572d MR |
124 | unsigned int tdm_slots; |
125 | unsigned int rx_mask; | |
126 | unsigned int tx_mask; | |
127 | unsigned int slot_width; | |
128 | unsigned int frame_length; | |
c6aeb7de | 129 | |
517e7a15 MS |
130 | struct regmap *i2s_regmap; |
131 | struct clk *clk; | |
132 | bool clk_prepared; | |
c6aeb7de FM |
133 | }; |
134 | ||
135 | static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) | |
136 | { | |
c6aeb7de FM |
137 | unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; |
138 | ||
517e7a15 MS |
139 | if (dev->clk_prepared) |
140 | return; | |
141 | ||
c6aeb7de FM |
142 | switch (master) { |
143 | case SND_SOC_DAIFMT_CBS_CFS: | |
144 | case SND_SOC_DAIFMT_CBS_CFM: | |
517e7a15 MS |
145 | clk_prepare_enable(dev->clk); |
146 | dev->clk_prepared = true; | |
c6aeb7de FM |
147 | break; |
148 | default: | |
149 | break; | |
150 | } | |
151 | } | |
152 | ||
153 | static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev) | |
154 | { | |
517e7a15 MS |
155 | if (dev->clk_prepared) |
156 | clk_disable_unprepare(dev->clk); | |
157 | dev->clk_prepared = false; | |
c6aeb7de FM |
158 | } |
159 | ||
160 | static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, | |
161 | bool tx, bool rx) | |
162 | { | |
163 | int timeout = 1000; | |
164 | uint32_t syncval; | |
165 | uint32_t csreg; | |
166 | uint32_t i2s_active_state; | |
517e7a15 | 167 | bool clk_was_prepared; |
c6aeb7de FM |
168 | uint32_t off; |
169 | uint32_t clr; | |
170 | ||
171 | off = tx ? BCM2835_I2S_TXON : 0; | |
172 | off |= rx ? BCM2835_I2S_RXON : 0; | |
173 | ||
174 | clr = tx ? BCM2835_I2S_TXCLR : 0; | |
175 | clr |= rx ? BCM2835_I2S_RXCLR : 0; | |
176 | ||
177 | /* Backup the current state */ | |
178 | regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); | |
179 | i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON); | |
180 | ||
c6aeb7de | 181 | /* Start clock if not running */ |
517e7a15 MS |
182 | clk_was_prepared = dev->clk_prepared; |
183 | if (!clk_was_prepared) | |
184 | bcm2835_i2s_start_clock(dev); | |
c6aeb7de FM |
185 | |
186 | /* Stop I2S module */ | |
187 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0); | |
188 | ||
189 | /* | |
190 | * Clear the FIFOs | |
191 | * Requires at least 2 PCM clock cycles to take effect | |
192 | */ | |
193 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr); | |
194 | ||
195 | /* Wait for 2 PCM clock cycles */ | |
196 | ||
197 | /* | |
198 | * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back | |
199 | * FIXME: This does not seem to work for slave mode! | |
200 | */ | |
201 | regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval); | |
202 | syncval &= BCM2835_I2S_SYNC; | |
203 | ||
204 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, | |
205 | BCM2835_I2S_SYNC, ~syncval); | |
206 | ||
207 | /* Wait for the SYNC flag changing it's state */ | |
208 | while (--timeout) { | |
209 | regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); | |
210 | if ((csreg & BCM2835_I2S_SYNC) != syncval) | |
211 | break; | |
212 | } | |
213 | ||
214 | if (!timeout) | |
215 | dev_err(dev->dev, "I2S SYNC error!\n"); | |
216 | ||
217 | /* Stop clock if it was not running before */ | |
517e7a15 | 218 | if (!clk_was_prepared) |
c6aeb7de FM |
219 | bcm2835_i2s_stop_clock(dev); |
220 | ||
221 | /* Restore I2S state */ | |
222 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, | |
223 | BCM2835_I2S_RXON | BCM2835_I2S_TXON, i2s_active_state); | |
224 | } | |
225 | ||
226 | static int bcm2835_i2s_set_dai_fmt(struct snd_soc_dai *dai, | |
227 | unsigned int fmt) | |
228 | { | |
229 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
230 | dev->fmt = fmt; | |
231 | return 0; | |
232 | } | |
233 | ||
234 | static int bcm2835_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, | |
235 | unsigned int ratio) | |
236 | { | |
237 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
9448572d MR |
238 | |
239 | if (!ratio) { | |
240 | dev->tdm_slots = 0; | |
241 | return 0; | |
242 | } | |
243 | ||
244 | if (ratio > BCM2835_I2S_MAX_FRAME_LENGTH) | |
245 | return -EINVAL; | |
246 | ||
247 | dev->tdm_slots = 2; | |
248 | dev->rx_mask = 0x03; | |
249 | dev->tx_mask = 0x03; | |
250 | dev->slot_width = ratio / 2; | |
251 | dev->frame_length = ratio; | |
252 | ||
253 | return 0; | |
254 | } | |
255 | ||
256 | static int bcm2835_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai, | |
257 | unsigned int tx_mask, unsigned int rx_mask, | |
258 | int slots, int width) | |
259 | { | |
260 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
261 | ||
262 | if (slots) { | |
263 | if (slots < 0 || width < 0) | |
264 | return -EINVAL; | |
265 | ||
266 | /* Limit masks to available slots */ | |
267 | rx_mask &= GENMASK(slots - 1, 0); | |
268 | tx_mask &= GENMASK(slots - 1, 0); | |
269 | ||
270 | /* | |
271 | * The driver is limited to 2-channel setups. | |
272 | * Check that exactly 2 bits are set in the masks. | |
273 | */ | |
274 | if (hweight_long((unsigned long) rx_mask) != 2 | |
275 | || hweight_long((unsigned long) tx_mask) != 2) | |
276 | return -EINVAL; | |
277 | ||
278 | if (slots * width > BCM2835_I2S_MAX_FRAME_LENGTH) | |
279 | return -EINVAL; | |
280 | } | |
281 | ||
282 | dev->tdm_slots = slots; | |
283 | ||
284 | dev->rx_mask = rx_mask; | |
285 | dev->tx_mask = tx_mask; | |
286 | dev->slot_width = width; | |
287 | dev->frame_length = slots * width; | |
288 | ||
c6aeb7de FM |
289 | return 0; |
290 | } | |
291 | ||
9448572d MR |
292 | /* |
293 | * Convert logical slot number into physical slot number. | |
294 | * | |
295 | * If odd_offset is 0 sequential number is identical to logical number. | |
296 | * This is used for DSP modes with slot numbering 0 1 2 3 ... | |
297 | * | |
298 | * Otherwise odd_offset defines the physical offset for odd numbered | |
299 | * slots. This is used for I2S and left/right justified modes to | |
300 | * translate from logical slot numbers 0 1 2 3 ... into physical slot | |
301 | * numbers 0 2 ... 3 4 ... | |
302 | */ | |
303 | static int bcm2835_i2s_convert_slot(unsigned int slot, unsigned int odd_offset) | |
304 | { | |
305 | if (!odd_offset) | |
306 | return slot; | |
307 | ||
308 | if (slot & 1) | |
309 | return (slot >> 1) + odd_offset; | |
310 | ||
311 | return slot >> 1; | |
312 | } | |
313 | ||
314 | /* | |
315 | * Calculate channel position from mask and slot width. | |
316 | * | |
317 | * Mask must contain exactly 2 set bits. | |
318 | * Lowest set bit is channel 1 position, highest set bit channel 2. | |
319 | * The constant offset is added to both channel positions. | |
320 | * | |
321 | * If odd_offset is > 0 slot positions are translated to | |
322 | * I2S-style TDM slot numbering ( 0 2 ... 3 4 ...) with odd | |
323 | * logical slot numbers starting at physical slot odd_offset. | |
324 | */ | |
325 | static void bcm2835_i2s_calc_channel_pos( | |
326 | unsigned int *ch1_pos, unsigned int *ch2_pos, | |
327 | unsigned int mask, unsigned int width, | |
328 | unsigned int bit_offset, unsigned int odd_offset) | |
329 | { | |
330 | *ch1_pos = bcm2835_i2s_convert_slot((ffs(mask) - 1), odd_offset) | |
331 | * width + bit_offset; | |
332 | *ch2_pos = bcm2835_i2s_convert_slot((fls(mask) - 1), odd_offset) | |
333 | * width + bit_offset; | |
334 | } | |
335 | ||
c6aeb7de FM |
336 | static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, |
337 | struct snd_pcm_hw_params *params, | |
338 | struct snd_soc_dai *dai) | |
339 | { | |
340 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
9448572d MR |
341 | unsigned int data_length, data_delay, framesync_length; |
342 | unsigned int slots, slot_width, odd_slot_offset; | |
343 | int frame_length, bclk_rate; | |
344 | unsigned int rx_mask, tx_mask; | |
345 | unsigned int rx_ch1_pos, rx_ch2_pos, tx_ch1_pos, tx_ch2_pos; | |
346 | unsigned int mode, format; | |
abd4f0e1 MR |
347 | bool bit_clock_master = false; |
348 | bool frame_sync_master = false; | |
349 | bool frame_start_falling_edge = false; | |
c6aeb7de | 350 | uint32_t csreg; |
9448572d | 351 | int ret = 0; |
c6aeb7de FM |
352 | |
353 | /* | |
354 | * If a stream is already enabled, | |
355 | * the registers are already set properly. | |
356 | */ | |
357 | regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); | |
358 | ||
359 | if (csreg & (BCM2835_I2S_TXON | BCM2835_I2S_RXON)) | |
360 | return 0; | |
361 | ||
9448572d MR |
362 | data_length = params_width(params); |
363 | data_delay = 0; | |
364 | odd_slot_offset = 0; | |
365 | mode = 0; | |
366 | ||
367 | if (dev->tdm_slots) { | |
368 | slots = dev->tdm_slots; | |
369 | slot_width = dev->slot_width; | |
370 | frame_length = dev->frame_length; | |
371 | rx_mask = dev->rx_mask; | |
372 | tx_mask = dev->tx_mask; | |
373 | bclk_rate = dev->frame_length * params_rate(params); | |
374 | } else { | |
375 | slots = 2; | |
376 | slot_width = params_width(params); | |
377 | rx_mask = 0x03; | |
378 | tx_mask = 0x03; | |
379 | ||
380 | frame_length = snd_soc_params_to_frame_size(params); | |
381 | if (frame_length < 0) | |
382 | return frame_length; | |
383 | ||
384 | bclk_rate = snd_soc_params_to_bclk(params); | |
385 | if (bclk_rate < 0) | |
386 | return bclk_rate; | |
c6aeb7de FM |
387 | } |
388 | ||
9448572d MR |
389 | /* Check if data fits into slots */ |
390 | if (data_length > slot_width) | |
391 | return -EINVAL; | |
c6aeb7de | 392 | |
abd4f0e1 | 393 | /* Check if CPU is bit clock master */ |
60507fe1 MR |
394 | switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
395 | case SND_SOC_DAIFMT_CBS_CFS: | |
396 | case SND_SOC_DAIFMT_CBS_CFM: | |
abd4f0e1 MR |
397 | bit_clock_master = true; |
398 | break; | |
399 | case SND_SOC_DAIFMT_CBM_CFS: | |
400 | case SND_SOC_DAIFMT_CBM_CFM: | |
401 | bit_clock_master = false; | |
60507fe1 MR |
402 | break; |
403 | default: | |
abd4f0e1 MR |
404 | return -EINVAL; |
405 | } | |
406 | ||
407 | /* Check if CPU is frame sync master */ | |
408 | switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { | |
409 | case SND_SOC_DAIFMT_CBS_CFS: | |
410 | case SND_SOC_DAIFMT_CBM_CFS: | |
411 | frame_sync_master = true; | |
412 | break; | |
413 | case SND_SOC_DAIFMT_CBS_CFM: | |
414 | case SND_SOC_DAIFMT_CBM_CFM: | |
415 | frame_sync_master = false; | |
60507fe1 | 416 | break; |
abd4f0e1 MR |
417 | default: |
418 | return -EINVAL; | |
419 | } | |
420 | ||
421 | /* Clock should only be set up here if CPU is clock master */ | |
422 | if (bit_clock_master) { | |
423 | ret = clk_set_rate(dev->clk, bclk_rate); | |
424 | if (ret) | |
425 | return ret; | |
60507fe1 | 426 | } |
c6aeb7de FM |
427 | |
428 | /* Setup the frame format */ | |
429 | format = BCM2835_I2S_CHEN; | |
430 | ||
a34b027d | 431 | if (data_length >= 24) |
c6aeb7de FM |
432 | format |= BCM2835_I2S_CHWEX; |
433 | ||
434 | format |= BCM2835_I2S_CHWID((data_length-8)&0xf); | |
435 | ||
9448572d MR |
436 | /* CH2 format is the same as for CH1 */ |
437 | format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format); | |
438 | ||
c6aeb7de FM |
439 | switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
440 | case SND_SOC_DAIFMT_I2S: | |
9448572d MR |
441 | /* I2S mode needs an even number of slots */ |
442 | if (slots & 1) | |
443 | return -EINVAL; | |
444 | ||
445 | /* | |
446 | * Use I2S-style logical slot numbering: even slots | |
447 | * are in first half of frame, odd slots in second half. | |
448 | */ | |
449 | odd_slot_offset = slots >> 1; | |
450 | ||
451 | /* MSB starts one cycle after frame start */ | |
c6aeb7de | 452 | data_delay = 1; |
9448572d MR |
453 | |
454 | /* Setup frame sync signal for 50% duty cycle */ | |
455 | framesync_length = frame_length / 2; | |
abd4f0e1 MR |
456 | frame_start_falling_edge = true; |
457 | break; | |
458 | case SND_SOC_DAIFMT_LEFT_J: | |
459 | if (slots & 1) | |
460 | return -EINVAL; | |
461 | ||
462 | odd_slot_offset = slots >> 1; | |
463 | data_delay = 0; | |
464 | framesync_length = frame_length / 2; | |
465 | frame_start_falling_edge = false; | |
466 | break; | |
467 | case SND_SOC_DAIFMT_RIGHT_J: | |
468 | if (slots & 1) | |
469 | return -EINVAL; | |
470 | ||
471 | /* Odd frame lengths aren't supported */ | |
472 | if (frame_length & 1) | |
473 | return -EINVAL; | |
474 | ||
475 | odd_slot_offset = slots >> 1; | |
476 | data_delay = slot_width - data_length; | |
477 | framesync_length = frame_length / 2; | |
478 | frame_start_falling_edge = false; | |
479 | break; | |
480 | case SND_SOC_DAIFMT_DSP_A: | |
481 | data_delay = 1; | |
482 | framesync_length = 1; | |
483 | frame_start_falling_edge = false; | |
484 | break; | |
485 | case SND_SOC_DAIFMT_DSP_B: | |
486 | data_delay = 0; | |
487 | framesync_length = 1; | |
488 | frame_start_falling_edge = false; | |
c6aeb7de FM |
489 | break; |
490 | default: | |
c6aeb7de FM |
491 | return -EINVAL; |
492 | } | |
493 | ||
9448572d MR |
494 | bcm2835_i2s_calc_channel_pos(&rx_ch1_pos, &rx_ch2_pos, |
495 | rx_mask, slot_width, data_delay, odd_slot_offset); | |
496 | bcm2835_i2s_calc_channel_pos(&tx_ch1_pos, &tx_ch2_pos, | |
497 | tx_mask, slot_width, data_delay, odd_slot_offset); | |
c6aeb7de | 498 | |
abd4f0e1 MR |
499 | /* |
500 | * Transmitting data immediately after frame start, eg | |
501 | * in left-justified or DSP mode A, only works stable | |
502 | * if bcm2835 is the frame clock master. | |
503 | */ | |
504 | if ((!rx_ch1_pos || !tx_ch1_pos) && !frame_sync_master) | |
505 | dev_warn(dev->dev, | |
506 | "Unstable slave config detected, L/R may be swapped"); | |
507 | ||
c6aeb7de FM |
508 | /* |
509 | * Set format for both streams. | |
510 | * We cannot set another frame length | |
511 | * (and therefore word length) anyway, | |
512 | * so the format will be the same. | |
513 | */ | |
9448572d MR |
514 | regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, |
515 | format | |
516 | | BCM2835_I2S_CH1_POS(rx_ch1_pos) | |
517 | | BCM2835_I2S_CH2_POS(rx_ch2_pos)); | |
518 | regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, | |
519 | format | |
520 | | BCM2835_I2S_CH1_POS(tx_ch1_pos) | |
521 | | BCM2835_I2S_CH2_POS(tx_ch2_pos)); | |
c6aeb7de FM |
522 | |
523 | /* Setup the I2S mode */ | |
c6aeb7de FM |
524 | |
525 | if (data_length <= 16) { | |
526 | /* | |
527 | * Use frame packed mode (2 channels per 32 bit word) | |
528 | * We cannot set another frame length in the second stream | |
529 | * (and therefore word length) anyway, | |
530 | * so the format will be the same. | |
531 | */ | |
532 | mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP; | |
533 | } | |
534 | ||
9448572d MR |
535 | mode |= BCM2835_I2S_FLEN(frame_length - 1); |
536 | mode |= BCM2835_I2S_FSLEN(framesync_length); | |
c6aeb7de | 537 | |
abd4f0e1 MR |
538 | /* CLKM selects bcm2835 clock slave mode */ |
539 | if (!bit_clock_master) | |
c6aeb7de | 540 | mode |= BCM2835_I2S_CLKM; |
abd4f0e1 MR |
541 | |
542 | /* FSM selects bcm2835 frame sync slave mode */ | |
543 | if (!frame_sync_master) | |
c6aeb7de | 544 | mode |= BCM2835_I2S_FSM; |
abd4f0e1 MR |
545 | |
546 | /* CLKI selects normal clocking mode, sampling on rising edge */ | |
547 | switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { | |
548 | case SND_SOC_DAIFMT_NB_NF: | |
549 | case SND_SOC_DAIFMT_NB_IF: | |
550 | mode |= BCM2835_I2S_CLKI; | |
c6aeb7de | 551 | break; |
abd4f0e1 MR |
552 | case SND_SOC_DAIFMT_IB_NF: |
553 | case SND_SOC_DAIFMT_IB_IF: | |
c6aeb7de FM |
554 | break; |
555 | default: | |
c6aeb7de FM |
556 | return -EINVAL; |
557 | } | |
558 | ||
abd4f0e1 | 559 | /* FSI selects frame start on falling edge */ |
c6aeb7de FM |
560 | switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { |
561 | case SND_SOC_DAIFMT_NB_NF: | |
abd4f0e1 MR |
562 | case SND_SOC_DAIFMT_IB_NF: |
563 | if (frame_start_falling_edge) | |
564 | mode |= BCM2835_I2S_FSI; | |
c6aeb7de FM |
565 | break; |
566 | case SND_SOC_DAIFMT_NB_IF: | |
abd4f0e1 MR |
567 | case SND_SOC_DAIFMT_IB_IF: |
568 | if (!frame_start_falling_edge) | |
569 | mode |= BCM2835_I2S_FSI; | |
c6aeb7de FM |
570 | break; |
571 | default: | |
572 | return -EINVAL; | |
573 | } | |
574 | ||
575 | regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode); | |
576 | ||
577 | /* Setup the DMA parameters */ | |
578 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, | |
579 | BCM2835_I2S_RXTHR(1) | |
580 | | BCM2835_I2S_TXTHR(1) | |
581 | | BCM2835_I2S_DMAEN, 0xffffffff); | |
582 | ||
583 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, | |
584 | BCM2835_I2S_TX_PANIC(0x10) | |
585 | | BCM2835_I2S_RX_PANIC(0x30) | |
586 | | BCM2835_I2S_TX(0x30) | |
587 | | BCM2835_I2S_RX(0x20), 0xffffffff); | |
588 | ||
589 | /* Clear FIFOs */ | |
590 | bcm2835_i2s_clear_fifos(dev, true, true); | |
591 | ||
9448572d MR |
592 | dev_dbg(dev->dev, |
593 | "slots: %d width: %d rx mask: 0x%02x tx_mask: 0x%02x\n", | |
594 | slots, slot_width, rx_mask, tx_mask); | |
595 | ||
596 | dev_dbg(dev->dev, "frame len: %d sync len: %d data len: %d\n", | |
597 | frame_length, framesync_length, data_length); | |
598 | ||
599 | dev_dbg(dev->dev, "rx pos: %d,%d tx pos: %d,%d\n", | |
600 | rx_ch1_pos, rx_ch2_pos, tx_ch1_pos, tx_ch2_pos); | |
601 | ||
602 | dev_dbg(dev->dev, "sampling rate: %d bclk rate: %d\n", | |
603 | params_rate(params), bclk_rate); | |
604 | ||
abd4f0e1 MR |
605 | dev_dbg(dev->dev, "CLKM: %d CLKI: %d FSM: %d FSI: %d frame start: %s edge\n", |
606 | !!(mode & BCM2835_I2S_CLKM), | |
607 | !!(mode & BCM2835_I2S_CLKI), | |
608 | !!(mode & BCM2835_I2S_FSM), | |
609 | !!(mode & BCM2835_I2S_FSI), | |
610 | (mode & BCM2835_I2S_FSI) ? "falling" : "rising"); | |
611 | ||
9448572d | 612 | return ret; |
c6aeb7de FM |
613 | } |
614 | ||
615 | static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream, | |
616 | struct snd_soc_dai *dai) | |
617 | { | |
618 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
619 | uint32_t cs_reg; | |
620 | ||
621 | bcm2835_i2s_start_clock(dev); | |
622 | ||
623 | /* | |
624 | * Clear both FIFOs if the one that should be started | |
625 | * is not empty at the moment. This should only happen | |
626 | * after overrun. Otherwise, hw_params would have cleared | |
627 | * the FIFO. | |
628 | */ | |
629 | regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &cs_reg); | |
630 | ||
631 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK | |
632 | && !(cs_reg & BCM2835_I2S_TXE)) | |
633 | bcm2835_i2s_clear_fifos(dev, true, false); | |
634 | else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE | |
635 | && (cs_reg & BCM2835_I2S_RXD)) | |
636 | bcm2835_i2s_clear_fifos(dev, false, true); | |
637 | ||
638 | return 0; | |
639 | } | |
640 | ||
641 | static void bcm2835_i2s_stop(struct bcm2835_i2s_dev *dev, | |
642 | struct snd_pcm_substream *substream, | |
643 | struct snd_soc_dai *dai) | |
644 | { | |
645 | uint32_t mask; | |
646 | ||
647 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | |
648 | mask = BCM2835_I2S_RXON; | |
649 | else | |
650 | mask = BCM2835_I2S_TXON; | |
651 | ||
652 | regmap_update_bits(dev->i2s_regmap, | |
653 | BCM2835_I2S_CS_A_REG, mask, 0); | |
654 | ||
655 | /* Stop also the clock when not SND_SOC_DAIFMT_CONT */ | |
656 | if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT)) | |
657 | bcm2835_i2s_stop_clock(dev); | |
658 | } | |
659 | ||
660 | static int bcm2835_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |
661 | struct snd_soc_dai *dai) | |
662 | { | |
663 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
664 | uint32_t mask; | |
665 | ||
666 | switch (cmd) { | |
667 | case SNDRV_PCM_TRIGGER_START: | |
668 | case SNDRV_PCM_TRIGGER_RESUME: | |
669 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | |
670 | bcm2835_i2s_start_clock(dev); | |
671 | ||
672 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | |
673 | mask = BCM2835_I2S_RXON; | |
674 | else | |
675 | mask = BCM2835_I2S_TXON; | |
676 | ||
677 | regmap_update_bits(dev->i2s_regmap, | |
678 | BCM2835_I2S_CS_A_REG, mask, mask); | |
679 | break; | |
680 | ||
681 | case SNDRV_PCM_TRIGGER_STOP: | |
682 | case SNDRV_PCM_TRIGGER_SUSPEND: | |
683 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | |
684 | bcm2835_i2s_stop(dev, substream, dai); | |
685 | break; | |
686 | default: | |
687 | return -EINVAL; | |
688 | } | |
689 | ||
690 | return 0; | |
691 | } | |
692 | ||
693 | static int bcm2835_i2s_startup(struct snd_pcm_substream *substream, | |
694 | struct snd_soc_dai *dai) | |
695 | { | |
696 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
697 | ||
698 | if (dai->active) | |
699 | return 0; | |
700 | ||
701 | /* Should this still be running stop it */ | |
702 | bcm2835_i2s_stop_clock(dev); | |
703 | ||
704 | /* Enable PCM block */ | |
705 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, | |
706 | BCM2835_I2S_EN, BCM2835_I2S_EN); | |
707 | ||
708 | /* | |
709 | * Disable STBY. | |
710 | * Requires at least 4 PCM clock cycles to take effect. | |
711 | */ | |
712 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, | |
713 | BCM2835_I2S_STBY, BCM2835_I2S_STBY); | |
714 | ||
715 | return 0; | |
716 | } | |
717 | ||
718 | static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream, | |
719 | struct snd_soc_dai *dai) | |
720 | { | |
721 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
722 | ||
723 | bcm2835_i2s_stop(dev, substream, dai); | |
724 | ||
725 | /* If both streams are stopped, disable module and clock */ | |
726 | if (dai->active) | |
727 | return; | |
728 | ||
729 | /* Disable the module */ | |
730 | regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, | |
731 | BCM2835_I2S_EN, 0); | |
732 | ||
733 | /* | |
734 | * Stopping clock is necessary, because stop does | |
735 | * not stop the clock when SND_SOC_DAIFMT_CONT | |
736 | */ | |
737 | bcm2835_i2s_stop_clock(dev); | |
738 | } | |
739 | ||
740 | static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { | |
741 | .startup = bcm2835_i2s_startup, | |
742 | .shutdown = bcm2835_i2s_shutdown, | |
743 | .prepare = bcm2835_i2s_prepare, | |
744 | .trigger = bcm2835_i2s_trigger, | |
745 | .hw_params = bcm2835_i2s_hw_params, | |
746 | .set_fmt = bcm2835_i2s_set_dai_fmt, | |
517e7a15 | 747 | .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio, |
9448572d | 748 | .set_tdm_slot = bcm2835_i2s_set_dai_tdm_slot, |
c6aeb7de FM |
749 | }; |
750 | ||
751 | static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai) | |
752 | { | |
753 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | |
754 | ||
755 | snd_soc_dai_init_dma_data(dai, | |
756 | &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK], | |
757 | &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]); | |
758 | ||
759 | return 0; | |
760 | } | |
761 | ||
762 | static struct snd_soc_dai_driver bcm2835_i2s_dai = { | |
763 | .name = "bcm2835-i2s", | |
764 | .probe = bcm2835_i2s_dai_probe, | |
765 | .playback = { | |
766 | .channels_min = 2, | |
767 | .channels_max = 2, | |
675c0ee5 MR |
768 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
769 | .rate_min = 8000, | |
770 | .rate_max = 384000, | |
c6aeb7de | 771 | .formats = SNDRV_PCM_FMTBIT_S16_LE |
a34b027d | 772 | | SNDRV_PCM_FMTBIT_S24_LE |
c6aeb7de FM |
773 | | SNDRV_PCM_FMTBIT_S32_LE |
774 | }, | |
775 | .capture = { | |
776 | .channels_min = 2, | |
777 | .channels_max = 2, | |
675c0ee5 MR |
778 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
779 | .rate_min = 8000, | |
780 | .rate_max = 384000, | |
c6aeb7de | 781 | .formats = SNDRV_PCM_FMTBIT_S16_LE |
a34b027d | 782 | | SNDRV_PCM_FMTBIT_S24_LE |
c6aeb7de FM |
783 | | SNDRV_PCM_FMTBIT_S32_LE |
784 | }, | |
785 | .ops = &bcm2835_i2s_dai_ops, | |
3d2b3c70 MR |
786 | .symmetric_rates = 1, |
787 | .symmetric_samplebits = 1, | |
c6aeb7de FM |
788 | }; |
789 | ||
790 | static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg) | |
791 | { | |
792 | switch (reg) { | |
793 | case BCM2835_I2S_CS_A_REG: | |
794 | case BCM2835_I2S_FIFO_A_REG: | |
795 | case BCM2835_I2S_INTSTC_A_REG: | |
796 | case BCM2835_I2S_GRAY_REG: | |
797 | return true; | |
798 | default: | |
799 | return false; | |
800 | }; | |
801 | } | |
802 | ||
803 | static bool bcm2835_i2s_precious_reg(struct device *dev, unsigned int reg) | |
804 | { | |
805 | switch (reg) { | |
806 | case BCM2835_I2S_FIFO_A_REG: | |
807 | return true; | |
808 | default: | |
809 | return false; | |
810 | }; | |
811 | } | |
812 | ||
517e7a15 MS |
813 | static const struct regmap_config bcm2835_regmap_config = { |
814 | .reg_bits = 32, | |
815 | .reg_stride = 4, | |
816 | .val_bits = 32, | |
817 | .max_register = BCM2835_I2S_GRAY_REG, | |
818 | .precious_reg = bcm2835_i2s_precious_reg, | |
819 | .volatile_reg = bcm2835_i2s_volatile_reg, | |
820 | .cache_type = REGCACHE_RBTREE, | |
c6aeb7de FM |
821 | }; |
822 | ||
823 | static const struct snd_soc_component_driver bcm2835_i2s_component = { | |
824 | .name = "bcm2835-i2s-comp", | |
825 | }; | |
826 | ||
827 | static int bcm2835_i2s_probe(struct platform_device *pdev) | |
828 | { | |
829 | struct bcm2835_i2s_dev *dev; | |
c6aeb7de | 830 | int ret; |
517e7a15 MS |
831 | struct resource *mem; |
832 | void __iomem *base; | |
833 | const __be32 *addr; | |
834 | dma_addr_t dma_base; | |
c6aeb7de FM |
835 | |
836 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), | |
837 | GFP_KERNEL); | |
838 | if (!dev) | |
839 | return -ENOMEM; | |
840 | ||
517e7a15 MS |
841 | /* get the clock */ |
842 | dev->clk_prepared = false; | |
843 | dev->clk = devm_clk_get(&pdev->dev, NULL); | |
844 | if (IS_ERR(dev->clk)) { | |
845 | dev_err(&pdev->dev, "could not get clk: %ld\n", | |
846 | PTR_ERR(dev->clk)); | |
847 | return PTR_ERR(dev->clk); | |
848 | } | |
849 | ||
850 | /* Request ioarea */ | |
851 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
852 | base = devm_ioremap_resource(&pdev->dev, mem); | |
853 | if (IS_ERR(base)) | |
854 | return PTR_ERR(base); | |
855 | ||
856 | dev->i2s_regmap = devm_regmap_init_mmio(&pdev->dev, base, | |
857 | &bcm2835_regmap_config); | |
858 | if (IS_ERR(dev->i2s_regmap)) | |
859 | return PTR_ERR(dev->i2s_regmap); | |
860 | ||
861 | /* Set the DMA address - we have to parse DT ourselves */ | |
862 | addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); | |
863 | if (!addr) { | |
864 | dev_err(&pdev->dev, "could not get DMA-register address\n"); | |
865 | return -EINVAL; | |
866 | } | |
867 | dma_base = be32_to_cpup(addr); | |
c6aeb7de | 868 | |
c6aeb7de | 869 | dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = |
517e7a15 | 870 | dma_base + BCM2835_I2S_FIFO_A_REG; |
c6aeb7de FM |
871 | |
872 | dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = | |
517e7a15 | 873 | dma_base + BCM2835_I2S_FIFO_A_REG; |
c6aeb7de FM |
874 | |
875 | /* Set the bus width */ | |
876 | dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = | |
877 | DMA_SLAVE_BUSWIDTH_4_BYTES; | |
878 | dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = | |
879 | DMA_SLAVE_BUSWIDTH_4_BYTES; | |
880 | ||
881 | /* Set burst */ | |
882 | dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; | |
883 | dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; | |
884 | ||
beff053c MR |
885 | /* |
886 | * Set the PACK flag to enable S16_LE support (2 S16_LE values | |
887 | * packed into 32-bit transfers). | |
888 | */ | |
889 | dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags = | |
890 | SND_DMAENGINE_PCM_DAI_FLAG_PACK; | |
891 | dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags = | |
892 | SND_DMAENGINE_PCM_DAI_FLAG_PACK; | |
893 | ||
c6aeb7de FM |
894 | /* Store the pdev */ |
895 | dev->dev = &pdev->dev; | |
896 | dev_set_drvdata(&pdev->dev, dev); | |
897 | ||
898 | ret = devm_snd_soc_register_component(&pdev->dev, | |
899 | &bcm2835_i2s_component, &bcm2835_i2s_dai, 1); | |
900 | if (ret) { | |
901 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | |
902 | return ret; | |
903 | } | |
904 | ||
3990c516 | 905 | ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); |
c6aeb7de FM |
906 | if (ret) { |
907 | dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); | |
908 | return ret; | |
909 | } | |
910 | ||
911 | return 0; | |
912 | } | |
913 | ||
914 | static const struct of_device_id bcm2835_i2s_of_match[] = { | |
915 | { .compatible = "brcm,bcm2835-i2s", }, | |
916 | {}, | |
917 | }; | |
918 | ||
054bc835 LB |
919 | MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); |
920 | ||
c6aeb7de FM |
921 | static struct platform_driver bcm2835_i2s_driver = { |
922 | .probe = bcm2835_i2s_probe, | |
c6aeb7de FM |
923 | .driver = { |
924 | .name = "bcm2835-i2s", | |
c6aeb7de FM |
925 | .of_match_table = bcm2835_i2s_of_match, |
926 | }, | |
927 | }; | |
928 | ||
929 | module_platform_driver(bcm2835_i2s_driver); | |
930 | ||
931 | MODULE_ALIAS("platform:bcm2835-i2s"); | |
932 | MODULE_DESCRIPTION("BCM2835 I2S interface"); | |
933 | MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>"); | |
934 | MODULE_LICENSE("GPL v2"); |