xref: /OK3568_Linux_fs/u-boot/drivers/sound/samsung-i2s.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2012 Samsung Electronics
3*4882a593Smuzhiyun  * R. Chandrasekar <rcsekar@samsung.com>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <asm/arch/clk.h>
9*4882a593Smuzhiyun #include <asm/arch/pinmux.h>
10*4882a593Smuzhiyun #include <asm/arch/i2s-regs.h>
11*4882a593Smuzhiyun #include <asm/io.h>
12*4882a593Smuzhiyun #include <common.h>
13*4882a593Smuzhiyun #include <sound.h>
14*4882a593Smuzhiyun #include <i2s.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define FIC_TX2COUNT(x)		(((x) >>  24) & 0xf)
17*4882a593Smuzhiyun #define FIC_TX1COUNT(x)		(((x) >>  16) & 0xf)
18*4882a593Smuzhiyun #define FIC_TXCOUNT(x)		(((x) >>  8) & 0xf)
19*4882a593Smuzhiyun #define FIC_RXCOUNT(x)		(((x) >>  0) & 0xf)
20*4882a593Smuzhiyun #define FICS_TXCOUNT(x)		(((x) >>  8) & 0x7f)
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define TIMEOUT_I2S_TX		100	/* i2s transfer timeout */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun  * Sets the frame size for I2S LR clock
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
28*4882a593Smuzhiyun  * @param rfs		Frame Size
29*4882a593Smuzhiyun  */
i2s_set_lr_framesize(struct i2s_reg * i2s_reg,unsigned int rfs)30*4882a593Smuzhiyun static void i2s_set_lr_framesize(struct i2s_reg *i2s_reg, unsigned int rfs)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	unsigned int mod = readl(&i2s_reg->mod);
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	mod &= ~MOD_RCLK_MASK;
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	switch (rfs) {
37*4882a593Smuzhiyun 	case 768:
38*4882a593Smuzhiyun 		mod |= MOD_RCLK_768FS;
39*4882a593Smuzhiyun 		break;
40*4882a593Smuzhiyun 	case 512:
41*4882a593Smuzhiyun 		mod |= MOD_RCLK_512FS;
42*4882a593Smuzhiyun 		break;
43*4882a593Smuzhiyun 	case 384:
44*4882a593Smuzhiyun 		mod |= MOD_RCLK_384FS;
45*4882a593Smuzhiyun 		break;
46*4882a593Smuzhiyun 	default:
47*4882a593Smuzhiyun 		mod |= MOD_RCLK_256FS;
48*4882a593Smuzhiyun 		break;
49*4882a593Smuzhiyun 	}
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	writel(mod, &i2s_reg->mod);
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun  * Sets the i2s transfer control
56*4882a593Smuzhiyun  *
57*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
58*4882a593Smuzhiyun  * @param on		1 enable tx , 0 disable tx transfer
59*4882a593Smuzhiyun  */
i2s_txctrl(struct i2s_reg * i2s_reg,int on)60*4882a593Smuzhiyun static void i2s_txctrl(struct i2s_reg *i2s_reg, int on)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun 	unsigned int con = readl(&i2s_reg->con);
63*4882a593Smuzhiyun 	unsigned int mod = readl(&i2s_reg->mod) & ~MOD_MASK;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	if (on) {
66*4882a593Smuzhiyun 		con |= CON_ACTIVE;
67*4882a593Smuzhiyun 		con &= ~CON_TXCH_PAUSE;
68*4882a593Smuzhiyun 	} else {
69*4882a593Smuzhiyun 		con |=  CON_TXCH_PAUSE;
70*4882a593Smuzhiyun 		con &= ~CON_ACTIVE;
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	writel(mod, &i2s_reg->mod);
74*4882a593Smuzhiyun 	writel(con, &i2s_reg->con);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun  * set the bit clock frame size (in multiples of LRCLK)
79*4882a593Smuzhiyun  *
80*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
81*4882a593Smuzhiyun  * @param bfs		bit Frame Size
82*4882a593Smuzhiyun  */
i2s_set_bitclk_framesize(struct i2s_reg * i2s_reg,unsigned bfs)83*4882a593Smuzhiyun static void i2s_set_bitclk_framesize(struct i2s_reg *i2s_reg, unsigned bfs)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 	unsigned int mod = readl(&i2s_reg->mod);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	mod &= ~MOD_BCLK_MASK;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 	switch (bfs) {
90*4882a593Smuzhiyun 	case 48:
91*4882a593Smuzhiyun 		mod |= MOD_BCLK_48FS;
92*4882a593Smuzhiyun 		break;
93*4882a593Smuzhiyun 	case 32:
94*4882a593Smuzhiyun 		mod |= MOD_BCLK_32FS;
95*4882a593Smuzhiyun 		break;
96*4882a593Smuzhiyun 	case 24:
97*4882a593Smuzhiyun 		mod |= MOD_BCLK_24FS;
98*4882a593Smuzhiyun 		break;
99*4882a593Smuzhiyun 	case 16:
100*4882a593Smuzhiyun 		mod |= MOD_BCLK_16FS;
101*4882a593Smuzhiyun 		break;
102*4882a593Smuzhiyun 	default:
103*4882a593Smuzhiyun 		return;
104*4882a593Smuzhiyun 	}
105*4882a593Smuzhiyun 	writel(mod, &i2s_reg->mod);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun /*
109*4882a593Smuzhiyun  * flushes the i2stx fifo
110*4882a593Smuzhiyun  *
111*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
112*4882a593Smuzhiyun  * @param flush		Tx fifo flush command (0x00 - do not flush
113*4882a593Smuzhiyun  *				0x80 - flush tx fifo)
114*4882a593Smuzhiyun  */
i2s_fifo(struct i2s_reg * i2s_reg,unsigned int flush)115*4882a593Smuzhiyun void i2s_fifo(struct i2s_reg *i2s_reg, unsigned int flush)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	/* Flush the FIFO */
118*4882a593Smuzhiyun 	setbits_le32(&i2s_reg->fic, flush);
119*4882a593Smuzhiyun 	clrbits_le32(&i2s_reg->fic, flush);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun /*
123*4882a593Smuzhiyun  * Set System Clock direction
124*4882a593Smuzhiyun  *
125*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
126*4882a593Smuzhiyun  * @param dir		Clock direction
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  * @return		int value 0 for success, -1 in case of error
129*4882a593Smuzhiyun  */
i2s_set_sysclk_dir(struct i2s_reg * i2s_reg,int dir)130*4882a593Smuzhiyun int i2s_set_sysclk_dir(struct i2s_reg *i2s_reg, int dir)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun 	unsigned int mod = readl(&i2s_reg->mod);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	if (dir == SND_SOC_CLOCK_IN)
135*4882a593Smuzhiyun 		mod |= MOD_CDCLKCON;
136*4882a593Smuzhiyun 	else
137*4882a593Smuzhiyun 		mod &= ~MOD_CDCLKCON;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	writel(mod, &i2s_reg->mod);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	return 0;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun  * Sets I2S Clcok format
146*4882a593Smuzhiyun  *
147*4882a593Smuzhiyun  * @param fmt		i2s clock properties
148*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
149*4882a593Smuzhiyun  *
150*4882a593Smuzhiyun  * @return		int value 0 for success, -1 in case of error
151*4882a593Smuzhiyun  */
i2s_set_fmt(struct i2s_reg * i2s_reg,unsigned int fmt)152*4882a593Smuzhiyun int i2s_set_fmt(struct i2s_reg *i2s_reg, unsigned int fmt)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	unsigned int mod = readl(&i2s_reg->mod);
155*4882a593Smuzhiyun 	unsigned int tmp = 0;
156*4882a593Smuzhiyun 	unsigned int ret = 0;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	/* Format is priority */
159*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
160*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_RIGHT_J:
161*4882a593Smuzhiyun 		tmp |= MOD_LR_RLOW;
162*4882a593Smuzhiyun 		tmp |= MOD_SDF_MSB;
163*4882a593Smuzhiyun 		break;
164*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_LEFT_J:
165*4882a593Smuzhiyun 		tmp |= MOD_LR_RLOW;
166*4882a593Smuzhiyun 		tmp |= MOD_SDF_LSB;
167*4882a593Smuzhiyun 		break;
168*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_I2S:
169*4882a593Smuzhiyun 		tmp |= MOD_SDF_IIS;
170*4882a593Smuzhiyun 		break;
171*4882a593Smuzhiyun 	default:
172*4882a593Smuzhiyun 		debug("%s: Invalid format priority [0x%x]\n", __func__,
173*4882a593Smuzhiyun 		      (fmt & SND_SOC_DAIFMT_FORMAT_MASK));
174*4882a593Smuzhiyun 		return -1;
175*4882a593Smuzhiyun 	}
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	/*
178*4882a593Smuzhiyun 	 * INV flag is relative to the FORMAT flag - if set it simply
179*4882a593Smuzhiyun 	 * flips the polarity specified by the Standard
180*4882a593Smuzhiyun 	 */
181*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
182*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_NF:
183*4882a593Smuzhiyun 		break;
184*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_NB_IF:
185*4882a593Smuzhiyun 		if (tmp & MOD_LR_RLOW)
186*4882a593Smuzhiyun 			tmp &= ~MOD_LR_RLOW;
187*4882a593Smuzhiyun 		else
188*4882a593Smuzhiyun 			tmp |= MOD_LR_RLOW;
189*4882a593Smuzhiyun 		break;
190*4882a593Smuzhiyun 	default:
191*4882a593Smuzhiyun 		debug("%s: Invalid clock ploarity input [0x%x]\n", __func__,
192*4882a593Smuzhiyun 		      (fmt & SND_SOC_DAIFMT_INV_MASK));
193*4882a593Smuzhiyun 		return -1;
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
197*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBS_CFS:
198*4882a593Smuzhiyun 		tmp |= MOD_SLAVE;
199*4882a593Smuzhiyun 		break;
200*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFM:
201*4882a593Smuzhiyun 		/* Set default source clock in Master mode */
202*4882a593Smuzhiyun 		ret = i2s_set_sysclk_dir(i2s_reg, SND_SOC_CLOCK_OUT);
203*4882a593Smuzhiyun 		if (ret != 0) {
204*4882a593Smuzhiyun 			debug("%s:set i2s clock direction failed\n", __func__);
205*4882a593Smuzhiyun 			return -1;
206*4882a593Smuzhiyun 		}
207*4882a593Smuzhiyun 		break;
208*4882a593Smuzhiyun 	default:
209*4882a593Smuzhiyun 		debug("%s: Invalid master selection [0x%x]\n", __func__,
210*4882a593Smuzhiyun 		      (fmt & SND_SOC_DAIFMT_MASTER_MASK));
211*4882a593Smuzhiyun 		return -1;
212*4882a593Smuzhiyun 	}
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
215*4882a593Smuzhiyun 	mod |= tmp;
216*4882a593Smuzhiyun 	writel(mod, &i2s_reg->mod);
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	return 0;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /*
222*4882a593Smuzhiyun  * Sets the sample width in bits
223*4882a593Smuzhiyun  *
224*4882a593Smuzhiyun  * @param blc		samplewidth (size of sample in bits)
225*4882a593Smuzhiyun  * @param i2s_reg	i2s regiter address
226*4882a593Smuzhiyun  *
227*4882a593Smuzhiyun  * @return		int value 0 for success, -1 in case of error
228*4882a593Smuzhiyun  */
i2s_set_samplesize(struct i2s_reg * i2s_reg,unsigned int blc)229*4882a593Smuzhiyun int i2s_set_samplesize(struct i2s_reg *i2s_reg, unsigned int blc)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun 	unsigned int mod = readl(&i2s_reg->mod);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	mod &= ~MOD_BLCP_MASK;
234*4882a593Smuzhiyun 	mod &= ~MOD_BLC_MASK;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	switch (blc) {
237*4882a593Smuzhiyun 	case 8:
238*4882a593Smuzhiyun 		mod |= MOD_BLCP_8BIT;
239*4882a593Smuzhiyun 		mod |= MOD_BLC_8BIT;
240*4882a593Smuzhiyun 		break;
241*4882a593Smuzhiyun 	case 16:
242*4882a593Smuzhiyun 		mod |= MOD_BLCP_16BIT;
243*4882a593Smuzhiyun 		mod |= MOD_BLC_16BIT;
244*4882a593Smuzhiyun 		break;
245*4882a593Smuzhiyun 	case 24:
246*4882a593Smuzhiyun 		mod |= MOD_BLCP_24BIT;
247*4882a593Smuzhiyun 		mod |= MOD_BLC_24BIT;
248*4882a593Smuzhiyun 		break;
249*4882a593Smuzhiyun 	default:
250*4882a593Smuzhiyun 		debug("%s: Invalid sample size input [0x%x]\n",
251*4882a593Smuzhiyun 		      __func__, blc);
252*4882a593Smuzhiyun 		return -1;
253*4882a593Smuzhiyun 	}
254*4882a593Smuzhiyun 	writel(mod, &i2s_reg->mod);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	return 0;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
i2s_transfer_tx_data(struct i2stx_info * pi2s_tx,unsigned int * data,unsigned long data_size)259*4882a593Smuzhiyun int i2s_transfer_tx_data(struct i2stx_info *pi2s_tx, unsigned int *data,
260*4882a593Smuzhiyun 				unsigned long data_size)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	int i;
263*4882a593Smuzhiyun 	int start;
264*4882a593Smuzhiyun 	struct i2s_reg *i2s_reg =
265*4882a593Smuzhiyun 				(struct i2s_reg *)pi2s_tx->base_address;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	if (data_size < FIFO_LENGTH) {
268*4882a593Smuzhiyun 		debug("%s : Invalid data size\n", __func__);
269*4882a593Smuzhiyun 		return -1; /* invalid pcm data size */
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/* fill the tx buffer before stating the tx transmit */
273*4882a593Smuzhiyun 	for (i = 0; i < FIFO_LENGTH; i++)
274*4882a593Smuzhiyun 		writel(*data++, &i2s_reg->txd);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	data_size -= FIFO_LENGTH;
277*4882a593Smuzhiyun 	i2s_txctrl(i2s_reg, I2S_TX_ON);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	while (data_size > 0) {
280*4882a593Smuzhiyun 		start = get_timer(0);
281*4882a593Smuzhiyun 		if (!(CON_TXFIFO_FULL & (readl(&i2s_reg->con)))) {
282*4882a593Smuzhiyun 			writel(*data++, &i2s_reg->txd);
283*4882a593Smuzhiyun 			data_size--;
284*4882a593Smuzhiyun 		} else {
285*4882a593Smuzhiyun 			if (get_timer(start) > TIMEOUT_I2S_TX) {
286*4882a593Smuzhiyun 				i2s_txctrl(i2s_reg, I2S_TX_OFF);
287*4882a593Smuzhiyun 				debug("%s: I2S Transfer Timeout\n", __func__);
288*4882a593Smuzhiyun 				return -1;
289*4882a593Smuzhiyun 			}
290*4882a593Smuzhiyun 		}
291*4882a593Smuzhiyun 	}
292*4882a593Smuzhiyun 	i2s_txctrl(i2s_reg, I2S_TX_OFF);
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	return 0;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
i2s_tx_init(struct i2stx_info * pi2s_tx)297*4882a593Smuzhiyun int i2s_tx_init(struct i2stx_info *pi2s_tx)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun 	int ret;
300*4882a593Smuzhiyun 	struct i2s_reg *i2s_reg =
301*4882a593Smuzhiyun 				(struct i2s_reg *)pi2s_tx->base_address;
302*4882a593Smuzhiyun 	if (pi2s_tx->id == 0) {
303*4882a593Smuzhiyun 		/* Initialize GPIO for I2S-0 */
304*4882a593Smuzhiyun 		exynos_pinmux_config(PERIPH_ID_I2S0, 0);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 		/* Set EPLL Clock */
307*4882a593Smuzhiyun 		ret = set_epll_clk(pi2s_tx->samplingrate * pi2s_tx->rfs * 4);
308*4882a593Smuzhiyun 	} else if (pi2s_tx->id == 1) {
309*4882a593Smuzhiyun 		/* Initialize GPIO for I2S-1 */
310*4882a593Smuzhiyun 		exynos_pinmux_config(PERIPH_ID_I2S1, 0);
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 		/* Set EPLL Clock */
313*4882a593Smuzhiyun 		ret = set_epll_clk(pi2s_tx->audio_pll_clk);
314*4882a593Smuzhiyun 	} else {
315*4882a593Smuzhiyun 		debug("%s: unsupported i2s-%d bus\n", __func__, pi2s_tx->id);
316*4882a593Smuzhiyun 		return -1;
317*4882a593Smuzhiyun 	}
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	if (ret != 0) {
320*4882a593Smuzhiyun 		debug("%s: epll clock set rate failed\n", __func__);
321*4882a593Smuzhiyun 		return -1;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	/* Select Clk Source for Audio 0 or 1 */
325*4882a593Smuzhiyun 	ret = set_i2s_clk_source(pi2s_tx->id);
326*4882a593Smuzhiyun 	if (ret == -1) {
327*4882a593Smuzhiyun 		debug("%s: unsupported clock for i2s-%d\n", __func__,
328*4882a593Smuzhiyun 		      pi2s_tx->id);
329*4882a593Smuzhiyun 		return -1;
330*4882a593Smuzhiyun 	}
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	if (pi2s_tx->id == 0) {
333*4882a593Smuzhiyun 		/*Reset the i2s module */
334*4882a593Smuzhiyun 		writel(CON_RESET, &i2s_reg->con);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 		writel(MOD_OP_CLK | MOD_RCLKSRC, &i2s_reg->mod);
337*4882a593Smuzhiyun 		/* set i2s prescaler */
338*4882a593Smuzhiyun 		writel(PSREN | PSVAL, &i2s_reg->psr);
339*4882a593Smuzhiyun 	} else {
340*4882a593Smuzhiyun 		/* Set Prescaler to get MCLK */
341*4882a593Smuzhiyun 		ret = set_i2s_clk_prescaler(pi2s_tx->audio_pll_clk,
342*4882a593Smuzhiyun 				(pi2s_tx->samplingrate * (pi2s_tx->rfs)),
343*4882a593Smuzhiyun 				pi2s_tx->id);
344*4882a593Smuzhiyun 	}
345*4882a593Smuzhiyun 	if (ret == -1) {
346*4882a593Smuzhiyun 		debug("%s: unsupported prescalar for i2s-%d\n", __func__,
347*4882a593Smuzhiyun 		      pi2s_tx->id);
348*4882a593Smuzhiyun 		return -1;
349*4882a593Smuzhiyun 	}
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	/* Configure I2s format */
352*4882a593Smuzhiyun 	ret = i2s_set_fmt(i2s_reg, (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
353*4882a593Smuzhiyun 			  SND_SOC_DAIFMT_CBM_CFM));
354*4882a593Smuzhiyun 	if (ret == 0) {
355*4882a593Smuzhiyun 		i2s_set_lr_framesize(i2s_reg, pi2s_tx->rfs);
356*4882a593Smuzhiyun 		ret = i2s_set_samplesize(i2s_reg, pi2s_tx->bitspersample);
357*4882a593Smuzhiyun 		if (ret != 0) {
358*4882a593Smuzhiyun 			debug("%s:set sample rate failed\n", __func__);
359*4882a593Smuzhiyun 			return -1;
360*4882a593Smuzhiyun 		}
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 		i2s_set_bitclk_framesize(i2s_reg, pi2s_tx->bfs);
363*4882a593Smuzhiyun 		/* disable i2s transfer flag and flush the fifo */
364*4882a593Smuzhiyun 		i2s_txctrl(i2s_reg, I2S_TX_OFF);
365*4882a593Smuzhiyun 		i2s_fifo(i2s_reg, FIC_TXFLUSH);
366*4882a593Smuzhiyun 	} else {
367*4882a593Smuzhiyun 		debug("%s: failed\n", __func__);
368*4882a593Smuzhiyun 	}
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	return ret;
371*4882a593Smuzhiyun }
372