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