~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/bcm/bcm2835-i2s.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php