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

TOMOYO Linux Cross Reference
Linux/sound/soc/ti/davinci-i2s.c

Version: ~ [ linux-5.19-rc8 ] ~ [ linux-5.18.14 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.57 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.133 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.207 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.253 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.289 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.324 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ 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 (McBSP) Audio Layer for TI DAVINCI processor
  4  *
  5  * Author:      Vladimir Barinov, <vbarinov@embeddedalley.com>
  6  * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
  7  *
  8  * DT support   (c) 2016 Petr Kulhavy, Barix AG <petr@barix.com>
  9  *              based on davinci-mcasp.c DT support
 10  *
 11  * TODO:
 12  * on DA850 implement HW FIFOs instead of DMA into DXR and DRR registers
 13  */
 14 
 15 #include <linux/init.h>
 16 #include <linux/module.h>
 17 #include <linux/device.h>
 18 #include <linux/slab.h>
 19 #include <linux/delay.h>
 20 #include <linux/io.h>
 21 #include <linux/clk.h>
 22 #include <linux/platform_data/davinci_asp.h>
 23 
 24 #include <sound/core.h>
 25 #include <sound/pcm.h>
 26 #include <sound/pcm_params.h>
 27 #include <sound/initval.h>
 28 #include <sound/soc.h>
 29 #include <sound/dmaengine_pcm.h>
 30 
 31 #include "edma-pcm.h"
 32 #include "davinci-i2s.h"
 33 
 34 #define DRV_NAME "davinci-i2s"
 35 
 36 /*
 37  * NOTE:  terminology here is confusing.
 38  *
 39  *  - This driver supports the "Audio Serial Port" (ASP),
 40  *    found on dm6446, dm355, and other DaVinci chips.
 41  *
 42  *  - But it labels it a "Multi-channel Buffered Serial Port"
 43  *    (McBSP) as on older chips like the dm642 ... which was
 44  *    backward-compatible, possibly explaining that confusion.
 45  *
 46  *  - OMAP chips have a controller called McBSP, which is
 47  *    incompatible with the DaVinci flavor of McBSP.
 48  *
 49  *  - Newer DaVinci chips have a controller called McASP,
 50  *    incompatible with ASP and with either McBSP.
 51  *
 52  * In short:  this uses ASP to implement I2S, not McBSP.
 53  * And it won't be the only DaVinci implemention of I2S.
 54  */
 55 #define DAVINCI_MCBSP_DRR_REG   0x00
 56 #define DAVINCI_MCBSP_DXR_REG   0x04
 57 #define DAVINCI_MCBSP_SPCR_REG  0x08
 58 #define DAVINCI_MCBSP_RCR_REG   0x0c
 59 #define DAVINCI_MCBSP_XCR_REG   0x10
 60 #define DAVINCI_MCBSP_SRGR_REG  0x14
 61 #define DAVINCI_MCBSP_PCR_REG   0x24
 62 
 63 #define DAVINCI_MCBSP_SPCR_RRST         (1 << 0)
 64 #define DAVINCI_MCBSP_SPCR_RINTM(v)     ((v) << 4)
 65 #define DAVINCI_MCBSP_SPCR_XRST         (1 << 16)
 66 #define DAVINCI_MCBSP_SPCR_XINTM(v)     ((v) << 20)
 67 #define DAVINCI_MCBSP_SPCR_GRST         (1 << 22)
 68 #define DAVINCI_MCBSP_SPCR_FRST         (1 << 23)
 69 #define DAVINCI_MCBSP_SPCR_FREE         (1 << 25)
 70 
 71 #define DAVINCI_MCBSP_RCR_RWDLEN1(v)    ((v) << 5)
 72 #define DAVINCI_MCBSP_RCR_RFRLEN1(v)    ((v) << 8)
 73 #define DAVINCI_MCBSP_RCR_RDATDLY(v)    ((v) << 16)
 74 #define DAVINCI_MCBSP_RCR_RFIG          (1 << 18)
 75 #define DAVINCI_MCBSP_RCR_RWDLEN2(v)    ((v) << 21)
 76 #define DAVINCI_MCBSP_RCR_RFRLEN2(v)    ((v) << 24)
 77 #define DAVINCI_MCBSP_RCR_RPHASE        BIT(31)
 78 
 79 #define DAVINCI_MCBSP_XCR_XWDLEN1(v)    ((v) << 5)
 80 #define DAVINCI_MCBSP_XCR_XFRLEN1(v)    ((v) << 8)
 81 #define DAVINCI_MCBSP_XCR_XDATDLY(v)    ((v) << 16)
 82 #define DAVINCI_MCBSP_XCR_XFIG          (1 << 18)
 83 #define DAVINCI_MCBSP_XCR_XWDLEN2(v)    ((v) << 21)
 84 #define DAVINCI_MCBSP_XCR_XFRLEN2(v)    ((v) << 24)
 85 #define DAVINCI_MCBSP_XCR_XPHASE        BIT(31)
 86 
 87 #define DAVINCI_MCBSP_SRGR_FWID(v)      ((v) << 8)
 88 #define DAVINCI_MCBSP_SRGR_FPER(v)      ((v) << 16)
 89 #define DAVINCI_MCBSP_SRGR_FSGM         (1 << 28)
 90 #define DAVINCI_MCBSP_SRGR_CLKSM        BIT(29)
 91 
 92 #define DAVINCI_MCBSP_PCR_CLKRP         (1 << 0)
 93 #define DAVINCI_MCBSP_PCR_CLKXP         (1 << 1)
 94 #define DAVINCI_MCBSP_PCR_FSRP          (1 << 2)
 95 #define DAVINCI_MCBSP_PCR_FSXP          (1 << 3)
 96 #define DAVINCI_MCBSP_PCR_SCLKME        (1 << 7)
 97 #define DAVINCI_MCBSP_PCR_CLKRM         (1 << 8)
 98 #define DAVINCI_MCBSP_PCR_CLKXM         (1 << 9)
 99 #define DAVINCI_MCBSP_PCR_FSRM          (1 << 10)
100 #define DAVINCI_MCBSP_PCR_FSXM          (1 << 11)
101 
102 enum {
103         DAVINCI_MCBSP_WORD_8 = 0,
104         DAVINCI_MCBSP_WORD_12,
105         DAVINCI_MCBSP_WORD_16,
106         DAVINCI_MCBSP_WORD_20,
107         DAVINCI_MCBSP_WORD_24,
108         DAVINCI_MCBSP_WORD_32,
109 };
110 
111 static const unsigned char data_type[SNDRV_PCM_FORMAT_S32_LE + 1] = {
112         [SNDRV_PCM_FORMAT_S8]           = 1,
113         [SNDRV_PCM_FORMAT_S16_LE]       = 2,
114         [SNDRV_PCM_FORMAT_S32_LE]       = 4,
115 };
116 
117 static const unsigned char asp_word_length[SNDRV_PCM_FORMAT_S32_LE + 1] = {
118         [SNDRV_PCM_FORMAT_S8]           = DAVINCI_MCBSP_WORD_8,
119         [SNDRV_PCM_FORMAT_S16_LE]       = DAVINCI_MCBSP_WORD_16,
120         [SNDRV_PCM_FORMAT_S32_LE]       = DAVINCI_MCBSP_WORD_32,
121 };
122 
123 static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
124         [SNDRV_PCM_FORMAT_S8]           = SNDRV_PCM_FORMAT_S16_LE,
125         [SNDRV_PCM_FORMAT_S16_LE]       = SNDRV_PCM_FORMAT_S32_LE,
126 };
127 
128 struct davinci_mcbsp_dev {
129         struct device *dev;
130         struct snd_dmaengine_dai_dma_data dma_data[2];
131         int dma_request[2];
132         void __iomem                    *base;
133 #define MOD_DSP_A       0
134 #define MOD_DSP_B       1
135         int                             mode;
136         u32                             pcr;
137         struct clk                      *clk;
138         /*
139          * Combining both channels into 1 element will at least double the
140          * amount of time between servicing the dma channel, increase
141          * effiency, and reduce the chance of overrun/underrun. But,
142          * it will result in the left & right channels being swapped.
143          *
144          * If relabeling the left and right channels is not possible,
145          * you may want to let the codec know to swap them back.
146          *
147          * It may allow x10 the amount of time to service dma requests,
148          * if the codec is master and is using an unnecessarily fast bit clock
149          * (ie. tlvaic23b), independent of the sample rate. So, having an
150          * entire frame at once means it can be serviced at the sample rate
151          * instead of the bit clock rate.
152          *
153          * In the now unlikely case that an underrun still
154          * occurs, both the left and right samples will be repeated
155          * so that no pops are heard, and the left and right channels
156          * won't end up being swapped because of the underrun.
157          */
158         unsigned enable_channel_combine:1;
159 
160         unsigned int fmt;
161         int clk_div;
162         int clk_input_pin;
163         bool i2s_accurate_sck;
164 };
165 
166 static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
167                                            int reg, u32 val)
168 {
169         __raw_writel(val, dev->base + reg);
170 }
171 
172 static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
173 {
174         return __raw_readl(dev->base + reg);
175 }
176 
177 static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
178 {
179         u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
180         /* The clock needs to toggle to complete reset.
181          * So, fake it by toggling the clk polarity.
182          */
183         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
184         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
185 }
186 
187 static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
188                 struct snd_pcm_substream *substream)
189 {
190         int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
191         u32 spcr;
192         u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
193 
194         /* Enable transmitter or receiver */
195         spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
196         spcr |= mask;
197 
198         if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) {
199                 /* Start frame sync */
200                 spcr |= DAVINCI_MCBSP_SPCR_FRST;
201         }
202         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
203 }
204 
205 static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
206 {
207         u32 spcr;
208 
209         /* Reset transmitter/receiver and sample rate/frame sync generators */
210         spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
211         spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
212         spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST;
213         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
214         toggle_clock(dev, playback);
215 }
216 
217 #define DEFAULT_BITPERSAMPLE    16
218 
219 static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
220                                    unsigned int fmt)
221 {
222         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
223         unsigned int pcr;
224         unsigned int srgr;
225         bool inv_fs = false;
226         /* Attention srgr is updated by hw_params! */
227         srgr = DAVINCI_MCBSP_SRGR_FSGM |
228                 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
229                 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
230 
231         dev->fmt = fmt;
232         /* set master/slave audio interface */
233         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
234         case SND_SOC_DAIFMT_CBS_CFS:
235                 /* cpu is master */
236                 pcr = DAVINCI_MCBSP_PCR_FSXM |
237                         DAVINCI_MCBSP_PCR_FSRM |
238                         DAVINCI_MCBSP_PCR_CLKXM |
239                         DAVINCI_MCBSP_PCR_CLKRM;
240                 break;
241         case SND_SOC_DAIFMT_CBM_CFS:
242                 pcr = DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_FSXM;
243                 /*
244                  * Selection of the clock input pin that is the
245                  * input for the Sample Rate Generator.
246                  * McBSP FSR and FSX are driven by the Sample Rate
247                  * Generator.
248                  */
249                 switch (dev->clk_input_pin) {
250                 case MCBSP_CLKS:
251                         pcr |= DAVINCI_MCBSP_PCR_CLKXM |
252                                 DAVINCI_MCBSP_PCR_CLKRM;
253                         break;
254                 case MCBSP_CLKR:
255                         pcr |= DAVINCI_MCBSP_PCR_SCLKME;
256                         break;
257                 default:
258                         dev_err(dev->dev, "bad clk_input_pin\n");
259                         return -EINVAL;
260                 }
261 
262                 break;
263         case SND_SOC_DAIFMT_CBM_CFM:
264                 /* codec is master */
265                 pcr = 0;
266                 break;
267         default:
268                 printk(KERN_ERR "%s:bad master\n", __func__);
269                 return -EINVAL;
270         }
271 
272         /* interface format */
273         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
274         case SND_SOC_DAIFMT_I2S:
275                 /* Davinci doesn't support TRUE I2S, but some codecs will have
276                  * the left and right channels contiguous. This allows
277                  * dsp_a mode to be used with an inverted normal frame clk.
278                  * If your codec is master and does not have contiguous
279                  * channels, then you will have sound on only one channel.
280                  * Try using a different mode, or codec as slave.
281                  *
282                  * The TLV320AIC33 is an example of a codec where this works.
283                  * It has a variable bit clock frequency allowing it to have
284                  * valid data on every bit clock.
285                  *
286                  * The TLV320AIC23 is an example of a codec where this does not
287                  * work. It has a fixed bit clock frequency with progressively
288                  * more empty bit clock slots between channels as the sample
289                  * rate is lowered.
290                  */
291                 inv_fs = true;
292                 /* fall through */
293         case SND_SOC_DAIFMT_DSP_A:
294                 dev->mode = MOD_DSP_A;
295                 break;
296         case SND_SOC_DAIFMT_DSP_B:
297                 dev->mode = MOD_DSP_B;
298                 break;
299         default:
300                 printk(KERN_ERR "%s:bad format\n", __func__);
301                 return -EINVAL;
302         }
303 
304         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
305         case SND_SOC_DAIFMT_NB_NF:
306                 /* CLKRP Receive clock polarity,
307                  *      1 - sampled on rising edge of CLKR
308                  *      valid on rising edge
309                  * CLKXP Transmit clock polarity,
310                  *      1 - clocked on falling edge of CLKX
311                  *      valid on rising edge
312                  * FSRP  Receive frame sync pol, 0 - active high
313                  * FSXP  Transmit frame sync pol, 0 - active high
314                  */
315                 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP);
316                 break;
317         case SND_SOC_DAIFMT_IB_IF:
318                 /* CLKRP Receive clock polarity,
319                  *      0 - sampled on falling edge of CLKR
320                  *      valid on falling edge
321                  * CLKXP Transmit clock polarity,
322                  *      0 - clocked on rising edge of CLKX
323                  *      valid on falling edge
324                  * FSRP  Receive frame sync pol, 1 - active low
325                  * FSXP  Transmit frame sync pol, 1 - active low
326                  */
327                 pcr |= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
328                 break;
329         case SND_SOC_DAIFMT_NB_IF:
330                 /* CLKRP Receive clock polarity,
331                  *      1 - sampled on rising edge of CLKR
332                  *      valid on rising edge
333                  * CLKXP Transmit clock polarity,
334                  *      1 - clocked on falling edge of CLKX
335                  *      valid on rising edge
336                  * FSRP  Receive frame sync pol, 1 - active low
337                  * FSXP  Transmit frame sync pol, 1 - active low
338                  */
339                 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP |
340                         DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
341                 break;
342         case SND_SOC_DAIFMT_IB_NF:
343                 /* CLKRP Receive clock polarity,
344                  *      0 - sampled on falling edge of CLKR
345                  *      valid on falling edge
346                  * CLKXP Transmit clock polarity,
347                  *      0 - clocked on rising edge of CLKX
348                  *      valid on falling edge
349                  * FSRP  Receive frame sync pol, 0 - active high
350                  * FSXP  Transmit frame sync pol, 0 - active high
351                  */
352                 break;
353         default:
354                 return -EINVAL;
355         }
356         if (inv_fs == true)
357                 pcr ^= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
358         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
359         dev->pcr = pcr;
360         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
361         return 0;
362 }
363 
364 static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
365                                 int div_id, int div)
366 {
367         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
368 
369         if (div_id != DAVINCI_MCBSP_CLKGDV)
370                 return -ENODEV;
371 
372         dev->clk_div = div;
373         return 0;
374 }
375 
376 static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
377                                  struct snd_pcm_hw_params *params,
378                                  struct snd_soc_dai *dai)
379 {
380         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
381         struct snd_interval *i = NULL;
382         int mcbsp_word_length, master;
383         unsigned int rcr, xcr, srgr, clk_div, freq, framesize;
384         u32 spcr;
385         snd_pcm_format_t fmt;
386         unsigned element_cnt = 1;
387 
388         /* general line settings */
389         spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
390         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
391                 spcr |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
392                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
393         } else {
394                 spcr |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
395                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
396         }
397 
398         master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
399         fmt = params_format(params);
400         mcbsp_word_length = asp_word_length[fmt];
401 
402         switch (master) {
403         case SND_SOC_DAIFMT_CBS_CFS:
404                 freq = clk_get_rate(dev->clk);
405                 srgr = DAVINCI_MCBSP_SRGR_FSGM |
406                        DAVINCI_MCBSP_SRGR_CLKSM;
407                 srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length *
408                                                 8 - 1);
409                 if (dev->i2s_accurate_sck) {
410                         clk_div = 256;
411                         do {
412                                 framesize = (freq / (--clk_div)) /
413                                 params->rate_num *
414                                         params->rate_den;
415                         } while (((framesize < 33) || (framesize > 4095)) &&
416                                  (clk_div));
417                         clk_div--;
418                         srgr |= DAVINCI_MCBSP_SRGR_FPER(framesize - 1);
419                 } else {
420                         /* symmetric waveforms */
421                         clk_div = freq / (mcbsp_word_length * 16) /
422                                   params->rate_num * params->rate_den;
423                         srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length *
424                                                         16 - 1);
425                 }
426                 clk_div &= 0xFF;
427                 srgr |= clk_div;
428                 break;
429         case SND_SOC_DAIFMT_CBM_CFS:
430                 srgr = DAVINCI_MCBSP_SRGR_FSGM;
431                 clk_div = dev->clk_div - 1;
432                 srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1);
433                 srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * 16 - 1);
434                 clk_div &= 0xFF;
435                 srgr |= clk_div;
436                 break;
437         case SND_SOC_DAIFMT_CBM_CFM:
438                 /* Clock and frame sync given from external sources */
439                 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
440                 srgr = DAVINCI_MCBSP_SRGR_FSGM;
441                 srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1);
442                 pr_debug("%s - %d  FWID set: re-read srgr = %X\n",
443                         __func__, __LINE__, snd_interval_value(i) - 1);
444 
445                 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
446                 srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1);
447                 break;
448         default:
449                 return -EINVAL;
450         }
451         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
452 
453         rcr = DAVINCI_MCBSP_RCR_RFIG;
454         xcr = DAVINCI_MCBSP_XCR_XFIG;
455         if (dev->mode == MOD_DSP_B) {
456                 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(0);
457                 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(0);
458         } else {
459                 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
460                 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
461         }
462         /* Determine xfer data type */
463         fmt = params_format(params);
464         if ((fmt > SNDRV_PCM_FORMAT_S32_LE) || !data_type[fmt]) {
465                 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
466                 return -EINVAL;
467         }
468 
469         if (params_channels(params) == 2) {
470                 element_cnt = 2;
471                 if (double_fmt[fmt] && dev->enable_channel_combine) {
472                         element_cnt = 1;
473                         fmt = double_fmt[fmt];
474                 }
475                 switch (master) {
476                 case SND_SOC_DAIFMT_CBS_CFS:
477                 case SND_SOC_DAIFMT_CBS_CFM:
478                         rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(0);
479                         xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(0);
480                         rcr |= DAVINCI_MCBSP_RCR_RPHASE;
481                         xcr |= DAVINCI_MCBSP_XCR_XPHASE;
482                         break;
483                 case SND_SOC_DAIFMT_CBM_CFM:
484                 case SND_SOC_DAIFMT_CBM_CFS:
485                         rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(element_cnt - 1);
486                         xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(element_cnt - 1);
487                         break;
488                 default:
489                         return -EINVAL;
490                 }
491         }
492         mcbsp_word_length = asp_word_length[fmt];
493 
494         switch (master) {
495         case SND_SOC_DAIFMT_CBS_CFS:
496         case SND_SOC_DAIFMT_CBS_CFM:
497                 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(0);
498                 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(0);
499                 break;
500         case SND_SOC_DAIFMT_CBM_CFM:
501         case SND_SOC_DAIFMT_CBM_CFS:
502                 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
503                 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
504                 break;
505         default:
506                 return -EINVAL;
507         }
508 
509         rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
510                 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
511         xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
512                 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length);
513 
514         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
515                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
516         else
517                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
518 
519         pr_debug("%s - %d  srgr=%X\n", __func__, __LINE__, srgr);
520         pr_debug("%s - %d  xcr=%X\n", __func__, __LINE__, xcr);
521         pr_debug("%s - %d  rcr=%X\n", __func__, __LINE__, rcr);
522         return 0;
523 }
524 
525 static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
526                 struct snd_soc_dai *dai)
527 {
528         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
529         int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
530         u32 spcr;
531         u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
532 
533         davinci_mcbsp_stop(dev, playback);
534 
535         spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
536         if (spcr & mask) {
537                 /* start off disabled */
538                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
539                                         spcr & ~mask);
540                 toggle_clock(dev, playback);
541         }
542         if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
543                         DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
544                 /* Start the sample generator */
545                 spcr |= DAVINCI_MCBSP_SPCR_GRST;
546                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
547         }
548 
549         if (playback) {
550                 /* Enable the transmitter */
551                 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
552                 spcr |= DAVINCI_MCBSP_SPCR_XRST;
553                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
554 
555                 /* wait for any unexpected frame sync error to occur */
556                 udelay(100);
557 
558                 /* Disable the transmitter to clear any outstanding XSYNCERR */
559                 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
560                 spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
561                 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
562                 toggle_clock(dev, playback);
563         }
564 
565         return 0;
566 }
567 
568 static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
569                                struct snd_soc_dai *dai)
570 {
571         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
572         int ret = 0;
573         int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
574 
575         switch (cmd) {
576         case SNDRV_PCM_TRIGGER_START:
577         case SNDRV_PCM_TRIGGER_RESUME:
578         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
579                 davinci_mcbsp_start(dev, substream);
580                 break;
581         case SNDRV_PCM_TRIGGER_STOP:
582         case SNDRV_PCM_TRIGGER_SUSPEND:
583         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
584                 davinci_mcbsp_stop(dev, playback);
585                 break;
586         default:
587                 ret = -EINVAL;
588         }
589         return ret;
590 }
591 
592 static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
593                 struct snd_soc_dai *dai)
594 {
595         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
596         int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
597         davinci_mcbsp_stop(dev, playback);
598 }
599 
600 #define DAVINCI_I2S_RATES       SNDRV_PCM_RATE_8000_96000
601 #define DAVINCI_I2S_FORMATS     (SNDRV_PCM_FMTBIT_S16_LE | \
602                                  SNDRV_PCM_FMTBIT_S32_LE)
603 
604 static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
605         .shutdown       = davinci_i2s_shutdown,
606         .prepare        = davinci_i2s_prepare,
607         .trigger        = davinci_i2s_trigger,
608         .hw_params      = davinci_i2s_hw_params,
609         .set_fmt        = davinci_i2s_set_dai_fmt,
610         .set_clkdiv     = davinci_i2s_dai_set_clkdiv,
611 
612 };
613 
614 static int davinci_i2s_dai_probe(struct snd_soc_dai *dai)
615 {
616         struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
617 
618         dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
619         dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
620 
621         return 0;
622 }
623 
624 static struct snd_soc_dai_driver davinci_i2s_dai = {
625         .probe = davinci_i2s_dai_probe,
626         .playback = {
627                 .channels_min = 2,
628                 .channels_max = 2,
629                 .rates = DAVINCI_I2S_RATES,
630                 .formats = DAVINCI_I2S_FORMATS,
631         },
632         .capture = {
633                 .channels_min = 2,
634                 .channels_max = 2,
635                 .rates = DAVINCI_I2S_RATES,
636                 .formats = DAVINCI_I2S_FORMATS,
637         },
638         .ops = &davinci_i2s_dai_ops,
639 
640 };
641 
642 static const struct snd_soc_component_driver davinci_i2s_component = {
643         .name           = DRV_NAME,
644 };
645 
646 static int davinci_i2s_probe(struct platform_device *pdev)
647 {
648         struct snd_dmaengine_dai_dma_data *dma_data;
649         struct davinci_mcbsp_dev *dev;
650         struct resource *mem, *res;
651         void __iomem *io_base;
652         int *dma;
653         int ret;
654 
655         mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
656         if (!mem) {
657                 dev_warn(&pdev->dev,
658                          "\"mpu\" mem resource not found, using index 0\n");
659                 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
660                 if (!mem) {
661                         dev_err(&pdev->dev, "no mem resource?\n");
662                         return -ENODEV;
663                 }
664         }
665 
666         io_base = devm_ioremap_resource(&pdev->dev, mem);
667         if (IS_ERR(io_base))
668                 return PTR_ERR(io_base);
669 
670         dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev),
671                            GFP_KERNEL);
672         if (!dev)
673                 return -ENOMEM;
674 
675         dev->base = io_base;
676 
677         /* setup DMA, first TX, then RX */
678         dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
679         dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
680 
681         res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
682         if (res) {
683                 dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
684                 *dma = res->start;
685                 dma_data->filter_data = dma;
686         } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
687                 dma_data->filter_data = "tx";
688         } else {
689                 dev_err(&pdev->dev, "Missing DMA tx resource\n");
690                 return -ENODEV;
691         }
692 
693         dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
694         dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
695 
696         res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
697         if (res) {
698                 dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE];
699                 *dma = res->start;
700                 dma_data->filter_data = dma;
701         } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
702                 dma_data->filter_data = "rx";
703         } else {
704                 dev_err(&pdev->dev, "Missing DMA rx resource\n");
705                 return -ENODEV;
706         }
707 
708         dev->clk = clk_get(&pdev->dev, NULL);
709         if (IS_ERR(dev->clk))
710                 return -ENODEV;
711         clk_enable(dev->clk);
712 
713         dev->dev = &pdev->dev;
714         dev_set_drvdata(&pdev->dev, dev);
715 
716         ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component,
717                                          &davinci_i2s_dai, 1);
718         if (ret != 0)
719                 goto err_release_clk;
720 
721         ret = edma_pcm_platform_register(&pdev->dev);
722         if (ret) {
723                 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
724                 goto err_unregister_component;
725         }
726 
727         return 0;
728 
729 err_unregister_component:
730         snd_soc_unregister_component(&pdev->dev);
731 err_release_clk:
732         clk_disable(dev->clk);
733         clk_put(dev->clk);
734         return ret;
735 }
736 
737 static int davinci_i2s_remove(struct platform_device *pdev)
738 {
739         struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
740 
741         snd_soc_unregister_component(&pdev->dev);
742 
743         clk_disable(dev->clk);
744         clk_put(dev->clk);
745         dev->clk = NULL;
746 
747         return 0;
748 }
749 
750 static const struct of_device_id davinci_i2s_match[] = {
751         { .compatible = "ti,da850-mcbsp" },
752         {},
753 };
754 MODULE_DEVICE_TABLE(of, davinci_i2s_match);
755 
756 static struct platform_driver davinci_mcbsp_driver = {
757         .probe          = davinci_i2s_probe,
758         .remove         = davinci_i2s_remove,
759         .driver         = {
760                 .name   = "davinci-mcbsp",
761                 .of_match_table = of_match_ptr(davinci_i2s_match),
762         },
763 };
764 
765 module_platform_driver(davinci_mcbsp_driver);
766 
767 MODULE_AUTHOR("Vladimir Barinov");
768 MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
769 MODULE_LICENSE("GPL");
770 

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

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | 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.

osdn.jp