xref: /OK3568_Linux_fs/kernel/sound/aoa/soundbus/i2sbus/pcm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * i2sbus driver -- pcm routines
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/io.h>
9*4882a593Smuzhiyun #include <linux/delay.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <sound/core.h>
12*4882a593Smuzhiyun #include <asm/macio.h>
13*4882a593Smuzhiyun #include <linux/pci.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include "../soundbus.h"
16*4882a593Smuzhiyun #include "i2sbus.h"
17*4882a593Smuzhiyun 
get_pcm_info(struct i2sbus_dev * i2sdev,int in,struct pcm_info ** pi,struct pcm_info ** other)18*4882a593Smuzhiyun static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
19*4882a593Smuzhiyun 				struct pcm_info **pi, struct pcm_info **other)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	if (in) {
22*4882a593Smuzhiyun 		if (pi)
23*4882a593Smuzhiyun 			*pi = &i2sdev->in;
24*4882a593Smuzhiyun 		if (other)
25*4882a593Smuzhiyun 			*other = &i2sdev->out;
26*4882a593Smuzhiyun 	} else {
27*4882a593Smuzhiyun 		if (pi)
28*4882a593Smuzhiyun 			*pi = &i2sdev->out;
29*4882a593Smuzhiyun 		if (other)
30*4882a593Smuzhiyun 			*other = &i2sdev->in;
31*4882a593Smuzhiyun 	}
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun 
clock_and_divisors(int mclk,int sclk,int rate,int * out)34*4882a593Smuzhiyun static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	/* sclk must be derived from mclk! */
37*4882a593Smuzhiyun 	if (mclk % sclk)
38*4882a593Smuzhiyun 		return -1;
39*4882a593Smuzhiyun 	/* derive sclk register value */
40*4882a593Smuzhiyun 	if (i2s_sf_sclkdiv(mclk / sclk, out))
41*4882a593Smuzhiyun 		return -1;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	if (I2S_CLOCK_SPEED_18MHz % (rate * mclk) == 0) {
44*4882a593Smuzhiyun 		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
45*4882a593Smuzhiyun 			*out |= I2S_SF_CLOCK_SOURCE_18MHz;
46*4882a593Smuzhiyun 			return 0;
47*4882a593Smuzhiyun 		}
48*4882a593Smuzhiyun 	}
49*4882a593Smuzhiyun 	if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
50*4882a593Smuzhiyun 		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
51*4882a593Smuzhiyun 			*out |= I2S_SF_CLOCK_SOURCE_45MHz;
52*4882a593Smuzhiyun 			return 0;
53*4882a593Smuzhiyun 		}
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun 	if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
56*4882a593Smuzhiyun 		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
57*4882a593Smuzhiyun 			*out |= I2S_SF_CLOCK_SOURCE_49MHz;
58*4882a593Smuzhiyun 			return 0;
59*4882a593Smuzhiyun 		}
60*4882a593Smuzhiyun 	}
61*4882a593Smuzhiyun 	return -1;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define CHECK_RATE(rate)						\
65*4882a593Smuzhiyun 	do { if (rates & SNDRV_PCM_RATE_ ##rate) {			\
66*4882a593Smuzhiyun 		int dummy;						\
67*4882a593Smuzhiyun 		if (clock_and_divisors(sysclock_factor,			\
68*4882a593Smuzhiyun 				       bus_factor, rate, &dummy))	\
69*4882a593Smuzhiyun 			rates &= ~SNDRV_PCM_RATE_ ##rate;		\
70*4882a593Smuzhiyun 	} } while (0)
71*4882a593Smuzhiyun 
i2sbus_pcm_open(struct i2sbus_dev * i2sdev,int in)72*4882a593Smuzhiyun static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	struct pcm_info *pi, *other;
75*4882a593Smuzhiyun 	struct soundbus_dev *sdev;
76*4882a593Smuzhiyun 	int masks_inited = 0, err;
77*4882a593Smuzhiyun 	struct codec_info_item *cii, *rev;
78*4882a593Smuzhiyun 	struct snd_pcm_hardware *hw;
79*4882a593Smuzhiyun 	u64 formats = 0;
80*4882a593Smuzhiyun 	unsigned int rates = 0;
81*4882a593Smuzhiyun 	struct transfer_info v;
82*4882a593Smuzhiyun 	int result = 0;
83*4882a593Smuzhiyun 	int bus_factor = 0, sysclock_factor = 0;
84*4882a593Smuzhiyun 	int found_this;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	mutex_lock(&i2sdev->lock);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, &other);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	hw = &pi->substream->runtime->hw;
91*4882a593Smuzhiyun 	sdev = &i2sdev->sound;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	if (pi->active) {
94*4882a593Smuzhiyun 		/* alsa messed up */
95*4882a593Smuzhiyun 		result = -EBUSY;
96*4882a593Smuzhiyun 		goto out_unlock;
97*4882a593Smuzhiyun 	}
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	/* we now need to assign the hw */
100*4882a593Smuzhiyun 	list_for_each_entry(cii, &sdev->codec_list, list) {
101*4882a593Smuzhiyun 		struct transfer_info *ti = cii->codec->transfers;
102*4882a593Smuzhiyun 		bus_factor = cii->codec->bus_factor;
103*4882a593Smuzhiyun 		sysclock_factor = cii->codec->sysclock_factor;
104*4882a593Smuzhiyun 		while (ti->formats && ti->rates) {
105*4882a593Smuzhiyun 			v = *ti;
106*4882a593Smuzhiyun 			if (ti->transfer_in == in
107*4882a593Smuzhiyun 			    && cii->codec->usable(cii, ti, &v)) {
108*4882a593Smuzhiyun 				if (masks_inited) {
109*4882a593Smuzhiyun 					formats &= v.formats;
110*4882a593Smuzhiyun 					rates &= v.rates;
111*4882a593Smuzhiyun 				} else {
112*4882a593Smuzhiyun 					formats = v.formats;
113*4882a593Smuzhiyun 					rates = v.rates;
114*4882a593Smuzhiyun 					masks_inited = 1;
115*4882a593Smuzhiyun 				}
116*4882a593Smuzhiyun 			}
117*4882a593Smuzhiyun 			ti++;
118*4882a593Smuzhiyun 		}
119*4882a593Smuzhiyun 	}
120*4882a593Smuzhiyun 	if (!masks_inited || !bus_factor || !sysclock_factor) {
121*4882a593Smuzhiyun 		result = -ENODEV;
122*4882a593Smuzhiyun 		goto out_unlock;
123*4882a593Smuzhiyun 	}
124*4882a593Smuzhiyun 	/* bus dependent stuff */
125*4882a593Smuzhiyun 	hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
126*4882a593Smuzhiyun 		   SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME |
127*4882a593Smuzhiyun 		   SNDRV_PCM_INFO_JOINT_DUPLEX;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	CHECK_RATE(5512);
130*4882a593Smuzhiyun 	CHECK_RATE(8000);
131*4882a593Smuzhiyun 	CHECK_RATE(11025);
132*4882a593Smuzhiyun 	CHECK_RATE(16000);
133*4882a593Smuzhiyun 	CHECK_RATE(22050);
134*4882a593Smuzhiyun 	CHECK_RATE(32000);
135*4882a593Smuzhiyun 	CHECK_RATE(44100);
136*4882a593Smuzhiyun 	CHECK_RATE(48000);
137*4882a593Smuzhiyun 	CHECK_RATE(64000);
138*4882a593Smuzhiyun 	CHECK_RATE(88200);
139*4882a593Smuzhiyun 	CHECK_RATE(96000);
140*4882a593Smuzhiyun 	CHECK_RATE(176400);
141*4882a593Smuzhiyun 	CHECK_RATE(192000);
142*4882a593Smuzhiyun 	hw->rates = rates;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	/* well. the codec might want 24 bits only, and we'll
145*4882a593Smuzhiyun 	 * ever only transfer 24 bits, but they are top-aligned!
146*4882a593Smuzhiyun 	 * So for alsa, we claim that we're doing full 32 bit
147*4882a593Smuzhiyun 	 * while in reality we'll ignore the lower 8 bits of
148*4882a593Smuzhiyun 	 * that when doing playback (they're transferred as 0
149*4882a593Smuzhiyun 	 * as far as I know, no codecs we have are 32-bit capable
150*4882a593Smuzhiyun 	 * so I can't really test) and when doing recording we'll
151*4882a593Smuzhiyun 	 * always have those lower 8 bits recorded as 0 */
152*4882a593Smuzhiyun 	if (formats & SNDRV_PCM_FMTBIT_S24_BE)
153*4882a593Smuzhiyun 		formats |= SNDRV_PCM_FMTBIT_S32_BE;
154*4882a593Smuzhiyun 	if (formats & SNDRV_PCM_FMTBIT_U24_BE)
155*4882a593Smuzhiyun 		formats |= SNDRV_PCM_FMTBIT_U32_BE;
156*4882a593Smuzhiyun 	/* now mask off what we can support. I suppose we could
157*4882a593Smuzhiyun 	 * also support S24_3LE and some similar formats, but I
158*4882a593Smuzhiyun 	 * doubt there's a codec that would be able to use that,
159*4882a593Smuzhiyun 	 * so we don't support it here. */
160*4882a593Smuzhiyun 	hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
161*4882a593Smuzhiyun 				 SNDRV_PCM_FMTBIT_U16_BE |
162*4882a593Smuzhiyun 				 SNDRV_PCM_FMTBIT_S32_BE |
163*4882a593Smuzhiyun 				 SNDRV_PCM_FMTBIT_U32_BE);
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* we need to set the highest and lowest rate possible.
166*4882a593Smuzhiyun 	 * These are the highest and lowest rates alsa can
167*4882a593Smuzhiyun 	 * support properly in its bitfield.
168*4882a593Smuzhiyun 	 * Below, we'll use that to restrict to the rate
169*4882a593Smuzhiyun 	 * currently in use (if any). */
170*4882a593Smuzhiyun 	hw->rate_min = 5512;
171*4882a593Smuzhiyun 	hw->rate_max = 192000;
172*4882a593Smuzhiyun 	/* if the other stream is active, then we can only
173*4882a593Smuzhiyun 	 * support what it is currently using.
174*4882a593Smuzhiyun 	 * FIXME: I lied. This comment is wrong. We can support
175*4882a593Smuzhiyun 	 * anything that works with the same serial format, ie.
176*4882a593Smuzhiyun 	 * when recording 24 bit sound we can well play 16 bit
177*4882a593Smuzhiyun 	 * sound at the same time iff using the same transfer mode.
178*4882a593Smuzhiyun 	 */
179*4882a593Smuzhiyun 	if (other->active) {
180*4882a593Smuzhiyun 		/* FIXME: is this guaranteed by the alsa api? */
181*4882a593Smuzhiyun 		hw->formats &= pcm_format_to_bits(i2sdev->format);
182*4882a593Smuzhiyun 		/* see above, restrict rates to the one we already have */
183*4882a593Smuzhiyun 		hw->rate_min = i2sdev->rate;
184*4882a593Smuzhiyun 		hw->rate_max = i2sdev->rate;
185*4882a593Smuzhiyun 	}
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	hw->channels_min = 2;
188*4882a593Smuzhiyun 	hw->channels_max = 2;
189*4882a593Smuzhiyun 	/* these are somewhat arbitrary */
190*4882a593Smuzhiyun 	hw->buffer_bytes_max = 131072;
191*4882a593Smuzhiyun 	hw->period_bytes_min = 256;
192*4882a593Smuzhiyun 	hw->period_bytes_max = 16384;
193*4882a593Smuzhiyun 	hw->periods_min = 3;
194*4882a593Smuzhiyun 	hw->periods_max = MAX_DBDMA_COMMANDS;
195*4882a593Smuzhiyun 	err = snd_pcm_hw_constraint_integer(pi->substream->runtime,
196*4882a593Smuzhiyun 					    SNDRV_PCM_HW_PARAM_PERIODS);
197*4882a593Smuzhiyun 	if (err < 0) {
198*4882a593Smuzhiyun 		result = err;
199*4882a593Smuzhiyun 		goto out_unlock;
200*4882a593Smuzhiyun 	}
201*4882a593Smuzhiyun 	list_for_each_entry(cii, &sdev->codec_list, list) {
202*4882a593Smuzhiyun 		if (cii->codec->open) {
203*4882a593Smuzhiyun 			err = cii->codec->open(cii, pi->substream);
204*4882a593Smuzhiyun 			if (err) {
205*4882a593Smuzhiyun 				result = err;
206*4882a593Smuzhiyun 				/* unwind */
207*4882a593Smuzhiyun 				found_this = 0;
208*4882a593Smuzhiyun 				list_for_each_entry_reverse(rev,
209*4882a593Smuzhiyun 				    &sdev->codec_list, list) {
210*4882a593Smuzhiyun 					if (found_this && rev->codec->close) {
211*4882a593Smuzhiyun 						rev->codec->close(rev,
212*4882a593Smuzhiyun 								pi->substream);
213*4882a593Smuzhiyun 					}
214*4882a593Smuzhiyun 					if (rev == cii)
215*4882a593Smuzhiyun 						found_this = 1;
216*4882a593Smuzhiyun 				}
217*4882a593Smuzhiyun 				goto out_unlock;
218*4882a593Smuzhiyun 			}
219*4882a593Smuzhiyun 		}
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun  out_unlock:
223*4882a593Smuzhiyun 	mutex_unlock(&i2sdev->lock);
224*4882a593Smuzhiyun 	return result;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun #undef CHECK_RATE
228*4882a593Smuzhiyun 
i2sbus_pcm_close(struct i2sbus_dev * i2sdev,int in)229*4882a593Smuzhiyun static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun 	struct codec_info_item *cii;
232*4882a593Smuzhiyun 	struct pcm_info *pi;
233*4882a593Smuzhiyun 	int err = 0, tmp;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	mutex_lock(&i2sdev->lock);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, NULL);
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
240*4882a593Smuzhiyun 		if (cii->codec->close) {
241*4882a593Smuzhiyun 			tmp = cii->codec->close(cii, pi->substream);
242*4882a593Smuzhiyun 			if (tmp)
243*4882a593Smuzhiyun 				err = tmp;
244*4882a593Smuzhiyun 		}
245*4882a593Smuzhiyun 	}
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	pi->substream = NULL;
248*4882a593Smuzhiyun 	pi->active = 0;
249*4882a593Smuzhiyun 	mutex_unlock(&i2sdev->lock);
250*4882a593Smuzhiyun 	return err;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun 
i2sbus_wait_for_stop(struct i2sbus_dev * i2sdev,struct pcm_info * pi)253*4882a593Smuzhiyun static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev,
254*4882a593Smuzhiyun 				 struct pcm_info *pi)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun 	unsigned long flags;
257*4882a593Smuzhiyun 	DECLARE_COMPLETION_ONSTACK(done);
258*4882a593Smuzhiyun 	long timeout;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	spin_lock_irqsave(&i2sdev->low_lock, flags);
261*4882a593Smuzhiyun 	if (pi->dbdma_ring.stopping) {
262*4882a593Smuzhiyun 		pi->stop_completion = &done;
263*4882a593Smuzhiyun 		spin_unlock_irqrestore(&i2sdev->low_lock, flags);
264*4882a593Smuzhiyun 		timeout = wait_for_completion_timeout(&done, HZ);
265*4882a593Smuzhiyun 		spin_lock_irqsave(&i2sdev->low_lock, flags);
266*4882a593Smuzhiyun 		pi->stop_completion = NULL;
267*4882a593Smuzhiyun 		if (timeout == 0) {
268*4882a593Smuzhiyun 			/* timeout expired, stop dbdma forcefully */
269*4882a593Smuzhiyun 			printk(KERN_ERR "i2sbus_wait_for_stop: timed out\n");
270*4882a593Smuzhiyun 			/* make sure RUN, PAUSE and S0 bits are cleared */
271*4882a593Smuzhiyun 			out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
272*4882a593Smuzhiyun 			pi->dbdma_ring.stopping = 0;
273*4882a593Smuzhiyun 			timeout = 10;
274*4882a593Smuzhiyun 			while (in_le32(&pi->dbdma->status) & ACTIVE) {
275*4882a593Smuzhiyun 				if (--timeout <= 0)
276*4882a593Smuzhiyun 					break;
277*4882a593Smuzhiyun 				udelay(1);
278*4882a593Smuzhiyun 			}
279*4882a593Smuzhiyun 		}
280*4882a593Smuzhiyun 	}
281*4882a593Smuzhiyun 	spin_unlock_irqrestore(&i2sdev->low_lock, flags);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun #ifdef CONFIG_PM
i2sbus_wait_for_stop_both(struct i2sbus_dev * i2sdev)285*4882a593Smuzhiyun void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun 	struct pcm_info *pi;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	get_pcm_info(i2sdev, 0, &pi, NULL);
290*4882a593Smuzhiyun 	i2sbus_wait_for_stop(i2sdev, pi);
291*4882a593Smuzhiyun 	get_pcm_info(i2sdev, 1, &pi, NULL);
292*4882a593Smuzhiyun 	i2sbus_wait_for_stop(i2sdev, pi);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun #endif
295*4882a593Smuzhiyun 
i2sbus_hw_free(struct snd_pcm_substream * substream,int in)296*4882a593Smuzhiyun static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
299*4882a593Smuzhiyun 	struct pcm_info *pi;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, NULL);
302*4882a593Smuzhiyun 	if (pi->dbdma_ring.stopping)
303*4882a593Smuzhiyun 		i2sbus_wait_for_stop(i2sdev, pi);
304*4882a593Smuzhiyun 	return 0;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun 
i2sbus_playback_hw_free(struct snd_pcm_substream * substream)307*4882a593Smuzhiyun static int i2sbus_playback_hw_free(struct snd_pcm_substream *substream)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun 	return i2sbus_hw_free(substream, 0);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun 
i2sbus_record_hw_free(struct snd_pcm_substream * substream)312*4882a593Smuzhiyun static int i2sbus_record_hw_free(struct snd_pcm_substream *substream)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun 	return i2sbus_hw_free(substream, 1);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
i2sbus_pcm_prepare(struct i2sbus_dev * i2sdev,int in)317*4882a593Smuzhiyun static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	/* whee. Hard work now. The user has selected a bitrate
320*4882a593Smuzhiyun 	 * and bit format, so now we have to program our
321*4882a593Smuzhiyun 	 * I2S controller appropriately. */
322*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime;
323*4882a593Smuzhiyun 	struct dbdma_cmd *command;
324*4882a593Smuzhiyun 	int i, periodsize, nperiods;
325*4882a593Smuzhiyun 	dma_addr_t offset;
326*4882a593Smuzhiyun 	struct bus_info bi;
327*4882a593Smuzhiyun 	struct codec_info_item *cii;
328*4882a593Smuzhiyun 	int sfr = 0;		/* serial format register */
329*4882a593Smuzhiyun 	int dws = 0;		/* data word sizes reg */
330*4882a593Smuzhiyun 	int input_16bit;
331*4882a593Smuzhiyun 	struct pcm_info *pi, *other;
332*4882a593Smuzhiyun 	int cnt;
333*4882a593Smuzhiyun 	int result = 0;
334*4882a593Smuzhiyun 	unsigned int cmd, stopaddr;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	mutex_lock(&i2sdev->lock);
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, &other);
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	if (pi->dbdma_ring.running) {
341*4882a593Smuzhiyun 		result = -EBUSY;
342*4882a593Smuzhiyun 		goto out_unlock;
343*4882a593Smuzhiyun 	}
344*4882a593Smuzhiyun 	if (pi->dbdma_ring.stopping)
345*4882a593Smuzhiyun 		i2sbus_wait_for_stop(i2sdev, pi);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	if (!pi->substream || !pi->substream->runtime) {
348*4882a593Smuzhiyun 		result = -EINVAL;
349*4882a593Smuzhiyun 		goto out_unlock;
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	runtime = pi->substream->runtime;
353*4882a593Smuzhiyun 	pi->active = 1;
354*4882a593Smuzhiyun 	if (other->active &&
355*4882a593Smuzhiyun 	    ((i2sdev->format != runtime->format)
356*4882a593Smuzhiyun 	     || (i2sdev->rate != runtime->rate))) {
357*4882a593Smuzhiyun 		result = -EINVAL;
358*4882a593Smuzhiyun 		goto out_unlock;
359*4882a593Smuzhiyun 	}
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	i2sdev->format = runtime->format;
362*4882a593Smuzhiyun 	i2sdev->rate = runtime->rate;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	periodsize = snd_pcm_lib_period_bytes(pi->substream);
365*4882a593Smuzhiyun 	nperiods = pi->substream->runtime->periods;
366*4882a593Smuzhiyun 	pi->current_period = 0;
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	/* generate dbdma command ring first */
369*4882a593Smuzhiyun 	command = pi->dbdma_ring.cmds;
370*4882a593Smuzhiyun 	memset(command, 0, (nperiods + 2) * sizeof(struct dbdma_cmd));
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	/* commands to DMA to/from the ring */
373*4882a593Smuzhiyun 	/*
374*4882a593Smuzhiyun 	 * For input, we need to do a graceful stop; if we abort
375*4882a593Smuzhiyun 	 * the DMA, we end up with leftover bytes that corrupt
376*4882a593Smuzhiyun 	 * the next recording.  To do this we set the S0 status
377*4882a593Smuzhiyun 	 * bit and wait for the DMA controller to stop.  Each
378*4882a593Smuzhiyun 	 * command has a branch condition to
379*4882a593Smuzhiyun 	 * make it branch to a stop command if S0 is set.
380*4882a593Smuzhiyun 	 * On input we also need to wait for the S7 bit to be
381*4882a593Smuzhiyun 	 * set before turning off the DMA controller.
382*4882a593Smuzhiyun 	 * In fact we do the graceful stop for output as well.
383*4882a593Smuzhiyun 	 */
384*4882a593Smuzhiyun 	offset = runtime->dma_addr;
385*4882a593Smuzhiyun 	cmd = (in? INPUT_MORE: OUTPUT_MORE) | BR_IFSET | INTR_ALWAYS;
386*4882a593Smuzhiyun 	stopaddr = pi->dbdma_ring.bus_cmd_start +
387*4882a593Smuzhiyun 		(nperiods + 1) * sizeof(struct dbdma_cmd);
388*4882a593Smuzhiyun 	for (i = 0; i < nperiods; i++, command++, offset += periodsize) {
389*4882a593Smuzhiyun 		command->command = cpu_to_le16(cmd);
390*4882a593Smuzhiyun 		command->cmd_dep = cpu_to_le32(stopaddr);
391*4882a593Smuzhiyun 		command->phy_addr = cpu_to_le32(offset);
392*4882a593Smuzhiyun 		command->req_count = cpu_to_le16(periodsize);
393*4882a593Smuzhiyun 	}
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	/* branch back to beginning of ring */
396*4882a593Smuzhiyun 	command->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
397*4882a593Smuzhiyun 	command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
398*4882a593Smuzhiyun 	command++;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	/* set stop command */
401*4882a593Smuzhiyun 	command->command = cpu_to_le16(DBDMA_STOP);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	/* ok, let's set the serial format and stuff */
404*4882a593Smuzhiyun 	switch (runtime->format) {
405*4882a593Smuzhiyun 	/* 16 bit formats */
406*4882a593Smuzhiyun 	case SNDRV_PCM_FORMAT_S16_BE:
407*4882a593Smuzhiyun 	case SNDRV_PCM_FORMAT_U16_BE:
408*4882a593Smuzhiyun 		/* FIXME: if we add different bus factors we need to
409*4882a593Smuzhiyun 		 * do more here!! */
410*4882a593Smuzhiyun 		bi.bus_factor = 0;
411*4882a593Smuzhiyun 		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
412*4882a593Smuzhiyun 			bi.bus_factor = cii->codec->bus_factor;
413*4882a593Smuzhiyun 			break;
414*4882a593Smuzhiyun 		}
415*4882a593Smuzhiyun 		if (!bi.bus_factor) {
416*4882a593Smuzhiyun 			result = -ENODEV;
417*4882a593Smuzhiyun 			goto out_unlock;
418*4882a593Smuzhiyun 		}
419*4882a593Smuzhiyun 		input_16bit = 1;
420*4882a593Smuzhiyun 		break;
421*4882a593Smuzhiyun 	case SNDRV_PCM_FORMAT_S32_BE:
422*4882a593Smuzhiyun 	case SNDRV_PCM_FORMAT_U32_BE:
423*4882a593Smuzhiyun 		/* force 64x bus speed, otherwise the data cannot be
424*4882a593Smuzhiyun 		 * transferred quickly enough! */
425*4882a593Smuzhiyun 		bi.bus_factor = 64;
426*4882a593Smuzhiyun 		input_16bit = 0;
427*4882a593Smuzhiyun 		break;
428*4882a593Smuzhiyun 	default:
429*4882a593Smuzhiyun 		result = -EINVAL;
430*4882a593Smuzhiyun 		goto out_unlock;
431*4882a593Smuzhiyun 	}
432*4882a593Smuzhiyun 	/* we assume all sysclocks are the same! */
433*4882a593Smuzhiyun 	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
434*4882a593Smuzhiyun 		bi.sysclock_factor = cii->codec->sysclock_factor;
435*4882a593Smuzhiyun 		break;
436*4882a593Smuzhiyun 	}
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	if (clock_and_divisors(bi.sysclock_factor,
439*4882a593Smuzhiyun 			       bi.bus_factor,
440*4882a593Smuzhiyun 			       runtime->rate,
441*4882a593Smuzhiyun 			       &sfr) < 0) {
442*4882a593Smuzhiyun 		result = -EINVAL;
443*4882a593Smuzhiyun 		goto out_unlock;
444*4882a593Smuzhiyun 	}
445*4882a593Smuzhiyun 	switch (bi.bus_factor) {
446*4882a593Smuzhiyun 	case 32:
447*4882a593Smuzhiyun 		sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
448*4882a593Smuzhiyun 		break;
449*4882a593Smuzhiyun 	case 64:
450*4882a593Smuzhiyun 		sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
451*4882a593Smuzhiyun 		break;
452*4882a593Smuzhiyun 	}
453*4882a593Smuzhiyun 	/* FIXME: THIS ASSUMES MASTER ALL THE TIME */
454*4882a593Smuzhiyun 	sfr |= I2S_SF_SCLK_MASTER;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
457*4882a593Smuzhiyun 		int err = 0;
458*4882a593Smuzhiyun 		if (cii->codec->prepare)
459*4882a593Smuzhiyun 			err = cii->codec->prepare(cii, &bi, pi->substream);
460*4882a593Smuzhiyun 		if (err) {
461*4882a593Smuzhiyun 			result = err;
462*4882a593Smuzhiyun 			goto out_unlock;
463*4882a593Smuzhiyun 		}
464*4882a593Smuzhiyun 	}
465*4882a593Smuzhiyun 	/* codecs are fine with it, so set our clocks */
466*4882a593Smuzhiyun 	if (input_16bit)
467*4882a593Smuzhiyun 		dws =	(2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
468*4882a593Smuzhiyun 			(2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
469*4882a593Smuzhiyun 			I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
470*4882a593Smuzhiyun 	else
471*4882a593Smuzhiyun 		dws =	(2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
472*4882a593Smuzhiyun 			(2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
473*4882a593Smuzhiyun 			I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	/* early exit if already programmed correctly */
476*4882a593Smuzhiyun 	/* not locking these is fine since we touch them only in this function */
477*4882a593Smuzhiyun 	if (in_le32(&i2sdev->intfregs->serial_format) == sfr
478*4882a593Smuzhiyun 	 && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
479*4882a593Smuzhiyun 		goto out_unlock;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	/* let's notify the codecs about clocks going away.
482*4882a593Smuzhiyun 	 * For now we only do mastering on the i2s cell... */
483*4882a593Smuzhiyun 	list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
484*4882a593Smuzhiyun 		if (cii->codec->switch_clock)
485*4882a593Smuzhiyun 			cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	i2sbus_control_enable(i2sdev->control, i2sdev);
488*4882a593Smuzhiyun 	i2sbus_control_cell(i2sdev->control, i2sdev, 1);
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	i2sbus_control_clock(i2sdev->control, i2sdev, 0);
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	msleep(1);
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	/* wait for clock stopped. This can apparently take a while... */
497*4882a593Smuzhiyun 	cnt = 100;
498*4882a593Smuzhiyun 	while (cnt-- &&
499*4882a593Smuzhiyun 	    !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
500*4882a593Smuzhiyun 		msleep(5);
501*4882a593Smuzhiyun 	}
502*4882a593Smuzhiyun 	out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	/* not locking these is fine since we touch them only in this function */
505*4882a593Smuzhiyun 	out_le32(&i2sdev->intfregs->serial_format, sfr);
506*4882a593Smuzhiyun 	out_le32(&i2sdev->intfregs->data_word_sizes, dws);
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun         i2sbus_control_enable(i2sdev->control, i2sdev);
509*4882a593Smuzhiyun         i2sbus_control_cell(i2sdev->control, i2sdev, 1);
510*4882a593Smuzhiyun         i2sbus_control_clock(i2sdev->control, i2sdev, 1);
511*4882a593Smuzhiyun 	msleep(1);
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
514*4882a593Smuzhiyun 		if (cii->codec->switch_clock)
515*4882a593Smuzhiyun 			cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun  out_unlock:
518*4882a593Smuzhiyun 	mutex_unlock(&i2sdev->lock);
519*4882a593Smuzhiyun 	return result;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun #ifdef CONFIG_PM
i2sbus_pcm_prepare_both(struct i2sbus_dev * i2sdev)523*4882a593Smuzhiyun void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun 	i2sbus_pcm_prepare(i2sdev, 0);
526*4882a593Smuzhiyun 	i2sbus_pcm_prepare(i2sdev, 1);
527*4882a593Smuzhiyun }
528*4882a593Smuzhiyun #endif
529*4882a593Smuzhiyun 
i2sbus_pcm_trigger(struct i2sbus_dev * i2sdev,int in,int cmd)530*4882a593Smuzhiyun static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
531*4882a593Smuzhiyun {
532*4882a593Smuzhiyun 	struct codec_info_item *cii;
533*4882a593Smuzhiyun 	struct pcm_info *pi;
534*4882a593Smuzhiyun 	int result = 0;
535*4882a593Smuzhiyun 	unsigned long flags;
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	spin_lock_irqsave(&i2sdev->low_lock, flags);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, NULL);
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	switch (cmd) {
542*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_START:
543*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_RESUME:
544*4882a593Smuzhiyun 		if (pi->dbdma_ring.running) {
545*4882a593Smuzhiyun 			result = -EALREADY;
546*4882a593Smuzhiyun 			goto out_unlock;
547*4882a593Smuzhiyun 		}
548*4882a593Smuzhiyun 		list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
549*4882a593Smuzhiyun 			if (cii->codec->start)
550*4882a593Smuzhiyun 				cii->codec->start(cii, pi->substream);
551*4882a593Smuzhiyun 		pi->dbdma_ring.running = 1;
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 		if (pi->dbdma_ring.stopping) {
554*4882a593Smuzhiyun 			/* Clear the S0 bit, then see if we stopped yet */
555*4882a593Smuzhiyun 			out_le32(&pi->dbdma->control, 1 << 16);
556*4882a593Smuzhiyun 			if (in_le32(&pi->dbdma->status) & ACTIVE) {
557*4882a593Smuzhiyun 				/* possible race here? */
558*4882a593Smuzhiyun 				udelay(10);
559*4882a593Smuzhiyun 				if (in_le32(&pi->dbdma->status) & ACTIVE) {
560*4882a593Smuzhiyun 					pi->dbdma_ring.stopping = 0;
561*4882a593Smuzhiyun 					goto out_unlock; /* keep running */
562*4882a593Smuzhiyun 				}
563*4882a593Smuzhiyun 			}
564*4882a593Smuzhiyun 		}
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 		/* make sure RUN, PAUSE and S0 bits are cleared */
567*4882a593Smuzhiyun 		out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 		/* set branch condition select register */
570*4882a593Smuzhiyun 		out_le32(&pi->dbdma->br_sel, (1 << 16) | 1);
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 		/* write dma command buffer address to the dbdma chip */
573*4882a593Smuzhiyun 		out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 		/* initialize the frame count and current period */
576*4882a593Smuzhiyun 		pi->current_period = 0;
577*4882a593Smuzhiyun 		pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 		/* set the DMA controller running */
580*4882a593Smuzhiyun 		out_le32(&pi->dbdma->control, (RUN << 16) | RUN);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 		/* off you go! */
583*4882a593Smuzhiyun 		break;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_STOP:
586*4882a593Smuzhiyun 	case SNDRV_PCM_TRIGGER_SUSPEND:
587*4882a593Smuzhiyun 		if (!pi->dbdma_ring.running) {
588*4882a593Smuzhiyun 			result = -EALREADY;
589*4882a593Smuzhiyun 			goto out_unlock;
590*4882a593Smuzhiyun 		}
591*4882a593Smuzhiyun 		pi->dbdma_ring.running = 0;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 		/* Set the S0 bit to make the DMA branch to the stop cmd */
594*4882a593Smuzhiyun 		out_le32(&pi->dbdma->control, (1 << 16) | 1);
595*4882a593Smuzhiyun 		pi->dbdma_ring.stopping = 1;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 		list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
598*4882a593Smuzhiyun 			if (cii->codec->stop)
599*4882a593Smuzhiyun 				cii->codec->stop(cii, pi->substream);
600*4882a593Smuzhiyun 		break;
601*4882a593Smuzhiyun 	default:
602*4882a593Smuzhiyun 		result = -EINVAL;
603*4882a593Smuzhiyun 		goto out_unlock;
604*4882a593Smuzhiyun 	}
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun  out_unlock:
607*4882a593Smuzhiyun 	spin_unlock_irqrestore(&i2sdev->low_lock, flags);
608*4882a593Smuzhiyun 	return result;
609*4882a593Smuzhiyun }
610*4882a593Smuzhiyun 
i2sbus_pcm_pointer(struct i2sbus_dev * i2sdev,int in)611*4882a593Smuzhiyun static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun 	struct pcm_info *pi;
614*4882a593Smuzhiyun 	u32 fc;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, NULL);
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	fc = in_le32(&i2sdev->intfregs->frame_count);
619*4882a593Smuzhiyun 	fc = fc - pi->frame_count;
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	if (fc >= pi->substream->runtime->buffer_size)
622*4882a593Smuzhiyun 		fc %= pi->substream->runtime->buffer_size;
623*4882a593Smuzhiyun 	return fc;
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun 
handle_interrupt(struct i2sbus_dev * i2sdev,int in)626*4882a593Smuzhiyun static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
627*4882a593Smuzhiyun {
628*4882a593Smuzhiyun 	struct pcm_info *pi;
629*4882a593Smuzhiyun 	u32 fc, nframes;
630*4882a593Smuzhiyun 	u32 status;
631*4882a593Smuzhiyun 	int timeout, i;
632*4882a593Smuzhiyun 	int dma_stopped = 0;
633*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime;
634*4882a593Smuzhiyun 
635*4882a593Smuzhiyun 	spin_lock(&i2sdev->low_lock);
636*4882a593Smuzhiyun 	get_pcm_info(i2sdev, in, &pi, NULL);
637*4882a593Smuzhiyun 	if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping)
638*4882a593Smuzhiyun 		goto out_unlock;
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	i = pi->current_period;
641*4882a593Smuzhiyun 	runtime = pi->substream->runtime;
642*4882a593Smuzhiyun 	while (pi->dbdma_ring.cmds[i].xfer_status) {
643*4882a593Smuzhiyun 		if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT)
644*4882a593Smuzhiyun 			/*
645*4882a593Smuzhiyun 			 * BT is the branch taken bit.  If it took a branch
646*4882a593Smuzhiyun 			 * it is because we set the S0 bit to make it
647*4882a593Smuzhiyun 			 * branch to the stop command.
648*4882a593Smuzhiyun 			 */
649*4882a593Smuzhiyun 			dma_stopped = 1;
650*4882a593Smuzhiyun 		pi->dbdma_ring.cmds[i].xfer_status = 0;
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 		if (++i >= runtime->periods) {
653*4882a593Smuzhiyun 			i = 0;
654*4882a593Smuzhiyun 			pi->frame_count += runtime->buffer_size;
655*4882a593Smuzhiyun 		}
656*4882a593Smuzhiyun 		pi->current_period = i;
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 		/*
659*4882a593Smuzhiyun 		 * Check the frame count.  The DMA tends to get a bit
660*4882a593Smuzhiyun 		 * ahead of the frame counter, which confuses the core.
661*4882a593Smuzhiyun 		 */
662*4882a593Smuzhiyun 		fc = in_le32(&i2sdev->intfregs->frame_count);
663*4882a593Smuzhiyun 		nframes = i * runtime->period_size;
664*4882a593Smuzhiyun 		if (fc < pi->frame_count + nframes)
665*4882a593Smuzhiyun 			pi->frame_count = fc - nframes;
666*4882a593Smuzhiyun 	}
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun 	if (dma_stopped) {
669*4882a593Smuzhiyun 		timeout = 1000;
670*4882a593Smuzhiyun 		for (;;) {
671*4882a593Smuzhiyun 			status = in_le32(&pi->dbdma->status);
672*4882a593Smuzhiyun 			if (!(status & ACTIVE) && (!in || (status & 0x80)))
673*4882a593Smuzhiyun 				break;
674*4882a593Smuzhiyun 			if (--timeout <= 0) {
675*4882a593Smuzhiyun 				printk(KERN_ERR "i2sbus: timed out "
676*4882a593Smuzhiyun 				       "waiting for DMA to stop!\n");
677*4882a593Smuzhiyun 				break;
678*4882a593Smuzhiyun 			}
679*4882a593Smuzhiyun 			udelay(1);
680*4882a593Smuzhiyun 		}
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 		/* Turn off DMA controller, clear S0 bit */
683*4882a593Smuzhiyun 		out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 		pi->dbdma_ring.stopping = 0;
686*4882a593Smuzhiyun 		if (pi->stop_completion)
687*4882a593Smuzhiyun 			complete(pi->stop_completion);
688*4882a593Smuzhiyun 	}
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	if (!pi->dbdma_ring.running)
691*4882a593Smuzhiyun 		goto out_unlock;
692*4882a593Smuzhiyun 	spin_unlock(&i2sdev->low_lock);
693*4882a593Smuzhiyun 	/* may call _trigger again, hence needs to be unlocked */
694*4882a593Smuzhiyun 	snd_pcm_period_elapsed(pi->substream);
695*4882a593Smuzhiyun 	return;
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun  out_unlock:
698*4882a593Smuzhiyun 	spin_unlock(&i2sdev->low_lock);
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun 
i2sbus_tx_intr(int irq,void * devid)701*4882a593Smuzhiyun irqreturn_t i2sbus_tx_intr(int irq, void *devid)
702*4882a593Smuzhiyun {
703*4882a593Smuzhiyun 	handle_interrupt((struct i2sbus_dev *)devid, 0);
704*4882a593Smuzhiyun 	return IRQ_HANDLED;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun 
i2sbus_rx_intr(int irq,void * devid)707*4882a593Smuzhiyun irqreturn_t i2sbus_rx_intr(int irq, void *devid)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun 	handle_interrupt((struct i2sbus_dev *)devid, 1);
710*4882a593Smuzhiyun 	return IRQ_HANDLED;
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun 
i2sbus_playback_open(struct snd_pcm_substream * substream)713*4882a593Smuzhiyun static int i2sbus_playback_open(struct snd_pcm_substream *substream)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	if (!i2sdev)
718*4882a593Smuzhiyun 		return -EINVAL;
719*4882a593Smuzhiyun 	i2sdev->out.substream = substream;
720*4882a593Smuzhiyun 	return i2sbus_pcm_open(i2sdev, 0);
721*4882a593Smuzhiyun }
722*4882a593Smuzhiyun 
i2sbus_playback_close(struct snd_pcm_substream * substream)723*4882a593Smuzhiyun static int i2sbus_playback_close(struct snd_pcm_substream *substream)
724*4882a593Smuzhiyun {
725*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
726*4882a593Smuzhiyun 	int err;
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	if (!i2sdev)
729*4882a593Smuzhiyun 		return -EINVAL;
730*4882a593Smuzhiyun 	if (i2sdev->out.substream != substream)
731*4882a593Smuzhiyun 		return -EINVAL;
732*4882a593Smuzhiyun 	err = i2sbus_pcm_close(i2sdev, 0);
733*4882a593Smuzhiyun 	if (!err)
734*4882a593Smuzhiyun 		i2sdev->out.substream = NULL;
735*4882a593Smuzhiyun 	return err;
736*4882a593Smuzhiyun }
737*4882a593Smuzhiyun 
i2sbus_playback_prepare(struct snd_pcm_substream * substream)738*4882a593Smuzhiyun static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
739*4882a593Smuzhiyun {
740*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	if (!i2sdev)
743*4882a593Smuzhiyun 		return -EINVAL;
744*4882a593Smuzhiyun 	if (i2sdev->out.substream != substream)
745*4882a593Smuzhiyun 		return -EINVAL;
746*4882a593Smuzhiyun 	return i2sbus_pcm_prepare(i2sdev, 0);
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun 
i2sbus_playback_trigger(struct snd_pcm_substream * substream,int cmd)749*4882a593Smuzhiyun static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
750*4882a593Smuzhiyun {
751*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	if (!i2sdev)
754*4882a593Smuzhiyun 		return -EINVAL;
755*4882a593Smuzhiyun 	if (i2sdev->out.substream != substream)
756*4882a593Smuzhiyun 		return -EINVAL;
757*4882a593Smuzhiyun 	return i2sbus_pcm_trigger(i2sdev, 0, cmd);
758*4882a593Smuzhiyun }
759*4882a593Smuzhiyun 
i2sbus_playback_pointer(struct snd_pcm_substream * substream)760*4882a593Smuzhiyun static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
761*4882a593Smuzhiyun 						 *substream)
762*4882a593Smuzhiyun {
763*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	if (!i2sdev)
766*4882a593Smuzhiyun 		return -EINVAL;
767*4882a593Smuzhiyun 	if (i2sdev->out.substream != substream)
768*4882a593Smuzhiyun 		return 0;
769*4882a593Smuzhiyun 	return i2sbus_pcm_pointer(i2sdev, 0);
770*4882a593Smuzhiyun }
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun static const struct snd_pcm_ops i2sbus_playback_ops = {
773*4882a593Smuzhiyun 	.open =		i2sbus_playback_open,
774*4882a593Smuzhiyun 	.close =	i2sbus_playback_close,
775*4882a593Smuzhiyun 	.hw_free =	i2sbus_playback_hw_free,
776*4882a593Smuzhiyun 	.prepare =	i2sbus_playback_prepare,
777*4882a593Smuzhiyun 	.trigger =	i2sbus_playback_trigger,
778*4882a593Smuzhiyun 	.pointer =	i2sbus_playback_pointer,
779*4882a593Smuzhiyun };
780*4882a593Smuzhiyun 
i2sbus_record_open(struct snd_pcm_substream * substream)781*4882a593Smuzhiyun static int i2sbus_record_open(struct snd_pcm_substream *substream)
782*4882a593Smuzhiyun {
783*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	if (!i2sdev)
786*4882a593Smuzhiyun 		return -EINVAL;
787*4882a593Smuzhiyun 	i2sdev->in.substream = substream;
788*4882a593Smuzhiyun 	return i2sbus_pcm_open(i2sdev, 1);
789*4882a593Smuzhiyun }
790*4882a593Smuzhiyun 
i2sbus_record_close(struct snd_pcm_substream * substream)791*4882a593Smuzhiyun static int i2sbus_record_close(struct snd_pcm_substream *substream)
792*4882a593Smuzhiyun {
793*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
794*4882a593Smuzhiyun 	int err;
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	if (!i2sdev)
797*4882a593Smuzhiyun 		return -EINVAL;
798*4882a593Smuzhiyun 	if (i2sdev->in.substream != substream)
799*4882a593Smuzhiyun 		return -EINVAL;
800*4882a593Smuzhiyun 	err = i2sbus_pcm_close(i2sdev, 1);
801*4882a593Smuzhiyun 	if (!err)
802*4882a593Smuzhiyun 		i2sdev->in.substream = NULL;
803*4882a593Smuzhiyun 	return err;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun 
i2sbus_record_prepare(struct snd_pcm_substream * substream)806*4882a593Smuzhiyun static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
807*4882a593Smuzhiyun {
808*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 	if (!i2sdev)
811*4882a593Smuzhiyun 		return -EINVAL;
812*4882a593Smuzhiyun 	if (i2sdev->in.substream != substream)
813*4882a593Smuzhiyun 		return -EINVAL;
814*4882a593Smuzhiyun 	return i2sbus_pcm_prepare(i2sdev, 1);
815*4882a593Smuzhiyun }
816*4882a593Smuzhiyun 
i2sbus_record_trigger(struct snd_pcm_substream * substream,int cmd)817*4882a593Smuzhiyun static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
818*4882a593Smuzhiyun {
819*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 	if (!i2sdev)
822*4882a593Smuzhiyun 		return -EINVAL;
823*4882a593Smuzhiyun 	if (i2sdev->in.substream != substream)
824*4882a593Smuzhiyun 		return -EINVAL;
825*4882a593Smuzhiyun 	return i2sbus_pcm_trigger(i2sdev, 1, cmd);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun 
i2sbus_record_pointer(struct snd_pcm_substream * substream)828*4882a593Smuzhiyun static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
829*4882a593Smuzhiyun 					       *substream)
830*4882a593Smuzhiyun {
831*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	if (!i2sdev)
834*4882a593Smuzhiyun 		return -EINVAL;
835*4882a593Smuzhiyun 	if (i2sdev->in.substream != substream)
836*4882a593Smuzhiyun 		return 0;
837*4882a593Smuzhiyun 	return i2sbus_pcm_pointer(i2sdev, 1);
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun static const struct snd_pcm_ops i2sbus_record_ops = {
841*4882a593Smuzhiyun 	.open =		i2sbus_record_open,
842*4882a593Smuzhiyun 	.close =	i2sbus_record_close,
843*4882a593Smuzhiyun 	.hw_free =	i2sbus_record_hw_free,
844*4882a593Smuzhiyun 	.prepare =	i2sbus_record_prepare,
845*4882a593Smuzhiyun 	.trigger =	i2sbus_record_trigger,
846*4882a593Smuzhiyun 	.pointer =	i2sbus_record_pointer,
847*4882a593Smuzhiyun };
848*4882a593Smuzhiyun 
i2sbus_private_free(struct snd_pcm * pcm)849*4882a593Smuzhiyun static void i2sbus_private_free(struct snd_pcm *pcm)
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
852*4882a593Smuzhiyun 	struct codec_info_item *p, *tmp;
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	i2sdev->sound.pcm = NULL;
855*4882a593Smuzhiyun 	i2sdev->out.created = 0;
856*4882a593Smuzhiyun 	i2sdev->in.created = 0;
857*4882a593Smuzhiyun 	list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
858*4882a593Smuzhiyun 		printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
859*4882a593Smuzhiyun 		list_del(&p->list);
860*4882a593Smuzhiyun 		module_put(p->codec->owner);
861*4882a593Smuzhiyun 		kfree(p);
862*4882a593Smuzhiyun 	}
863*4882a593Smuzhiyun 	soundbus_dev_put(&i2sdev->sound);
864*4882a593Smuzhiyun 	module_put(THIS_MODULE);
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun int
i2sbus_attach_codec(struct soundbus_dev * dev,struct snd_card * card,struct codec_info * ci,void * data)868*4882a593Smuzhiyun i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
869*4882a593Smuzhiyun 		    struct codec_info *ci, void *data)
870*4882a593Smuzhiyun {
871*4882a593Smuzhiyun 	int err, in = 0, out = 0;
872*4882a593Smuzhiyun 	struct transfer_info *tmp;
873*4882a593Smuzhiyun 	struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
874*4882a593Smuzhiyun 	struct codec_info_item *cii;
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	if (!dev->pcmname || dev->pcmid == -1) {
877*4882a593Smuzhiyun 		printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");
878*4882a593Smuzhiyun 		return -EINVAL;
879*4882a593Smuzhiyun 	}
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	list_for_each_entry(cii, &dev->codec_list, list) {
882*4882a593Smuzhiyun 		if (cii->codec_data == data)
883*4882a593Smuzhiyun 			return -EALREADY;
884*4882a593Smuzhiyun 	}
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	if (!ci->transfers || !ci->transfers->formats
887*4882a593Smuzhiyun 	    || !ci->transfers->rates || !ci->usable)
888*4882a593Smuzhiyun 		return -EINVAL;
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun 	/* we currently code the i2s transfer on the clock, and support only
891*4882a593Smuzhiyun 	 * 32 and 64 */
892*4882a593Smuzhiyun 	if (ci->bus_factor != 32 && ci->bus_factor != 64)
893*4882a593Smuzhiyun 		return -EINVAL;
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 	/* If you want to fix this, you need to keep track of what transport infos
896*4882a593Smuzhiyun 	 * are to be used, which codecs they belong to, and then fix all the
897*4882a593Smuzhiyun 	 * sysclock/busclock stuff above to depend on which is usable */
898*4882a593Smuzhiyun 	list_for_each_entry(cii, &dev->codec_list, list) {
899*4882a593Smuzhiyun 		if (cii->codec->sysclock_factor != ci->sysclock_factor) {
900*4882a593Smuzhiyun 			printk(KERN_DEBUG
901*4882a593Smuzhiyun 			       "cannot yet handle multiple different sysclocks!\n");
902*4882a593Smuzhiyun 			return -EINVAL;
903*4882a593Smuzhiyun 		}
904*4882a593Smuzhiyun 		if (cii->codec->bus_factor != ci->bus_factor) {
905*4882a593Smuzhiyun 			printk(KERN_DEBUG
906*4882a593Smuzhiyun 			       "cannot yet handle multiple different bus clocks!\n");
907*4882a593Smuzhiyun 			return -EINVAL;
908*4882a593Smuzhiyun 		}
909*4882a593Smuzhiyun 	}
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	tmp = ci->transfers;
912*4882a593Smuzhiyun 	while (tmp->formats && tmp->rates) {
913*4882a593Smuzhiyun 		if (tmp->transfer_in)
914*4882a593Smuzhiyun 			in = 1;
915*4882a593Smuzhiyun 		else
916*4882a593Smuzhiyun 			out = 1;
917*4882a593Smuzhiyun 		tmp++;
918*4882a593Smuzhiyun 	}
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 	cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
921*4882a593Smuzhiyun 	if (!cii) {
922*4882a593Smuzhiyun 		printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
923*4882a593Smuzhiyun 		return -ENOMEM;
924*4882a593Smuzhiyun 	}
925*4882a593Smuzhiyun 
926*4882a593Smuzhiyun 	/* use the private data to point to the codec info */
927*4882a593Smuzhiyun 	cii->sdev = soundbus_dev_get(dev);
928*4882a593Smuzhiyun 	cii->codec = ci;
929*4882a593Smuzhiyun 	cii->codec_data = data;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 	if (!cii->sdev) {
932*4882a593Smuzhiyun 		printk(KERN_DEBUG
933*4882a593Smuzhiyun 		       "i2sbus: failed to get soundbus dev reference\n");
934*4882a593Smuzhiyun 		err = -ENODEV;
935*4882a593Smuzhiyun 		goto out_free_cii;
936*4882a593Smuzhiyun 	}
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 	if (!try_module_get(THIS_MODULE)) {
939*4882a593Smuzhiyun 		printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
940*4882a593Smuzhiyun 		err = -EBUSY;
941*4882a593Smuzhiyun 		goto out_put_sdev;
942*4882a593Smuzhiyun 	}
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun 	if (!try_module_get(ci->owner)) {
945*4882a593Smuzhiyun 		printk(KERN_DEBUG
946*4882a593Smuzhiyun 		       "i2sbus: failed to get module reference to codec owner!\n");
947*4882a593Smuzhiyun 		err = -EBUSY;
948*4882a593Smuzhiyun 		goto out_put_this_module;
949*4882a593Smuzhiyun 	}
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	if (!dev->pcm) {
952*4882a593Smuzhiyun 		err = snd_pcm_new(card, dev->pcmname, dev->pcmid, 0, 0,
953*4882a593Smuzhiyun 				  &dev->pcm);
954*4882a593Smuzhiyun 		if (err) {
955*4882a593Smuzhiyun 			printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
956*4882a593Smuzhiyun 			goto out_put_ci_module;
957*4882a593Smuzhiyun 		}
958*4882a593Smuzhiyun 	}
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	/* ALSA yet again sucks.
961*4882a593Smuzhiyun 	 * If it is ever fixed, remove this line. See below. */
962*4882a593Smuzhiyun 	out = in = 1;
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	if (!i2sdev->out.created && out) {
965*4882a593Smuzhiyun 		if (dev->pcm->card != card) {
966*4882a593Smuzhiyun 			/* eh? */
967*4882a593Smuzhiyun 			printk(KERN_ERR
968*4882a593Smuzhiyun 			       "Can't attach same bus to different cards!\n");
969*4882a593Smuzhiyun 			err = -EINVAL;
970*4882a593Smuzhiyun 			goto out_put_ci_module;
971*4882a593Smuzhiyun 		}
972*4882a593Smuzhiyun 		err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1);
973*4882a593Smuzhiyun 		if (err)
974*4882a593Smuzhiyun 			goto out_put_ci_module;
975*4882a593Smuzhiyun 		snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
976*4882a593Smuzhiyun 				&i2sbus_playback_ops);
977*4882a593Smuzhiyun 		dev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].dev.parent =
978*4882a593Smuzhiyun 			&dev->ofdev.dev;
979*4882a593Smuzhiyun 		i2sdev->out.created = 1;
980*4882a593Smuzhiyun 	}
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	if (!i2sdev->in.created && in) {
983*4882a593Smuzhiyun 		if (dev->pcm->card != card) {
984*4882a593Smuzhiyun 			printk(KERN_ERR
985*4882a593Smuzhiyun 			       "Can't attach same bus to different cards!\n");
986*4882a593Smuzhiyun 			err = -EINVAL;
987*4882a593Smuzhiyun 			goto out_put_ci_module;
988*4882a593Smuzhiyun 		}
989*4882a593Smuzhiyun 		err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1);
990*4882a593Smuzhiyun 		if (err)
991*4882a593Smuzhiyun 			goto out_put_ci_module;
992*4882a593Smuzhiyun 		snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
993*4882a593Smuzhiyun 				&i2sbus_record_ops);
994*4882a593Smuzhiyun 		dev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].dev.parent =
995*4882a593Smuzhiyun 			&dev->ofdev.dev;
996*4882a593Smuzhiyun 		i2sdev->in.created = 1;
997*4882a593Smuzhiyun 	}
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun 	/* so we have to register the pcm after adding any substream
1000*4882a593Smuzhiyun 	 * to it because alsa doesn't create the devices for the
1001*4882a593Smuzhiyun 	 * substreams when we add them later.
1002*4882a593Smuzhiyun 	 * Therefore, force in and out on both busses (above) and
1003*4882a593Smuzhiyun 	 * register the pcm now instead of just after creating it.
1004*4882a593Smuzhiyun 	 */
1005*4882a593Smuzhiyun 	err = snd_device_register(card, dev->pcm);
1006*4882a593Smuzhiyun 	if (err) {
1007*4882a593Smuzhiyun 		printk(KERN_ERR "i2sbus: error registering new pcm\n");
1008*4882a593Smuzhiyun 		goto out_put_ci_module;
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun 	/* no errors any more, so let's add this to our list */
1011*4882a593Smuzhiyun 	list_add(&cii->list, &dev->codec_list);
1012*4882a593Smuzhiyun 
1013*4882a593Smuzhiyun 	dev->pcm->private_data = i2sdev;
1014*4882a593Smuzhiyun 	dev->pcm->private_free = i2sbus_private_free;
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 	/* well, we really should support scatter/gather DMA */
1017*4882a593Smuzhiyun 	snd_pcm_set_managed_buffer_all(
1018*4882a593Smuzhiyun 		dev->pcm, SNDRV_DMA_TYPE_DEV,
1019*4882a593Smuzhiyun 		&macio_get_pci_dev(i2sdev->macio)->dev,
1020*4882a593Smuzhiyun 		64 * 1024, 64 * 1024);
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	return 0;
1023*4882a593Smuzhiyun  out_put_ci_module:
1024*4882a593Smuzhiyun 	module_put(ci->owner);
1025*4882a593Smuzhiyun  out_put_this_module:
1026*4882a593Smuzhiyun 	module_put(THIS_MODULE);
1027*4882a593Smuzhiyun  out_put_sdev:
1028*4882a593Smuzhiyun 	soundbus_dev_put(dev);
1029*4882a593Smuzhiyun  out_free_cii:
1030*4882a593Smuzhiyun 	kfree(cii);
1031*4882a593Smuzhiyun 	return err;
1032*4882a593Smuzhiyun }
1033*4882a593Smuzhiyun 
i2sbus_detach_codec(struct soundbus_dev * dev,void * data)1034*4882a593Smuzhiyun void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
1035*4882a593Smuzhiyun {
1036*4882a593Smuzhiyun 	struct codec_info_item *cii = NULL, *i;
1037*4882a593Smuzhiyun 
1038*4882a593Smuzhiyun 	list_for_each_entry(i, &dev->codec_list, list) {
1039*4882a593Smuzhiyun 		if (i->codec_data == data) {
1040*4882a593Smuzhiyun 			cii = i;
1041*4882a593Smuzhiyun 			break;
1042*4882a593Smuzhiyun 		}
1043*4882a593Smuzhiyun 	}
1044*4882a593Smuzhiyun 	if (cii) {
1045*4882a593Smuzhiyun 		list_del(&cii->list);
1046*4882a593Smuzhiyun 		module_put(cii->codec->owner);
1047*4882a593Smuzhiyun 		kfree(cii);
1048*4882a593Smuzhiyun 	}
1049*4882a593Smuzhiyun 	/* no more codecs, but still a pcm? */
1050*4882a593Smuzhiyun 	if (list_empty(&dev->codec_list) && dev->pcm) {
1051*4882a593Smuzhiyun 		/* the actual cleanup is done by the callback above! */
1052*4882a593Smuzhiyun 		snd_device_free(dev->pcm->card, dev->pcm);
1053*4882a593Smuzhiyun 	}
1054*4882a593Smuzhiyun }
1055