1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * ALSA SoC McASP Audio Layer for TI DAVINCI processor
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Multi-channel Audio Serial Port Driver
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Author: Nirmal Pandey <n-pandey@ti.com>,
8*4882a593Smuzhiyun * Suresh Rajashekara <suresh.r@ti.com>
9*4882a593Smuzhiyun * Steve Chen <schen@.mvista.com>
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
12*4882a593Smuzhiyun * Copyright: (C) 2009 Texas Instruments, India
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <linux/init.h>
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/device.h>
18*4882a593Smuzhiyun #include <linux/slab.h>
19*4882a593Smuzhiyun #include <linux/delay.h>
20*4882a593Smuzhiyun #include <linux/io.h>
21*4882a593Smuzhiyun #include <linux/clk.h>
22*4882a593Smuzhiyun #include <linux/pm_runtime.h>
23*4882a593Smuzhiyun #include <linux/of.h>
24*4882a593Smuzhiyun #include <linux/of_platform.h>
25*4882a593Smuzhiyun #include <linux/of_device.h>
26*4882a593Smuzhiyun #include <linux/platform_data/davinci_asp.h>
27*4882a593Smuzhiyun #include <linux/math64.h>
28*4882a593Smuzhiyun #include <linux/bitmap.h>
29*4882a593Smuzhiyun #include <linux/gpio/driver.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include <sound/asoundef.h>
32*4882a593Smuzhiyun #include <sound/core.h>
33*4882a593Smuzhiyun #include <sound/pcm.h>
34*4882a593Smuzhiyun #include <sound/pcm_params.h>
35*4882a593Smuzhiyun #include <sound/initval.h>
36*4882a593Smuzhiyun #include <sound/soc.h>
37*4882a593Smuzhiyun #include <sound/dmaengine_pcm.h>
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #include "edma-pcm.h"
40*4882a593Smuzhiyun #include "sdma-pcm.h"
41*4882a593Smuzhiyun #include "udma-pcm.h"
42*4882a593Smuzhiyun #include "davinci-mcasp.h"
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define MCASP_MAX_AFIFO_DEPTH 64
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #ifdef CONFIG_PM
47*4882a593Smuzhiyun static u32 context_regs[] = {
48*4882a593Smuzhiyun DAVINCI_MCASP_TXFMCTL_REG,
49*4882a593Smuzhiyun DAVINCI_MCASP_RXFMCTL_REG,
50*4882a593Smuzhiyun DAVINCI_MCASP_TXFMT_REG,
51*4882a593Smuzhiyun DAVINCI_MCASP_RXFMT_REG,
52*4882a593Smuzhiyun DAVINCI_MCASP_ACLKXCTL_REG,
53*4882a593Smuzhiyun DAVINCI_MCASP_ACLKRCTL_REG,
54*4882a593Smuzhiyun DAVINCI_MCASP_AHCLKXCTL_REG,
55*4882a593Smuzhiyun DAVINCI_MCASP_AHCLKRCTL_REG,
56*4882a593Smuzhiyun DAVINCI_MCASP_PDIR_REG,
57*4882a593Smuzhiyun DAVINCI_MCASP_PFUNC_REG,
58*4882a593Smuzhiyun DAVINCI_MCASP_RXMASK_REG,
59*4882a593Smuzhiyun DAVINCI_MCASP_TXMASK_REG,
60*4882a593Smuzhiyun DAVINCI_MCASP_RXTDM_REG,
61*4882a593Smuzhiyun DAVINCI_MCASP_TXTDM_REG,
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun struct davinci_mcasp_context {
65*4882a593Smuzhiyun u32 config_regs[ARRAY_SIZE(context_regs)];
66*4882a593Smuzhiyun u32 afifo_regs[2]; /* for read/write fifo control registers */
67*4882a593Smuzhiyun u32 *xrsr_regs; /* for serializer configuration */
68*4882a593Smuzhiyun bool pm_state;
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun #endif
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun struct davinci_mcasp_ruledata {
73*4882a593Smuzhiyun struct davinci_mcasp *mcasp;
74*4882a593Smuzhiyun int serializers;
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun struct davinci_mcasp {
78*4882a593Smuzhiyun struct snd_dmaengine_dai_dma_data dma_data[2];
79*4882a593Smuzhiyun void __iomem *base;
80*4882a593Smuzhiyun u32 fifo_base;
81*4882a593Smuzhiyun struct device *dev;
82*4882a593Smuzhiyun struct snd_pcm_substream *substreams[2];
83*4882a593Smuzhiyun unsigned int dai_fmt;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /* McASP specific data */
86*4882a593Smuzhiyun int tdm_slots;
87*4882a593Smuzhiyun u32 tdm_mask[2];
88*4882a593Smuzhiyun int slot_width;
89*4882a593Smuzhiyun u8 op_mode;
90*4882a593Smuzhiyun u8 dismod;
91*4882a593Smuzhiyun u8 num_serializer;
92*4882a593Smuzhiyun u8 *serial_dir;
93*4882a593Smuzhiyun u8 version;
94*4882a593Smuzhiyun u8 bclk_div;
95*4882a593Smuzhiyun int streams;
96*4882a593Smuzhiyun u32 irq_request[2];
97*4882a593Smuzhiyun int dma_request[2];
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun int sysclk_freq;
100*4882a593Smuzhiyun bool bclk_master;
101*4882a593Smuzhiyun u32 auxclk_fs_ratio;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun unsigned long pdir; /* Pin direction bitfield */
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /* McASP FIFO related */
106*4882a593Smuzhiyun u8 txnumevt;
107*4882a593Smuzhiyun u8 rxnumevt;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun bool dat_port;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* Used for comstraint setting on the second stream */
112*4882a593Smuzhiyun u32 channels;
113*4882a593Smuzhiyun int max_format_width;
114*4882a593Smuzhiyun u8 active_serializers[2];
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun #ifdef CONFIG_GPIOLIB
117*4882a593Smuzhiyun struct gpio_chip gpio_chip;
118*4882a593Smuzhiyun #endif
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun #ifdef CONFIG_PM
121*4882a593Smuzhiyun struct davinci_mcasp_context context;
122*4882a593Smuzhiyun #endif
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun struct davinci_mcasp_ruledata ruledata[2];
125*4882a593Smuzhiyun struct snd_pcm_hw_constraint_list chconstr[2];
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun
mcasp_set_bits(struct davinci_mcasp * mcasp,u32 offset,u32 val)128*4882a593Smuzhiyun static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset,
129*4882a593Smuzhiyun u32 val)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun void __iomem *reg = mcasp->base + offset;
132*4882a593Smuzhiyun __raw_writel(__raw_readl(reg) | val, reg);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
mcasp_clr_bits(struct davinci_mcasp * mcasp,u32 offset,u32 val)135*4882a593Smuzhiyun static inline void mcasp_clr_bits(struct davinci_mcasp *mcasp, u32 offset,
136*4882a593Smuzhiyun u32 val)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun void __iomem *reg = mcasp->base + offset;
139*4882a593Smuzhiyun __raw_writel((__raw_readl(reg) & ~(val)), reg);
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
mcasp_mod_bits(struct davinci_mcasp * mcasp,u32 offset,u32 val,u32 mask)142*4882a593Smuzhiyun static inline void mcasp_mod_bits(struct davinci_mcasp *mcasp, u32 offset,
143*4882a593Smuzhiyun u32 val, u32 mask)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun void __iomem *reg = mcasp->base + offset;
146*4882a593Smuzhiyun __raw_writel((__raw_readl(reg) & ~mask) | val, reg);
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
mcasp_set_reg(struct davinci_mcasp * mcasp,u32 offset,u32 val)149*4882a593Smuzhiyun static inline void mcasp_set_reg(struct davinci_mcasp *mcasp, u32 offset,
150*4882a593Smuzhiyun u32 val)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun __raw_writel(val, mcasp->base + offset);
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
mcasp_get_reg(struct davinci_mcasp * mcasp,u32 offset)155*4882a593Smuzhiyun static inline u32 mcasp_get_reg(struct davinci_mcasp *mcasp, u32 offset)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun return (u32)__raw_readl(mcasp->base + offset);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
mcasp_set_ctl_reg(struct davinci_mcasp * mcasp,u32 ctl_reg,u32 val)160*4882a593Smuzhiyun static void mcasp_set_ctl_reg(struct davinci_mcasp *mcasp, u32 ctl_reg, u32 val)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun int i = 0;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun mcasp_set_bits(mcasp, ctl_reg, val);
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /* programming GBLCTL needs to read back from GBLCTL and verfiy */
167*4882a593Smuzhiyun /* loop count is to avoid the lock-up */
168*4882a593Smuzhiyun for (i = 0; i < 1000; i++) {
169*4882a593Smuzhiyun if ((mcasp_get_reg(mcasp, ctl_reg) & val) == val)
170*4882a593Smuzhiyun break;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if (i == 1000 && ((mcasp_get_reg(mcasp, ctl_reg) & val) != val))
174*4882a593Smuzhiyun printk(KERN_ERR "GBLCTL write error\n");
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
mcasp_is_synchronous(struct davinci_mcasp * mcasp)177*4882a593Smuzhiyun static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun u32 rxfmctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG);
180*4882a593Smuzhiyun u32 aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun return !(aclkxctl & TX_ASYNC) && rxfmctl & AFSRE;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
mcasp_set_clk_pdir(struct davinci_mcasp * mcasp,bool enable)185*4882a593Smuzhiyun static inline void mcasp_set_clk_pdir(struct davinci_mcasp *mcasp, bool enable)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun u32 bit = PIN_BIT_AMUTE;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun for_each_set_bit_from(bit, &mcasp->pdir, PIN_BIT_AFSR + 1) {
190*4882a593Smuzhiyun if (enable)
191*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
192*4882a593Smuzhiyun else
193*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
mcasp_set_axr_pdir(struct davinci_mcasp * mcasp,bool enable)197*4882a593Smuzhiyun static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun u32 bit;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AMUTE) {
202*4882a593Smuzhiyun if (enable)
203*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
204*4882a593Smuzhiyun else
205*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
mcasp_start_rx(struct davinci_mcasp * mcasp)209*4882a593Smuzhiyun static void mcasp_start_rx(struct davinci_mcasp *mcasp)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun if (mcasp->rxnumevt) { /* enable FIFO */
212*4882a593Smuzhiyun u32 reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun mcasp_clr_bits(mcasp, reg, FIFO_ENABLE);
215*4882a593Smuzhiyun mcasp_set_bits(mcasp, reg, FIFO_ENABLE);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /* Start clocks */
219*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
220*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST);
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun * When ASYNC == 0 the transmit and receive sections operate
223*4882a593Smuzhiyun * synchronously from the transmit clock and frame sync. We need to make
224*4882a593Smuzhiyun * sure that the TX signlas are enabled when starting reception.
225*4882a593Smuzhiyun */
226*4882a593Smuzhiyun if (mcasp_is_synchronous(mcasp)) {
227*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
228*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
229*4882a593Smuzhiyun mcasp_set_clk_pdir(mcasp, true);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /* Activate serializer(s) */
233*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
234*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
235*4882a593Smuzhiyun /* Release RX state machine */
236*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
237*4882a593Smuzhiyun /* Release Frame Sync generator */
238*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
239*4882a593Smuzhiyun if (mcasp_is_synchronous(mcasp))
240*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun /* enable receive IRQs */
243*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_EVTCTLR_REG,
244*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE]);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
mcasp_start_tx(struct davinci_mcasp * mcasp)247*4882a593Smuzhiyun static void mcasp_start_tx(struct davinci_mcasp *mcasp)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun u32 cnt;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun if (mcasp->txnumevt) { /* enable FIFO */
252*4882a593Smuzhiyun u32 reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun mcasp_clr_bits(mcasp, reg, FIFO_ENABLE);
255*4882a593Smuzhiyun mcasp_set_bits(mcasp, reg, FIFO_ENABLE);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /* Start clocks */
259*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
260*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
261*4882a593Smuzhiyun mcasp_set_clk_pdir(mcasp, true);
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /* Activate serializer(s) */
264*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
265*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /* wait for XDATA to be cleared */
268*4882a593Smuzhiyun cnt = 0;
269*4882a593Smuzhiyun while ((mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG) & XRDATA) &&
270*4882a593Smuzhiyun (cnt < 100000))
271*4882a593Smuzhiyun cnt++;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun mcasp_set_axr_pdir(mcasp, true);
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun /* Release TX state machine */
276*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
277*4882a593Smuzhiyun /* Release Frame Sync generator */
278*4882a593Smuzhiyun mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /* enable transmit IRQs */
281*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_EVTCTLX_REG,
282*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK]);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
davinci_mcasp_start(struct davinci_mcasp * mcasp,int stream)285*4882a593Smuzhiyun static void davinci_mcasp_start(struct davinci_mcasp *mcasp, int stream)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun mcasp->streams++;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun if (stream == SNDRV_PCM_STREAM_PLAYBACK)
290*4882a593Smuzhiyun mcasp_start_tx(mcasp);
291*4882a593Smuzhiyun else
292*4882a593Smuzhiyun mcasp_start_rx(mcasp);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
mcasp_stop_rx(struct davinci_mcasp * mcasp)295*4882a593Smuzhiyun static void mcasp_stop_rx(struct davinci_mcasp *mcasp)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun /* disable IRQ sources */
298*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_EVTCTLR_REG,
299*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE]);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /*
302*4882a593Smuzhiyun * In synchronous mode stop the TX clocks if no other stream is
303*4882a593Smuzhiyun * running
304*4882a593Smuzhiyun */
305*4882a593Smuzhiyun if (mcasp_is_synchronous(mcasp) && !mcasp->streams) {
306*4882a593Smuzhiyun mcasp_set_clk_pdir(mcasp, false);
307*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0);
311*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun if (mcasp->rxnumevt) { /* disable FIFO */
314*4882a593Smuzhiyun u32 reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun mcasp_clr_bits(mcasp, reg, FIFO_ENABLE);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun }
319*4882a593Smuzhiyun
mcasp_stop_tx(struct davinci_mcasp * mcasp)320*4882a593Smuzhiyun static void mcasp_stop_tx(struct davinci_mcasp *mcasp)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun u32 val = 0;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun /* disable IRQ sources */
325*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_EVTCTLX_REG,
326*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK]);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun /*
329*4882a593Smuzhiyun * In synchronous mode keep TX clocks running if the capture stream is
330*4882a593Smuzhiyun * still running.
331*4882a593Smuzhiyun */
332*4882a593Smuzhiyun if (mcasp_is_synchronous(mcasp) && mcasp->streams)
333*4882a593Smuzhiyun val = TXHCLKRST | TXCLKRST | TXFSRST;
334*4882a593Smuzhiyun else
335*4882a593Smuzhiyun mcasp_set_clk_pdir(mcasp, false);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val);
339*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun if (mcasp->txnumevt) { /* disable FIFO */
342*4882a593Smuzhiyun u32 reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun mcasp_clr_bits(mcasp, reg, FIFO_ENABLE);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun mcasp_set_axr_pdir(mcasp, false);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
davinci_mcasp_stop(struct davinci_mcasp * mcasp,int stream)350*4882a593Smuzhiyun static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun mcasp->streams--;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (stream == SNDRV_PCM_STREAM_PLAYBACK)
355*4882a593Smuzhiyun mcasp_stop_tx(mcasp);
356*4882a593Smuzhiyun else
357*4882a593Smuzhiyun mcasp_stop_rx(mcasp);
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
davinci_mcasp_tx_irq_handler(int irq,void * data)360*4882a593Smuzhiyun static irqreturn_t davinci_mcasp_tx_irq_handler(int irq, void *data)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun struct davinci_mcasp *mcasp = (struct davinci_mcasp *)data;
363*4882a593Smuzhiyun struct snd_pcm_substream *substream;
364*4882a593Smuzhiyun u32 irq_mask = mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK];
365*4882a593Smuzhiyun u32 handled_mask = 0;
366*4882a593Smuzhiyun u32 stat;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun stat = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG);
369*4882a593Smuzhiyun if (stat & XUNDRN & irq_mask) {
370*4882a593Smuzhiyun dev_warn(mcasp->dev, "Transmit buffer underflow\n");
371*4882a593Smuzhiyun handled_mask |= XUNDRN;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun substream = mcasp->substreams[SNDRV_PCM_STREAM_PLAYBACK];
374*4882a593Smuzhiyun if (substream)
375*4882a593Smuzhiyun snd_pcm_stop_xrun(substream);
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun if (!handled_mask)
379*4882a593Smuzhiyun dev_warn(mcasp->dev, "unhandled tx event. txstat: 0x%08x\n",
380*4882a593Smuzhiyun stat);
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun if (stat & XRERR)
383*4882a593Smuzhiyun handled_mask |= XRERR;
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun /* Ack the handled event only */
386*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, handled_mask);
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun return IRQ_RETVAL(handled_mask);
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
davinci_mcasp_rx_irq_handler(int irq,void * data)391*4882a593Smuzhiyun static irqreturn_t davinci_mcasp_rx_irq_handler(int irq, void *data)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun struct davinci_mcasp *mcasp = (struct davinci_mcasp *)data;
394*4882a593Smuzhiyun struct snd_pcm_substream *substream;
395*4882a593Smuzhiyun u32 irq_mask = mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE];
396*4882a593Smuzhiyun u32 handled_mask = 0;
397*4882a593Smuzhiyun u32 stat;
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun stat = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG);
400*4882a593Smuzhiyun if (stat & ROVRN & irq_mask) {
401*4882a593Smuzhiyun dev_warn(mcasp->dev, "Receive buffer overflow\n");
402*4882a593Smuzhiyun handled_mask |= ROVRN;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun substream = mcasp->substreams[SNDRV_PCM_STREAM_CAPTURE];
405*4882a593Smuzhiyun if (substream)
406*4882a593Smuzhiyun snd_pcm_stop_xrun(substream);
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (!handled_mask)
410*4882a593Smuzhiyun dev_warn(mcasp->dev, "unhandled rx event. rxstat: 0x%08x\n",
411*4882a593Smuzhiyun stat);
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun if (stat & XRERR)
414*4882a593Smuzhiyun handled_mask |= XRERR;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /* Ack the handled event only */
417*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, handled_mask);
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun return IRQ_RETVAL(handled_mask);
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun
davinci_mcasp_common_irq_handler(int irq,void * data)422*4882a593Smuzhiyun static irqreturn_t davinci_mcasp_common_irq_handler(int irq, void *data)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun struct davinci_mcasp *mcasp = (struct davinci_mcasp *)data;
425*4882a593Smuzhiyun irqreturn_t ret = IRQ_NONE;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun if (mcasp->substreams[SNDRV_PCM_STREAM_PLAYBACK])
428*4882a593Smuzhiyun ret = davinci_mcasp_tx_irq_handler(irq, data);
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun if (mcasp->substreams[SNDRV_PCM_STREAM_CAPTURE])
431*4882a593Smuzhiyun ret |= davinci_mcasp_rx_irq_handler(irq, data);
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun return ret;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
davinci_mcasp_set_dai_fmt(struct snd_soc_dai * cpu_dai,unsigned int fmt)436*4882a593Smuzhiyun static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
437*4882a593Smuzhiyun unsigned int fmt)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
440*4882a593Smuzhiyun int ret = 0;
441*4882a593Smuzhiyun u32 data_delay;
442*4882a593Smuzhiyun bool fs_pol_rising;
443*4882a593Smuzhiyun bool inv_fs = false;
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun if (!fmt)
446*4882a593Smuzhiyun return 0;
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun pm_runtime_get_sync(mcasp->dev);
449*4882a593Smuzhiyun switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
450*4882a593Smuzhiyun case SND_SOC_DAIFMT_DSP_A:
451*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
452*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
453*4882a593Smuzhiyun /* 1st data bit occur one ACLK cycle after the frame sync */
454*4882a593Smuzhiyun data_delay = 1;
455*4882a593Smuzhiyun break;
456*4882a593Smuzhiyun case SND_SOC_DAIFMT_DSP_B:
457*4882a593Smuzhiyun case SND_SOC_DAIFMT_AC97:
458*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
459*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
460*4882a593Smuzhiyun /* No delay after FS */
461*4882a593Smuzhiyun data_delay = 0;
462*4882a593Smuzhiyun break;
463*4882a593Smuzhiyun case SND_SOC_DAIFMT_I2S:
464*4882a593Smuzhiyun /* configure a full-word SYNC pulse (LRCLK) */
465*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
466*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
467*4882a593Smuzhiyun /* 1st data bit occur one ACLK cycle after the frame sync */
468*4882a593Smuzhiyun data_delay = 1;
469*4882a593Smuzhiyun /* FS need to be inverted */
470*4882a593Smuzhiyun inv_fs = true;
471*4882a593Smuzhiyun break;
472*4882a593Smuzhiyun case SND_SOC_DAIFMT_RIGHT_J:
473*4882a593Smuzhiyun case SND_SOC_DAIFMT_LEFT_J:
474*4882a593Smuzhiyun /* configure a full-word SYNC pulse (LRCLK) */
475*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
476*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
477*4882a593Smuzhiyun /* No delay after FS */
478*4882a593Smuzhiyun data_delay = 0;
479*4882a593Smuzhiyun break;
480*4882a593Smuzhiyun default:
481*4882a593Smuzhiyun ret = -EINVAL;
482*4882a593Smuzhiyun goto out;
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay),
486*4882a593Smuzhiyun FSXDLY(3));
487*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay),
488*4882a593Smuzhiyun FSRDLY(3));
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
491*4882a593Smuzhiyun case SND_SOC_DAIFMT_CBS_CFS:
492*4882a593Smuzhiyun /* codec is clock and frame slave */
493*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
494*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
497*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun /* BCLK */
500*4882a593Smuzhiyun set_bit(PIN_BIT_ACLKX, &mcasp->pdir);
501*4882a593Smuzhiyun set_bit(PIN_BIT_ACLKR, &mcasp->pdir);
502*4882a593Smuzhiyun /* Frame Sync */
503*4882a593Smuzhiyun set_bit(PIN_BIT_AFSX, &mcasp->pdir);
504*4882a593Smuzhiyun set_bit(PIN_BIT_AFSR, &mcasp->pdir);
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun mcasp->bclk_master = 1;
507*4882a593Smuzhiyun break;
508*4882a593Smuzhiyun case SND_SOC_DAIFMT_CBS_CFM:
509*4882a593Smuzhiyun /* codec is clock slave and frame master */
510*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
511*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
514*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun /* BCLK */
517*4882a593Smuzhiyun set_bit(PIN_BIT_ACLKX, &mcasp->pdir);
518*4882a593Smuzhiyun set_bit(PIN_BIT_ACLKR, &mcasp->pdir);
519*4882a593Smuzhiyun /* Frame Sync */
520*4882a593Smuzhiyun clear_bit(PIN_BIT_AFSX, &mcasp->pdir);
521*4882a593Smuzhiyun clear_bit(PIN_BIT_AFSR, &mcasp->pdir);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun mcasp->bclk_master = 1;
524*4882a593Smuzhiyun break;
525*4882a593Smuzhiyun case SND_SOC_DAIFMT_CBM_CFS:
526*4882a593Smuzhiyun /* codec is clock master and frame slave */
527*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
528*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
531*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun /* BCLK */
534*4882a593Smuzhiyun clear_bit(PIN_BIT_ACLKX, &mcasp->pdir);
535*4882a593Smuzhiyun clear_bit(PIN_BIT_ACLKR, &mcasp->pdir);
536*4882a593Smuzhiyun /* Frame Sync */
537*4882a593Smuzhiyun set_bit(PIN_BIT_AFSX, &mcasp->pdir);
538*4882a593Smuzhiyun set_bit(PIN_BIT_AFSR, &mcasp->pdir);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun mcasp->bclk_master = 0;
541*4882a593Smuzhiyun break;
542*4882a593Smuzhiyun case SND_SOC_DAIFMT_CBM_CFM:
543*4882a593Smuzhiyun /* codec is clock and frame master */
544*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
545*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
548*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun /* BCLK */
551*4882a593Smuzhiyun clear_bit(PIN_BIT_ACLKX, &mcasp->pdir);
552*4882a593Smuzhiyun clear_bit(PIN_BIT_ACLKR, &mcasp->pdir);
553*4882a593Smuzhiyun /* Frame Sync */
554*4882a593Smuzhiyun clear_bit(PIN_BIT_AFSX, &mcasp->pdir);
555*4882a593Smuzhiyun clear_bit(PIN_BIT_AFSR, &mcasp->pdir);
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun mcasp->bclk_master = 0;
558*4882a593Smuzhiyun break;
559*4882a593Smuzhiyun default:
560*4882a593Smuzhiyun ret = -EINVAL;
561*4882a593Smuzhiyun goto out;
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
565*4882a593Smuzhiyun case SND_SOC_DAIFMT_IB_NF:
566*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
567*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
568*4882a593Smuzhiyun fs_pol_rising = true;
569*4882a593Smuzhiyun break;
570*4882a593Smuzhiyun case SND_SOC_DAIFMT_NB_IF:
571*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
572*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
573*4882a593Smuzhiyun fs_pol_rising = false;
574*4882a593Smuzhiyun break;
575*4882a593Smuzhiyun case SND_SOC_DAIFMT_IB_IF:
576*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
577*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
578*4882a593Smuzhiyun fs_pol_rising = false;
579*4882a593Smuzhiyun break;
580*4882a593Smuzhiyun case SND_SOC_DAIFMT_NB_NF:
581*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
582*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
583*4882a593Smuzhiyun fs_pol_rising = true;
584*4882a593Smuzhiyun break;
585*4882a593Smuzhiyun default:
586*4882a593Smuzhiyun ret = -EINVAL;
587*4882a593Smuzhiyun goto out;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun if (inv_fs)
591*4882a593Smuzhiyun fs_pol_rising = !fs_pol_rising;
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun if (fs_pol_rising) {
594*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
595*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
596*4882a593Smuzhiyun } else {
597*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
598*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun mcasp->dai_fmt = fmt;
602*4882a593Smuzhiyun out:
603*4882a593Smuzhiyun pm_runtime_put(mcasp->dev);
604*4882a593Smuzhiyun return ret;
605*4882a593Smuzhiyun }
606*4882a593Smuzhiyun
__davinci_mcasp_set_clkdiv(struct davinci_mcasp * mcasp,int div_id,int div,bool explicit)607*4882a593Smuzhiyun static int __davinci_mcasp_set_clkdiv(struct davinci_mcasp *mcasp, int div_id,
608*4882a593Smuzhiyun int div, bool explicit)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun pm_runtime_get_sync(mcasp->dev);
611*4882a593Smuzhiyun switch (div_id) {
612*4882a593Smuzhiyun case MCASP_CLKDIV_AUXCLK: /* MCLK divider */
613*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG,
614*4882a593Smuzhiyun AHCLKXDIV(div - 1), AHCLKXDIV_MASK);
615*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG,
616*4882a593Smuzhiyun AHCLKRDIV(div - 1), AHCLKRDIV_MASK);
617*4882a593Smuzhiyun break;
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun case MCASP_CLKDIV_BCLK: /* BCLK divider */
620*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG,
621*4882a593Smuzhiyun ACLKXDIV(div - 1), ACLKXDIV_MASK);
622*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG,
623*4882a593Smuzhiyun ACLKRDIV(div - 1), ACLKRDIV_MASK);
624*4882a593Smuzhiyun if (explicit)
625*4882a593Smuzhiyun mcasp->bclk_div = div;
626*4882a593Smuzhiyun break;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun case MCASP_CLKDIV_BCLK_FS_RATIO:
629*4882a593Smuzhiyun /*
630*4882a593Smuzhiyun * BCLK/LRCLK ratio descries how many bit-clock cycles
631*4882a593Smuzhiyun * fit into one frame. The clock ratio is given for a
632*4882a593Smuzhiyun * full period of data (for I2S format both left and
633*4882a593Smuzhiyun * right channels), so it has to be divided by number
634*4882a593Smuzhiyun * of tdm-slots (for I2S - divided by 2).
635*4882a593Smuzhiyun * Instead of storing this ratio, we calculate a new
636*4882a593Smuzhiyun * tdm_slot width by dividing the ratio by the
637*4882a593Smuzhiyun * number of configured tdm slots.
638*4882a593Smuzhiyun */
639*4882a593Smuzhiyun mcasp->slot_width = div / mcasp->tdm_slots;
640*4882a593Smuzhiyun if (div % mcasp->tdm_slots)
641*4882a593Smuzhiyun dev_warn(mcasp->dev,
642*4882a593Smuzhiyun "%s(): BCLK/LRCLK %d is not divisible by %d tdm slots",
643*4882a593Smuzhiyun __func__, div, mcasp->tdm_slots);
644*4882a593Smuzhiyun break;
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun default:
647*4882a593Smuzhiyun return -EINVAL;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun pm_runtime_put(mcasp->dev);
651*4882a593Smuzhiyun return 0;
652*4882a593Smuzhiyun }
653*4882a593Smuzhiyun
davinci_mcasp_set_clkdiv(struct snd_soc_dai * dai,int div_id,int div)654*4882a593Smuzhiyun static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
655*4882a593Smuzhiyun int div)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun return __davinci_mcasp_set_clkdiv(mcasp, div_id, div, 1);
660*4882a593Smuzhiyun }
661*4882a593Smuzhiyun
davinci_mcasp_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)662*4882a593Smuzhiyun static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
663*4882a593Smuzhiyun unsigned int freq, int dir)
664*4882a593Smuzhiyun {
665*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun pm_runtime_get_sync(mcasp->dev);
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun if (dir == SND_SOC_CLOCK_IN) {
670*4882a593Smuzhiyun switch (clk_id) {
671*4882a593Smuzhiyun case MCASP_CLK_HCLK_AHCLK:
672*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG,
673*4882a593Smuzhiyun AHCLKXE);
674*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG,
675*4882a593Smuzhiyun AHCLKRE);
676*4882a593Smuzhiyun clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir);
677*4882a593Smuzhiyun break;
678*4882a593Smuzhiyun case MCASP_CLK_HCLK_AUXCLK:
679*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG,
680*4882a593Smuzhiyun AHCLKXE);
681*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG,
682*4882a593Smuzhiyun AHCLKRE);
683*4882a593Smuzhiyun set_bit(PIN_BIT_AHCLKX, &mcasp->pdir);
684*4882a593Smuzhiyun break;
685*4882a593Smuzhiyun default:
686*4882a593Smuzhiyun dev_err(mcasp->dev, "Invalid clk id: %d\n", clk_id);
687*4882a593Smuzhiyun goto out;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun } else {
690*4882a593Smuzhiyun /* Select AUXCLK as HCLK */
691*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
692*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
693*4882a593Smuzhiyun set_bit(PIN_BIT_AHCLKX, &mcasp->pdir);
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun /*
696*4882a593Smuzhiyun * When AHCLK X/R is selected to be output it means that the HCLK is
697*4882a593Smuzhiyun * the same clock - coming via AUXCLK.
698*4882a593Smuzhiyun */
699*4882a593Smuzhiyun mcasp->sysclk_freq = freq;
700*4882a593Smuzhiyun out:
701*4882a593Smuzhiyun pm_runtime_put(mcasp->dev);
702*4882a593Smuzhiyun return 0;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun /* All serializers must have equal number of channels */
davinci_mcasp_ch_constraint(struct davinci_mcasp * mcasp,int stream,int serializers)706*4882a593Smuzhiyun static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream,
707*4882a593Smuzhiyun int serializers)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream];
710*4882a593Smuzhiyun unsigned int *list = (unsigned int *) cl->list;
711*4882a593Smuzhiyun int slots = mcasp->tdm_slots;
712*4882a593Smuzhiyun int i, count = 0;
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun if (mcasp->tdm_mask[stream])
715*4882a593Smuzhiyun slots = hweight32(mcasp->tdm_mask[stream]);
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun for (i = 1; i <= slots; i++)
718*4882a593Smuzhiyun list[count++] = i;
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun for (i = 2; i <= serializers; i++)
721*4882a593Smuzhiyun list[count++] = i*slots;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun cl->count = count;
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun return 0;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun
davinci_mcasp_set_ch_constraints(struct davinci_mcasp * mcasp)728*4882a593Smuzhiyun static int davinci_mcasp_set_ch_constraints(struct davinci_mcasp *mcasp)
729*4882a593Smuzhiyun {
730*4882a593Smuzhiyun int rx_serializers = 0, tx_serializers = 0, ret, i;
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun for (i = 0; i < mcasp->num_serializer; i++)
733*4882a593Smuzhiyun if (mcasp->serial_dir[i] == TX_MODE)
734*4882a593Smuzhiyun tx_serializers++;
735*4882a593Smuzhiyun else if (mcasp->serial_dir[i] == RX_MODE)
736*4882a593Smuzhiyun rx_serializers++;
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_PLAYBACK,
739*4882a593Smuzhiyun tx_serializers);
740*4882a593Smuzhiyun if (ret)
741*4882a593Smuzhiyun return ret;
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_CAPTURE,
744*4882a593Smuzhiyun rx_serializers);
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun return ret;
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun
davinci_mcasp_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)750*4882a593Smuzhiyun static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
751*4882a593Smuzhiyun unsigned int tx_mask,
752*4882a593Smuzhiyun unsigned int rx_mask,
753*4882a593Smuzhiyun int slots, int slot_width)
754*4882a593Smuzhiyun {
755*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun dev_dbg(mcasp->dev,
758*4882a593Smuzhiyun "%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",
759*4882a593Smuzhiyun __func__, tx_mask, rx_mask, slots, slot_width);
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
762*4882a593Smuzhiyun dev_err(mcasp->dev,
763*4882a593Smuzhiyun "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
764*4882a593Smuzhiyun tx_mask, rx_mask, slots);
765*4882a593Smuzhiyun return -EINVAL;
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun if (slot_width &&
769*4882a593Smuzhiyun (slot_width < 8 || slot_width > 32 || slot_width % 4 != 0)) {
770*4882a593Smuzhiyun dev_err(mcasp->dev, "%s: Unsupported slot_width %d\n",
771*4882a593Smuzhiyun __func__, slot_width);
772*4882a593Smuzhiyun return -EINVAL;
773*4882a593Smuzhiyun }
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun mcasp->tdm_slots = slots;
776*4882a593Smuzhiyun mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
777*4882a593Smuzhiyun mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
778*4882a593Smuzhiyun mcasp->slot_width = slot_width;
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun return davinci_mcasp_set_ch_constraints(mcasp);
781*4882a593Smuzhiyun }
782*4882a593Smuzhiyun
davinci_config_channel_size(struct davinci_mcasp * mcasp,int sample_width)783*4882a593Smuzhiyun static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
784*4882a593Smuzhiyun int sample_width)
785*4882a593Smuzhiyun {
786*4882a593Smuzhiyun u32 fmt;
787*4882a593Smuzhiyun u32 tx_rotate, rx_rotate, slot_width;
788*4882a593Smuzhiyun u32 mask = (1ULL << sample_width) - 1;
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun if (mcasp->slot_width)
791*4882a593Smuzhiyun slot_width = mcasp->slot_width;
792*4882a593Smuzhiyun else if (mcasp->max_format_width)
793*4882a593Smuzhiyun slot_width = mcasp->max_format_width;
794*4882a593Smuzhiyun else
795*4882a593Smuzhiyun slot_width = sample_width;
796*4882a593Smuzhiyun /*
797*4882a593Smuzhiyun * TX rotation:
798*4882a593Smuzhiyun * right aligned formats: rotate w/ slot_width
799*4882a593Smuzhiyun * left aligned formats: rotate w/ sample_width
800*4882a593Smuzhiyun *
801*4882a593Smuzhiyun * RX rotation:
802*4882a593Smuzhiyun * right aligned formats: no rotation needed
803*4882a593Smuzhiyun * left aligned formats: rotate w/ (slot_width - sample_width)
804*4882a593Smuzhiyun */
805*4882a593Smuzhiyun if ((mcasp->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
806*4882a593Smuzhiyun SND_SOC_DAIFMT_RIGHT_J) {
807*4882a593Smuzhiyun tx_rotate = (slot_width / 4) & 0x7;
808*4882a593Smuzhiyun rx_rotate = 0;
809*4882a593Smuzhiyun } else {
810*4882a593Smuzhiyun tx_rotate = (sample_width / 4) & 0x7;
811*4882a593Smuzhiyun rx_rotate = (slot_width - sample_width) / 4;
812*4882a593Smuzhiyun }
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun /* mapping of the XSSZ bit-field as described in the datasheet */
815*4882a593Smuzhiyun fmt = (slot_width >> 1) - 1;
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
818*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),
819*4882a593Smuzhiyun RXSSZ(0x0F));
820*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt),
821*4882a593Smuzhiyun TXSSZ(0x0F));
822*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate),
823*4882a593Smuzhiyun TXROT(7));
824*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate),
825*4882a593Smuzhiyun RXROT(7));
826*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask);
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun
829*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask);
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun return 0;
832*4882a593Smuzhiyun }
833*4882a593Smuzhiyun
mcasp_common_hw_param(struct davinci_mcasp * mcasp,int stream,int period_words,int channels)834*4882a593Smuzhiyun static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
835*4882a593Smuzhiyun int period_words, int channels)
836*4882a593Smuzhiyun {
837*4882a593Smuzhiyun struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream];
838*4882a593Smuzhiyun int i;
839*4882a593Smuzhiyun u8 tx_ser = 0;
840*4882a593Smuzhiyun u8 rx_ser = 0;
841*4882a593Smuzhiyun u8 slots = mcasp->tdm_slots;
842*4882a593Smuzhiyun u8 max_active_serializers = (channels + slots - 1) / slots;
843*4882a593Smuzhiyun u8 max_rx_serializers, max_tx_serializers;
844*4882a593Smuzhiyun int active_serializers, numevt;
845*4882a593Smuzhiyun u32 reg;
846*4882a593Smuzhiyun /* Default configuration */
847*4882a593Smuzhiyun if (mcasp->version < MCASP_VERSION_3)
848*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
851*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
852*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
853*4882a593Smuzhiyun max_tx_serializers = max_active_serializers;
854*4882a593Smuzhiyun max_rx_serializers =
855*4882a593Smuzhiyun mcasp->active_serializers[SNDRV_PCM_STREAM_CAPTURE];
856*4882a593Smuzhiyun } else {
857*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
858*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_REVTCTL_REG, RXDATADMADIS);
859*4882a593Smuzhiyun max_tx_serializers =
860*4882a593Smuzhiyun mcasp->active_serializers[SNDRV_PCM_STREAM_PLAYBACK];
861*4882a593Smuzhiyun max_rx_serializers = max_active_serializers;
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun for (i = 0; i < mcasp->num_serializer; i++) {
865*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
866*4882a593Smuzhiyun mcasp->serial_dir[i]);
867*4882a593Smuzhiyun if (mcasp->serial_dir[i] == TX_MODE &&
868*4882a593Smuzhiyun tx_ser < max_tx_serializers) {
869*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
870*4882a593Smuzhiyun mcasp->dismod, DISMOD_MASK);
871*4882a593Smuzhiyun set_bit(PIN_BIT_AXR(i), &mcasp->pdir);
872*4882a593Smuzhiyun tx_ser++;
873*4882a593Smuzhiyun } else if (mcasp->serial_dir[i] == RX_MODE &&
874*4882a593Smuzhiyun rx_ser < max_rx_serializers) {
875*4882a593Smuzhiyun clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
876*4882a593Smuzhiyun rx_ser++;
877*4882a593Smuzhiyun } else {
878*4882a593Smuzhiyun /* Inactive or unused pin, set it to inactive */
879*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
880*4882a593Smuzhiyun SRMOD_INACTIVE, SRMOD_MASK);
881*4882a593Smuzhiyun /* If unused, set DISMOD for the pin */
882*4882a593Smuzhiyun if (mcasp->serial_dir[i] != INACTIVE_MODE)
883*4882a593Smuzhiyun mcasp_mod_bits(mcasp,
884*4882a593Smuzhiyun DAVINCI_MCASP_XRSRCTL_REG(i),
885*4882a593Smuzhiyun mcasp->dismod, DISMOD_MASK);
886*4882a593Smuzhiyun clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
887*4882a593Smuzhiyun }
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
891*4882a593Smuzhiyun active_serializers = tx_ser;
892*4882a593Smuzhiyun numevt = mcasp->txnumevt;
893*4882a593Smuzhiyun reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
894*4882a593Smuzhiyun } else {
895*4882a593Smuzhiyun active_serializers = rx_ser;
896*4882a593Smuzhiyun numevt = mcasp->rxnumevt;
897*4882a593Smuzhiyun reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun if (active_serializers < max_active_serializers) {
901*4882a593Smuzhiyun dev_warn(mcasp->dev, "stream has more channels (%d) than are "
902*4882a593Smuzhiyun "enabled in mcasp (%d)\n", channels,
903*4882a593Smuzhiyun active_serializers * slots);
904*4882a593Smuzhiyun return -EINVAL;
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun /* AFIFO is not in use */
908*4882a593Smuzhiyun if (!numevt) {
909*4882a593Smuzhiyun /* Configure the burst size for platform drivers */
910*4882a593Smuzhiyun if (active_serializers > 1) {
911*4882a593Smuzhiyun /*
912*4882a593Smuzhiyun * If more than one serializers are in use we have one
913*4882a593Smuzhiyun * DMA request to provide data for all serializers.
914*4882a593Smuzhiyun * For example if three serializers are enabled the DMA
915*4882a593Smuzhiyun * need to transfer three words per DMA request.
916*4882a593Smuzhiyun */
917*4882a593Smuzhiyun dma_data->maxburst = active_serializers;
918*4882a593Smuzhiyun } else {
919*4882a593Smuzhiyun dma_data->maxburst = 0;
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun goto out;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun if (period_words % active_serializers) {
926*4882a593Smuzhiyun dev_err(mcasp->dev, "Invalid combination of period words and "
927*4882a593Smuzhiyun "active serializers: %d, %d\n", period_words,
928*4882a593Smuzhiyun active_serializers);
929*4882a593Smuzhiyun return -EINVAL;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun /*
933*4882a593Smuzhiyun * Calculate the optimal AFIFO depth for platform side:
934*4882a593Smuzhiyun * The number of words for numevt need to be in steps of active
935*4882a593Smuzhiyun * serializers.
936*4882a593Smuzhiyun */
937*4882a593Smuzhiyun numevt = (numevt / active_serializers) * active_serializers;
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun while (period_words % numevt && numevt > 0)
940*4882a593Smuzhiyun numevt -= active_serializers;
941*4882a593Smuzhiyun if (numevt <= 0)
942*4882a593Smuzhiyun numevt = active_serializers;
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK);
945*4882a593Smuzhiyun mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK);
946*4882a593Smuzhiyun
947*4882a593Smuzhiyun /* Configure the burst size for platform drivers */
948*4882a593Smuzhiyun if (numevt == 1)
949*4882a593Smuzhiyun numevt = 0;
950*4882a593Smuzhiyun dma_data->maxburst = numevt;
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun out:
953*4882a593Smuzhiyun mcasp->active_serializers[stream] = active_serializers;
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun return 0;
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun
mcasp_i2s_hw_param(struct davinci_mcasp * mcasp,int stream,int channels)958*4882a593Smuzhiyun static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
959*4882a593Smuzhiyun int channels)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun int i, active_slots;
962*4882a593Smuzhiyun int total_slots;
963*4882a593Smuzhiyun int active_serializers;
964*4882a593Smuzhiyun u32 mask = 0;
965*4882a593Smuzhiyun u32 busel = 0;
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun total_slots = mcasp->tdm_slots;
968*4882a593Smuzhiyun
969*4882a593Smuzhiyun /*
970*4882a593Smuzhiyun * If more than one serializer is needed, then use them with
971*4882a593Smuzhiyun * all the specified tdm_slots. Otherwise, one serializer can
972*4882a593Smuzhiyun * cope with the transaction using just as many slots as there
973*4882a593Smuzhiyun * are channels in the stream.
974*4882a593Smuzhiyun */
975*4882a593Smuzhiyun if (mcasp->tdm_mask[stream]) {
976*4882a593Smuzhiyun active_slots = hweight32(mcasp->tdm_mask[stream]);
977*4882a593Smuzhiyun active_serializers = (channels + active_slots - 1) /
978*4882a593Smuzhiyun active_slots;
979*4882a593Smuzhiyun if (active_serializers == 1)
980*4882a593Smuzhiyun active_slots = channels;
981*4882a593Smuzhiyun for (i = 0; i < total_slots; i++) {
982*4882a593Smuzhiyun if ((1 << i) & mcasp->tdm_mask[stream]) {
983*4882a593Smuzhiyun mask |= (1 << i);
984*4882a593Smuzhiyun if (--active_slots <= 0)
985*4882a593Smuzhiyun break;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun }
988*4882a593Smuzhiyun } else {
989*4882a593Smuzhiyun active_serializers = (channels + total_slots - 1) / total_slots;
990*4882a593Smuzhiyun if (active_serializers == 1)
991*4882a593Smuzhiyun active_slots = channels;
992*4882a593Smuzhiyun else
993*4882a593Smuzhiyun active_slots = total_slots;
994*4882a593Smuzhiyun
995*4882a593Smuzhiyun for (i = 0; i < active_slots; i++)
996*4882a593Smuzhiyun mask |= (1 << i);
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
1000*4882a593Smuzhiyun
1001*4882a593Smuzhiyun if (!mcasp->dat_port)
1002*4882a593Smuzhiyun busel = TXSEL;
1003*4882a593Smuzhiyun
1004*4882a593Smuzhiyun if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1005*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
1006*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
1007*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
1008*4882a593Smuzhiyun FSXMOD(total_slots), FSXMOD(0x1FF));
1009*4882a593Smuzhiyun } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
1010*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
1011*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
1012*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
1013*4882a593Smuzhiyun FSRMOD(total_slots), FSRMOD(0x1FF));
1014*4882a593Smuzhiyun /*
1015*4882a593Smuzhiyun * If McASP is set to be TX/RX synchronous and the playback is
1016*4882a593Smuzhiyun * not running already we need to configure the TX slots in
1017*4882a593Smuzhiyun * order to have correct FSX on the bus
1018*4882a593Smuzhiyun */
1019*4882a593Smuzhiyun if (mcasp_is_synchronous(mcasp) && !mcasp->channels)
1020*4882a593Smuzhiyun mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
1021*4882a593Smuzhiyun FSXMOD(total_slots), FSXMOD(0x1FF));
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun return 0;
1025*4882a593Smuzhiyun }
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun /* S/PDIF */
mcasp_dit_hw_param(struct davinci_mcasp * mcasp,unsigned int rate)1028*4882a593Smuzhiyun static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
1029*4882a593Smuzhiyun unsigned int rate)
1030*4882a593Smuzhiyun {
1031*4882a593Smuzhiyun u32 cs_value = 0;
1032*4882a593Smuzhiyun u8 *cs_bytes = (u8*) &cs_value;
1033*4882a593Smuzhiyun
1034*4882a593Smuzhiyun /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
1035*4882a593Smuzhiyun and LSB first */
1036*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15));
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
1039*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE | FSXMOD(0x180));
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun /* Set the TX tdm : for all the slots */
1042*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
1043*4882a593Smuzhiyun
1044*4882a593Smuzhiyun /* Set the TX clock controls : div = 1 and internal */
1045*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE | TX_ASYNC);
1046*4882a593Smuzhiyun
1047*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
1048*4882a593Smuzhiyun
1049*4882a593Smuzhiyun /* Only 44100 and 48000 are valid, both have the same setting */
1050*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun /* Enable the DIT */
1053*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN);
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun /* Set S/PDIF channel status bits */
1056*4882a593Smuzhiyun cs_bytes[0] = IEC958_AES0_CON_NOT_COPYRIGHT;
1057*4882a593Smuzhiyun cs_bytes[1] = IEC958_AES1_CON_PCM_CODER;
1058*4882a593Smuzhiyun
1059*4882a593Smuzhiyun switch (rate) {
1060*4882a593Smuzhiyun case 22050:
1061*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_22050;
1062*4882a593Smuzhiyun break;
1063*4882a593Smuzhiyun case 24000:
1064*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_24000;
1065*4882a593Smuzhiyun break;
1066*4882a593Smuzhiyun case 32000:
1067*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_32000;
1068*4882a593Smuzhiyun break;
1069*4882a593Smuzhiyun case 44100:
1070*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_44100;
1071*4882a593Smuzhiyun break;
1072*4882a593Smuzhiyun case 48000:
1073*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_48000;
1074*4882a593Smuzhiyun break;
1075*4882a593Smuzhiyun case 88200:
1076*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_88200;
1077*4882a593Smuzhiyun break;
1078*4882a593Smuzhiyun case 96000:
1079*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_96000;
1080*4882a593Smuzhiyun break;
1081*4882a593Smuzhiyun case 176400:
1082*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_176400;
1083*4882a593Smuzhiyun break;
1084*4882a593Smuzhiyun case 192000:
1085*4882a593Smuzhiyun cs_bytes[3] |= IEC958_AES3_CON_FS_192000;
1086*4882a593Smuzhiyun break;
1087*4882a593Smuzhiyun default:
1088*4882a593Smuzhiyun printk(KERN_WARNING "unsupported sampling rate: %d\n", rate);
1089*4882a593Smuzhiyun return -EINVAL;
1090*4882a593Smuzhiyun }
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRA_REG, cs_value);
1093*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_DITCSRB_REG, cs_value);
1094*4882a593Smuzhiyun
1095*4882a593Smuzhiyun return 0;
1096*4882a593Smuzhiyun }
1097*4882a593Smuzhiyun
davinci_mcasp_calc_clk_div(struct davinci_mcasp * mcasp,unsigned int sysclk_freq,unsigned int bclk_freq,bool set)1098*4882a593Smuzhiyun static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
1099*4882a593Smuzhiyun unsigned int sysclk_freq,
1100*4882a593Smuzhiyun unsigned int bclk_freq, bool set)
1101*4882a593Smuzhiyun {
1102*4882a593Smuzhiyun u32 reg = mcasp_get_reg(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG);
1103*4882a593Smuzhiyun int div = sysclk_freq / bclk_freq;
1104*4882a593Smuzhiyun int rem = sysclk_freq % bclk_freq;
1105*4882a593Smuzhiyun int error_ppm;
1106*4882a593Smuzhiyun int aux_div = 1;
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun if (div > (ACLKXDIV_MASK + 1)) {
1109*4882a593Smuzhiyun if (reg & AHCLKXE) {
1110*4882a593Smuzhiyun aux_div = div / (ACLKXDIV_MASK + 1);
1111*4882a593Smuzhiyun if (div % (ACLKXDIV_MASK + 1))
1112*4882a593Smuzhiyun aux_div++;
1113*4882a593Smuzhiyun
1114*4882a593Smuzhiyun sysclk_freq /= aux_div;
1115*4882a593Smuzhiyun div = sysclk_freq / bclk_freq;
1116*4882a593Smuzhiyun rem = sysclk_freq % bclk_freq;
1117*4882a593Smuzhiyun } else if (set) {
1118*4882a593Smuzhiyun dev_warn(mcasp->dev, "Too fast reference clock (%u)\n",
1119*4882a593Smuzhiyun sysclk_freq);
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun }
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun if (rem != 0) {
1124*4882a593Smuzhiyun if (div == 0 ||
1125*4882a593Smuzhiyun ((sysclk_freq / div) - bclk_freq) >
1126*4882a593Smuzhiyun (bclk_freq - (sysclk_freq / (div+1)))) {
1127*4882a593Smuzhiyun div++;
1128*4882a593Smuzhiyun rem = rem - bclk_freq;
1129*4882a593Smuzhiyun }
1130*4882a593Smuzhiyun }
1131*4882a593Smuzhiyun error_ppm = (div*1000000 + (int)div64_long(1000000LL*rem,
1132*4882a593Smuzhiyun (int)bclk_freq)) / div - 1000000;
1133*4882a593Smuzhiyun
1134*4882a593Smuzhiyun if (set) {
1135*4882a593Smuzhiyun if (error_ppm)
1136*4882a593Smuzhiyun dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n",
1137*4882a593Smuzhiyun error_ppm);
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_BCLK, div, 0);
1140*4882a593Smuzhiyun if (reg & AHCLKXE)
1141*4882a593Smuzhiyun __davinci_mcasp_set_clkdiv(mcasp, MCASP_CLKDIV_AUXCLK,
1142*4882a593Smuzhiyun aux_div, 0);
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun return error_ppm;
1146*4882a593Smuzhiyun }
1147*4882a593Smuzhiyun
davinci_mcasp_tx_delay(struct davinci_mcasp * mcasp)1148*4882a593Smuzhiyun static inline u32 davinci_mcasp_tx_delay(struct davinci_mcasp *mcasp)
1149*4882a593Smuzhiyun {
1150*4882a593Smuzhiyun if (!mcasp->txnumevt)
1151*4882a593Smuzhiyun return 0;
1152*4882a593Smuzhiyun
1153*4882a593Smuzhiyun return mcasp_get_reg(mcasp, mcasp->fifo_base + MCASP_WFIFOSTS_OFFSET);
1154*4882a593Smuzhiyun }
1155*4882a593Smuzhiyun
davinci_mcasp_rx_delay(struct davinci_mcasp * mcasp)1156*4882a593Smuzhiyun static inline u32 davinci_mcasp_rx_delay(struct davinci_mcasp *mcasp)
1157*4882a593Smuzhiyun {
1158*4882a593Smuzhiyun if (!mcasp->rxnumevt)
1159*4882a593Smuzhiyun return 0;
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun return mcasp_get_reg(mcasp, mcasp->fifo_base + MCASP_RFIFOSTS_OFFSET);
1162*4882a593Smuzhiyun }
1163*4882a593Smuzhiyun
davinci_mcasp_delay(struct snd_pcm_substream * substream,struct snd_soc_dai * cpu_dai)1164*4882a593Smuzhiyun static snd_pcm_sframes_t davinci_mcasp_delay(
1165*4882a593Smuzhiyun struct snd_pcm_substream *substream,
1166*4882a593Smuzhiyun struct snd_soc_dai *cpu_dai)
1167*4882a593Smuzhiyun {
1168*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1169*4882a593Smuzhiyun u32 fifo_use;
1170*4882a593Smuzhiyun
1171*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1172*4882a593Smuzhiyun fifo_use = davinci_mcasp_tx_delay(mcasp);
1173*4882a593Smuzhiyun else
1174*4882a593Smuzhiyun fifo_use = davinci_mcasp_rx_delay(mcasp);
1175*4882a593Smuzhiyun
1176*4882a593Smuzhiyun /*
1177*4882a593Smuzhiyun * Divide the used locations with the channel count to get the
1178*4882a593Smuzhiyun * FIFO usage in samples (don't care about partial samples in the
1179*4882a593Smuzhiyun * buffer).
1180*4882a593Smuzhiyun */
1181*4882a593Smuzhiyun return fifo_use / substream->runtime->channels;
1182*4882a593Smuzhiyun }
1183*4882a593Smuzhiyun
davinci_mcasp_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * cpu_dai)1184*4882a593Smuzhiyun static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
1185*4882a593Smuzhiyun struct snd_pcm_hw_params *params,
1186*4882a593Smuzhiyun struct snd_soc_dai *cpu_dai)
1187*4882a593Smuzhiyun {
1188*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1189*4882a593Smuzhiyun int word_length;
1190*4882a593Smuzhiyun int channels = params_channels(params);
1191*4882a593Smuzhiyun int period_size = params_period_size(params);
1192*4882a593Smuzhiyun int ret;
1193*4882a593Smuzhiyun
1194*4882a593Smuzhiyun switch (params_format(params)) {
1195*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_U8:
1196*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_S8:
1197*4882a593Smuzhiyun word_length = 8;
1198*4882a593Smuzhiyun break;
1199*4882a593Smuzhiyun
1200*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_U16_LE:
1201*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_S16_LE:
1202*4882a593Smuzhiyun word_length = 16;
1203*4882a593Smuzhiyun break;
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_U24_3LE:
1206*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_S24_3LE:
1207*4882a593Smuzhiyun word_length = 24;
1208*4882a593Smuzhiyun break;
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_U24_LE:
1211*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_S24_LE:
1212*4882a593Smuzhiyun word_length = 24;
1213*4882a593Smuzhiyun break;
1214*4882a593Smuzhiyun
1215*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_U32_LE:
1216*4882a593Smuzhiyun case SNDRV_PCM_FORMAT_S32_LE:
1217*4882a593Smuzhiyun word_length = 32;
1218*4882a593Smuzhiyun break;
1219*4882a593Smuzhiyun
1220*4882a593Smuzhiyun default:
1221*4882a593Smuzhiyun printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
1222*4882a593Smuzhiyun return -EINVAL;
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun ret = davinci_mcasp_set_dai_fmt(cpu_dai, mcasp->dai_fmt);
1226*4882a593Smuzhiyun if (ret)
1227*4882a593Smuzhiyun return ret;
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun /*
1230*4882a593Smuzhiyun * If mcasp is BCLK master, and a BCLK divider was not provided by
1231*4882a593Smuzhiyun * the machine driver, we need to calculate the ratio.
1232*4882a593Smuzhiyun */
1233*4882a593Smuzhiyun if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
1234*4882a593Smuzhiyun int slots = mcasp->tdm_slots;
1235*4882a593Smuzhiyun int rate = params_rate(params);
1236*4882a593Smuzhiyun int sbits = params_width(params);
1237*4882a593Smuzhiyun
1238*4882a593Smuzhiyun if (mcasp->slot_width)
1239*4882a593Smuzhiyun sbits = mcasp->slot_width;
1240*4882a593Smuzhiyun
1241*4882a593Smuzhiyun davinci_mcasp_calc_clk_div(mcasp, mcasp->sysclk_freq,
1242*4882a593Smuzhiyun rate * sbits * slots, true);
1243*4882a593Smuzhiyun }
1244*4882a593Smuzhiyun
1245*4882a593Smuzhiyun ret = mcasp_common_hw_param(mcasp, substream->stream,
1246*4882a593Smuzhiyun period_size * channels, channels);
1247*4882a593Smuzhiyun if (ret)
1248*4882a593Smuzhiyun return ret;
1249*4882a593Smuzhiyun
1250*4882a593Smuzhiyun if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
1251*4882a593Smuzhiyun ret = mcasp_dit_hw_param(mcasp, params_rate(params));
1252*4882a593Smuzhiyun else
1253*4882a593Smuzhiyun ret = mcasp_i2s_hw_param(mcasp, substream->stream,
1254*4882a593Smuzhiyun channels);
1255*4882a593Smuzhiyun
1256*4882a593Smuzhiyun if (ret)
1257*4882a593Smuzhiyun return ret;
1258*4882a593Smuzhiyun
1259*4882a593Smuzhiyun davinci_config_channel_size(mcasp, word_length);
1260*4882a593Smuzhiyun
1261*4882a593Smuzhiyun if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) {
1262*4882a593Smuzhiyun mcasp->channels = channels;
1263*4882a593Smuzhiyun if (!mcasp->max_format_width)
1264*4882a593Smuzhiyun mcasp->max_format_width = word_length;
1265*4882a593Smuzhiyun }
1266*4882a593Smuzhiyun
1267*4882a593Smuzhiyun return 0;
1268*4882a593Smuzhiyun }
1269*4882a593Smuzhiyun
davinci_mcasp_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * cpu_dai)1270*4882a593Smuzhiyun static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
1271*4882a593Smuzhiyun int cmd, struct snd_soc_dai *cpu_dai)
1272*4882a593Smuzhiyun {
1273*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1274*4882a593Smuzhiyun int ret = 0;
1275*4882a593Smuzhiyun
1276*4882a593Smuzhiyun switch (cmd) {
1277*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_RESUME:
1278*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_START:
1279*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1280*4882a593Smuzhiyun davinci_mcasp_start(mcasp, substream->stream);
1281*4882a593Smuzhiyun break;
1282*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_SUSPEND:
1283*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_STOP:
1284*4882a593Smuzhiyun case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1285*4882a593Smuzhiyun davinci_mcasp_stop(mcasp, substream->stream);
1286*4882a593Smuzhiyun break;
1287*4882a593Smuzhiyun
1288*4882a593Smuzhiyun default:
1289*4882a593Smuzhiyun ret = -EINVAL;
1290*4882a593Smuzhiyun }
1291*4882a593Smuzhiyun
1292*4882a593Smuzhiyun return ret;
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun
davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)1295*4882a593Smuzhiyun static int davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params *params,
1296*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
1297*4882a593Smuzhiyun {
1298*4882a593Smuzhiyun struct davinci_mcasp_ruledata *rd = rule->private;
1299*4882a593Smuzhiyun struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1300*4882a593Smuzhiyun struct snd_mask nfmt;
1301*4882a593Smuzhiyun int i, slot_width;
1302*4882a593Smuzhiyun
1303*4882a593Smuzhiyun snd_mask_none(&nfmt);
1304*4882a593Smuzhiyun slot_width = rd->mcasp->slot_width;
1305*4882a593Smuzhiyun
1306*4882a593Smuzhiyun for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
1307*4882a593Smuzhiyun if (snd_mask_test(fmt, i)) {
1308*4882a593Smuzhiyun if (snd_pcm_format_width(i) <= slot_width) {
1309*4882a593Smuzhiyun snd_mask_set(&nfmt, i);
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun }
1312*4882a593Smuzhiyun }
1313*4882a593Smuzhiyun
1314*4882a593Smuzhiyun return snd_mask_refine(fmt, &nfmt);
1315*4882a593Smuzhiyun }
1316*4882a593Smuzhiyun
davinci_mcasp_hw_rule_format_width(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)1317*4882a593Smuzhiyun static int davinci_mcasp_hw_rule_format_width(struct snd_pcm_hw_params *params,
1318*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
1319*4882a593Smuzhiyun {
1320*4882a593Smuzhiyun struct davinci_mcasp_ruledata *rd = rule->private;
1321*4882a593Smuzhiyun struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1322*4882a593Smuzhiyun struct snd_mask nfmt;
1323*4882a593Smuzhiyun int i, format_width;
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun snd_mask_none(&nfmt);
1326*4882a593Smuzhiyun format_width = rd->mcasp->max_format_width;
1327*4882a593Smuzhiyun
1328*4882a593Smuzhiyun for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
1329*4882a593Smuzhiyun if (snd_mask_test(fmt, i)) {
1330*4882a593Smuzhiyun if (snd_pcm_format_width(i) == format_width) {
1331*4882a593Smuzhiyun snd_mask_set(&nfmt, i);
1332*4882a593Smuzhiyun }
1333*4882a593Smuzhiyun }
1334*4882a593Smuzhiyun }
1335*4882a593Smuzhiyun
1336*4882a593Smuzhiyun return snd_mask_refine(fmt, &nfmt);
1337*4882a593Smuzhiyun }
1338*4882a593Smuzhiyun
1339*4882a593Smuzhiyun static const unsigned int davinci_mcasp_dai_rates[] = {
1340*4882a593Smuzhiyun 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
1341*4882a593Smuzhiyun 88200, 96000, 176400, 192000,
1342*4882a593Smuzhiyun };
1343*4882a593Smuzhiyun
1344*4882a593Smuzhiyun #define DAVINCI_MAX_RATE_ERROR_PPM 1000
1345*4882a593Smuzhiyun
davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)1346*4882a593Smuzhiyun static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params,
1347*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
1348*4882a593Smuzhiyun {
1349*4882a593Smuzhiyun struct davinci_mcasp_ruledata *rd = rule->private;
1350*4882a593Smuzhiyun struct snd_interval *ri =
1351*4882a593Smuzhiyun hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1352*4882a593Smuzhiyun int sbits = params_width(params);
1353*4882a593Smuzhiyun int slots = rd->mcasp->tdm_slots;
1354*4882a593Smuzhiyun struct snd_interval range;
1355*4882a593Smuzhiyun int i;
1356*4882a593Smuzhiyun
1357*4882a593Smuzhiyun if (rd->mcasp->slot_width)
1358*4882a593Smuzhiyun sbits = rd->mcasp->slot_width;
1359*4882a593Smuzhiyun
1360*4882a593Smuzhiyun snd_interval_any(&range);
1361*4882a593Smuzhiyun range.empty = 1;
1362*4882a593Smuzhiyun
1363*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) {
1364*4882a593Smuzhiyun if (snd_interval_test(ri, davinci_mcasp_dai_rates[i])) {
1365*4882a593Smuzhiyun uint bclk_freq = sbits * slots *
1366*4882a593Smuzhiyun davinci_mcasp_dai_rates[i];
1367*4882a593Smuzhiyun unsigned int sysclk_freq;
1368*4882a593Smuzhiyun int ppm;
1369*4882a593Smuzhiyun
1370*4882a593Smuzhiyun if (rd->mcasp->auxclk_fs_ratio)
1371*4882a593Smuzhiyun sysclk_freq = davinci_mcasp_dai_rates[i] *
1372*4882a593Smuzhiyun rd->mcasp->auxclk_fs_ratio;
1373*4882a593Smuzhiyun else
1374*4882a593Smuzhiyun sysclk_freq = rd->mcasp->sysclk_freq;
1375*4882a593Smuzhiyun
1376*4882a593Smuzhiyun ppm = davinci_mcasp_calc_clk_div(rd->mcasp, sysclk_freq,
1377*4882a593Smuzhiyun bclk_freq, false);
1378*4882a593Smuzhiyun if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1379*4882a593Smuzhiyun if (range.empty) {
1380*4882a593Smuzhiyun range.min = davinci_mcasp_dai_rates[i];
1381*4882a593Smuzhiyun range.empty = 0;
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun range.max = davinci_mcasp_dai_rates[i];
1384*4882a593Smuzhiyun }
1385*4882a593Smuzhiyun }
1386*4882a593Smuzhiyun }
1387*4882a593Smuzhiyun
1388*4882a593Smuzhiyun dev_dbg(rd->mcasp->dev,
1389*4882a593Smuzhiyun "Frequencies %d-%d -> %d-%d for %d sbits and %d tdm slots\n",
1390*4882a593Smuzhiyun ri->min, ri->max, range.min, range.max, sbits, slots);
1391*4882a593Smuzhiyun
1392*4882a593Smuzhiyun return snd_interval_refine(hw_param_interval(params, rule->var),
1393*4882a593Smuzhiyun &range);
1394*4882a593Smuzhiyun }
1395*4882a593Smuzhiyun
davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)1396*4882a593Smuzhiyun static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1397*4882a593Smuzhiyun struct snd_pcm_hw_rule *rule)
1398*4882a593Smuzhiyun {
1399*4882a593Smuzhiyun struct davinci_mcasp_ruledata *rd = rule->private;
1400*4882a593Smuzhiyun struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1401*4882a593Smuzhiyun struct snd_mask nfmt;
1402*4882a593Smuzhiyun int rate = params_rate(params);
1403*4882a593Smuzhiyun int slots = rd->mcasp->tdm_slots;
1404*4882a593Smuzhiyun int i, count = 0;
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun snd_mask_none(&nfmt);
1407*4882a593Smuzhiyun
1408*4882a593Smuzhiyun for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
1409*4882a593Smuzhiyun if (snd_mask_test(fmt, i)) {
1410*4882a593Smuzhiyun uint sbits = snd_pcm_format_width(i);
1411*4882a593Smuzhiyun unsigned int sysclk_freq;
1412*4882a593Smuzhiyun int ppm;
1413*4882a593Smuzhiyun
1414*4882a593Smuzhiyun if (rd->mcasp->auxclk_fs_ratio)
1415*4882a593Smuzhiyun sysclk_freq = rate *
1416*4882a593Smuzhiyun rd->mcasp->auxclk_fs_ratio;
1417*4882a593Smuzhiyun else
1418*4882a593Smuzhiyun sysclk_freq = rd->mcasp->sysclk_freq;
1419*4882a593Smuzhiyun
1420*4882a593Smuzhiyun if (rd->mcasp->slot_width)
1421*4882a593Smuzhiyun sbits = rd->mcasp->slot_width;
1422*4882a593Smuzhiyun
1423*4882a593Smuzhiyun ppm = davinci_mcasp_calc_clk_div(rd->mcasp, sysclk_freq,
1424*4882a593Smuzhiyun sbits * slots * rate,
1425*4882a593Smuzhiyun false);
1426*4882a593Smuzhiyun if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1427*4882a593Smuzhiyun snd_mask_set(&nfmt, i);
1428*4882a593Smuzhiyun count++;
1429*4882a593Smuzhiyun }
1430*4882a593Smuzhiyun }
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun dev_dbg(rd->mcasp->dev,
1433*4882a593Smuzhiyun "%d possible sample format for %d Hz and %d tdm slots\n",
1434*4882a593Smuzhiyun count, rate, slots);
1435*4882a593Smuzhiyun
1436*4882a593Smuzhiyun return snd_mask_refine(fmt, &nfmt);
1437*4882a593Smuzhiyun }
1438*4882a593Smuzhiyun
davinci_mcasp_hw_rule_min_periodsize(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)1439*4882a593Smuzhiyun static int davinci_mcasp_hw_rule_min_periodsize(
1440*4882a593Smuzhiyun struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun struct snd_interval *period_size = hw_param_interval(params,
1443*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
1444*4882a593Smuzhiyun struct snd_interval frames;
1445*4882a593Smuzhiyun
1446*4882a593Smuzhiyun snd_interval_any(&frames);
1447*4882a593Smuzhiyun frames.min = 64;
1448*4882a593Smuzhiyun frames.integer = 1;
1449*4882a593Smuzhiyun
1450*4882a593Smuzhiyun return snd_interval_refine(period_size, &frames);
1451*4882a593Smuzhiyun }
1452*4882a593Smuzhiyun
davinci_mcasp_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * cpu_dai)1453*4882a593Smuzhiyun static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1454*4882a593Smuzhiyun struct snd_soc_dai *cpu_dai)
1455*4882a593Smuzhiyun {
1456*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1457*4882a593Smuzhiyun struct davinci_mcasp_ruledata *ruledata =
1458*4882a593Smuzhiyun &mcasp->ruledata[substream->stream];
1459*4882a593Smuzhiyun u32 max_channels = 0;
1460*4882a593Smuzhiyun int i, dir, ret;
1461*4882a593Smuzhiyun int tdm_slots = mcasp->tdm_slots;
1462*4882a593Smuzhiyun
1463*4882a593Smuzhiyun /* Do not allow more then one stream per direction */
1464*4882a593Smuzhiyun if (mcasp->substreams[substream->stream])
1465*4882a593Smuzhiyun return -EBUSY;
1466*4882a593Smuzhiyun
1467*4882a593Smuzhiyun mcasp->substreams[substream->stream] = substream;
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun if (mcasp->tdm_mask[substream->stream])
1470*4882a593Smuzhiyun tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]);
1471*4882a593Smuzhiyun
1472*4882a593Smuzhiyun if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
1473*4882a593Smuzhiyun return 0;
1474*4882a593Smuzhiyun
1475*4882a593Smuzhiyun /*
1476*4882a593Smuzhiyun * Limit the maximum allowed channels for the first stream:
1477*4882a593Smuzhiyun * number of serializers for the direction * tdm slots per serializer
1478*4882a593Smuzhiyun */
1479*4882a593Smuzhiyun if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1480*4882a593Smuzhiyun dir = TX_MODE;
1481*4882a593Smuzhiyun else
1482*4882a593Smuzhiyun dir = RX_MODE;
1483*4882a593Smuzhiyun
1484*4882a593Smuzhiyun for (i = 0; i < mcasp->num_serializer; i++) {
1485*4882a593Smuzhiyun if (mcasp->serial_dir[i] == dir)
1486*4882a593Smuzhiyun max_channels++;
1487*4882a593Smuzhiyun }
1488*4882a593Smuzhiyun ruledata->serializers = max_channels;
1489*4882a593Smuzhiyun ruledata->mcasp = mcasp;
1490*4882a593Smuzhiyun max_channels *= tdm_slots;
1491*4882a593Smuzhiyun /*
1492*4882a593Smuzhiyun * If the already active stream has less channels than the calculated
1493*4882a593Smuzhiyun * limit based on the seirializers * tdm_slots, and only one serializer
1494*4882a593Smuzhiyun * is in use we need to use that as a constraint for the second stream.
1495*4882a593Smuzhiyun * Otherwise (first stream or less allowed channels or more than one
1496*4882a593Smuzhiyun * serializer in use) we use the calculated constraint.
1497*4882a593Smuzhiyun */
1498*4882a593Smuzhiyun if (mcasp->channels && mcasp->channels < max_channels &&
1499*4882a593Smuzhiyun ruledata->serializers == 1)
1500*4882a593Smuzhiyun max_channels = mcasp->channels;
1501*4882a593Smuzhiyun /*
1502*4882a593Smuzhiyun * But we can always allow channels upto the amount of
1503*4882a593Smuzhiyun * the available tdm_slots.
1504*4882a593Smuzhiyun */
1505*4882a593Smuzhiyun if (max_channels < tdm_slots)
1506*4882a593Smuzhiyun max_channels = tdm_slots;
1507*4882a593Smuzhiyun
1508*4882a593Smuzhiyun snd_pcm_hw_constraint_minmax(substream->runtime,
1509*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_CHANNELS,
1510*4882a593Smuzhiyun 0, max_channels);
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun snd_pcm_hw_constraint_list(substream->runtime,
1513*4882a593Smuzhiyun 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1514*4882a593Smuzhiyun &mcasp->chconstr[substream->stream]);
1515*4882a593Smuzhiyun
1516*4882a593Smuzhiyun if (mcasp->max_format_width) {
1517*4882a593Smuzhiyun /*
1518*4882a593Smuzhiyun * Only allow formats which require same amount of bits on the
1519*4882a593Smuzhiyun * bus as the currently running stream
1520*4882a593Smuzhiyun */
1521*4882a593Smuzhiyun ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1522*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_FORMAT,
1523*4882a593Smuzhiyun davinci_mcasp_hw_rule_format_width,
1524*4882a593Smuzhiyun ruledata,
1525*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_FORMAT, -1);
1526*4882a593Smuzhiyun if (ret)
1527*4882a593Smuzhiyun return ret;
1528*4882a593Smuzhiyun }
1529*4882a593Smuzhiyun else if (mcasp->slot_width) {
1530*4882a593Smuzhiyun /* Only allow formats require <= slot_width bits on the bus */
1531*4882a593Smuzhiyun ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1532*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_FORMAT,
1533*4882a593Smuzhiyun davinci_mcasp_hw_rule_slot_width,
1534*4882a593Smuzhiyun ruledata,
1535*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_FORMAT, -1);
1536*4882a593Smuzhiyun if (ret)
1537*4882a593Smuzhiyun return ret;
1538*4882a593Smuzhiyun }
1539*4882a593Smuzhiyun
1540*4882a593Smuzhiyun /*
1541*4882a593Smuzhiyun * If we rely on implicit BCLK divider setting we should
1542*4882a593Smuzhiyun * set constraints based on what we can provide.
1543*4882a593Smuzhiyun */
1544*4882a593Smuzhiyun if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
1545*4882a593Smuzhiyun ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1546*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_RATE,
1547*4882a593Smuzhiyun davinci_mcasp_hw_rule_rate,
1548*4882a593Smuzhiyun ruledata,
1549*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_FORMAT, -1);
1550*4882a593Smuzhiyun if (ret)
1551*4882a593Smuzhiyun return ret;
1552*4882a593Smuzhiyun ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1553*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_FORMAT,
1554*4882a593Smuzhiyun davinci_mcasp_hw_rule_format,
1555*4882a593Smuzhiyun ruledata,
1556*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_RATE, -1);
1557*4882a593Smuzhiyun if (ret)
1558*4882a593Smuzhiyun return ret;
1559*4882a593Smuzhiyun }
1560*4882a593Smuzhiyun
1561*4882a593Smuzhiyun snd_pcm_hw_rule_add(substream->runtime, 0,
1562*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1563*4882a593Smuzhiyun davinci_mcasp_hw_rule_min_periodsize, NULL,
1564*4882a593Smuzhiyun SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
1565*4882a593Smuzhiyun
1566*4882a593Smuzhiyun return 0;
1567*4882a593Smuzhiyun }
1568*4882a593Smuzhiyun
davinci_mcasp_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * cpu_dai)1569*4882a593Smuzhiyun static void davinci_mcasp_shutdown(struct snd_pcm_substream *substream,
1570*4882a593Smuzhiyun struct snd_soc_dai *cpu_dai)
1571*4882a593Smuzhiyun {
1572*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1573*4882a593Smuzhiyun
1574*4882a593Smuzhiyun mcasp->substreams[substream->stream] = NULL;
1575*4882a593Smuzhiyun mcasp->active_serializers[substream->stream] = 0;
1576*4882a593Smuzhiyun
1577*4882a593Smuzhiyun if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
1578*4882a593Smuzhiyun return;
1579*4882a593Smuzhiyun
1580*4882a593Smuzhiyun if (!snd_soc_dai_active(cpu_dai)) {
1581*4882a593Smuzhiyun mcasp->channels = 0;
1582*4882a593Smuzhiyun mcasp->max_format_width = 0;
1583*4882a593Smuzhiyun }
1584*4882a593Smuzhiyun }
1585*4882a593Smuzhiyun
1586*4882a593Smuzhiyun static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
1587*4882a593Smuzhiyun .startup = davinci_mcasp_startup,
1588*4882a593Smuzhiyun .shutdown = davinci_mcasp_shutdown,
1589*4882a593Smuzhiyun .trigger = davinci_mcasp_trigger,
1590*4882a593Smuzhiyun .delay = davinci_mcasp_delay,
1591*4882a593Smuzhiyun .hw_params = davinci_mcasp_hw_params,
1592*4882a593Smuzhiyun .set_fmt = davinci_mcasp_set_dai_fmt,
1593*4882a593Smuzhiyun .set_clkdiv = davinci_mcasp_set_clkdiv,
1594*4882a593Smuzhiyun .set_sysclk = davinci_mcasp_set_sysclk,
1595*4882a593Smuzhiyun .set_tdm_slot = davinci_mcasp_set_tdm_slot,
1596*4882a593Smuzhiyun };
1597*4882a593Smuzhiyun
davinci_mcasp_dai_probe(struct snd_soc_dai * dai)1598*4882a593Smuzhiyun static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
1599*4882a593Smuzhiyun {
1600*4882a593Smuzhiyun struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
1601*4882a593Smuzhiyun
1602*4882a593Smuzhiyun dai->playback_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
1603*4882a593Smuzhiyun dai->capture_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
1604*4882a593Smuzhiyun
1605*4882a593Smuzhiyun return 0;
1606*4882a593Smuzhiyun }
1607*4882a593Smuzhiyun
1608*4882a593Smuzhiyun #define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000
1609*4882a593Smuzhiyun
1610*4882a593Smuzhiyun #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
1611*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_U8 | \
1612*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_S16_LE | \
1613*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_U16_LE | \
1614*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_S24_LE | \
1615*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_U24_LE | \
1616*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_S24_3LE | \
1617*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_U24_3LE | \
1618*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_S32_LE | \
1619*4882a593Smuzhiyun SNDRV_PCM_FMTBIT_U32_LE)
1620*4882a593Smuzhiyun
1621*4882a593Smuzhiyun static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
1622*4882a593Smuzhiyun {
1623*4882a593Smuzhiyun .name = "davinci-mcasp.0",
1624*4882a593Smuzhiyun .probe = davinci_mcasp_dai_probe,
1625*4882a593Smuzhiyun .playback = {
1626*4882a593Smuzhiyun .stream_name = "IIS Playback",
1627*4882a593Smuzhiyun .channels_min = 1,
1628*4882a593Smuzhiyun .channels_max = 32 * 16,
1629*4882a593Smuzhiyun .rates = DAVINCI_MCASP_RATES,
1630*4882a593Smuzhiyun .formats = DAVINCI_MCASP_PCM_FMTS,
1631*4882a593Smuzhiyun },
1632*4882a593Smuzhiyun .capture = {
1633*4882a593Smuzhiyun .stream_name = "IIS Capture",
1634*4882a593Smuzhiyun .channels_min = 1,
1635*4882a593Smuzhiyun .channels_max = 32 * 16,
1636*4882a593Smuzhiyun .rates = DAVINCI_MCASP_RATES,
1637*4882a593Smuzhiyun .formats = DAVINCI_MCASP_PCM_FMTS,
1638*4882a593Smuzhiyun },
1639*4882a593Smuzhiyun .ops = &davinci_mcasp_dai_ops,
1640*4882a593Smuzhiyun
1641*4882a593Smuzhiyun .symmetric_rates = 1,
1642*4882a593Smuzhiyun },
1643*4882a593Smuzhiyun {
1644*4882a593Smuzhiyun .name = "davinci-mcasp.1",
1645*4882a593Smuzhiyun .probe = davinci_mcasp_dai_probe,
1646*4882a593Smuzhiyun .playback = {
1647*4882a593Smuzhiyun .stream_name = "DIT Playback",
1648*4882a593Smuzhiyun .channels_min = 1,
1649*4882a593Smuzhiyun .channels_max = 384,
1650*4882a593Smuzhiyun .rates = DAVINCI_MCASP_RATES,
1651*4882a593Smuzhiyun .formats = DAVINCI_MCASP_PCM_FMTS,
1652*4882a593Smuzhiyun },
1653*4882a593Smuzhiyun .ops = &davinci_mcasp_dai_ops,
1654*4882a593Smuzhiyun },
1655*4882a593Smuzhiyun
1656*4882a593Smuzhiyun };
1657*4882a593Smuzhiyun
1658*4882a593Smuzhiyun static const struct snd_soc_component_driver davinci_mcasp_component = {
1659*4882a593Smuzhiyun .name = "davinci-mcasp",
1660*4882a593Smuzhiyun };
1661*4882a593Smuzhiyun
1662*4882a593Smuzhiyun /* Some HW specific values and defaults. The rest is filled in from DT. */
1663*4882a593Smuzhiyun static struct davinci_mcasp_pdata dm646x_mcasp_pdata = {
1664*4882a593Smuzhiyun .tx_dma_offset = 0x400,
1665*4882a593Smuzhiyun .rx_dma_offset = 0x400,
1666*4882a593Smuzhiyun .version = MCASP_VERSION_1,
1667*4882a593Smuzhiyun };
1668*4882a593Smuzhiyun
1669*4882a593Smuzhiyun static struct davinci_mcasp_pdata da830_mcasp_pdata = {
1670*4882a593Smuzhiyun .tx_dma_offset = 0x2000,
1671*4882a593Smuzhiyun .rx_dma_offset = 0x2000,
1672*4882a593Smuzhiyun .version = MCASP_VERSION_2,
1673*4882a593Smuzhiyun };
1674*4882a593Smuzhiyun
1675*4882a593Smuzhiyun static struct davinci_mcasp_pdata am33xx_mcasp_pdata = {
1676*4882a593Smuzhiyun .tx_dma_offset = 0,
1677*4882a593Smuzhiyun .rx_dma_offset = 0,
1678*4882a593Smuzhiyun .version = MCASP_VERSION_3,
1679*4882a593Smuzhiyun };
1680*4882a593Smuzhiyun
1681*4882a593Smuzhiyun static struct davinci_mcasp_pdata dra7_mcasp_pdata = {
1682*4882a593Smuzhiyun /* The CFG port offset will be calculated if it is needed */
1683*4882a593Smuzhiyun .tx_dma_offset = 0,
1684*4882a593Smuzhiyun .rx_dma_offset = 0,
1685*4882a593Smuzhiyun .version = MCASP_VERSION_4,
1686*4882a593Smuzhiyun };
1687*4882a593Smuzhiyun
1688*4882a593Smuzhiyun static const struct of_device_id mcasp_dt_ids[] = {
1689*4882a593Smuzhiyun {
1690*4882a593Smuzhiyun .compatible = "ti,dm646x-mcasp-audio",
1691*4882a593Smuzhiyun .data = &dm646x_mcasp_pdata,
1692*4882a593Smuzhiyun },
1693*4882a593Smuzhiyun {
1694*4882a593Smuzhiyun .compatible = "ti,da830-mcasp-audio",
1695*4882a593Smuzhiyun .data = &da830_mcasp_pdata,
1696*4882a593Smuzhiyun },
1697*4882a593Smuzhiyun {
1698*4882a593Smuzhiyun .compatible = "ti,am33xx-mcasp-audio",
1699*4882a593Smuzhiyun .data = &am33xx_mcasp_pdata,
1700*4882a593Smuzhiyun },
1701*4882a593Smuzhiyun {
1702*4882a593Smuzhiyun .compatible = "ti,dra7-mcasp-audio",
1703*4882a593Smuzhiyun .data = &dra7_mcasp_pdata,
1704*4882a593Smuzhiyun },
1705*4882a593Smuzhiyun { /* sentinel */ }
1706*4882a593Smuzhiyun };
1707*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, mcasp_dt_ids);
1708*4882a593Smuzhiyun
mcasp_reparent_fck(struct platform_device * pdev)1709*4882a593Smuzhiyun static int mcasp_reparent_fck(struct platform_device *pdev)
1710*4882a593Smuzhiyun {
1711*4882a593Smuzhiyun struct device_node *node = pdev->dev.of_node;
1712*4882a593Smuzhiyun struct clk *gfclk, *parent_clk;
1713*4882a593Smuzhiyun const char *parent_name;
1714*4882a593Smuzhiyun int ret;
1715*4882a593Smuzhiyun
1716*4882a593Smuzhiyun if (!node)
1717*4882a593Smuzhiyun return 0;
1718*4882a593Smuzhiyun
1719*4882a593Smuzhiyun parent_name = of_get_property(node, "fck_parent", NULL);
1720*4882a593Smuzhiyun if (!parent_name)
1721*4882a593Smuzhiyun return 0;
1722*4882a593Smuzhiyun
1723*4882a593Smuzhiyun dev_warn(&pdev->dev, "Update the bindings to use assigned-clocks!\n");
1724*4882a593Smuzhiyun
1725*4882a593Smuzhiyun gfclk = clk_get(&pdev->dev, "fck");
1726*4882a593Smuzhiyun if (IS_ERR(gfclk)) {
1727*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get fck\n");
1728*4882a593Smuzhiyun return PTR_ERR(gfclk);
1729*4882a593Smuzhiyun }
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun parent_clk = clk_get(NULL, parent_name);
1732*4882a593Smuzhiyun if (IS_ERR(parent_clk)) {
1733*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get parent clock\n");
1734*4882a593Smuzhiyun ret = PTR_ERR(parent_clk);
1735*4882a593Smuzhiyun goto err1;
1736*4882a593Smuzhiyun }
1737*4882a593Smuzhiyun
1738*4882a593Smuzhiyun ret = clk_set_parent(gfclk, parent_clk);
1739*4882a593Smuzhiyun if (ret) {
1740*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to reparent fck\n");
1741*4882a593Smuzhiyun goto err2;
1742*4882a593Smuzhiyun }
1743*4882a593Smuzhiyun
1744*4882a593Smuzhiyun err2:
1745*4882a593Smuzhiyun clk_put(parent_clk);
1746*4882a593Smuzhiyun err1:
1747*4882a593Smuzhiyun clk_put(gfclk);
1748*4882a593Smuzhiyun return ret;
1749*4882a593Smuzhiyun }
1750*4882a593Smuzhiyun
davinci_mcasp_set_pdata_from_of(struct platform_device * pdev)1751*4882a593Smuzhiyun static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
1752*4882a593Smuzhiyun struct platform_device *pdev)
1753*4882a593Smuzhiyun {
1754*4882a593Smuzhiyun struct device_node *np = pdev->dev.of_node;
1755*4882a593Smuzhiyun struct davinci_mcasp_pdata *pdata = NULL;
1756*4882a593Smuzhiyun const struct of_device_id *match =
1757*4882a593Smuzhiyun of_match_device(mcasp_dt_ids, &pdev->dev);
1758*4882a593Smuzhiyun struct of_phandle_args dma_spec;
1759*4882a593Smuzhiyun
1760*4882a593Smuzhiyun const u32 *of_serial_dir32;
1761*4882a593Smuzhiyun u32 val;
1762*4882a593Smuzhiyun int i, ret = 0;
1763*4882a593Smuzhiyun
1764*4882a593Smuzhiyun if (pdev->dev.platform_data) {
1765*4882a593Smuzhiyun pdata = pdev->dev.platform_data;
1766*4882a593Smuzhiyun pdata->dismod = DISMOD_LOW;
1767*4882a593Smuzhiyun return pdata;
1768*4882a593Smuzhiyun } else if (match) {
1769*4882a593Smuzhiyun pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata),
1770*4882a593Smuzhiyun GFP_KERNEL);
1771*4882a593Smuzhiyun if (!pdata)
1772*4882a593Smuzhiyun return NULL;
1773*4882a593Smuzhiyun } else {
1774*4882a593Smuzhiyun /* control shouldn't reach here. something is wrong */
1775*4882a593Smuzhiyun ret = -EINVAL;
1776*4882a593Smuzhiyun goto nodata;
1777*4882a593Smuzhiyun }
1778*4882a593Smuzhiyun
1779*4882a593Smuzhiyun ret = of_property_read_u32(np, "op-mode", &val);
1780*4882a593Smuzhiyun if (ret >= 0)
1781*4882a593Smuzhiyun pdata->op_mode = val;
1782*4882a593Smuzhiyun
1783*4882a593Smuzhiyun ret = of_property_read_u32(np, "tdm-slots", &val);
1784*4882a593Smuzhiyun if (ret >= 0) {
1785*4882a593Smuzhiyun if (val < 2 || val > 32) {
1786*4882a593Smuzhiyun dev_err(&pdev->dev,
1787*4882a593Smuzhiyun "tdm-slots must be in rage [2-32]\n");
1788*4882a593Smuzhiyun ret = -EINVAL;
1789*4882a593Smuzhiyun goto nodata;
1790*4882a593Smuzhiyun }
1791*4882a593Smuzhiyun
1792*4882a593Smuzhiyun pdata->tdm_slots = val;
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun
1795*4882a593Smuzhiyun of_serial_dir32 = of_get_property(np, "serial-dir", &val);
1796*4882a593Smuzhiyun val /= sizeof(u32);
1797*4882a593Smuzhiyun if (of_serial_dir32) {
1798*4882a593Smuzhiyun u8 *of_serial_dir = devm_kzalloc(&pdev->dev,
1799*4882a593Smuzhiyun (sizeof(*of_serial_dir) * val),
1800*4882a593Smuzhiyun GFP_KERNEL);
1801*4882a593Smuzhiyun if (!of_serial_dir) {
1802*4882a593Smuzhiyun ret = -ENOMEM;
1803*4882a593Smuzhiyun goto nodata;
1804*4882a593Smuzhiyun }
1805*4882a593Smuzhiyun
1806*4882a593Smuzhiyun for (i = 0; i < val; i++)
1807*4882a593Smuzhiyun of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]);
1808*4882a593Smuzhiyun
1809*4882a593Smuzhiyun pdata->num_serializer = val;
1810*4882a593Smuzhiyun pdata->serial_dir = of_serial_dir;
1811*4882a593Smuzhiyun }
1812*4882a593Smuzhiyun
1813*4882a593Smuzhiyun ret = of_property_match_string(np, "dma-names", "tx");
1814*4882a593Smuzhiyun if (ret < 0)
1815*4882a593Smuzhiyun goto nodata;
1816*4882a593Smuzhiyun
1817*4882a593Smuzhiyun ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret,
1818*4882a593Smuzhiyun &dma_spec);
1819*4882a593Smuzhiyun if (ret < 0)
1820*4882a593Smuzhiyun goto nodata;
1821*4882a593Smuzhiyun
1822*4882a593Smuzhiyun pdata->tx_dma_channel = dma_spec.args[0];
1823*4882a593Smuzhiyun
1824*4882a593Smuzhiyun /* RX is not valid in DIT mode */
1825*4882a593Smuzhiyun if (pdata->op_mode != DAVINCI_MCASP_DIT_MODE) {
1826*4882a593Smuzhiyun ret = of_property_match_string(np, "dma-names", "rx");
1827*4882a593Smuzhiyun if (ret < 0)
1828*4882a593Smuzhiyun goto nodata;
1829*4882a593Smuzhiyun
1830*4882a593Smuzhiyun ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret,
1831*4882a593Smuzhiyun &dma_spec);
1832*4882a593Smuzhiyun if (ret < 0)
1833*4882a593Smuzhiyun goto nodata;
1834*4882a593Smuzhiyun
1835*4882a593Smuzhiyun pdata->rx_dma_channel = dma_spec.args[0];
1836*4882a593Smuzhiyun }
1837*4882a593Smuzhiyun
1838*4882a593Smuzhiyun ret = of_property_read_u32(np, "tx-num-evt", &val);
1839*4882a593Smuzhiyun if (ret >= 0)
1840*4882a593Smuzhiyun pdata->txnumevt = val;
1841*4882a593Smuzhiyun
1842*4882a593Smuzhiyun ret = of_property_read_u32(np, "rx-num-evt", &val);
1843*4882a593Smuzhiyun if (ret >= 0)
1844*4882a593Smuzhiyun pdata->rxnumevt = val;
1845*4882a593Smuzhiyun
1846*4882a593Smuzhiyun ret = of_property_read_u32(np, "sram-size-playback", &val);
1847*4882a593Smuzhiyun if (ret >= 0)
1848*4882a593Smuzhiyun pdata->sram_size_playback = val;
1849*4882a593Smuzhiyun
1850*4882a593Smuzhiyun ret = of_property_read_u32(np, "sram-size-capture", &val);
1851*4882a593Smuzhiyun if (ret >= 0)
1852*4882a593Smuzhiyun pdata->sram_size_capture = val;
1853*4882a593Smuzhiyun
1854*4882a593Smuzhiyun ret = of_property_read_u32(np, "dismod", &val);
1855*4882a593Smuzhiyun if (ret >= 0) {
1856*4882a593Smuzhiyun if (val == 0 || val == 2 || val == 3) {
1857*4882a593Smuzhiyun pdata->dismod = DISMOD_VAL(val);
1858*4882a593Smuzhiyun } else {
1859*4882a593Smuzhiyun dev_warn(&pdev->dev, "Invalid dismod value: %u\n", val);
1860*4882a593Smuzhiyun pdata->dismod = DISMOD_LOW;
1861*4882a593Smuzhiyun }
1862*4882a593Smuzhiyun } else {
1863*4882a593Smuzhiyun pdata->dismod = DISMOD_LOW;
1864*4882a593Smuzhiyun }
1865*4882a593Smuzhiyun
1866*4882a593Smuzhiyun return pdata;
1867*4882a593Smuzhiyun
1868*4882a593Smuzhiyun nodata:
1869*4882a593Smuzhiyun if (ret < 0) {
1870*4882a593Smuzhiyun dev_err(&pdev->dev, "Error populating platform data, err %d\n",
1871*4882a593Smuzhiyun ret);
1872*4882a593Smuzhiyun pdata = NULL;
1873*4882a593Smuzhiyun }
1874*4882a593Smuzhiyun return pdata;
1875*4882a593Smuzhiyun }
1876*4882a593Smuzhiyun
1877*4882a593Smuzhiyun enum {
1878*4882a593Smuzhiyun PCM_EDMA,
1879*4882a593Smuzhiyun PCM_SDMA,
1880*4882a593Smuzhiyun PCM_UDMA,
1881*4882a593Smuzhiyun };
1882*4882a593Smuzhiyun static const char *sdma_prefix = "ti,omap";
1883*4882a593Smuzhiyun
davinci_mcasp_get_dma_type(struct davinci_mcasp * mcasp)1884*4882a593Smuzhiyun static int davinci_mcasp_get_dma_type(struct davinci_mcasp *mcasp)
1885*4882a593Smuzhiyun {
1886*4882a593Smuzhiyun struct dma_chan *chan;
1887*4882a593Smuzhiyun const char *tmp;
1888*4882a593Smuzhiyun int ret = PCM_EDMA;
1889*4882a593Smuzhiyun
1890*4882a593Smuzhiyun if (!mcasp->dev->of_node)
1891*4882a593Smuzhiyun return PCM_EDMA;
1892*4882a593Smuzhiyun
1893*4882a593Smuzhiyun tmp = mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data;
1894*4882a593Smuzhiyun chan = dma_request_chan(mcasp->dev, tmp);
1895*4882a593Smuzhiyun if (IS_ERR(chan)) {
1896*4882a593Smuzhiyun if (PTR_ERR(chan) != -EPROBE_DEFER)
1897*4882a593Smuzhiyun dev_err(mcasp->dev,
1898*4882a593Smuzhiyun "Can't verify DMA configuration (%ld)\n",
1899*4882a593Smuzhiyun PTR_ERR(chan));
1900*4882a593Smuzhiyun return PTR_ERR(chan);
1901*4882a593Smuzhiyun }
1902*4882a593Smuzhiyun if (WARN_ON(!chan->device || !chan->device->dev)) {
1903*4882a593Smuzhiyun dma_release_channel(chan);
1904*4882a593Smuzhiyun return -EINVAL;
1905*4882a593Smuzhiyun }
1906*4882a593Smuzhiyun
1907*4882a593Smuzhiyun if (chan->device->dev->of_node)
1908*4882a593Smuzhiyun ret = of_property_read_string(chan->device->dev->of_node,
1909*4882a593Smuzhiyun "compatible", &tmp);
1910*4882a593Smuzhiyun else
1911*4882a593Smuzhiyun dev_dbg(mcasp->dev, "DMA controller has no of-node\n");
1912*4882a593Smuzhiyun
1913*4882a593Smuzhiyun dma_release_channel(chan);
1914*4882a593Smuzhiyun if (ret)
1915*4882a593Smuzhiyun return ret;
1916*4882a593Smuzhiyun
1917*4882a593Smuzhiyun dev_dbg(mcasp->dev, "DMA controller compatible = \"%s\"\n", tmp);
1918*4882a593Smuzhiyun if (!strncmp(tmp, sdma_prefix, strlen(sdma_prefix)))
1919*4882a593Smuzhiyun return PCM_SDMA;
1920*4882a593Smuzhiyun else if (strstr(tmp, "udmap"))
1921*4882a593Smuzhiyun return PCM_UDMA;
1922*4882a593Smuzhiyun
1923*4882a593Smuzhiyun return PCM_EDMA;
1924*4882a593Smuzhiyun }
1925*4882a593Smuzhiyun
davinci_mcasp_txdma_offset(struct davinci_mcasp_pdata * pdata)1926*4882a593Smuzhiyun static u32 davinci_mcasp_txdma_offset(struct davinci_mcasp_pdata *pdata)
1927*4882a593Smuzhiyun {
1928*4882a593Smuzhiyun int i;
1929*4882a593Smuzhiyun u32 offset = 0;
1930*4882a593Smuzhiyun
1931*4882a593Smuzhiyun if (pdata->version != MCASP_VERSION_4)
1932*4882a593Smuzhiyun return pdata->tx_dma_offset;
1933*4882a593Smuzhiyun
1934*4882a593Smuzhiyun for (i = 0; i < pdata->num_serializer; i++) {
1935*4882a593Smuzhiyun if (pdata->serial_dir[i] == TX_MODE) {
1936*4882a593Smuzhiyun if (!offset) {
1937*4882a593Smuzhiyun offset = DAVINCI_MCASP_TXBUF_REG(i);
1938*4882a593Smuzhiyun } else {
1939*4882a593Smuzhiyun pr_err("%s: Only one serializer allowed!\n",
1940*4882a593Smuzhiyun __func__);
1941*4882a593Smuzhiyun break;
1942*4882a593Smuzhiyun }
1943*4882a593Smuzhiyun }
1944*4882a593Smuzhiyun }
1945*4882a593Smuzhiyun
1946*4882a593Smuzhiyun return offset;
1947*4882a593Smuzhiyun }
1948*4882a593Smuzhiyun
davinci_mcasp_rxdma_offset(struct davinci_mcasp_pdata * pdata)1949*4882a593Smuzhiyun static u32 davinci_mcasp_rxdma_offset(struct davinci_mcasp_pdata *pdata)
1950*4882a593Smuzhiyun {
1951*4882a593Smuzhiyun int i;
1952*4882a593Smuzhiyun u32 offset = 0;
1953*4882a593Smuzhiyun
1954*4882a593Smuzhiyun if (pdata->version != MCASP_VERSION_4)
1955*4882a593Smuzhiyun return pdata->rx_dma_offset;
1956*4882a593Smuzhiyun
1957*4882a593Smuzhiyun for (i = 0; i < pdata->num_serializer; i++) {
1958*4882a593Smuzhiyun if (pdata->serial_dir[i] == RX_MODE) {
1959*4882a593Smuzhiyun if (!offset) {
1960*4882a593Smuzhiyun offset = DAVINCI_MCASP_RXBUF_REG(i);
1961*4882a593Smuzhiyun } else {
1962*4882a593Smuzhiyun pr_err("%s: Only one serializer allowed!\n",
1963*4882a593Smuzhiyun __func__);
1964*4882a593Smuzhiyun break;
1965*4882a593Smuzhiyun }
1966*4882a593Smuzhiyun }
1967*4882a593Smuzhiyun }
1968*4882a593Smuzhiyun
1969*4882a593Smuzhiyun return offset;
1970*4882a593Smuzhiyun }
1971*4882a593Smuzhiyun
1972*4882a593Smuzhiyun #ifdef CONFIG_GPIOLIB
davinci_mcasp_gpio_request(struct gpio_chip * chip,unsigned offset)1973*4882a593Smuzhiyun static int davinci_mcasp_gpio_request(struct gpio_chip *chip, unsigned offset)
1974*4882a593Smuzhiyun {
1975*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
1976*4882a593Smuzhiyun
1977*4882a593Smuzhiyun if (mcasp->num_serializer && offset < mcasp->num_serializer &&
1978*4882a593Smuzhiyun mcasp->serial_dir[offset] != INACTIVE_MODE) {
1979*4882a593Smuzhiyun dev_err(mcasp->dev, "AXR%u pin is used for audio\n", offset);
1980*4882a593Smuzhiyun return -EBUSY;
1981*4882a593Smuzhiyun }
1982*4882a593Smuzhiyun
1983*4882a593Smuzhiyun /* Do not change the PIN yet */
1984*4882a593Smuzhiyun
1985*4882a593Smuzhiyun return pm_runtime_get_sync(mcasp->dev);
1986*4882a593Smuzhiyun }
1987*4882a593Smuzhiyun
davinci_mcasp_gpio_free(struct gpio_chip * chip,unsigned offset)1988*4882a593Smuzhiyun static void davinci_mcasp_gpio_free(struct gpio_chip *chip, unsigned offset)
1989*4882a593Smuzhiyun {
1990*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
1991*4882a593Smuzhiyun
1992*4882a593Smuzhiyun /* Set the direction to input */
1993*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(offset));
1994*4882a593Smuzhiyun
1995*4882a593Smuzhiyun /* Set the pin as McASP pin */
1996*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PFUNC_REG, BIT(offset));
1997*4882a593Smuzhiyun
1998*4882a593Smuzhiyun pm_runtime_put_sync(mcasp->dev);
1999*4882a593Smuzhiyun }
2000*4882a593Smuzhiyun
davinci_mcasp_gpio_direction_out(struct gpio_chip * chip,unsigned offset,int value)2001*4882a593Smuzhiyun static int davinci_mcasp_gpio_direction_out(struct gpio_chip *chip,
2002*4882a593Smuzhiyun unsigned offset, int value)
2003*4882a593Smuzhiyun {
2004*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
2005*4882a593Smuzhiyun u32 val;
2006*4882a593Smuzhiyun
2007*4882a593Smuzhiyun if (value)
2008*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PDOUT_REG, BIT(offset));
2009*4882a593Smuzhiyun else
2010*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDOUT_REG, BIT(offset));
2011*4882a593Smuzhiyun
2012*4882a593Smuzhiyun val = mcasp_get_reg(mcasp, DAVINCI_MCASP_PFUNC_REG);
2013*4882a593Smuzhiyun if (!(val & BIT(offset))) {
2014*4882a593Smuzhiyun /* Set the pin as GPIO pin */
2015*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PFUNC_REG, BIT(offset));
2016*4882a593Smuzhiyun
2017*4882a593Smuzhiyun /* Set the direction to output */
2018*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(offset));
2019*4882a593Smuzhiyun }
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun return 0;
2022*4882a593Smuzhiyun }
2023*4882a593Smuzhiyun
davinci_mcasp_gpio_set(struct gpio_chip * chip,unsigned offset,int value)2024*4882a593Smuzhiyun static void davinci_mcasp_gpio_set(struct gpio_chip *chip, unsigned offset,
2025*4882a593Smuzhiyun int value)
2026*4882a593Smuzhiyun {
2027*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
2028*4882a593Smuzhiyun
2029*4882a593Smuzhiyun if (value)
2030*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PDOUT_REG, BIT(offset));
2031*4882a593Smuzhiyun else
2032*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDOUT_REG, BIT(offset));
2033*4882a593Smuzhiyun }
2034*4882a593Smuzhiyun
davinci_mcasp_gpio_direction_in(struct gpio_chip * chip,unsigned offset)2035*4882a593Smuzhiyun static int davinci_mcasp_gpio_direction_in(struct gpio_chip *chip,
2036*4882a593Smuzhiyun unsigned offset)
2037*4882a593Smuzhiyun {
2038*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
2039*4882a593Smuzhiyun u32 val;
2040*4882a593Smuzhiyun
2041*4882a593Smuzhiyun val = mcasp_get_reg(mcasp, DAVINCI_MCASP_PFUNC_REG);
2042*4882a593Smuzhiyun if (!(val & BIT(offset))) {
2043*4882a593Smuzhiyun /* Set the direction to input */
2044*4882a593Smuzhiyun mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(offset));
2045*4882a593Smuzhiyun
2046*4882a593Smuzhiyun /* Set the pin as GPIO pin */
2047*4882a593Smuzhiyun mcasp_set_bits(mcasp, DAVINCI_MCASP_PFUNC_REG, BIT(offset));
2048*4882a593Smuzhiyun }
2049*4882a593Smuzhiyun
2050*4882a593Smuzhiyun return 0;
2051*4882a593Smuzhiyun }
2052*4882a593Smuzhiyun
davinci_mcasp_gpio_get(struct gpio_chip * chip,unsigned offset)2053*4882a593Smuzhiyun static int davinci_mcasp_gpio_get(struct gpio_chip *chip, unsigned offset)
2054*4882a593Smuzhiyun {
2055*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
2056*4882a593Smuzhiyun u32 val;
2057*4882a593Smuzhiyun
2058*4882a593Smuzhiyun val = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDSET_REG);
2059*4882a593Smuzhiyun if (val & BIT(offset))
2060*4882a593Smuzhiyun return 1;
2061*4882a593Smuzhiyun
2062*4882a593Smuzhiyun return 0;
2063*4882a593Smuzhiyun }
2064*4882a593Smuzhiyun
davinci_mcasp_gpio_get_direction(struct gpio_chip * chip,unsigned offset)2065*4882a593Smuzhiyun static int davinci_mcasp_gpio_get_direction(struct gpio_chip *chip,
2066*4882a593Smuzhiyun unsigned offset)
2067*4882a593Smuzhiyun {
2068*4882a593Smuzhiyun struct davinci_mcasp *mcasp = gpiochip_get_data(chip);
2069*4882a593Smuzhiyun u32 val;
2070*4882a593Smuzhiyun
2071*4882a593Smuzhiyun val = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG);
2072*4882a593Smuzhiyun if (val & BIT(offset))
2073*4882a593Smuzhiyun return 0;
2074*4882a593Smuzhiyun
2075*4882a593Smuzhiyun return 1;
2076*4882a593Smuzhiyun }
2077*4882a593Smuzhiyun
2078*4882a593Smuzhiyun static const struct gpio_chip davinci_mcasp_template_chip = {
2079*4882a593Smuzhiyun .owner = THIS_MODULE,
2080*4882a593Smuzhiyun .request = davinci_mcasp_gpio_request,
2081*4882a593Smuzhiyun .free = davinci_mcasp_gpio_free,
2082*4882a593Smuzhiyun .direction_output = davinci_mcasp_gpio_direction_out,
2083*4882a593Smuzhiyun .set = davinci_mcasp_gpio_set,
2084*4882a593Smuzhiyun .direction_input = davinci_mcasp_gpio_direction_in,
2085*4882a593Smuzhiyun .get = davinci_mcasp_gpio_get,
2086*4882a593Smuzhiyun .get_direction = davinci_mcasp_gpio_get_direction,
2087*4882a593Smuzhiyun .base = -1,
2088*4882a593Smuzhiyun .ngpio = 32,
2089*4882a593Smuzhiyun };
2090*4882a593Smuzhiyun
davinci_mcasp_init_gpiochip(struct davinci_mcasp * mcasp)2091*4882a593Smuzhiyun static int davinci_mcasp_init_gpiochip(struct davinci_mcasp *mcasp)
2092*4882a593Smuzhiyun {
2093*4882a593Smuzhiyun if (!of_property_read_bool(mcasp->dev->of_node, "gpio-controller"))
2094*4882a593Smuzhiyun return 0;
2095*4882a593Smuzhiyun
2096*4882a593Smuzhiyun mcasp->gpio_chip = davinci_mcasp_template_chip;
2097*4882a593Smuzhiyun mcasp->gpio_chip.label = dev_name(mcasp->dev);
2098*4882a593Smuzhiyun mcasp->gpio_chip.parent = mcasp->dev;
2099*4882a593Smuzhiyun #ifdef CONFIG_OF_GPIO
2100*4882a593Smuzhiyun mcasp->gpio_chip.of_node = mcasp->dev->of_node;
2101*4882a593Smuzhiyun #endif
2102*4882a593Smuzhiyun
2103*4882a593Smuzhiyun return devm_gpiochip_add_data(mcasp->dev, &mcasp->gpio_chip, mcasp);
2104*4882a593Smuzhiyun }
2105*4882a593Smuzhiyun
2106*4882a593Smuzhiyun #else /* CONFIG_GPIOLIB */
davinci_mcasp_init_gpiochip(struct davinci_mcasp * mcasp)2107*4882a593Smuzhiyun static inline int davinci_mcasp_init_gpiochip(struct davinci_mcasp *mcasp)
2108*4882a593Smuzhiyun {
2109*4882a593Smuzhiyun return 0;
2110*4882a593Smuzhiyun }
2111*4882a593Smuzhiyun #endif /* CONFIG_GPIOLIB */
2112*4882a593Smuzhiyun
davinci_mcasp_get_dt_params(struct davinci_mcasp * mcasp)2113*4882a593Smuzhiyun static int davinci_mcasp_get_dt_params(struct davinci_mcasp *mcasp)
2114*4882a593Smuzhiyun {
2115*4882a593Smuzhiyun struct device_node *np = mcasp->dev->of_node;
2116*4882a593Smuzhiyun int ret;
2117*4882a593Smuzhiyun u32 val;
2118*4882a593Smuzhiyun
2119*4882a593Smuzhiyun if (!np)
2120*4882a593Smuzhiyun return 0;
2121*4882a593Smuzhiyun
2122*4882a593Smuzhiyun ret = of_property_read_u32(np, "auxclk-fs-ratio", &val);
2123*4882a593Smuzhiyun if (ret >= 0)
2124*4882a593Smuzhiyun mcasp->auxclk_fs_ratio = val;
2125*4882a593Smuzhiyun
2126*4882a593Smuzhiyun return 0;
2127*4882a593Smuzhiyun }
2128*4882a593Smuzhiyun
davinci_mcasp_probe(struct platform_device * pdev)2129*4882a593Smuzhiyun static int davinci_mcasp_probe(struct platform_device *pdev)
2130*4882a593Smuzhiyun {
2131*4882a593Smuzhiyun struct snd_dmaengine_dai_dma_data *dma_data;
2132*4882a593Smuzhiyun struct resource *mem, *res, *dat;
2133*4882a593Smuzhiyun struct davinci_mcasp_pdata *pdata;
2134*4882a593Smuzhiyun struct davinci_mcasp *mcasp;
2135*4882a593Smuzhiyun char *irq_name;
2136*4882a593Smuzhiyun int *dma;
2137*4882a593Smuzhiyun int irq;
2138*4882a593Smuzhiyun int ret;
2139*4882a593Smuzhiyun
2140*4882a593Smuzhiyun if (!pdev->dev.platform_data && !pdev->dev.of_node) {
2141*4882a593Smuzhiyun dev_err(&pdev->dev, "No platform data supplied\n");
2142*4882a593Smuzhiyun return -EINVAL;
2143*4882a593Smuzhiyun }
2144*4882a593Smuzhiyun
2145*4882a593Smuzhiyun mcasp = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcasp),
2146*4882a593Smuzhiyun GFP_KERNEL);
2147*4882a593Smuzhiyun if (!mcasp)
2148*4882a593Smuzhiyun return -ENOMEM;
2149*4882a593Smuzhiyun
2150*4882a593Smuzhiyun pdata = davinci_mcasp_set_pdata_from_of(pdev);
2151*4882a593Smuzhiyun if (!pdata) {
2152*4882a593Smuzhiyun dev_err(&pdev->dev, "no platform data\n");
2153*4882a593Smuzhiyun return -EINVAL;
2154*4882a593Smuzhiyun }
2155*4882a593Smuzhiyun
2156*4882a593Smuzhiyun mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
2157*4882a593Smuzhiyun if (!mem) {
2158*4882a593Smuzhiyun dev_warn(&pdev->dev,
2159*4882a593Smuzhiyun "\"mpu\" mem resource not found, using index 0\n");
2160*4882a593Smuzhiyun mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2161*4882a593Smuzhiyun if (!mem) {
2162*4882a593Smuzhiyun dev_err(&pdev->dev, "no mem resource?\n");
2163*4882a593Smuzhiyun return -ENODEV;
2164*4882a593Smuzhiyun }
2165*4882a593Smuzhiyun }
2166*4882a593Smuzhiyun
2167*4882a593Smuzhiyun mcasp->base = devm_ioremap_resource(&pdev->dev, mem);
2168*4882a593Smuzhiyun if (IS_ERR(mcasp->base))
2169*4882a593Smuzhiyun return PTR_ERR(mcasp->base);
2170*4882a593Smuzhiyun
2171*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
2172*4882a593Smuzhiyun
2173*4882a593Smuzhiyun mcasp->op_mode = pdata->op_mode;
2174*4882a593Smuzhiyun /* sanity check for tdm slots parameter */
2175*4882a593Smuzhiyun if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) {
2176*4882a593Smuzhiyun if (pdata->tdm_slots < 2) {
2177*4882a593Smuzhiyun dev_err(&pdev->dev, "invalid tdm slots: %d\n",
2178*4882a593Smuzhiyun pdata->tdm_slots);
2179*4882a593Smuzhiyun mcasp->tdm_slots = 2;
2180*4882a593Smuzhiyun } else if (pdata->tdm_slots > 32) {
2181*4882a593Smuzhiyun dev_err(&pdev->dev, "invalid tdm slots: %d\n",
2182*4882a593Smuzhiyun pdata->tdm_slots);
2183*4882a593Smuzhiyun mcasp->tdm_slots = 32;
2184*4882a593Smuzhiyun } else {
2185*4882a593Smuzhiyun mcasp->tdm_slots = pdata->tdm_slots;
2186*4882a593Smuzhiyun }
2187*4882a593Smuzhiyun }
2188*4882a593Smuzhiyun
2189*4882a593Smuzhiyun mcasp->num_serializer = pdata->num_serializer;
2190*4882a593Smuzhiyun #ifdef CONFIG_PM
2191*4882a593Smuzhiyun mcasp->context.xrsr_regs = devm_kcalloc(&pdev->dev,
2192*4882a593Smuzhiyun mcasp->num_serializer, sizeof(u32),
2193*4882a593Smuzhiyun GFP_KERNEL);
2194*4882a593Smuzhiyun if (!mcasp->context.xrsr_regs) {
2195*4882a593Smuzhiyun ret = -ENOMEM;
2196*4882a593Smuzhiyun goto err;
2197*4882a593Smuzhiyun }
2198*4882a593Smuzhiyun #endif
2199*4882a593Smuzhiyun mcasp->serial_dir = pdata->serial_dir;
2200*4882a593Smuzhiyun mcasp->version = pdata->version;
2201*4882a593Smuzhiyun mcasp->txnumevt = pdata->txnumevt;
2202*4882a593Smuzhiyun mcasp->rxnumevt = pdata->rxnumevt;
2203*4882a593Smuzhiyun mcasp->dismod = pdata->dismod;
2204*4882a593Smuzhiyun
2205*4882a593Smuzhiyun mcasp->dev = &pdev->dev;
2206*4882a593Smuzhiyun
2207*4882a593Smuzhiyun irq = platform_get_irq_byname(pdev, "common");
2208*4882a593Smuzhiyun if (irq >= 0) {
2209*4882a593Smuzhiyun irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_common",
2210*4882a593Smuzhiyun dev_name(&pdev->dev));
2211*4882a593Smuzhiyun if (!irq_name) {
2212*4882a593Smuzhiyun ret = -ENOMEM;
2213*4882a593Smuzhiyun goto err;
2214*4882a593Smuzhiyun }
2215*4882a593Smuzhiyun ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
2216*4882a593Smuzhiyun davinci_mcasp_common_irq_handler,
2217*4882a593Smuzhiyun IRQF_ONESHOT | IRQF_SHARED,
2218*4882a593Smuzhiyun irq_name, mcasp);
2219*4882a593Smuzhiyun if (ret) {
2220*4882a593Smuzhiyun dev_err(&pdev->dev, "common IRQ request failed\n");
2221*4882a593Smuzhiyun goto err;
2222*4882a593Smuzhiyun }
2223*4882a593Smuzhiyun
2224*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN;
2225*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN;
2226*4882a593Smuzhiyun }
2227*4882a593Smuzhiyun
2228*4882a593Smuzhiyun irq = platform_get_irq_byname(pdev, "rx");
2229*4882a593Smuzhiyun if (irq >= 0) {
2230*4882a593Smuzhiyun irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx",
2231*4882a593Smuzhiyun dev_name(&pdev->dev));
2232*4882a593Smuzhiyun if (!irq_name) {
2233*4882a593Smuzhiyun ret = -ENOMEM;
2234*4882a593Smuzhiyun goto err;
2235*4882a593Smuzhiyun }
2236*4882a593Smuzhiyun ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
2237*4882a593Smuzhiyun davinci_mcasp_rx_irq_handler,
2238*4882a593Smuzhiyun IRQF_ONESHOT, irq_name, mcasp);
2239*4882a593Smuzhiyun if (ret) {
2240*4882a593Smuzhiyun dev_err(&pdev->dev, "RX IRQ request failed\n");
2241*4882a593Smuzhiyun goto err;
2242*4882a593Smuzhiyun }
2243*4882a593Smuzhiyun
2244*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN;
2245*4882a593Smuzhiyun }
2246*4882a593Smuzhiyun
2247*4882a593Smuzhiyun irq = platform_get_irq_byname(pdev, "tx");
2248*4882a593Smuzhiyun if (irq >= 0) {
2249*4882a593Smuzhiyun irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_tx",
2250*4882a593Smuzhiyun dev_name(&pdev->dev));
2251*4882a593Smuzhiyun if (!irq_name) {
2252*4882a593Smuzhiyun ret = -ENOMEM;
2253*4882a593Smuzhiyun goto err;
2254*4882a593Smuzhiyun }
2255*4882a593Smuzhiyun ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
2256*4882a593Smuzhiyun davinci_mcasp_tx_irq_handler,
2257*4882a593Smuzhiyun IRQF_ONESHOT, irq_name, mcasp);
2258*4882a593Smuzhiyun if (ret) {
2259*4882a593Smuzhiyun dev_err(&pdev->dev, "TX IRQ request failed\n");
2260*4882a593Smuzhiyun goto err;
2261*4882a593Smuzhiyun }
2262*4882a593Smuzhiyun
2263*4882a593Smuzhiyun mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN;
2264*4882a593Smuzhiyun }
2265*4882a593Smuzhiyun
2266*4882a593Smuzhiyun dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
2267*4882a593Smuzhiyun if (dat)
2268*4882a593Smuzhiyun mcasp->dat_port = true;
2269*4882a593Smuzhiyun
2270*4882a593Smuzhiyun dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
2271*4882a593Smuzhiyun if (dat)
2272*4882a593Smuzhiyun dma_data->addr = dat->start;
2273*4882a593Smuzhiyun else
2274*4882a593Smuzhiyun dma_data->addr = mem->start + davinci_mcasp_txdma_offset(pdata);
2275*4882a593Smuzhiyun
2276*4882a593Smuzhiyun dma = &mcasp->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
2277*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
2278*4882a593Smuzhiyun if (res)
2279*4882a593Smuzhiyun *dma = res->start;
2280*4882a593Smuzhiyun else
2281*4882a593Smuzhiyun *dma = pdata->tx_dma_channel;
2282*4882a593Smuzhiyun
2283*4882a593Smuzhiyun /* dmaengine filter data for DT and non-DT boot */
2284*4882a593Smuzhiyun if (pdev->dev.of_node)
2285*4882a593Smuzhiyun dma_data->filter_data = "tx";
2286*4882a593Smuzhiyun else
2287*4882a593Smuzhiyun dma_data->filter_data = dma;
2288*4882a593Smuzhiyun
2289*4882a593Smuzhiyun /* RX is not valid in DIT mode */
2290*4882a593Smuzhiyun if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
2291*4882a593Smuzhiyun dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
2292*4882a593Smuzhiyun if (dat)
2293*4882a593Smuzhiyun dma_data->addr = dat->start;
2294*4882a593Smuzhiyun else
2295*4882a593Smuzhiyun dma_data->addr =
2296*4882a593Smuzhiyun mem->start + davinci_mcasp_rxdma_offset(pdata);
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun dma = &mcasp->dma_request[SNDRV_PCM_STREAM_CAPTURE];
2299*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
2300*4882a593Smuzhiyun if (res)
2301*4882a593Smuzhiyun *dma = res->start;
2302*4882a593Smuzhiyun else
2303*4882a593Smuzhiyun *dma = pdata->rx_dma_channel;
2304*4882a593Smuzhiyun
2305*4882a593Smuzhiyun /* dmaengine filter data for DT and non-DT boot */
2306*4882a593Smuzhiyun if (pdev->dev.of_node)
2307*4882a593Smuzhiyun dma_data->filter_data = "rx";
2308*4882a593Smuzhiyun else
2309*4882a593Smuzhiyun dma_data->filter_data = dma;
2310*4882a593Smuzhiyun }
2311*4882a593Smuzhiyun
2312*4882a593Smuzhiyun if (mcasp->version < MCASP_VERSION_3) {
2313*4882a593Smuzhiyun mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
2314*4882a593Smuzhiyun /* dma_params->dma_addr is pointing to the data port address */
2315*4882a593Smuzhiyun mcasp->dat_port = true;
2316*4882a593Smuzhiyun } else {
2317*4882a593Smuzhiyun mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
2318*4882a593Smuzhiyun }
2319*4882a593Smuzhiyun
2320*4882a593Smuzhiyun /* Allocate memory for long enough list for all possible
2321*4882a593Smuzhiyun * scenarios. Maximum number tdm slots is 32 and there cannot
2322*4882a593Smuzhiyun * be more serializers than given in the configuration. The
2323*4882a593Smuzhiyun * serializer directions could be taken into account, but it
2324*4882a593Smuzhiyun * would make code much more complex and save only couple of
2325*4882a593Smuzhiyun * bytes.
2326*4882a593Smuzhiyun */
2327*4882a593Smuzhiyun mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list =
2328*4882a593Smuzhiyun devm_kcalloc(mcasp->dev,
2329*4882a593Smuzhiyun 32 + mcasp->num_serializer - 1,
2330*4882a593Smuzhiyun sizeof(unsigned int),
2331*4882a593Smuzhiyun GFP_KERNEL);
2332*4882a593Smuzhiyun
2333*4882a593Smuzhiyun mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list =
2334*4882a593Smuzhiyun devm_kcalloc(mcasp->dev,
2335*4882a593Smuzhiyun 32 + mcasp->num_serializer - 1,
2336*4882a593Smuzhiyun sizeof(unsigned int),
2337*4882a593Smuzhiyun GFP_KERNEL);
2338*4882a593Smuzhiyun
2339*4882a593Smuzhiyun if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||
2340*4882a593Smuzhiyun !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list) {
2341*4882a593Smuzhiyun ret = -ENOMEM;
2342*4882a593Smuzhiyun goto err;
2343*4882a593Smuzhiyun }
2344*4882a593Smuzhiyun
2345*4882a593Smuzhiyun ret = davinci_mcasp_set_ch_constraints(mcasp);
2346*4882a593Smuzhiyun if (ret)
2347*4882a593Smuzhiyun goto err;
2348*4882a593Smuzhiyun
2349*4882a593Smuzhiyun dev_set_drvdata(&pdev->dev, mcasp);
2350*4882a593Smuzhiyun
2351*4882a593Smuzhiyun mcasp_reparent_fck(pdev);
2352*4882a593Smuzhiyun
2353*4882a593Smuzhiyun /* All PINS as McASP */
2354*4882a593Smuzhiyun pm_runtime_get_sync(mcasp->dev);
2355*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_PFUNC_REG, 0x00000000);
2356*4882a593Smuzhiyun pm_runtime_put(mcasp->dev);
2357*4882a593Smuzhiyun
2358*4882a593Smuzhiyun ret = davinci_mcasp_init_gpiochip(mcasp);
2359*4882a593Smuzhiyun if (ret)
2360*4882a593Smuzhiyun goto err;
2361*4882a593Smuzhiyun
2362*4882a593Smuzhiyun ret = davinci_mcasp_get_dt_params(mcasp);
2363*4882a593Smuzhiyun if (ret)
2364*4882a593Smuzhiyun return -EINVAL;
2365*4882a593Smuzhiyun
2366*4882a593Smuzhiyun ret = devm_snd_soc_register_component(&pdev->dev,
2367*4882a593Smuzhiyun &davinci_mcasp_component,
2368*4882a593Smuzhiyun &davinci_mcasp_dai[pdata->op_mode], 1);
2369*4882a593Smuzhiyun
2370*4882a593Smuzhiyun if (ret != 0)
2371*4882a593Smuzhiyun goto err;
2372*4882a593Smuzhiyun
2373*4882a593Smuzhiyun ret = davinci_mcasp_get_dma_type(mcasp);
2374*4882a593Smuzhiyun switch (ret) {
2375*4882a593Smuzhiyun case PCM_EDMA:
2376*4882a593Smuzhiyun ret = edma_pcm_platform_register(&pdev->dev);
2377*4882a593Smuzhiyun break;
2378*4882a593Smuzhiyun case PCM_SDMA:
2379*4882a593Smuzhiyun ret = sdma_pcm_platform_register(&pdev->dev, "tx", "rx");
2380*4882a593Smuzhiyun break;
2381*4882a593Smuzhiyun case PCM_UDMA:
2382*4882a593Smuzhiyun ret = udma_pcm_platform_register(&pdev->dev);
2383*4882a593Smuzhiyun break;
2384*4882a593Smuzhiyun default:
2385*4882a593Smuzhiyun dev_err(&pdev->dev, "No DMA controller found (%d)\n", ret);
2386*4882a593Smuzhiyun case -EPROBE_DEFER:
2387*4882a593Smuzhiyun goto err;
2388*4882a593Smuzhiyun break;
2389*4882a593Smuzhiyun }
2390*4882a593Smuzhiyun
2391*4882a593Smuzhiyun if (ret) {
2392*4882a593Smuzhiyun dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
2393*4882a593Smuzhiyun goto err;
2394*4882a593Smuzhiyun }
2395*4882a593Smuzhiyun
2396*4882a593Smuzhiyun return 0;
2397*4882a593Smuzhiyun
2398*4882a593Smuzhiyun err:
2399*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
2400*4882a593Smuzhiyun return ret;
2401*4882a593Smuzhiyun }
2402*4882a593Smuzhiyun
davinci_mcasp_remove(struct platform_device * pdev)2403*4882a593Smuzhiyun static int davinci_mcasp_remove(struct platform_device *pdev)
2404*4882a593Smuzhiyun {
2405*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
2406*4882a593Smuzhiyun
2407*4882a593Smuzhiyun return 0;
2408*4882a593Smuzhiyun }
2409*4882a593Smuzhiyun
2410*4882a593Smuzhiyun #ifdef CONFIG_PM
davinci_mcasp_runtime_suspend(struct device * dev)2411*4882a593Smuzhiyun static int davinci_mcasp_runtime_suspend(struct device *dev)
2412*4882a593Smuzhiyun {
2413*4882a593Smuzhiyun struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
2414*4882a593Smuzhiyun struct davinci_mcasp_context *context = &mcasp->context;
2415*4882a593Smuzhiyun u32 reg;
2416*4882a593Smuzhiyun int i;
2417*4882a593Smuzhiyun
2418*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(context_regs); i++)
2419*4882a593Smuzhiyun context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
2420*4882a593Smuzhiyun
2421*4882a593Smuzhiyun if (mcasp->txnumevt) {
2422*4882a593Smuzhiyun reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
2423*4882a593Smuzhiyun context->afifo_regs[0] = mcasp_get_reg(mcasp, reg);
2424*4882a593Smuzhiyun }
2425*4882a593Smuzhiyun if (mcasp->rxnumevt) {
2426*4882a593Smuzhiyun reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
2427*4882a593Smuzhiyun context->afifo_regs[1] = mcasp_get_reg(mcasp, reg);
2428*4882a593Smuzhiyun }
2429*4882a593Smuzhiyun
2430*4882a593Smuzhiyun for (i = 0; i < mcasp->num_serializer; i++)
2431*4882a593Smuzhiyun context->xrsr_regs[i] = mcasp_get_reg(mcasp,
2432*4882a593Smuzhiyun DAVINCI_MCASP_XRSRCTL_REG(i));
2433*4882a593Smuzhiyun
2434*4882a593Smuzhiyun return 0;
2435*4882a593Smuzhiyun }
2436*4882a593Smuzhiyun
davinci_mcasp_runtime_resume(struct device * dev)2437*4882a593Smuzhiyun static int davinci_mcasp_runtime_resume(struct device *dev)
2438*4882a593Smuzhiyun {
2439*4882a593Smuzhiyun struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
2440*4882a593Smuzhiyun struct davinci_mcasp_context *context = &mcasp->context;
2441*4882a593Smuzhiyun u32 reg;
2442*4882a593Smuzhiyun int i;
2443*4882a593Smuzhiyun
2444*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(context_regs); i++)
2445*4882a593Smuzhiyun mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
2446*4882a593Smuzhiyun
2447*4882a593Smuzhiyun if (mcasp->txnumevt) {
2448*4882a593Smuzhiyun reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET;
2449*4882a593Smuzhiyun mcasp_set_reg(mcasp, reg, context->afifo_regs[0]);
2450*4882a593Smuzhiyun }
2451*4882a593Smuzhiyun if (mcasp->rxnumevt) {
2452*4882a593Smuzhiyun reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET;
2453*4882a593Smuzhiyun mcasp_set_reg(mcasp, reg, context->afifo_regs[1]);
2454*4882a593Smuzhiyun }
2455*4882a593Smuzhiyun
2456*4882a593Smuzhiyun for (i = 0; i < mcasp->num_serializer; i++)
2457*4882a593Smuzhiyun mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
2458*4882a593Smuzhiyun context->xrsr_regs[i]);
2459*4882a593Smuzhiyun
2460*4882a593Smuzhiyun return 0;
2461*4882a593Smuzhiyun }
2462*4882a593Smuzhiyun
2463*4882a593Smuzhiyun #endif
2464*4882a593Smuzhiyun
2465*4882a593Smuzhiyun static const struct dev_pm_ops davinci_mcasp_pm_ops = {
2466*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(davinci_mcasp_runtime_suspend,
2467*4882a593Smuzhiyun davinci_mcasp_runtime_resume,
2468*4882a593Smuzhiyun NULL)
2469*4882a593Smuzhiyun };
2470*4882a593Smuzhiyun
2471*4882a593Smuzhiyun static struct platform_driver davinci_mcasp_driver = {
2472*4882a593Smuzhiyun .probe = davinci_mcasp_probe,
2473*4882a593Smuzhiyun .remove = davinci_mcasp_remove,
2474*4882a593Smuzhiyun .driver = {
2475*4882a593Smuzhiyun .name = "davinci-mcasp",
2476*4882a593Smuzhiyun .pm = &davinci_mcasp_pm_ops,
2477*4882a593Smuzhiyun .of_match_table = mcasp_dt_ids,
2478*4882a593Smuzhiyun },
2479*4882a593Smuzhiyun };
2480*4882a593Smuzhiyun
2481*4882a593Smuzhiyun module_platform_driver(davinci_mcasp_driver);
2482*4882a593Smuzhiyun
2483*4882a593Smuzhiyun MODULE_AUTHOR("Steve Chen");
2484*4882a593Smuzhiyun MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
2485*4882a593Smuzhiyun MODULE_LICENSE("GPL");
2486