Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
0004  *
0005  * Author:      Vladimir Barinov, <vbarinov@embeddedalley.com>
0006  * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
0007  *
0008  * DT support   (c) 2016 Petr Kulhavy, Barix AG <petr@barix.com>
0009  *      based on davinci-mcasp.c DT support
0010  *
0011  * TODO:
0012  * on DA850 implement HW FIFOs instead of DMA into DXR and DRR registers
0013  */
0014 
0015 #include <linux/init.h>
0016 #include <linux/module.h>
0017 #include <linux/device.h>
0018 #include <linux/slab.h>
0019 #include <linux/delay.h>
0020 #include <linux/io.h>
0021 #include <linux/clk.h>
0022 #include <linux/platform_data/davinci_asp.h>
0023 
0024 #include <sound/core.h>
0025 #include <sound/pcm.h>
0026 #include <sound/pcm_params.h>
0027 #include <sound/initval.h>
0028 #include <sound/soc.h>
0029 #include <sound/dmaengine_pcm.h>
0030 
0031 #include "edma-pcm.h"
0032 #include "davinci-i2s.h"
0033 
0034 #define DRV_NAME "davinci-i2s"
0035 
0036 /*
0037  * NOTE:  terminology here is confusing.
0038  *
0039  *  - This driver supports the "Audio Serial Port" (ASP),
0040  *    found on dm6446, dm355, and other DaVinci chips.
0041  *
0042  *  - But it labels it a "Multi-channel Buffered Serial Port"
0043  *    (McBSP) as on older chips like the dm642 ... which was
0044  *    backward-compatible, possibly explaining that confusion.
0045  *
0046  *  - OMAP chips have a controller called McBSP, which is
0047  *    incompatible with the DaVinci flavor of McBSP.
0048  *
0049  *  - Newer DaVinci chips have a controller called McASP,
0050  *    incompatible with ASP and with either McBSP.
0051  *
0052  * In short:  this uses ASP to implement I2S, not McBSP.
0053  * And it won't be the only DaVinci implemention of I2S.
0054  */
0055 #define DAVINCI_MCBSP_DRR_REG   0x00
0056 #define DAVINCI_MCBSP_DXR_REG   0x04
0057 #define DAVINCI_MCBSP_SPCR_REG  0x08
0058 #define DAVINCI_MCBSP_RCR_REG   0x0c
0059 #define DAVINCI_MCBSP_XCR_REG   0x10
0060 #define DAVINCI_MCBSP_SRGR_REG  0x14
0061 #define DAVINCI_MCBSP_PCR_REG   0x24
0062 
0063 #define DAVINCI_MCBSP_SPCR_RRST     (1 << 0)
0064 #define DAVINCI_MCBSP_SPCR_RINTM(v) ((v) << 4)
0065 #define DAVINCI_MCBSP_SPCR_XRST     (1 << 16)
0066 #define DAVINCI_MCBSP_SPCR_XINTM(v) ((v) << 20)
0067 #define DAVINCI_MCBSP_SPCR_GRST     (1 << 22)
0068 #define DAVINCI_MCBSP_SPCR_FRST     (1 << 23)
0069 #define DAVINCI_MCBSP_SPCR_FREE     (1 << 25)
0070 
0071 #define DAVINCI_MCBSP_RCR_RWDLEN1(v)    ((v) << 5)
0072 #define DAVINCI_MCBSP_RCR_RFRLEN1(v)    ((v) << 8)
0073 #define DAVINCI_MCBSP_RCR_RDATDLY(v)    ((v) << 16)
0074 #define DAVINCI_MCBSP_RCR_RFIG      (1 << 18)
0075 #define DAVINCI_MCBSP_RCR_RWDLEN2(v)    ((v) << 21)
0076 #define DAVINCI_MCBSP_RCR_RFRLEN2(v)    ((v) << 24)
0077 #define DAVINCI_MCBSP_RCR_RPHASE    BIT(31)
0078 
0079 #define DAVINCI_MCBSP_XCR_XWDLEN1(v)    ((v) << 5)
0080 #define DAVINCI_MCBSP_XCR_XFRLEN1(v)    ((v) << 8)
0081 #define DAVINCI_MCBSP_XCR_XDATDLY(v)    ((v) << 16)
0082 #define DAVINCI_MCBSP_XCR_XFIG      (1 << 18)
0083 #define DAVINCI_MCBSP_XCR_XWDLEN2(v)    ((v) << 21)
0084 #define DAVINCI_MCBSP_XCR_XFRLEN2(v)    ((v) << 24)
0085 #define DAVINCI_MCBSP_XCR_XPHASE    BIT(31)
0086 
0087 #define DAVINCI_MCBSP_SRGR_FWID(v)  ((v) << 8)
0088 #define DAVINCI_MCBSP_SRGR_FPER(v)  ((v) << 16)
0089 #define DAVINCI_MCBSP_SRGR_FSGM     (1 << 28)
0090 #define DAVINCI_MCBSP_SRGR_CLKSM    BIT(29)
0091 
0092 #define DAVINCI_MCBSP_PCR_CLKRP     (1 << 0)
0093 #define DAVINCI_MCBSP_PCR_CLKXP     (1 << 1)
0094 #define DAVINCI_MCBSP_PCR_FSRP      (1 << 2)
0095 #define DAVINCI_MCBSP_PCR_FSXP      (1 << 3)
0096 #define DAVINCI_MCBSP_PCR_SCLKME    (1 << 7)
0097 #define DAVINCI_MCBSP_PCR_CLKRM     (1 << 8)
0098 #define DAVINCI_MCBSP_PCR_CLKXM     (1 << 9)
0099 #define DAVINCI_MCBSP_PCR_FSRM      (1 << 10)
0100 #define DAVINCI_MCBSP_PCR_FSXM      (1 << 11)
0101 
0102 enum {
0103     DAVINCI_MCBSP_WORD_8 = 0,
0104     DAVINCI_MCBSP_WORD_12,
0105     DAVINCI_MCBSP_WORD_16,
0106     DAVINCI_MCBSP_WORD_20,
0107     DAVINCI_MCBSP_WORD_24,
0108     DAVINCI_MCBSP_WORD_32,
0109 };
0110 
0111 static const unsigned char data_type[SNDRV_PCM_FORMAT_S32_LE + 1] = {
0112     [SNDRV_PCM_FORMAT_S8]       = 1,
0113     [SNDRV_PCM_FORMAT_S16_LE]   = 2,
0114     [SNDRV_PCM_FORMAT_S32_LE]   = 4,
0115 };
0116 
0117 static const unsigned char asp_word_length[SNDRV_PCM_FORMAT_S32_LE + 1] = {
0118     [SNDRV_PCM_FORMAT_S8]       = DAVINCI_MCBSP_WORD_8,
0119     [SNDRV_PCM_FORMAT_S16_LE]   = DAVINCI_MCBSP_WORD_16,
0120     [SNDRV_PCM_FORMAT_S32_LE]   = DAVINCI_MCBSP_WORD_32,
0121 };
0122 
0123 static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
0124     [SNDRV_PCM_FORMAT_S8]       = SNDRV_PCM_FORMAT_S16_LE,
0125     [SNDRV_PCM_FORMAT_S16_LE]   = SNDRV_PCM_FORMAT_S32_LE,
0126 };
0127 
0128 struct davinci_mcbsp_dev {
0129     struct device *dev;
0130     struct snd_dmaengine_dai_dma_data dma_data[2];
0131     int dma_request[2];
0132     void __iomem            *base;
0133 #define MOD_DSP_A   0
0134 #define MOD_DSP_B   1
0135     int             mode;
0136     u32             pcr;
0137     struct clk          *clk;
0138     /*
0139      * Combining both channels into 1 element will at least double the
0140      * amount of time between servicing the dma channel, increase
0141      * effiency, and reduce the chance of overrun/underrun. But,
0142      * it will result in the left & right channels being swapped.
0143      *
0144      * If relabeling the left and right channels is not possible,
0145      * you may want to let the codec know to swap them back.
0146      *
0147      * It may allow x10 the amount of time to service dma requests,
0148      * if the codec is master and is using an unnecessarily fast bit clock
0149      * (ie. tlvaic23b), independent of the sample rate. So, having an
0150      * entire frame at once means it can be serviced at the sample rate
0151      * instead of the bit clock rate.
0152      *
0153      * In the now unlikely case that an underrun still
0154      * occurs, both the left and right samples will be repeated
0155      * so that no pops are heard, and the left and right channels
0156      * won't end up being swapped because of the underrun.
0157      */
0158     unsigned enable_channel_combine:1;
0159 
0160     unsigned int fmt;
0161     int clk_div;
0162     int clk_input_pin;
0163     bool i2s_accurate_sck;
0164 };
0165 
0166 static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
0167                        int reg, u32 val)
0168 {
0169     __raw_writel(val, dev->base + reg);
0170 }
0171 
0172 static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
0173 {
0174     return __raw_readl(dev->base + reg);
0175 }
0176 
0177 static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
0178 {
0179     u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
0180     /* The clock needs to toggle to complete reset.
0181      * So, fake it by toggling the clk polarity.
0182      */
0183     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
0184     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
0185 }
0186 
0187 static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
0188         struct snd_pcm_substream *substream)
0189 {
0190     int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
0191     u32 spcr;
0192     u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
0193 
0194     /* Enable transmitter or receiver */
0195     spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
0196     spcr |= mask;
0197 
0198     if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) {
0199         /* Start frame sync */
0200         spcr |= DAVINCI_MCBSP_SPCR_FRST;
0201     }
0202     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0203 }
0204 
0205 static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
0206 {
0207     u32 spcr;
0208 
0209     /* Reset transmitter/receiver and sample rate/frame sync generators */
0210     spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
0211     spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
0212     spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST;
0213     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0214     toggle_clock(dev, playback);
0215 }
0216 
0217 #define DEFAULT_BITPERSAMPLE    16
0218 
0219 static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
0220                    unsigned int fmt)
0221 {
0222     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
0223     unsigned int pcr;
0224     unsigned int srgr;
0225     bool inv_fs = false;
0226     /* Attention srgr is updated by hw_params! */
0227     srgr = DAVINCI_MCBSP_SRGR_FSGM |
0228         DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
0229         DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
0230 
0231     dev->fmt = fmt;
0232     /* set master/slave audio interface */
0233     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0234     case SND_SOC_DAIFMT_BP_FP:
0235         /* cpu is master */
0236         pcr = DAVINCI_MCBSP_PCR_FSXM |
0237             DAVINCI_MCBSP_PCR_FSRM |
0238             DAVINCI_MCBSP_PCR_CLKXM |
0239             DAVINCI_MCBSP_PCR_CLKRM;
0240         break;
0241     case SND_SOC_DAIFMT_BC_FP:
0242         pcr = DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_FSXM;
0243         /*
0244          * Selection of the clock input pin that is the
0245          * input for the Sample Rate Generator.
0246          * McBSP FSR and FSX are driven by the Sample Rate
0247          * Generator.
0248          */
0249         switch (dev->clk_input_pin) {
0250         case MCBSP_CLKS:
0251             pcr |= DAVINCI_MCBSP_PCR_CLKXM |
0252                 DAVINCI_MCBSP_PCR_CLKRM;
0253             break;
0254         case MCBSP_CLKR:
0255             pcr |= DAVINCI_MCBSP_PCR_SCLKME;
0256             break;
0257         default:
0258             dev_err(dev->dev, "bad clk_input_pin\n");
0259             return -EINVAL;
0260         }
0261 
0262         break;
0263     case SND_SOC_DAIFMT_BC_FC:
0264         /* codec is master */
0265         pcr = 0;
0266         break;
0267     default:
0268         printk(KERN_ERR "%s:bad master\n", __func__);
0269         return -EINVAL;
0270     }
0271 
0272     /* interface format */
0273     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0274     case SND_SOC_DAIFMT_I2S:
0275         /* Davinci doesn't support TRUE I2S, but some codecs will have
0276          * the left and right channels contiguous. This allows
0277          * dsp_a mode to be used with an inverted normal frame clk.
0278          * If your codec is master and does not have contiguous
0279          * channels, then you will have sound on only one channel.
0280          * Try using a different mode, or codec as slave.
0281          *
0282          * The TLV320AIC33 is an example of a codec where this works.
0283          * It has a variable bit clock frequency allowing it to have
0284          * valid data on every bit clock.
0285          *
0286          * The TLV320AIC23 is an example of a codec where this does not
0287          * work. It has a fixed bit clock frequency with progressively
0288          * more empty bit clock slots between channels as the sample
0289          * rate is lowered.
0290          */
0291         inv_fs = true;
0292         fallthrough;
0293     case SND_SOC_DAIFMT_DSP_A:
0294         dev->mode = MOD_DSP_A;
0295         break;
0296     case SND_SOC_DAIFMT_DSP_B:
0297         dev->mode = MOD_DSP_B;
0298         break;
0299     default:
0300         printk(KERN_ERR "%s:bad format\n", __func__);
0301         return -EINVAL;
0302     }
0303 
0304     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0305     case SND_SOC_DAIFMT_NB_NF:
0306         /* CLKRP Receive clock polarity,
0307          *  1 - sampled on rising edge of CLKR
0308          *  valid on rising edge
0309          * CLKXP Transmit clock polarity,
0310          *  1 - clocked on falling edge of CLKX
0311          *  valid on rising edge
0312          * FSRP  Receive frame sync pol, 0 - active high
0313          * FSXP  Transmit frame sync pol, 0 - active high
0314          */
0315         pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP);
0316         break;
0317     case SND_SOC_DAIFMT_IB_IF:
0318         /* CLKRP Receive clock polarity,
0319          *  0 - sampled on falling edge of CLKR
0320          *  valid on falling edge
0321          * CLKXP Transmit clock polarity,
0322          *  0 - clocked on rising edge of CLKX
0323          *  valid on falling edge
0324          * FSRP  Receive frame sync pol, 1 - active low
0325          * FSXP  Transmit frame sync pol, 1 - active low
0326          */
0327         pcr |= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
0328         break;
0329     case SND_SOC_DAIFMT_NB_IF:
0330         /* CLKRP Receive clock polarity,
0331          *  1 - sampled on rising edge of CLKR
0332          *  valid on rising edge
0333          * CLKXP Transmit clock polarity,
0334          *  1 - clocked on falling edge of CLKX
0335          *  valid on rising edge
0336          * FSRP  Receive frame sync pol, 1 - active low
0337          * FSXP  Transmit frame sync pol, 1 - active low
0338          */
0339         pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP |
0340             DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
0341         break;
0342     case SND_SOC_DAIFMT_IB_NF:
0343         /* CLKRP Receive clock polarity,
0344          *  0 - sampled on falling edge of CLKR
0345          *  valid on falling edge
0346          * CLKXP Transmit clock polarity,
0347          *  0 - clocked on rising edge of CLKX
0348          *  valid on falling edge
0349          * FSRP  Receive frame sync pol, 0 - active high
0350          * FSXP  Transmit frame sync pol, 0 - active high
0351          */
0352         break;
0353     default:
0354         return -EINVAL;
0355     }
0356     if (inv_fs == true)
0357         pcr ^= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
0358     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
0359     dev->pcr = pcr;
0360     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
0361     return 0;
0362 }
0363 
0364 static int davinci_i2s_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
0365                 int div_id, int div)
0366 {
0367     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
0368 
0369     if (div_id != DAVINCI_MCBSP_CLKGDV)
0370         return -ENODEV;
0371 
0372     dev->clk_div = div;
0373     return 0;
0374 }
0375 
0376 static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
0377                  struct snd_pcm_hw_params *params,
0378                  struct snd_soc_dai *dai)
0379 {
0380     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
0381     struct snd_interval *i = NULL;
0382     int mcbsp_word_length, master;
0383     unsigned int rcr, xcr, srgr, clk_div, freq, framesize;
0384     u32 spcr;
0385     snd_pcm_format_t fmt;
0386     unsigned element_cnt = 1;
0387 
0388     /* general line settings */
0389     spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
0390     if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0391         spcr |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
0392         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0393     } else {
0394         spcr |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
0395         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0396     }
0397 
0398     master = dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
0399     fmt = params_format(params);
0400     mcbsp_word_length = asp_word_length[fmt];
0401 
0402     switch (master) {
0403     case SND_SOC_DAIFMT_BP_FP:
0404         freq = clk_get_rate(dev->clk);
0405         srgr = DAVINCI_MCBSP_SRGR_FSGM |
0406                DAVINCI_MCBSP_SRGR_CLKSM;
0407         srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length *
0408                         8 - 1);
0409         if (dev->i2s_accurate_sck) {
0410             clk_div = 256;
0411             do {
0412                 framesize = (freq / (--clk_div)) /
0413                 params->rate_num *
0414                     params->rate_den;
0415             } while (((framesize < 33) || (framesize > 4095)) &&
0416                  (clk_div));
0417             clk_div--;
0418             srgr |= DAVINCI_MCBSP_SRGR_FPER(framesize - 1);
0419         } else {
0420             /* symmetric waveforms */
0421             clk_div = freq / (mcbsp_word_length * 16) /
0422                   params->rate_num * params->rate_den;
0423             srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length *
0424                             16 - 1);
0425         }
0426         clk_div &= 0xFF;
0427         srgr |= clk_div;
0428         break;
0429     case SND_SOC_DAIFMT_BC_FP:
0430         srgr = DAVINCI_MCBSP_SRGR_FSGM;
0431         clk_div = dev->clk_div - 1;
0432         srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1);
0433         srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * 16 - 1);
0434         clk_div &= 0xFF;
0435         srgr |= clk_div;
0436         break;
0437     case SND_SOC_DAIFMT_BC_FC:
0438         /* Clock and frame sync given from external sources */
0439         i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
0440         srgr = DAVINCI_MCBSP_SRGR_FSGM;
0441         srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1);
0442         pr_debug("%s - %d  FWID set: re-read srgr = %X\n",
0443             __func__, __LINE__, snd_interval_value(i) - 1);
0444 
0445         i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
0446         srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1);
0447         break;
0448     default:
0449         return -EINVAL;
0450     }
0451     davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
0452 
0453     rcr = DAVINCI_MCBSP_RCR_RFIG;
0454     xcr = DAVINCI_MCBSP_XCR_XFIG;
0455     if (dev->mode == MOD_DSP_B) {
0456         rcr |= DAVINCI_MCBSP_RCR_RDATDLY(0);
0457         xcr |= DAVINCI_MCBSP_XCR_XDATDLY(0);
0458     } else {
0459         rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
0460         xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
0461     }
0462     /* Determine xfer data type */
0463     fmt = params_format(params);
0464     if ((fmt > SNDRV_PCM_FORMAT_S32_LE) || !data_type[fmt]) {
0465         printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
0466         return -EINVAL;
0467     }
0468 
0469     if (params_channels(params) == 2) {
0470         element_cnt = 2;
0471         if (double_fmt[fmt] && dev->enable_channel_combine) {
0472             element_cnt = 1;
0473             fmt = double_fmt[fmt];
0474         }
0475         switch (master) {
0476         case SND_SOC_DAIFMT_BP_FP:
0477         case SND_SOC_DAIFMT_BP_FC:
0478             rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(0);
0479             xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(0);
0480             rcr |= DAVINCI_MCBSP_RCR_RPHASE;
0481             xcr |= DAVINCI_MCBSP_XCR_XPHASE;
0482             break;
0483         case SND_SOC_DAIFMT_BC_FC:
0484         case SND_SOC_DAIFMT_BC_FP:
0485             rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(element_cnt - 1);
0486             xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(element_cnt - 1);
0487             break;
0488         default:
0489             return -EINVAL;
0490         }
0491     }
0492     mcbsp_word_length = asp_word_length[fmt];
0493 
0494     switch (master) {
0495     case SND_SOC_DAIFMT_BP_FP:
0496     case SND_SOC_DAIFMT_BP_FC:
0497         rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(0);
0498         xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(0);
0499         break;
0500     case SND_SOC_DAIFMT_BC_FC:
0501     case SND_SOC_DAIFMT_BC_FP:
0502         rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
0503         xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
0504         break;
0505     default:
0506         return -EINVAL;
0507     }
0508 
0509     rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
0510         DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
0511     xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
0512         DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length);
0513 
0514     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0515         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
0516     else
0517         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
0518 
0519     pr_debug("%s - %d  srgr=%X\n", __func__, __LINE__, srgr);
0520     pr_debug("%s - %d  xcr=%X\n", __func__, __LINE__, xcr);
0521     pr_debug("%s - %d  rcr=%X\n", __func__, __LINE__, rcr);
0522     return 0;
0523 }
0524 
0525 static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
0526         struct snd_soc_dai *dai)
0527 {
0528     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
0529     int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
0530     u32 spcr;
0531     u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
0532 
0533     davinci_mcbsp_stop(dev, playback);
0534 
0535     spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
0536     if (spcr & mask) {
0537         /* start off disabled */
0538         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
0539                     spcr & ~mask);
0540         toggle_clock(dev, playback);
0541     }
0542     if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
0543             DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
0544         /* Start the sample generator */
0545         spcr |= DAVINCI_MCBSP_SPCR_GRST;
0546         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0547     }
0548 
0549     if (playback) {
0550         /* Enable the transmitter */
0551         spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
0552         spcr |= DAVINCI_MCBSP_SPCR_XRST;
0553         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0554 
0555         /* wait for any unexpected frame sync error to occur */
0556         udelay(100);
0557 
0558         /* Disable the transmitter to clear any outstanding XSYNCERR */
0559         spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
0560         spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
0561         davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
0562         toggle_clock(dev, playback);
0563     }
0564 
0565     return 0;
0566 }
0567 
0568 static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
0569                    struct snd_soc_dai *dai)
0570 {
0571     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
0572     int ret = 0;
0573     int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
0574 
0575     switch (cmd) {
0576     case SNDRV_PCM_TRIGGER_START:
0577     case SNDRV_PCM_TRIGGER_RESUME:
0578     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0579         davinci_mcbsp_start(dev, substream);
0580         break;
0581     case SNDRV_PCM_TRIGGER_STOP:
0582     case SNDRV_PCM_TRIGGER_SUSPEND:
0583     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0584         davinci_mcbsp_stop(dev, playback);
0585         break;
0586     default:
0587         ret = -EINVAL;
0588     }
0589     return ret;
0590 }
0591 
0592 static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
0593         struct snd_soc_dai *dai)
0594 {
0595     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
0596     int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
0597     davinci_mcbsp_stop(dev, playback);
0598 }
0599 
0600 #define DAVINCI_I2S_RATES   SNDRV_PCM_RATE_8000_96000
0601 #define DAVINCI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
0602                  SNDRV_PCM_FMTBIT_S32_LE)
0603 
0604 static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
0605     .shutdown   = davinci_i2s_shutdown,
0606     .prepare    = davinci_i2s_prepare,
0607     .trigger    = davinci_i2s_trigger,
0608     .hw_params  = davinci_i2s_hw_params,
0609     .set_fmt    = davinci_i2s_set_dai_fmt,
0610     .set_clkdiv = davinci_i2s_dai_set_clkdiv,
0611 
0612 };
0613 
0614 static int davinci_i2s_dai_probe(struct snd_soc_dai *dai)
0615 {
0616     struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
0617 
0618     dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
0619     dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
0620 
0621     return 0;
0622 }
0623 
0624 static struct snd_soc_dai_driver davinci_i2s_dai = {
0625     .probe = davinci_i2s_dai_probe,
0626     .playback = {
0627         .channels_min = 2,
0628         .channels_max = 2,
0629         .rates = DAVINCI_I2S_RATES,
0630         .formats = DAVINCI_I2S_FORMATS,
0631     },
0632     .capture = {
0633         .channels_min = 2,
0634         .channels_max = 2,
0635         .rates = DAVINCI_I2S_RATES,
0636         .formats = DAVINCI_I2S_FORMATS,
0637     },
0638     .ops = &davinci_i2s_dai_ops,
0639 
0640 };
0641 
0642 static const struct snd_soc_component_driver davinci_i2s_component = {
0643     .name           = DRV_NAME,
0644     .legacy_dai_naming  = 1,
0645 };
0646 
0647 static int davinci_i2s_probe(struct platform_device *pdev)
0648 {
0649     struct snd_dmaengine_dai_dma_data *dma_data;
0650     struct davinci_mcbsp_dev *dev;
0651     struct resource *mem, *res;
0652     void __iomem *io_base;
0653     int *dma;
0654     int ret;
0655 
0656     mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
0657     if (!mem) {
0658         dev_warn(&pdev->dev,
0659              "\"mpu\" mem resource not found, using index 0\n");
0660         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0661         if (!mem) {
0662             dev_err(&pdev->dev, "no mem resource?\n");
0663             return -ENODEV;
0664         }
0665     }
0666 
0667     io_base = devm_ioremap_resource(&pdev->dev, mem);
0668     if (IS_ERR(io_base))
0669         return PTR_ERR(io_base);
0670 
0671     dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev),
0672                GFP_KERNEL);
0673     if (!dev)
0674         return -ENOMEM;
0675 
0676     dev->base = io_base;
0677 
0678     /* setup DMA, first TX, then RX */
0679     dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
0680     dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
0681 
0682     res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
0683     if (res) {
0684         dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
0685         *dma = res->start;
0686         dma_data->filter_data = dma;
0687     } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
0688         dma_data->filter_data = "tx";
0689     } else {
0690         dev_err(&pdev->dev, "Missing DMA tx resource\n");
0691         return -ENODEV;
0692     }
0693 
0694     dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
0695     dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
0696 
0697     res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
0698     if (res) {
0699         dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE];
0700         *dma = res->start;
0701         dma_data->filter_data = dma;
0702     } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
0703         dma_data->filter_data = "rx";
0704     } else {
0705         dev_err(&pdev->dev, "Missing DMA rx resource\n");
0706         return -ENODEV;
0707     }
0708 
0709     dev->clk = clk_get(&pdev->dev, NULL);
0710     if (IS_ERR(dev->clk))
0711         return -ENODEV;
0712     ret = clk_enable(dev->clk);
0713     if (ret)
0714         goto err_put_clk;
0715 
0716     dev->dev = &pdev->dev;
0717     dev_set_drvdata(&pdev->dev, dev);
0718 
0719     ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component,
0720                      &davinci_i2s_dai, 1);
0721     if (ret != 0)
0722         goto err_release_clk;
0723 
0724     ret = edma_pcm_platform_register(&pdev->dev);
0725     if (ret) {
0726         dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
0727         goto err_unregister_component;
0728     }
0729 
0730     return 0;
0731 
0732 err_unregister_component:
0733     snd_soc_unregister_component(&pdev->dev);
0734 err_release_clk:
0735     clk_disable(dev->clk);
0736 err_put_clk:
0737     clk_put(dev->clk);
0738     return ret;
0739 }
0740 
0741 static int davinci_i2s_remove(struct platform_device *pdev)
0742 {
0743     struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
0744 
0745     snd_soc_unregister_component(&pdev->dev);
0746 
0747     clk_disable(dev->clk);
0748     clk_put(dev->clk);
0749     dev->clk = NULL;
0750 
0751     return 0;
0752 }
0753 
0754 static const struct of_device_id davinci_i2s_match[] __maybe_unused = {
0755     { .compatible = "ti,da850-mcbsp" },
0756     {},
0757 };
0758 MODULE_DEVICE_TABLE(of, davinci_i2s_match);
0759 
0760 static struct platform_driver davinci_mcbsp_driver = {
0761     .probe      = davinci_i2s_probe,
0762     .remove     = davinci_i2s_remove,
0763     .driver     = {
0764         .name   = "davinci-mcbsp",
0765         .of_match_table = of_match_ptr(davinci_i2s_match),
0766     },
0767 };
0768 
0769 module_platform_driver(davinci_mcbsp_driver);
0770 
0771 MODULE_AUTHOR("Vladimir Barinov");
0772 MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
0773 MODULE_LICENSE("GPL");