Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");