diff options
Diffstat (limited to 'sound/sparc')
-rw-r--r-- | sound/sparc/cs4231.c | 805 | ||||
-rw-r--r-- | sound/sparc/dbri.c | 581 |
2 files changed, 651 insertions, 735 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index f2950cab74a6..9785382a5f39 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -3,9 +3,9 @@ | |||
3 | * Copyright (C) 2002 David S. Miller <davem@redhat.com> | 3 | * Copyright (C) 2002 David S. Miller <davem@redhat.com> |
4 | * | 4 | * |
5 | * Based entirely upon drivers/sbus/audio/cs4231.c which is: | 5 | * Based entirely upon drivers/sbus/audio/cs4231.c which is: |
6 | * Copyright (C) 1996, 1997, 1998, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) | 6 | * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) |
7 | * and also sound/isa/cs423x/cs4231_lib.c which is: | 7 | * and also sound/isa/cs423x/cs4231_lib.c which is: |
8 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | 8 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
@@ -15,6 +15,9 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/irq.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
18 | 21 | ||
19 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
20 | #include <sound/core.h> | 23 | #include <sound/core.h> |
@@ -25,29 +28,21 @@ | |||
25 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
26 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
27 | 30 | ||
28 | #include <asm/io.h> | ||
29 | #include <asm/irq.h> | ||
30 | |||
31 | #ifdef CONFIG_SBUS | 31 | #ifdef CONFIG_SBUS |
32 | #define SBUS_SUPPORT | 32 | #define SBUS_SUPPORT |
33 | #endif | ||
34 | |||
35 | #ifdef SBUS_SUPPORT | ||
36 | #include <asm/sbus.h> | 33 | #include <asm/sbus.h> |
37 | #endif | 34 | #endif |
38 | 35 | ||
39 | #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) | 36 | #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) |
40 | #define EBUS_SUPPORT | 37 | #define EBUS_SUPPORT |
41 | #endif | ||
42 | |||
43 | #ifdef EBUS_SUPPORT | ||
44 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
45 | #include <asm/ebus.h> | 39 | #include <asm/ebus.h> |
46 | #endif | 40 | #endif |
47 | 41 | ||
48 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 42 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
49 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 43 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
50 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 44 | /* Enable this card */ |
45 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
51 | 46 | ||
52 | module_param_array(index, int, NULL, 0444); | 47 | module_param_array(index, int, NULL, 0444); |
53 | MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard."); | 48 | MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard."); |
@@ -62,19 +57,22 @@ MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}"); | |||
62 | 57 | ||
63 | #ifdef SBUS_SUPPORT | 58 | #ifdef SBUS_SUPPORT |
64 | struct sbus_dma_info { | 59 | struct sbus_dma_info { |
65 | spinlock_t lock; | 60 | spinlock_t lock; /* DMA access lock */ |
66 | int dir; | 61 | int dir; |
67 | void __iomem *regs; | 62 | void __iomem *regs; |
68 | }; | 63 | }; |
69 | #endif | 64 | #endif |
70 | 65 | ||
71 | struct snd_cs4231; | 66 | struct snd_cs4231; |
72 | struct cs4231_dma_control { | 67 | struct cs4231_dma_control { |
73 | void (*prepare)(struct cs4231_dma_control *dma_cont, int dir); | 68 | void (*prepare)(struct cs4231_dma_control *dma_cont, |
74 | void (*enable)(struct cs4231_dma_control *dma_cont, int on); | 69 | int dir); |
75 | int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len); | 70 | void (*enable)(struct cs4231_dma_control *dma_cont, int on); |
76 | unsigned int (*address)(struct cs4231_dma_control *dma_cont); | 71 | int (*request)(struct cs4231_dma_control *dma_cont, |
77 | void (*preallocate)(struct snd_cs4231 *chip, struct snd_pcm *pcm); | 72 | dma_addr_t bus_addr, size_t len); |
73 | unsigned int (*address)(struct cs4231_dma_control *dma_cont); | ||
74 | void (*preallocate)(struct snd_cs4231 *chip, | ||
75 | struct snd_pcm *pcm); | ||
78 | #ifdef EBUS_SUPPORT | 76 | #ifdef EBUS_SUPPORT |
79 | struct ebus_dma_info ebus_info; | 77 | struct ebus_dma_info ebus_info; |
80 | #endif | 78 | #endif |
@@ -84,7 +82,7 @@ struct cs4231_dma_control { | |||
84 | }; | 82 | }; |
85 | 83 | ||
86 | struct snd_cs4231 { | 84 | struct snd_cs4231 { |
87 | spinlock_t lock; | 85 | spinlock_t lock; /* registers access lock */ |
88 | void __iomem *port; | 86 | void __iomem *port; |
89 | 87 | ||
90 | struct cs4231_dma_control p_dma; | 88 | struct cs4231_dma_control p_dma; |
@@ -108,13 +106,14 @@ struct snd_cs4231 { | |||
108 | #define CS4231_MODE_PLAY 0x0001 | 106 | #define CS4231_MODE_PLAY 0x0001 |
109 | #define CS4231_MODE_RECORD 0x0002 | 107 | #define CS4231_MODE_RECORD 0x0002 |
110 | #define CS4231_MODE_TIMER 0x0004 | 108 | #define CS4231_MODE_TIMER 0x0004 |
111 | #define CS4231_MODE_OPEN (CS4231_MODE_PLAY|CS4231_MODE_RECORD|CS4231_MODE_TIMER) | 109 | #define CS4231_MODE_OPEN (CS4231_MODE_PLAY | CS4231_MODE_RECORD | \ |
110 | CS4231_MODE_TIMER) | ||
112 | 111 | ||
113 | unsigned char image[32]; /* registers image */ | 112 | unsigned char image[32]; /* registers image */ |
114 | int mce_bit; | 113 | int mce_bit; |
115 | int calibrate_mute; | 114 | int calibrate_mute; |
116 | struct mutex mce_mutex; | 115 | struct mutex mce_mutex; /* mutex for mce register */ |
117 | struct mutex open_mutex; | 116 | struct mutex open_mutex; /* mutex for ALSA open/close */ |
118 | 117 | ||
119 | union { | 118 | union { |
120 | #ifdef SBUS_SUPPORT | 119 | #ifdef SBUS_SUPPORT |
@@ -136,129 +135,10 @@ static struct snd_cs4231 *cs4231_list; | |||
136 | */ | 135 | */ |
137 | 136 | ||
138 | /* IO ports */ | 137 | /* IO ports */ |
139 | 138 | #include <sound/cs4231-regs.h> | |
140 | #define CS4231P(chip, x) ((chip)->port + c_d_c_CS4231##x) | ||
141 | 139 | ||
142 | /* XXX offsets are different than PC ISA chips... */ | 140 | /* XXX offsets are different than PC ISA chips... */ |
143 | #define c_d_c_CS4231REGSEL 0x0 | 141 | #define CS4231U(chip, x) ((chip)->port + ((c_d_c_CS4231##x) << 2)) |
144 | #define c_d_c_CS4231REG 0x4 | ||
145 | #define c_d_c_CS4231STATUS 0x8 | ||
146 | #define c_d_c_CS4231PIO 0xc | ||
147 | |||
148 | /* codec registers */ | ||
149 | |||
150 | #define CS4231_LEFT_INPUT 0x00 /* left input control */ | ||
151 | #define CS4231_RIGHT_INPUT 0x01 /* right input control */ | ||
152 | #define CS4231_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */ | ||
153 | #define CS4231_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */ | ||
154 | #define CS4231_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */ | ||
155 | #define CS4231_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */ | ||
156 | #define CS4231_LEFT_OUTPUT 0x06 /* left output control register */ | ||
157 | #define CS4231_RIGHT_OUTPUT 0x07 /* right output control register */ | ||
158 | #define CS4231_PLAYBK_FORMAT 0x08 /* clock and data format - playback - bits 7-0 MCE */ | ||
159 | #define CS4231_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */ | ||
160 | #define CS4231_PIN_CTRL 0x0a /* pin control */ | ||
161 | #define CS4231_TEST_INIT 0x0b /* test and initialization */ | ||
162 | #define CS4231_MISC_INFO 0x0c /* miscellaneaous information */ | ||
163 | #define CS4231_LOOPBACK 0x0d /* loopback control */ | ||
164 | #define CS4231_PLY_UPR_CNT 0x0e /* playback upper base count */ | ||
165 | #define CS4231_PLY_LWR_CNT 0x0f /* playback lower base count */ | ||
166 | #define CS4231_ALT_FEATURE_1 0x10 /* alternate #1 feature enable */ | ||
167 | #define CS4231_ALT_FEATURE_2 0x11 /* alternate #2 feature enable */ | ||
168 | #define CS4231_LEFT_LINE_IN 0x12 /* left line input control */ | ||
169 | #define CS4231_RIGHT_LINE_IN 0x13 /* right line input control */ | ||
170 | #define CS4231_TIMER_LOW 0x14 /* timer low byte */ | ||
171 | #define CS4231_TIMER_HIGH 0x15 /* timer high byte */ | ||
172 | #define CS4231_LEFT_MIC_INPUT 0x16 /* left MIC input control register (InterWave only) */ | ||
173 | #define CS4231_RIGHT_MIC_INPUT 0x17 /* right MIC input control register (InterWave only) */ | ||
174 | #define CS4236_EXT_REG 0x17 /* extended register access */ | ||
175 | #define CS4231_IRQ_STATUS 0x18 /* irq status register */ | ||
176 | #define CS4231_LINE_LEFT_OUTPUT 0x19 /* left line output control register (InterWave only) */ | ||
177 | #define CS4231_VERSION 0x19 /* CS4231(A) - version values */ | ||
178 | #define CS4231_MONO_CTRL 0x1a /* mono input/output control */ | ||
179 | #define CS4231_LINE_RIGHT_OUTPUT 0x1b /* right line output control register (InterWave only) */ | ||
180 | #define CS4235_LEFT_MASTER 0x1b /* left master output control */ | ||
181 | #define CS4231_REC_FORMAT 0x1c /* clock and data format - record - bits 7-0 MCE */ | ||
182 | #define CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */ | ||
183 | #define CS4235_RIGHT_MASTER 0x1d /* right master output control */ | ||
184 | #define CS4231_REC_UPR_CNT 0x1e /* record upper count */ | ||
185 | #define CS4231_REC_LWR_CNT 0x1f /* record lower count */ | ||
186 | |||
187 | /* definitions for codec register select port - CODECP( REGSEL ) */ | ||
188 | |||
189 | #define CS4231_INIT 0x80 /* CODEC is initializing */ | ||
190 | #define CS4231_MCE 0x40 /* mode change enable */ | ||
191 | #define CS4231_TRD 0x20 /* transfer request disable */ | ||
192 | |||
193 | /* definitions for codec status register - CODECP( STATUS ) */ | ||
194 | |||
195 | #define CS4231_GLOBALIRQ 0x01 /* IRQ is active */ | ||
196 | |||
197 | /* definitions for codec irq status - CS4231_IRQ_STATUS */ | ||
198 | |||
199 | #define CS4231_PLAYBACK_IRQ 0x10 | ||
200 | #define CS4231_RECORD_IRQ 0x20 | ||
201 | #define CS4231_TIMER_IRQ 0x40 | ||
202 | #define CS4231_ALL_IRQS 0x70 | ||
203 | #define CS4231_REC_UNDERRUN 0x08 | ||
204 | #define CS4231_REC_OVERRUN 0x04 | ||
205 | #define CS4231_PLY_OVERRUN 0x02 | ||
206 | #define CS4231_PLY_UNDERRUN 0x01 | ||
207 | |||
208 | /* definitions for CS4231_LEFT_INPUT and CS4231_RIGHT_INPUT registers */ | ||
209 | |||
210 | #define CS4231_ENABLE_MIC_GAIN 0x20 | ||
211 | |||
212 | #define CS4231_MIXS_LINE 0x00 | ||
213 | #define CS4231_MIXS_AUX1 0x40 | ||
214 | #define CS4231_MIXS_MIC 0x80 | ||
215 | #define CS4231_MIXS_ALL 0xc0 | ||
216 | |||
217 | /* definitions for clock and data format register - CS4231_PLAYBK_FORMAT */ | ||
218 | |||
219 | #define CS4231_LINEAR_8 0x00 /* 8-bit unsigned data */ | ||
220 | #define CS4231_ALAW_8 0x60 /* 8-bit A-law companded */ | ||
221 | #define CS4231_ULAW_8 0x20 /* 8-bit U-law companded */ | ||
222 | #define CS4231_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */ | ||
223 | #define CS4231_LINEAR_16_BIG 0xc0 /* 16-bit twos complement data - big endian */ | ||
224 | #define CS4231_ADPCM_16 0xa0 /* 16-bit ADPCM */ | ||
225 | #define CS4231_STEREO 0x10 /* stereo mode */ | ||
226 | /* bits 3-1 define frequency divisor */ | ||
227 | #define CS4231_XTAL1 0x00 /* 24.576 crystal */ | ||
228 | #define CS4231_XTAL2 0x01 /* 16.9344 crystal */ | ||
229 | |||
230 | /* definitions for interface control register - CS4231_IFACE_CTRL */ | ||
231 | |||
232 | #define CS4231_RECORD_PIO 0x80 /* record PIO enable */ | ||
233 | #define CS4231_PLAYBACK_PIO 0x40 /* playback PIO enable */ | ||
234 | #define CS4231_CALIB_MODE 0x18 /* calibration mode bits */ | ||
235 | #define CS4231_AUTOCALIB 0x08 /* auto calibrate */ | ||
236 | #define CS4231_SINGLE_DMA 0x04 /* use single DMA channel */ | ||
237 | #define CS4231_RECORD_ENABLE 0x02 /* record enable */ | ||
238 | #define CS4231_PLAYBACK_ENABLE 0x01 /* playback enable */ | ||
239 | |||
240 | /* definitions for pin control register - CS4231_PIN_CTRL */ | ||
241 | |||
242 | #define CS4231_IRQ_ENABLE 0x02 /* enable IRQ */ | ||
243 | #define CS4231_XCTL1 0x40 /* external control #1 */ | ||
244 | #define CS4231_XCTL0 0x80 /* external control #0 */ | ||
245 | |||
246 | /* definitions for test and init register - CS4231_TEST_INIT */ | ||
247 | |||
248 | #define CS4231_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */ | ||
249 | #define CS4231_DMA_REQUEST 0x10 /* DMA request in progress */ | ||
250 | |||
251 | /* definitions for misc control register - CS4231_MISC_INFO */ | ||
252 | |||
253 | #define CS4231_MODE2 0x40 /* MODE 2 */ | ||
254 | #define CS4231_IW_MODE3 0x6c /* MODE 3 - InterWave enhanced mode */ | ||
255 | #define CS4231_4236_MODE3 0xe0 /* MODE 3 - CS4236+ enhanced mode */ | ||
256 | |||
257 | /* definitions for alternate feature 1 register - CS4231_ALT_FEATURE_1 */ | ||
258 | |||
259 | #define CS4231_DACZ 0x01 /* zero DAC when underrun */ | ||
260 | #define CS4231_TIMER_ENABLE 0x40 /* codec timer enable */ | ||
261 | #define CS4231_OLB 0x80 /* output level bit */ | ||
262 | 142 | ||
263 | /* SBUS DMA register defines. */ | 143 | /* SBUS DMA register defines. */ |
264 | 144 | ||
@@ -339,7 +219,7 @@ static unsigned int rates[14] = { | |||
339 | }; | 219 | }; |
340 | 220 | ||
341 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { | 221 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
342 | .count = 14, | 222 | .count = ARRAY_SIZE(rates), |
343 | .list = rates, | 223 | .list = rates, |
344 | }; | 224 | }; |
345 | 225 | ||
@@ -389,116 +269,89 @@ static unsigned char snd_cs4231_original_image[32] = | |||
389 | static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) | 269 | static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) |
390 | { | 270 | { |
391 | #ifdef EBUS_SUPPORT | 271 | #ifdef EBUS_SUPPORT |
392 | if (cp->flags & CS4231_FLAG_EBUS) { | 272 | if (cp->flags & CS4231_FLAG_EBUS) |
393 | return readb(reg_addr); | 273 | return readb(reg_addr); |
394 | } else { | 274 | else |
395 | #endif | 275 | #endif |
396 | #ifdef SBUS_SUPPORT | 276 | #ifdef SBUS_SUPPORT |
397 | return sbus_readb(reg_addr); | 277 | return sbus_readb(reg_addr); |
398 | #endif | 278 | #endif |
399 | #ifdef EBUS_SUPPORT | ||
400 | } | ||
401 | #endif | ||
402 | } | 279 | } |
403 | 280 | ||
404 | static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, void __iomem *reg_addr) | 281 | static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, |
282 | void __iomem *reg_addr) | ||
405 | { | 283 | { |
406 | #ifdef EBUS_SUPPORT | 284 | #ifdef EBUS_SUPPORT |
407 | if (cp->flags & CS4231_FLAG_EBUS) { | 285 | if (cp->flags & CS4231_FLAG_EBUS) |
408 | return writeb(val, reg_addr); | 286 | return writeb(val, reg_addr); |
409 | } else { | 287 | else |
410 | #endif | 288 | #endif |
411 | #ifdef SBUS_SUPPORT | 289 | #ifdef SBUS_SUPPORT |
412 | return sbus_writeb(val, reg_addr); | 290 | return sbus_writeb(val, reg_addr); |
413 | #endif | 291 | #endif |
414 | #ifdef EBUS_SUPPORT | ||
415 | } | ||
416 | #endif | ||
417 | } | 292 | } |
418 | 293 | ||
419 | /* | 294 | /* |
420 | * Basic I/O functions | 295 | * Basic I/O functions |
421 | */ | 296 | */ |
422 | 297 | ||
423 | static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, | 298 | static void snd_cs4231_ready(struct snd_cs4231 *chip) |
424 | unsigned char mask, unsigned char value) | ||
425 | { | 299 | { |
426 | int timeout; | 300 | int timeout; |
427 | unsigned char tmp; | ||
428 | 301 | ||
429 | for (timeout = 250; | 302 | for (timeout = 250; timeout > 0; timeout--) { |
430 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | 303 | int val = __cs4231_readb(chip, CS4231U(chip, REGSEL)); |
431 | timeout--) | 304 | if ((val & CS4231_INIT) == 0) |
432 | udelay(100); | 305 | break; |
433 | #ifdef CONFIG_SND_DEBUG | 306 | udelay(100); |
434 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | ||
435 | snd_printdd("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | ||
436 | #endif | ||
437 | if (chip->calibrate_mute) { | ||
438 | chip->image[reg] &= mask; | ||
439 | chip->image[reg] |= value; | ||
440 | } else { | ||
441 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | ||
442 | mb(); | ||
443 | tmp = (chip->image[reg] & mask) | value; | ||
444 | __cs4231_writeb(chip, tmp, CS4231P(chip, REG)); | ||
445 | chip->image[reg] = tmp; | ||
446 | mb(); | ||
447 | } | 307 | } |
448 | } | 308 | } |
449 | 309 | ||
450 | static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) | 310 | static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, |
311 | unsigned char value) | ||
451 | { | 312 | { |
452 | int timeout; | 313 | snd_cs4231_ready(chip); |
453 | |||
454 | for (timeout = 250; | ||
455 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | ||
456 | timeout--) | ||
457 | udelay(100); | ||
458 | #ifdef CONFIG_SND_DEBUG | 314 | #ifdef CONFIG_SND_DEBUG |
459 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 315 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) |
460 | snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | 316 | snd_printdd("out: auto calibration time out - reg = 0x%x, " |
317 | "value = 0x%x\n", | ||
318 | reg, value); | ||
461 | #endif | 319 | #endif |
462 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | 320 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL)); |
463 | __cs4231_writeb(chip, value, CS4231P(chip, REG)); | 321 | wmb(); |
322 | __cs4231_writeb(chip, value, CS4231U(chip, REG)); | ||
464 | mb(); | 323 | mb(); |
465 | } | 324 | } |
466 | 325 | ||
467 | static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value) | 326 | static inline void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg, |
327 | unsigned char mask, unsigned char value) | ||
468 | { | 328 | { |
469 | int timeout; | 329 | unsigned char tmp = (chip->image[reg] & mask) | value; |
470 | 330 | ||
471 | for (timeout = 250; | 331 | chip->image[reg] = tmp; |
472 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | 332 | if (!chip->calibrate_mute) |
473 | timeout--) | 333 | snd_cs4231_dout(chip, reg, tmp); |
474 | udelay(100); | 334 | } |
475 | #ifdef CONFIG_SND_DEBUG | 335 | |
476 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 336 | static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, |
477 | snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); | 337 | unsigned char value) |
478 | #endif | 338 | { |
479 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | 339 | snd_cs4231_dout(chip, reg, value); |
480 | __cs4231_writeb(chip, value, CS4231P(chip, REG)); | ||
481 | chip->image[reg] = value; | 340 | chip->image[reg] = value; |
482 | mb(); | 341 | mb(); |
483 | } | 342 | } |
484 | 343 | ||
485 | static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) | 344 | static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg) |
486 | { | 345 | { |
487 | int timeout; | 346 | snd_cs4231_ready(chip); |
488 | unsigned char ret; | ||
489 | |||
490 | for (timeout = 250; | ||
491 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | ||
492 | timeout--) | ||
493 | udelay(100); | ||
494 | #ifdef CONFIG_SND_DEBUG | 347 | #ifdef CONFIG_SND_DEBUG |
495 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 348 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) |
496 | snd_printdd("in: auto calibration time out - reg = 0x%x\n", reg); | 349 | snd_printdd("in: auto calibration time out - reg = 0x%x\n", |
350 | reg); | ||
497 | #endif | 351 | #endif |
498 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); | 352 | __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL)); |
499 | mb(); | 353 | mb(); |
500 | ret = __cs4231_readb(chip, CS4231P(chip, REG)); | 354 | return __cs4231_readb(chip, CS4231U(chip, REG)); |
501 | return ret; | ||
502 | } | 355 | } |
503 | 356 | ||
504 | /* | 357 | /* |
@@ -509,15 +362,17 @@ static void snd_cs4231_busy_wait(struct snd_cs4231 *chip) | |||
509 | { | 362 | { |
510 | int timeout; | 363 | int timeout; |
511 | 364 | ||
512 | /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */ | 365 | /* looks like this sequence is proper for CS4231A chip (GUS MAX) */ |
513 | for (timeout = 5; timeout > 0; timeout--) | 366 | for (timeout = 5; timeout > 0; timeout--) |
514 | __cs4231_readb(chip, CS4231P(chip, REGSEL)); | 367 | __cs4231_readb(chip, CS4231U(chip, REGSEL)); |
515 | 368 | ||
516 | /* end of cleanup sequence */ | 369 | /* end of cleanup sequence */ |
517 | for (timeout = 500; | 370 | for (timeout = 500; timeout > 0; timeout--) { |
518 | timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); | 371 | int val = __cs4231_readb(chip, CS4231U(chip, REGSEL)); |
519 | timeout--) | 372 | if ((val & CS4231_INIT) == 0) |
520 | udelay(1000); | 373 | break; |
374 | msleep(1); | ||
375 | } | ||
521 | } | 376 | } |
522 | 377 | ||
523 | static void snd_cs4231_mce_up(struct snd_cs4231 *chip) | 378 | static void snd_cs4231_mce_up(struct snd_cs4231 *chip) |
@@ -526,74 +381,81 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip) | |||
526 | int timeout; | 381 | int timeout; |
527 | 382 | ||
528 | spin_lock_irqsave(&chip->lock, flags); | 383 | spin_lock_irqsave(&chip->lock, flags); |
529 | for (timeout = 250; timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); timeout--) | 384 | snd_cs4231_ready(chip); |
530 | udelay(100); | ||
531 | #ifdef CONFIG_SND_DEBUG | 385 | #ifdef CONFIG_SND_DEBUG |
532 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 386 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) |
533 | snd_printdd("mce_up - auto calibration time out (0)\n"); | 387 | snd_printdd("mce_up - auto calibration time out (0)\n"); |
534 | #endif | 388 | #endif |
535 | chip->mce_bit |= CS4231_MCE; | 389 | chip->mce_bit |= CS4231_MCE; |
536 | timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL)); | 390 | timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL)); |
537 | if (timeout == 0x80) | 391 | if (timeout == 0x80) |
538 | snd_printdd("mce_up [%p]: serious init problem - codec still busy\n", chip->port); | 392 | snd_printdd("mce_up [%p]: serious init problem - " |
393 | "codec still busy\n", | ||
394 | chip->port); | ||
539 | if (!(timeout & CS4231_MCE)) | 395 | if (!(timeout & CS4231_MCE)) |
540 | __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); | 396 | __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), |
397 | CS4231U(chip, REGSEL)); | ||
541 | spin_unlock_irqrestore(&chip->lock, flags); | 398 | spin_unlock_irqrestore(&chip->lock, flags); |
542 | } | 399 | } |
543 | 400 | ||
544 | static void snd_cs4231_mce_down(struct snd_cs4231 *chip) | 401 | static void snd_cs4231_mce_down(struct snd_cs4231 *chip) |
545 | { | 402 | { |
546 | unsigned long flags; | 403 | unsigned long flags; |
404 | unsigned long end_time; | ||
547 | int timeout; | 405 | int timeout; |
548 | 406 | ||
549 | spin_lock_irqsave(&chip->lock, flags); | 407 | spin_lock_irqsave(&chip->lock, flags); |
550 | snd_cs4231_busy_wait(chip); | 408 | snd_cs4231_busy_wait(chip); |
551 | #ifdef CONFIG_SND_DEBUG | 409 | #ifdef CONFIG_SND_DEBUG |
552 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 410 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) |
553 | snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL)); | 411 | snd_printdd("mce_down [%p] - auto calibration time out (0)\n", |
412 | CS4231U(chip, REGSEL)); | ||
554 | #endif | 413 | #endif |
555 | chip->mce_bit &= ~CS4231_MCE; | 414 | chip->mce_bit &= ~CS4231_MCE; |
556 | timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL)); | 415 | timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL)); |
557 | __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); | 416 | __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), |
417 | CS4231U(chip, REGSEL)); | ||
558 | if (timeout == 0x80) | 418 | if (timeout == 0x80) |
559 | snd_printdd("mce_down [%p]: serious init problem - codec still busy\n", chip->port); | 419 | snd_printdd("mce_down [%p]: serious init problem - " |
420 | "codec still busy\n", | ||
421 | chip->port); | ||
560 | if ((timeout & CS4231_MCE) == 0) { | 422 | if ((timeout & CS4231_MCE) == 0) { |
561 | spin_unlock_irqrestore(&chip->lock, flags); | 423 | spin_unlock_irqrestore(&chip->lock, flags); |
562 | return; | 424 | return; |
563 | } | 425 | } |
564 | snd_cs4231_busy_wait(chip); | ||
565 | 426 | ||
566 | /* calibration process */ | 427 | /* |
428 | * Wait for (possible -- during init auto-calibration may not be set) | ||
429 | * calibration process to start. Needs upto 5 sample periods on AD1848 | ||
430 | * which at the slowest possible rate of 5.5125 kHz means 907 us. | ||
431 | */ | ||
432 | msleep(1); | ||
567 | 433 | ||
568 | for (timeout = 500; timeout > 0 && (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0; timeout--) | 434 | /* check condition up to 250ms */ |
569 | udelay(100); | 435 | end_time = jiffies + msecs_to_jiffies(250); |
570 | if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) { | 436 | while (snd_cs4231_in(chip, CS4231_TEST_INIT) & |
571 | snd_printd("cs4231_mce_down - auto calibration time out (1)\n"); | 437 | CS4231_CALIB_IN_PROGRESS) { |
572 | spin_unlock_irqrestore(&chip->lock, flags); | ||
573 | return; | ||
574 | } | ||
575 | 438 | ||
576 | /* in 10ms increments, check condition, up to 250ms */ | ||
577 | timeout = 25; | ||
578 | while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) { | ||
579 | spin_unlock_irqrestore(&chip->lock, flags); | 439 | spin_unlock_irqrestore(&chip->lock, flags); |
580 | if (--timeout < 0) { | 440 | if (time_after(jiffies, end_time)) { |
581 | snd_printk("mce_down - auto calibration time out (2)\n"); | 441 | snd_printk("mce_down - " |
442 | "auto calibration time out (2)\n"); | ||
582 | return; | 443 | return; |
583 | } | 444 | } |
584 | msleep(10); | 445 | msleep(1); |
585 | spin_lock_irqsave(&chip->lock, flags); | 446 | spin_lock_irqsave(&chip->lock, flags); |
586 | } | 447 | } |
587 | 448 | ||
588 | /* in 10ms increments, check condition, up to 100ms */ | 449 | /* check condition up to 100ms */ |
589 | timeout = 10; | 450 | end_time = jiffies + msecs_to_jiffies(100); |
590 | while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) { | 451 | while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) { |
591 | spin_unlock_irqrestore(&chip->lock, flags); | 452 | spin_unlock_irqrestore(&chip->lock, flags); |
592 | if (--timeout < 0) { | 453 | if (time_after(jiffies, end_time)) { |
593 | snd_printk("mce_down - auto calibration time out (3)\n"); | 454 | snd_printk("mce_down - " |
455 | "auto calibration time out (3)\n"); | ||
594 | return; | 456 | return; |
595 | } | 457 | } |
596 | msleep(10); | 458 | msleep(1); |
597 | spin_lock_irqsave(&chip->lock, flags); | 459 | spin_lock_irqsave(&chip->lock, flags); |
598 | } | 460 | } |
599 | spin_unlock_irqrestore(&chip->lock, flags); | 461 | spin_unlock_irqrestore(&chip->lock, flags); |
@@ -611,7 +473,8 @@ static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, | |||
611 | 473 | ||
612 | BUG_ON(period_size >= (1 << 24)); | 474 | BUG_ON(period_size >= (1 << 24)); |
613 | 475 | ||
614 | if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size)) | 476 | if (dma_cont->request(dma_cont, |
477 | runtime->dma_addr + offset, period_size)) | ||
615 | return; | 478 | return; |
616 | (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; | 479 | (*periods_sent) = ((*periods_sent) + 1) % runtime->periods; |
617 | } | 480 | } |
@@ -704,21 +567,32 @@ static unsigned char snd_cs4231_get_rate(unsigned int rate) | |||
704 | for (i = 0; i < 14; i++) | 567 | for (i = 0; i < 14; i++) |
705 | if (rate == rates[i]) | 568 | if (rate == rates[i]) |
706 | return freq_bits[i]; | 569 | return freq_bits[i]; |
707 | // snd_BUG(); | 570 | |
708 | return freq_bits[13]; | 571 | return freq_bits[13]; |
709 | } | 572 | } |
710 | 573 | ||
711 | static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format, int channels) | 574 | static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format, |
575 | int channels) | ||
712 | { | 576 | { |
713 | unsigned char rformat; | 577 | unsigned char rformat; |
714 | 578 | ||
715 | rformat = CS4231_LINEAR_8; | 579 | rformat = CS4231_LINEAR_8; |
716 | switch (format) { | 580 | switch (format) { |
717 | case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break; | 581 | case SNDRV_PCM_FORMAT_MU_LAW: |
718 | case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break; | 582 | rformat = CS4231_ULAW_8; |
719 | case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break; | 583 | break; |
720 | case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break; | 584 | case SNDRV_PCM_FORMAT_A_LAW: |
721 | case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break; | 585 | rformat = CS4231_ALAW_8; |
586 | break; | ||
587 | case SNDRV_PCM_FORMAT_S16_LE: | ||
588 | rformat = CS4231_LINEAR_16; | ||
589 | break; | ||
590 | case SNDRV_PCM_FORMAT_S16_BE: | ||
591 | rformat = CS4231_LINEAR_16_BIG; | ||
592 | break; | ||
593 | case SNDRV_PCM_FORMAT_IMA_ADPCM: | ||
594 | rformat = CS4231_ADPCM_16; | ||
595 | break; | ||
722 | } | 596 | } |
723 | if (channels > 1) | 597 | if (channels > 1) |
724 | rformat |= CS4231_STEREO; | 598 | rformat |= CS4231_STEREO; |
@@ -765,7 +639,8 @@ static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute) | |||
765 | spin_unlock_irqrestore(&chip->lock, flags); | 639 | spin_unlock_irqrestore(&chip->lock, flags); |
766 | } | 640 | } |
767 | 641 | ||
768 | static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, | 642 | static void snd_cs4231_playback_format(struct snd_cs4231 *chip, |
643 | struct snd_pcm_hw_params *params, | ||
769 | unsigned char pdfr) | 644 | unsigned char pdfr) |
770 | { | 645 | { |
771 | unsigned long flags; | 646 | unsigned long flags; |
@@ -788,8 +663,9 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_h | |||
788 | mutex_unlock(&chip->mce_mutex); | 663 | mutex_unlock(&chip->mce_mutex); |
789 | } | 664 | } |
790 | 665 | ||
791 | static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, | 666 | static void snd_cs4231_capture_format(struct snd_cs4231 *chip, |
792 | unsigned char cdfr) | 667 | struct snd_pcm_hw_params *params, |
668 | unsigned char cdfr) | ||
793 | { | 669 | { |
794 | unsigned long flags; | 670 | unsigned long flags; |
795 | 671 | ||
@@ -846,7 +722,8 @@ static int snd_cs4231_timer_start(struct snd_timer *timer) | |||
846 | chip->image[CS4231_TIMER_LOW] = | 722 | chip->image[CS4231_TIMER_LOW] = |
847 | (unsigned char) ticks); | 723 | (unsigned char) ticks); |
848 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, | 724 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, |
849 | chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE); | 725 | chip->image[CS4231_ALT_FEATURE_1] | |
726 | CS4231_TIMER_ENABLE); | ||
850 | } | 727 | } |
851 | spin_unlock_irqrestore(&chip->lock, flags); | 728 | spin_unlock_irqrestore(&chip->lock, flags); |
852 | 729 | ||
@@ -859,8 +736,9 @@ static int snd_cs4231_timer_stop(struct snd_timer *timer) | |||
859 | struct snd_cs4231 *chip = snd_timer_chip(timer); | 736 | struct snd_cs4231 *chip = snd_timer_chip(timer); |
860 | 737 | ||
861 | spin_lock_irqsave(&chip->lock, flags); | 738 | spin_lock_irqsave(&chip->lock, flags); |
739 | chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE; | ||
862 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, | 740 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, |
863 | chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE); | 741 | chip->image[CS4231_ALT_FEATURE_1]); |
864 | spin_unlock_irqrestore(&chip->lock, flags); | 742 | spin_unlock_irqrestore(&chip->lock, flags); |
865 | 743 | ||
866 | return 0; | 744 | return 0; |
@@ -877,8 +755,10 @@ static void __init snd_cs4231_init(struct snd_cs4231 *chip) | |||
877 | #endif | 755 | #endif |
878 | snd_cs4231_mce_up(chip); | 756 | snd_cs4231_mce_up(chip); |
879 | spin_lock_irqsave(&chip->lock, flags); | 757 | spin_lock_irqsave(&chip->lock, flags); |
880 | chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | | 758 | chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | |
881 | CS4231_RECORD_ENABLE | CS4231_RECORD_PIO | | 759 | CS4231_PLAYBACK_PIO | |
760 | CS4231_RECORD_ENABLE | | ||
761 | CS4231_RECORD_PIO | | ||
882 | CS4231_CALIB_MODE); | 762 | CS4231_CALIB_MODE); |
883 | chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB; | 763 | chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB; |
884 | snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); | 764 | snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); |
@@ -891,21 +771,25 @@ static void __init snd_cs4231_init(struct snd_cs4231 *chip) | |||
891 | 771 | ||
892 | snd_cs4231_mce_up(chip); | 772 | snd_cs4231_mce_up(chip); |
893 | spin_lock_irqsave(&chip->lock, flags); | 773 | spin_lock_irqsave(&chip->lock, flags); |
894 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]); | 774 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, |
775 | chip->image[CS4231_ALT_FEATURE_1]); | ||
895 | spin_unlock_irqrestore(&chip->lock, flags); | 776 | spin_unlock_irqrestore(&chip->lock, flags); |
896 | snd_cs4231_mce_down(chip); | 777 | snd_cs4231_mce_down(chip); |
897 | 778 | ||
898 | #ifdef SNDRV_DEBUG_MCE | 779 | #ifdef SNDRV_DEBUG_MCE |
899 | snd_printdd("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]); | 780 | snd_printdd("init: (3) - afei = 0x%x\n", |
781 | chip->image[CS4231_ALT_FEATURE_1]); | ||
900 | #endif | 782 | #endif |
901 | 783 | ||
902 | spin_lock_irqsave(&chip->lock, flags); | 784 | spin_lock_irqsave(&chip->lock, flags); |
903 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]); | 785 | snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, |
786 | chip->image[CS4231_ALT_FEATURE_2]); | ||
904 | spin_unlock_irqrestore(&chip->lock, flags); | 787 | spin_unlock_irqrestore(&chip->lock, flags); |
905 | 788 | ||
906 | snd_cs4231_mce_up(chip); | 789 | snd_cs4231_mce_up(chip); |
907 | spin_lock_irqsave(&chip->lock, flags); | 790 | spin_lock_irqsave(&chip->lock, flags); |
908 | snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]); | 791 | snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, |
792 | chip->image[CS4231_PLAYBK_FORMAT]); | ||
909 | spin_unlock_irqrestore(&chip->lock, flags); | 793 | spin_unlock_irqrestore(&chip->lock, flags); |
910 | snd_cs4231_mce_down(chip); | 794 | snd_cs4231_mce_down(chip); |
911 | 795 | ||
@@ -944,8 +828,8 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) | |||
944 | CS4231_RECORD_IRQ | | 828 | CS4231_RECORD_IRQ | |
945 | CS4231_TIMER_IRQ); | 829 | CS4231_TIMER_IRQ); |
946 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); | 830 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); |
947 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ | 831 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */ |
948 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ | 832 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */ |
949 | 833 | ||
950 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | | 834 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | |
951 | CS4231_RECORD_IRQ | | 835 | CS4231_RECORD_IRQ | |
@@ -974,8 +858,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
974 | /* disable IRQ */ | 858 | /* disable IRQ */ |
975 | spin_lock_irqsave(&chip->lock, flags); | 859 | spin_lock_irqsave(&chip->lock, flags); |
976 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); | 860 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); |
977 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ | 861 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */ |
978 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ | 862 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */ |
979 | 863 | ||
980 | /* now disable record & playback */ | 864 | /* now disable record & playback */ |
981 | 865 | ||
@@ -988,7 +872,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
988 | chip->image[CS4231_IFACE_CTRL] &= | 872 | chip->image[CS4231_IFACE_CTRL] &= |
989 | ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | | 873 | ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO | |
990 | CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); | 874 | CS4231_RECORD_ENABLE | CS4231_RECORD_PIO); |
991 | snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); | 875 | snd_cs4231_out(chip, CS4231_IFACE_CTRL, |
876 | chip->image[CS4231_IFACE_CTRL]); | ||
992 | spin_unlock_irqrestore(&chip->lock, flags); | 877 | spin_unlock_irqrestore(&chip->lock, flags); |
993 | snd_cs4231_mce_down(chip); | 878 | snd_cs4231_mce_down(chip); |
994 | spin_lock_irqsave(&chip->lock, flags); | 879 | spin_lock_irqsave(&chip->lock, flags); |
@@ -996,8 +881,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
996 | 881 | ||
997 | /* clear IRQ again */ | 882 | /* clear IRQ again */ |
998 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); | 883 | snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); |
999 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ | 884 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */ |
1000 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ | 885 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */ |
1001 | spin_unlock_irqrestore(&chip->lock, flags); | 886 | spin_unlock_irqrestore(&chip->lock, flags); |
1002 | 887 | ||
1003 | snd_cs4231_calibrate_mute(chip, 0); | 888 | snd_cs4231_calibrate_mute(chip, 0); |
@@ -1017,15 +902,14 @@ static int snd_cs4231_timer_open(struct snd_timer *timer) | |||
1017 | return 0; | 902 | return 0; |
1018 | } | 903 | } |
1019 | 904 | ||
1020 | static int snd_cs4231_timer_close(struct snd_timer * timer) | 905 | static int snd_cs4231_timer_close(struct snd_timer *timer) |
1021 | { | 906 | { |
1022 | struct snd_cs4231 *chip = snd_timer_chip(timer); | 907 | struct snd_cs4231 *chip = snd_timer_chip(timer); |
1023 | snd_cs4231_close(chip, CS4231_MODE_TIMER); | 908 | snd_cs4231_close(chip, CS4231_MODE_TIMER); |
1024 | return 0; | 909 | return 0; |
1025 | } | 910 | } |
1026 | 911 | ||
1027 | static struct snd_timer_hardware snd_cs4231_timer_table = | 912 | static struct snd_timer_hardware snd_cs4231_timer_table = { |
1028 | { | ||
1029 | .flags = SNDRV_TIMER_HW_AUTO, | 913 | .flags = SNDRV_TIMER_HW_AUTO, |
1030 | .resolution = 9945, | 914 | .resolution = 9945, |
1031 | .ticks = 65535, | 915 | .ticks = 65535, |
@@ -1047,8 +931,9 @@ static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream, | |||
1047 | unsigned char new_pdfr; | 931 | unsigned char new_pdfr; |
1048 | int err; | 932 | int err; |
1049 | 933 | ||
1050 | if ((err = snd_pcm_lib_malloc_pages(substream, | 934 | err = snd_pcm_lib_malloc_pages(substream, |
1051 | params_buffer_bytes(hw_params))) < 0) | 935 | params_buffer_bytes(hw_params)); |
936 | if (err < 0) | ||
1052 | return err; | 937 | return err; |
1053 | new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), | 938 | new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params), |
1054 | params_channels(hw_params)) | | 939 | params_channels(hw_params)) | |
@@ -1058,11 +943,6 @@ static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream, | |||
1058 | return 0; | 943 | return 0; |
1059 | } | 944 | } |
1060 | 945 | ||
1061 | static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream) | ||
1062 | { | ||
1063 | return snd_pcm_lib_free_pages(substream); | ||
1064 | } | ||
1065 | |||
1066 | static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) | 946 | static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream) |
1067 | { | 947 | { |
1068 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 948 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
@@ -1089,8 +969,9 @@ static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream, | |||
1089 | unsigned char new_cdfr; | 969 | unsigned char new_cdfr; |
1090 | int err; | 970 | int err; |
1091 | 971 | ||
1092 | if ((err = snd_pcm_lib_malloc_pages(substream, | 972 | err = snd_pcm_lib_malloc_pages(substream, |
1093 | params_buffer_bytes(hw_params))) < 0) | 973 | params_buffer_bytes(hw_params)); |
974 | if (err < 0) | ||
1094 | return err; | 975 | return err; |
1095 | new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), | 976 | new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params), |
1096 | params_channels(hw_params)) | | 977 | params_channels(hw_params)) | |
@@ -1100,11 +981,6 @@ static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream, | |||
1100 | return 0; | 981 | return 0; |
1101 | } | 982 | } |
1102 | 983 | ||
1103 | static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream) | ||
1104 | { | ||
1105 | return snd_pcm_lib_free_pages(substream); | ||
1106 | } | ||
1107 | |||
1108 | static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) | 984 | static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream) |
1109 | { | 985 | { |
1110 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 986 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
@@ -1130,7 +1006,8 @@ static void snd_cs4231_overrange(struct snd_cs4231 *chip) | |||
1130 | res = snd_cs4231_in(chip, CS4231_TEST_INIT); | 1006 | res = snd_cs4231_in(chip, CS4231_TEST_INIT); |
1131 | spin_unlock_irqrestore(&chip->lock, flags); | 1007 | spin_unlock_irqrestore(&chip->lock, flags); |
1132 | 1008 | ||
1133 | if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */ | 1009 | /* detect overrange only above 0dB; may be user selectable? */ |
1010 | if (res & (0x08 | 0x02)) | ||
1134 | chip->capture_substream->runtime->overrange++; | 1011 | chip->capture_substream->runtime->overrange++; |
1135 | } | 1012 | } |
1136 | 1013 | ||
@@ -1152,51 +1029,50 @@ static void snd_cs4231_capture_callback(struct snd_cs4231 *chip) | |||
1152 | } | 1029 | } |
1153 | } | 1030 | } |
1154 | 1031 | ||
1155 | static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream) | 1032 | static snd_pcm_uframes_t snd_cs4231_playback_pointer( |
1033 | struct snd_pcm_substream *substream) | ||
1156 | { | 1034 | { |
1157 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 1035 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
1158 | struct cs4231_dma_control *dma_cont = &chip->p_dma; | 1036 | struct cs4231_dma_control *dma_cont = &chip->p_dma; |
1159 | size_t ptr; | 1037 | size_t ptr; |
1160 | 1038 | ||
1161 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) | 1039 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) |
1162 | return 0; | 1040 | return 0; |
1163 | ptr = dma_cont->address(dma_cont); | 1041 | ptr = dma_cont->address(dma_cont); |
1164 | if (ptr != 0) | 1042 | if (ptr != 0) |
1165 | ptr -= substream->runtime->dma_addr; | 1043 | ptr -= substream->runtime->dma_addr; |
1166 | 1044 | ||
1167 | return bytes_to_frames(substream->runtime, ptr); | 1045 | return bytes_to_frames(substream->runtime, ptr); |
1168 | } | 1046 | } |
1169 | 1047 | ||
1170 | static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream) | 1048 | static snd_pcm_uframes_t snd_cs4231_capture_pointer( |
1049 | struct snd_pcm_substream *substream) | ||
1171 | { | 1050 | { |
1172 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); | 1051 | struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); |
1173 | struct cs4231_dma_control *dma_cont = &chip->c_dma; | 1052 | struct cs4231_dma_control *dma_cont = &chip->c_dma; |
1174 | size_t ptr; | 1053 | size_t ptr; |
1175 | 1054 | ||
1176 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) | 1055 | if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) |
1177 | return 0; | 1056 | return 0; |
1178 | ptr = dma_cont->address(dma_cont); | 1057 | ptr = dma_cont->address(dma_cont); |
1179 | if (ptr != 0) | 1058 | if (ptr != 0) |
1180 | ptr -= substream->runtime->dma_addr; | 1059 | ptr -= substream->runtime->dma_addr; |
1181 | 1060 | ||
1182 | return bytes_to_frames(substream->runtime, ptr); | 1061 | return bytes_to_frames(substream->runtime, ptr); |
1183 | } | 1062 | } |
1184 | 1063 | ||
1185 | /* | ||
1186 | |||
1187 | */ | ||
1188 | |||
1189 | static int __init snd_cs4231_probe(struct snd_cs4231 *chip) | 1064 | static int __init snd_cs4231_probe(struct snd_cs4231 *chip) |
1190 | { | 1065 | { |
1191 | unsigned long flags; | 1066 | unsigned long flags; |
1192 | int i, id, vers; | 1067 | int i; |
1068 | int id = 0; | ||
1069 | int vers = 0; | ||
1193 | unsigned char *ptr; | 1070 | unsigned char *ptr; |
1194 | 1071 | ||
1195 | id = vers = 0; | ||
1196 | for (i = 0; i < 50; i++) { | 1072 | for (i = 0; i < 50; i++) { |
1197 | mb(); | 1073 | mb(); |
1198 | if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) | 1074 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) |
1199 | udelay(2000); | 1075 | msleep(2); |
1200 | else { | 1076 | else { |
1201 | spin_lock_irqsave(&chip->lock, flags); | 1077 | spin_lock_irqsave(&chip->lock, flags); |
1202 | snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2); | 1078 | snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2); |
@@ -1213,8 +1089,9 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip) | |||
1213 | 1089 | ||
1214 | spin_lock_irqsave(&chip->lock, flags); | 1090 | spin_lock_irqsave(&chip->lock, flags); |
1215 | 1091 | ||
1216 | __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ | 1092 | /* clear any pendings IRQ */ |
1217 | __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); | 1093 | __cs4231_readb(chip, CS4231U(chip, STATUS)); |
1094 | __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); | ||
1218 | mb(); | 1095 | mb(); |
1219 | 1096 | ||
1220 | spin_unlock_irqrestore(&chip->lock, flags); | 1097 | spin_unlock_irqrestore(&chip->lock, flags); |
@@ -1247,42 +1124,50 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip) | |||
1247 | return 0; /* all things are ok.. */ | 1124 | return 0; /* all things are ok.. */ |
1248 | } | 1125 | } |
1249 | 1126 | ||
1250 | static struct snd_pcm_hardware snd_cs4231_playback = | 1127 | static struct snd_pcm_hardware snd_cs4231_playback = { |
1251 | { | 1128 | .info = SNDRV_PCM_INFO_MMAP | |
1252 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1129 | SNDRV_PCM_INFO_INTERLEAVED | |
1253 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), | 1130 | SNDRV_PCM_INFO_MMAP_VALID | |
1254 | .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | | 1131 | SNDRV_PCM_INFO_SYNC_START, |
1255 | SNDRV_PCM_FMTBIT_IMA_ADPCM | | 1132 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | |
1256 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1133 | SNDRV_PCM_FMTBIT_A_LAW | |
1257 | SNDRV_PCM_FMTBIT_S16_BE), | 1134 | SNDRV_PCM_FMTBIT_IMA_ADPCM | |
1258 | .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, | 1135 | SNDRV_PCM_FMTBIT_U8 | |
1136 | SNDRV_PCM_FMTBIT_S16_LE | | ||
1137 | SNDRV_PCM_FMTBIT_S16_BE, | ||
1138 | .rates = SNDRV_PCM_RATE_KNOT | | ||
1139 | SNDRV_PCM_RATE_8000_48000, | ||
1259 | .rate_min = 5510, | 1140 | .rate_min = 5510, |
1260 | .rate_max = 48000, | 1141 | .rate_max = 48000, |
1261 | .channels_min = 1, | 1142 | .channels_min = 1, |
1262 | .channels_max = 2, | 1143 | .channels_max = 2, |
1263 | .buffer_bytes_max = (32*1024), | 1144 | .buffer_bytes_max = 32 * 1024, |
1264 | .period_bytes_min = 64, | 1145 | .period_bytes_min = 64, |
1265 | .period_bytes_max = (32*1024), | 1146 | .period_bytes_max = 32 * 1024, |
1266 | .periods_min = 1, | 1147 | .periods_min = 1, |
1267 | .periods_max = 1024, | 1148 | .periods_max = 1024, |
1268 | }; | 1149 | }; |
1269 | 1150 | ||
1270 | static struct snd_pcm_hardware snd_cs4231_capture = | 1151 | static struct snd_pcm_hardware snd_cs4231_capture = { |
1271 | { | 1152 | .info = SNDRV_PCM_INFO_MMAP | |
1272 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1153 | SNDRV_PCM_INFO_INTERLEAVED | |
1273 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START), | 1154 | SNDRV_PCM_INFO_MMAP_VALID | |
1274 | .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | | 1155 | SNDRV_PCM_INFO_SYNC_START, |
1275 | SNDRV_PCM_FMTBIT_IMA_ADPCM | | 1156 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | |
1276 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1157 | SNDRV_PCM_FMTBIT_A_LAW | |
1277 | SNDRV_PCM_FMTBIT_S16_BE), | 1158 | SNDRV_PCM_FMTBIT_IMA_ADPCM | |
1278 | .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, | 1159 | SNDRV_PCM_FMTBIT_U8 | |
1160 | SNDRV_PCM_FMTBIT_S16_LE | | ||
1161 | SNDRV_PCM_FMTBIT_S16_BE, | ||
1162 | .rates = SNDRV_PCM_RATE_KNOT | | ||
1163 | SNDRV_PCM_RATE_8000_48000, | ||
1279 | .rate_min = 5510, | 1164 | .rate_min = 5510, |
1280 | .rate_max = 48000, | 1165 | .rate_max = 48000, |
1281 | .channels_min = 1, | 1166 | .channels_min = 1, |
1282 | .channels_max = 2, | 1167 | .channels_max = 2, |
1283 | .buffer_bytes_max = (32*1024), | 1168 | .buffer_bytes_max = 32 * 1024, |
1284 | .period_bytes_min = 64, | 1169 | .period_bytes_min = 64, |
1285 | .period_bytes_max = (32*1024), | 1170 | .period_bytes_max = 32 * 1024, |
1286 | .periods_min = 1, | 1171 | .periods_min = 1, |
1287 | .periods_max = 1024, | 1172 | .periods_max = 1024, |
1288 | }; | 1173 | }; |
@@ -1295,7 +1180,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) | |||
1295 | 1180 | ||
1296 | runtime->hw = snd_cs4231_playback; | 1181 | runtime->hw = snd_cs4231_playback; |
1297 | 1182 | ||
1298 | if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) { | 1183 | err = snd_cs4231_open(chip, CS4231_MODE_PLAY); |
1184 | if (err < 0) { | ||
1299 | snd_free_pages(runtime->dma_area, runtime->dma_bytes); | 1185 | snd_free_pages(runtime->dma_area, runtime->dma_bytes); |
1300 | return err; | 1186 | return err; |
1301 | } | 1187 | } |
@@ -1315,7 +1201,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) | |||
1315 | 1201 | ||
1316 | runtime->hw = snd_cs4231_capture; | 1202 | runtime->hw = snd_cs4231_capture; |
1317 | 1203 | ||
1318 | if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) { | 1204 | err = snd_cs4231_open(chip, CS4231_MODE_RECORD); |
1205 | if (err < 0) { | ||
1319 | snd_free_pages(runtime->dma_area, runtime->dma_bytes); | 1206 | snd_free_pages(runtime->dma_area, runtime->dma_bytes); |
1320 | return err; | 1207 | return err; |
1321 | } | 1208 | } |
@@ -1356,7 +1243,7 @@ static struct snd_pcm_ops snd_cs4231_playback_ops = { | |||
1356 | .close = snd_cs4231_playback_close, | 1243 | .close = snd_cs4231_playback_close, |
1357 | .ioctl = snd_pcm_lib_ioctl, | 1244 | .ioctl = snd_pcm_lib_ioctl, |
1358 | .hw_params = snd_cs4231_playback_hw_params, | 1245 | .hw_params = snd_cs4231_playback_hw_params, |
1359 | .hw_free = snd_cs4231_playback_hw_free, | 1246 | .hw_free = snd_pcm_lib_free_pages, |
1360 | .prepare = snd_cs4231_playback_prepare, | 1247 | .prepare = snd_cs4231_playback_prepare, |
1361 | .trigger = snd_cs4231_trigger, | 1248 | .trigger = snd_cs4231_trigger, |
1362 | .pointer = snd_cs4231_playback_pointer, | 1249 | .pointer = snd_cs4231_playback_pointer, |
@@ -1367,23 +1254,27 @@ static struct snd_pcm_ops snd_cs4231_capture_ops = { | |||
1367 | .close = snd_cs4231_capture_close, | 1254 | .close = snd_cs4231_capture_close, |
1368 | .ioctl = snd_pcm_lib_ioctl, | 1255 | .ioctl = snd_pcm_lib_ioctl, |
1369 | .hw_params = snd_cs4231_capture_hw_params, | 1256 | .hw_params = snd_cs4231_capture_hw_params, |
1370 | .hw_free = snd_cs4231_capture_hw_free, | 1257 | .hw_free = snd_pcm_lib_free_pages, |
1371 | .prepare = snd_cs4231_capture_prepare, | 1258 | .prepare = snd_cs4231_capture_prepare, |
1372 | .trigger = snd_cs4231_trigger, | 1259 | .trigger = snd_cs4231_trigger, |
1373 | .pointer = snd_cs4231_capture_pointer, | 1260 | .pointer = snd_cs4231_capture_pointer, |
1374 | }; | 1261 | }; |
1375 | 1262 | ||
1376 | static int __init snd_cs4231_pcm(struct snd_cs4231 *chip) | 1263 | static int __init snd_cs4231_pcm(struct snd_card *card) |
1377 | { | 1264 | { |
1265 | struct snd_cs4231 *chip = card->private_data; | ||
1378 | struct snd_pcm *pcm; | 1266 | struct snd_pcm *pcm; |
1379 | int err; | 1267 | int err; |
1380 | 1268 | ||
1381 | if ((err = snd_pcm_new(chip->card, "CS4231", 0, 1, 1, &pcm)) < 0) | 1269 | err = snd_pcm_new(card, "CS4231", 0, 1, 1, &pcm); |
1270 | if (err < 0) | ||
1382 | return err; | 1271 | return err; |
1383 | 1272 | ||
1384 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); | 1273 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1385 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); | 1274 | &snd_cs4231_playback_ops); |
1386 | 1275 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | |
1276 | &snd_cs4231_capture_ops); | ||
1277 | |||
1387 | /* global setup */ | 1278 | /* global setup */ |
1388 | pcm->private_data = chip; | 1279 | pcm->private_data = chip; |
1389 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; | 1280 | pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; |
@@ -1396,8 +1287,9 @@ static int __init snd_cs4231_pcm(struct snd_cs4231 *chip) | |||
1396 | return 0; | 1287 | return 0; |
1397 | } | 1288 | } |
1398 | 1289 | ||
1399 | static int __init snd_cs4231_timer(struct snd_cs4231 *chip) | 1290 | static int __init snd_cs4231_timer(struct snd_card *card) |
1400 | { | 1291 | { |
1292 | struct snd_cs4231 *chip = card->private_data; | ||
1401 | struct snd_timer *timer; | 1293 | struct snd_timer *timer; |
1402 | struct snd_timer_id tid; | 1294 | struct snd_timer_id tid; |
1403 | int err; | 1295 | int err; |
@@ -1405,10 +1297,11 @@ static int __init snd_cs4231_timer(struct snd_cs4231 *chip) | |||
1405 | /* Timer initialization */ | 1297 | /* Timer initialization */ |
1406 | tid.dev_class = SNDRV_TIMER_CLASS_CARD; | 1298 | tid.dev_class = SNDRV_TIMER_CLASS_CARD; |
1407 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; | 1299 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; |
1408 | tid.card = chip->card->number; | 1300 | tid.card = card->number; |
1409 | tid.device = 0; | 1301 | tid.device = 0; |
1410 | tid.subdevice = 0; | 1302 | tid.subdevice = 0; |
1411 | if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0) | 1303 | err = snd_timer_new(card, "CS4231", &tid, &timer); |
1304 | if (err < 0) | ||
1412 | return err; | 1305 | return err; |
1413 | strcpy(timer->name, "CS4231"); | 1306 | strcpy(timer->name, "CS4231"); |
1414 | timer->private_data = chip; | 1307 | timer->private_data = chip; |
@@ -1417,7 +1310,7 @@ static int __init snd_cs4231_timer(struct snd_cs4231 *chip) | |||
1417 | 1310 | ||
1418 | return 0; | 1311 | return 0; |
1419 | } | 1312 | } |
1420 | 1313 | ||
1421 | /* | 1314 | /* |
1422 | * MIXER part | 1315 | * MIXER part |
1423 | */ | 1316 | */ |
@@ -1428,15 +1321,14 @@ static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, | |||
1428 | static char *texts[4] = { | 1321 | static char *texts[4] = { |
1429 | "Line", "CD", "Mic", "Mix" | 1322 | "Line", "CD", "Mic", "Mix" |
1430 | }; | 1323 | }; |
1431 | struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); | ||
1432 | 1324 | ||
1433 | snd_assert(chip->card != NULL, return -EINVAL); | ||
1434 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1325 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1435 | uinfo->count = 2; | 1326 | uinfo->count = 2; |
1436 | uinfo->value.enumerated.items = 4; | 1327 | uinfo->value.enumerated.items = 4; |
1437 | if (uinfo->value.enumerated.item > 3) | 1328 | if (uinfo->value.enumerated.item > 3) |
1438 | uinfo->value.enumerated.item = 3; | 1329 | uinfo->value.enumerated.item = 3; |
1439 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 1330 | strcpy(uinfo->value.enumerated.name, |
1331 | texts[uinfo->value.enumerated.item]); | ||
1440 | 1332 | ||
1441 | return 0; | 1333 | return 0; |
1442 | } | 1334 | } |
@@ -1446,7 +1338,7 @@ static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, | |||
1446 | { | 1338 | { |
1447 | struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); | 1339 | struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol); |
1448 | unsigned long flags; | 1340 | unsigned long flags; |
1449 | 1341 | ||
1450 | spin_lock_irqsave(&chip->lock, flags); | 1342 | spin_lock_irqsave(&chip->lock, flags); |
1451 | ucontrol->value.enumerated.item[0] = | 1343 | ucontrol->value.enumerated.item[0] = |
1452 | (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6; | 1344 | (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6; |
@@ -1464,7 +1356,7 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, | |||
1464 | unsigned long flags; | 1356 | unsigned long flags; |
1465 | unsigned short left, right; | 1357 | unsigned short left, right; |
1466 | int change; | 1358 | int change; |
1467 | 1359 | ||
1468 | if (ucontrol->value.enumerated.item[0] > 3 || | 1360 | if (ucontrol->value.enumerated.item[0] > 3 || |
1469 | ucontrol->value.enumerated.item[1] > 3) | 1361 | ucontrol->value.enumerated.item[1] > 3) |
1470 | return -EINVAL; | 1362 | return -EINVAL; |
@@ -1476,7 +1368,7 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, | |||
1476 | left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left; | 1368 | left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left; |
1477 | right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right; | 1369 | right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right; |
1478 | change = left != chip->image[CS4231_LEFT_INPUT] || | 1370 | change = left != chip->image[CS4231_LEFT_INPUT] || |
1479 | right != chip->image[CS4231_RIGHT_INPUT]; | 1371 | right != chip->image[CS4231_RIGHT_INPUT]; |
1480 | snd_cs4231_out(chip, CS4231_LEFT_INPUT, left); | 1372 | snd_cs4231_out(chip, CS4231_LEFT_INPUT, left); |
1481 | snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right); | 1373 | snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right); |
1482 | 1374 | ||
@@ -1508,7 +1400,7 @@ static int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, | |||
1508 | int shift = (kcontrol->private_value >> 8) & 0xff; | 1400 | int shift = (kcontrol->private_value >> 8) & 0xff; |
1509 | int mask = (kcontrol->private_value >> 16) & 0xff; | 1401 | int mask = (kcontrol->private_value >> 16) & 0xff; |
1510 | int invert = (kcontrol->private_value >> 24) & 0xff; | 1402 | int invert = (kcontrol->private_value >> 24) & 0xff; |
1511 | 1403 | ||
1512 | spin_lock_irqsave(&chip->lock, flags); | 1404 | spin_lock_irqsave(&chip->lock, flags); |
1513 | 1405 | ||
1514 | ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask; | 1406 | ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask; |
@@ -1533,7 +1425,7 @@ static int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, | |||
1533 | int invert = (kcontrol->private_value >> 24) & 0xff; | 1425 | int invert = (kcontrol->private_value >> 24) & 0xff; |
1534 | int change; | 1426 | int change; |
1535 | unsigned short val; | 1427 | unsigned short val; |
1536 | 1428 | ||
1537 | val = (ucontrol->value.integer.value[0] & mask); | 1429 | val = (ucontrol->value.integer.value[0] & mask); |
1538 | if (invert) | 1430 | if (invert) |
1539 | val = mask - val; | 1431 | val = mask - val; |
@@ -1575,11 +1467,13 @@ static int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, | |||
1575 | int shift_right = (kcontrol->private_value >> 19) & 0x07; | 1467 | int shift_right = (kcontrol->private_value >> 19) & 0x07; |
1576 | int mask = (kcontrol->private_value >> 24) & 0xff; | 1468 | int mask = (kcontrol->private_value >> 24) & 0xff; |
1577 | int invert = (kcontrol->private_value >> 22) & 1; | 1469 | int invert = (kcontrol->private_value >> 22) & 1; |
1578 | 1470 | ||
1579 | spin_lock_irqsave(&chip->lock, flags); | 1471 | spin_lock_irqsave(&chip->lock, flags); |
1580 | 1472 | ||
1581 | ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask; | 1473 | ucontrol->value.integer.value[0] = |
1582 | ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask; | 1474 | (chip->image[left_reg] >> shift_left) & mask; |
1475 | ucontrol->value.integer.value[1] = | ||
1476 | (chip->image[right_reg] >> shift_right) & mask; | ||
1583 | 1477 | ||
1584 | spin_unlock_irqrestore(&chip->lock, flags); | 1478 | spin_unlock_irqrestore(&chip->lock, flags); |
1585 | 1479 | ||
@@ -1606,7 +1500,7 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, | |||
1606 | int invert = (kcontrol->private_value >> 22) & 1; | 1500 | int invert = (kcontrol->private_value >> 22) & 1; |
1607 | int change; | 1501 | int change; |
1608 | unsigned short val1, val2; | 1502 | unsigned short val1, val2; |
1609 | 1503 | ||
1610 | val1 = ucontrol->value.integer.value[0] & mask; | 1504 | val1 = ucontrol->value.integer.value[0] & mask; |
1611 | val2 = ucontrol->value.integer.value[1] & mask; | 1505 | val2 = ucontrol->value.integer.value[1] & mask; |
1612 | if (invert) { | 1506 | if (invert) { |
@@ -1620,7 +1514,8 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, | |||
1620 | 1514 | ||
1621 | val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; | 1515 | val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1; |
1622 | val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; | 1516 | val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2; |
1623 | change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg]; | 1517 | change = val1 != chip->image[left_reg]; |
1518 | change |= val2 != chip->image[right_reg]; | ||
1624 | snd_cs4231_out(chip, left_reg, val1); | 1519 | snd_cs4231_out(chip, left_reg, val1); |
1625 | snd_cs4231_out(chip, right_reg, val2); | 1520 | snd_cs4231_out(chip, right_reg, val2); |
1626 | 1521 | ||
@@ -1630,31 +1525,42 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, | |||
1630 | } | 1525 | } |
1631 | 1526 | ||
1632 | #define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \ | 1527 | #define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \ |
1633 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | 1528 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .index = (xindex), \ |
1634 | .info = snd_cs4231_info_single, \ | 1529 | .info = snd_cs4231_info_single, \ |
1635 | .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \ | 1530 | .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \ |
1636 | .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } | 1531 | .private_value = (reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24) } |
1637 | 1532 | ||
1638 | #define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ | 1533 | #define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, \ |
1639 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | 1534 | shift_right, mask, invert) \ |
1640 | .info = snd_cs4231_info_double, \ | 1535 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .index = (xindex), \ |
1641 | .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \ | 1536 | .info = snd_cs4231_info_double, \ |
1642 | .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } | 1537 | .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \ |
1538 | .private_value = (left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | \ | ||
1539 | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22) } | ||
1643 | 1540 | ||
1644 | static struct snd_kcontrol_new snd_cs4231_controls[] __initdata = { | 1541 | static struct snd_kcontrol_new snd_cs4231_controls[] __initdata = { |
1645 | CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), | 1542 | CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, |
1646 | CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), | 1543 | CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), |
1647 | CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), | 1544 | CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, |
1648 | CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), | 1545 | CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), |
1649 | CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), | 1546 | CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, |
1650 | CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), | 1547 | CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), |
1651 | CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), | 1548 | CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, |
1652 | CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), | 1549 | CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), |
1550 | CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, | ||
1551 | CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), | ||
1552 | CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, | ||
1553 | CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), | ||
1554 | CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, | ||
1555 | CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), | ||
1556 | CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, | ||
1557 | CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), | ||
1653 | CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1), | 1558 | CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1), |
1654 | CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), | 1559 | CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), |
1655 | CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1), | 1560 | CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1), |
1656 | CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), | 1561 | CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), |
1657 | CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), | 1562 | CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, |
1563 | 15, 0), | ||
1658 | { | 1564 | { |
1659 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1565 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1660 | .name = "Capture Source", | 1566 | .name = "Capture Source", |
@@ -1662,29 +1568,28 @@ CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, | |||
1662 | .get = snd_cs4231_get_mux, | 1568 | .get = snd_cs4231_get_mux, |
1663 | .put = snd_cs4231_put_mux, | 1569 | .put = snd_cs4231_put_mux, |
1664 | }, | 1570 | }, |
1665 | CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), | 1571 | CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, |
1572 | 1, 0), | ||
1666 | CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), | 1573 | CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0), |
1667 | CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1), | 1574 | CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1), |
1668 | /* SPARC specific uses of XCTL{0,1} general purpose outputs. */ | 1575 | /* SPARC specific uses of XCTL{0,1} general purpose outputs. */ |
1669 | CS4231_SINGLE("Line Out Switch", 0, CS4231_PIN_CTRL, 6, 1, 1), | 1576 | CS4231_SINGLE("Line Out Switch", 0, CS4231_PIN_CTRL, 6, 1, 1), |
1670 | CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1) | 1577 | CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1) |
1671 | }; | 1578 | }; |
1672 | 1579 | ||
1673 | static int __init snd_cs4231_mixer(struct snd_cs4231 *chip) | 1580 | static int __init snd_cs4231_mixer(struct snd_card *card) |
1674 | { | 1581 | { |
1675 | struct snd_card *card; | 1582 | struct snd_cs4231 *chip = card->private_data; |
1676 | int err, idx; | 1583 | int err, idx; |
1677 | 1584 | ||
1678 | snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); | 1585 | snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); |
1679 | 1586 | ||
1680 | card = chip->card; | ||
1681 | |||
1682 | strcpy(card->mixername, chip->pcm->name); | 1587 | strcpy(card->mixername, chip->pcm->name); |
1683 | 1588 | ||
1684 | for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { | 1589 | for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) { |
1685 | if ((err = snd_ctl_add(card, | 1590 | err = snd_ctl_add(card, |
1686 | snd_ctl_new1(&snd_cs4231_controls[idx], | 1591 | snd_ctl_new1(&snd_cs4231_controls[idx], chip)); |
1687 | chip))) < 0) | 1592 | if (err < 0) |
1688 | return err; | 1593 | return err; |
1689 | } | 1594 | } |
1690 | return 0; | 1595 | return 0; |
@@ -1695,6 +1600,7 @@ static int dev; | |||
1695 | static int __init cs4231_attach_begin(struct snd_card **rcard) | 1600 | static int __init cs4231_attach_begin(struct snd_card **rcard) |
1696 | { | 1601 | { |
1697 | struct snd_card *card; | 1602 | struct snd_card *card; |
1603 | struct snd_cs4231 *chip; | ||
1698 | 1604 | ||
1699 | *rcard = NULL; | 1605 | *rcard = NULL; |
1700 | 1606 | ||
@@ -1706,31 +1612,40 @@ static int __init cs4231_attach_begin(struct snd_card **rcard) | |||
1706 | return -ENOENT; | 1612 | return -ENOENT; |
1707 | } | 1613 | } |
1708 | 1614 | ||
1709 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | 1615 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, |
1616 | sizeof(struct snd_cs4231)); | ||
1710 | if (card == NULL) | 1617 | if (card == NULL) |
1711 | return -ENOMEM; | 1618 | return -ENOMEM; |
1712 | 1619 | ||
1713 | strcpy(card->driver, "CS4231"); | 1620 | strcpy(card->driver, "CS4231"); |
1714 | strcpy(card->shortname, "Sun CS4231"); | 1621 | strcpy(card->shortname, "Sun CS4231"); |
1715 | 1622 | ||
1623 | chip = card->private_data; | ||
1624 | chip->card = card; | ||
1625 | |||
1716 | *rcard = card; | 1626 | *rcard = card; |
1717 | return 0; | 1627 | return 0; |
1718 | } | 1628 | } |
1719 | 1629 | ||
1720 | static int __init cs4231_attach_finish(struct snd_card *card, struct snd_cs4231 *chip) | 1630 | static int __init cs4231_attach_finish(struct snd_card *card) |
1721 | { | 1631 | { |
1632 | struct snd_cs4231 *chip = card->private_data; | ||
1722 | int err; | 1633 | int err; |
1723 | 1634 | ||
1724 | if ((err = snd_cs4231_pcm(chip)) < 0) | 1635 | err = snd_cs4231_pcm(card); |
1636 | if (err < 0) | ||
1725 | goto out_err; | 1637 | goto out_err; |
1726 | 1638 | ||
1727 | if ((err = snd_cs4231_mixer(chip)) < 0) | 1639 | err = snd_cs4231_mixer(card); |
1640 | if (err < 0) | ||
1728 | goto out_err; | 1641 | goto out_err; |
1729 | 1642 | ||
1730 | if ((err = snd_cs4231_timer(chip)) < 0) | 1643 | err = snd_cs4231_timer(card); |
1644 | if (err < 0) | ||
1731 | goto out_err; | 1645 | goto out_err; |
1732 | 1646 | ||
1733 | if ((err = snd_card_register(card)) < 0) | 1647 | err = snd_card_register(card); |
1648 | if (err < 0) | ||
1734 | goto out_err; | 1649 | goto out_err; |
1735 | 1650 | ||
1736 | chip->next = cs4231_list; | 1651 | chip->next = cs4231_list; |
@@ -1754,7 +1669,7 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id) | |||
1754 | struct snd_cs4231 *chip = dev_id; | 1669 | struct snd_cs4231 *chip = dev_id; |
1755 | 1670 | ||
1756 | /*This is IRQ is not raised by the cs4231*/ | 1671 | /*This is IRQ is not raised by the cs4231*/ |
1757 | if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ)) | 1672 | if (!(__cs4231_readb(chip, CS4231U(chip, STATUS)) & CS4231_GLOBALIRQ)) |
1758 | return IRQ_NONE; | 1673 | return IRQ_NONE; |
1759 | 1674 | ||
1760 | /* ACK the APC interrupt. */ | 1675 | /* ACK the APC interrupt. */ |
@@ -1762,24 +1677,24 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id) | |||
1762 | 1677 | ||
1763 | sbus_writel(csr, chip->port + APCCSR); | 1678 | sbus_writel(csr, chip->port + APCCSR); |
1764 | 1679 | ||
1765 | if ((csr & APC_PDMA_READY) && | 1680 | if ((csr & APC_PDMA_READY) && |
1766 | (csr & APC_PLAY_INT) && | 1681 | (csr & APC_PLAY_INT) && |
1767 | (csr & APC_XINT_PNVA) && | 1682 | (csr & APC_XINT_PNVA) && |
1768 | !(csr & APC_XINT_EMPT)) | 1683 | !(csr & APC_XINT_EMPT)) |
1769 | snd_cs4231_play_callback(chip); | 1684 | snd_cs4231_play_callback(chip); |
1770 | 1685 | ||
1771 | if ((csr & APC_CDMA_READY) && | 1686 | if ((csr & APC_CDMA_READY) && |
1772 | (csr & APC_CAPT_INT) && | 1687 | (csr & APC_CAPT_INT) && |
1773 | (csr & APC_XINT_CNVA) && | 1688 | (csr & APC_XINT_CNVA) && |
1774 | !(csr & APC_XINT_EMPT)) | 1689 | !(csr & APC_XINT_EMPT)) |
1775 | snd_cs4231_capture_callback(chip); | 1690 | snd_cs4231_capture_callback(chip); |
1776 | 1691 | ||
1777 | status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); | 1692 | status = snd_cs4231_in(chip, CS4231_IRQ_STATUS); |
1778 | 1693 | ||
1779 | if (status & CS4231_TIMER_IRQ) { | 1694 | if (status & CS4231_TIMER_IRQ) { |
1780 | if (chip->timer) | 1695 | if (chip->timer) |
1781 | snd_timer_interrupt(chip->timer, chip->timer->sticks); | 1696 | snd_timer_interrupt(chip->timer, chip->timer->sticks); |
1782 | } | 1697 | } |
1783 | 1698 | ||
1784 | if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY)) | 1699 | if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY)) |
1785 | snd_cs4231_overrange(chip); | 1700 | snd_cs4231_overrange(chip); |
@@ -1796,26 +1711,27 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id) | |||
1796 | * SBUS DMA routines | 1711 | * SBUS DMA routines |
1797 | */ | 1712 | */ |
1798 | 1713 | ||
1799 | static int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len) | 1714 | static int sbus_dma_request(struct cs4231_dma_control *dma_cont, |
1715 | dma_addr_t bus_addr, size_t len) | ||
1800 | { | 1716 | { |
1801 | unsigned long flags; | 1717 | unsigned long flags; |
1802 | u32 test, csr; | 1718 | u32 test, csr; |
1803 | int err; | 1719 | int err; |
1804 | struct sbus_dma_info *base = &dma_cont->sbus_info; | 1720 | struct sbus_dma_info *base = &dma_cont->sbus_info; |
1805 | 1721 | ||
1806 | if (len >= (1 << 24)) | 1722 | if (len >= (1 << 24)) |
1807 | return -EINVAL; | 1723 | return -EINVAL; |
1808 | spin_lock_irqsave(&base->lock, flags); | 1724 | spin_lock_irqsave(&base->lock, flags); |
1809 | csr = sbus_readl(base->regs + APCCSR); | 1725 | csr = sbus_readl(base->regs + APCCSR); |
1810 | err = -EINVAL; | 1726 | err = -EINVAL; |
1811 | test = APC_CDMA_READY; | 1727 | test = APC_CDMA_READY; |
1812 | if ( base->dir == APC_PLAY ) | 1728 | if (base->dir == APC_PLAY) |
1813 | test = APC_PDMA_READY; | 1729 | test = APC_PDMA_READY; |
1814 | if (!(csr & test)) | 1730 | if (!(csr & test)) |
1815 | goto out; | 1731 | goto out; |
1816 | err = -EBUSY; | 1732 | err = -EBUSY; |
1817 | test = APC_XINT_CNVA; | 1733 | test = APC_XINT_CNVA; |
1818 | if ( base->dir == APC_PLAY ) | 1734 | if (base->dir == APC_PLAY) |
1819 | test = APC_XINT_PNVA; | 1735 | test = APC_XINT_PNVA; |
1820 | if (!(csr & test)) | 1736 | if (!(csr & test)) |
1821 | goto out; | 1737 | goto out; |
@@ -1838,7 +1754,7 @@ static void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d) | |||
1838 | test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA | | 1754 | test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA | |
1839 | APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL | | 1755 | APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL | |
1840 | APC_XINT_PENA; | 1756 | APC_XINT_PENA; |
1841 | if ( base->dir == APC_RECORD ) | 1757 | if (base->dir == APC_RECORD) |
1842 | test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA | | 1758 | test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA | |
1843 | APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL; | 1759 | APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL; |
1844 | csr |= test; | 1760 | csr |= test; |
@@ -1856,28 +1772,28 @@ static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on) | |||
1856 | if (!on) { | 1772 | if (!on) { |
1857 | sbus_writel(0, base->regs + base->dir + APCNC); | 1773 | sbus_writel(0, base->regs + base->dir + APCNC); |
1858 | sbus_writel(0, base->regs + base->dir + APCNVA); | 1774 | sbus_writel(0, base->regs + base->dir + APCNVA); |
1859 | if ( base->dir == APC_PLAY ) { | 1775 | if (base->dir == APC_PLAY) { |
1860 | sbus_writel(0, base->regs + base->dir + APCC); | 1776 | sbus_writel(0, base->regs + base->dir + APCC); |
1861 | sbus_writel(0, base->regs + base->dir + APCVA); | 1777 | sbus_writel(0, base->regs + base->dir + APCVA); |
1862 | } | 1778 | } |
1863 | 1779 | ||
1864 | udelay(1200); | 1780 | udelay(1200); |
1865 | } | 1781 | } |
1866 | csr = sbus_readl(base->regs + APCCSR); | 1782 | csr = sbus_readl(base->regs + APCCSR); |
1867 | shift = 0; | 1783 | shift = 0; |
1868 | if ( base->dir == APC_PLAY ) | 1784 | if (base->dir == APC_PLAY) |
1869 | shift = 1; | 1785 | shift = 1; |
1870 | if (on) | 1786 | if (on) |
1871 | csr &= ~(APC_CPAUSE << shift); | 1787 | csr &= ~(APC_CPAUSE << shift); |
1872 | else | 1788 | else |
1873 | csr |= (APC_CPAUSE << shift); | 1789 | csr |= (APC_CPAUSE << shift); |
1874 | sbus_writel(csr, base->regs + APCCSR); | 1790 | sbus_writel(csr, base->regs + APCCSR); |
1875 | if (on) | 1791 | if (on) |
1876 | csr |= (APC_CDMA_READY << shift); | 1792 | csr |= (APC_CDMA_READY << shift); |
1877 | else | 1793 | else |
1878 | csr &= ~(APC_CDMA_READY << shift); | 1794 | csr &= ~(APC_CDMA_READY << shift); |
1879 | sbus_writel(csr, base->regs + APCCSR); | 1795 | sbus_writel(csr, base->regs + APCCSR); |
1880 | 1796 | ||
1881 | spin_unlock_irqrestore(&base->lock, flags); | 1797 | spin_unlock_irqrestore(&base->lock, flags); |
1882 | } | 1798 | } |
1883 | 1799 | ||
@@ -1885,14 +1801,14 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) | |||
1885 | { | 1801 | { |
1886 | struct sbus_dma_info *base = &dma_cont->sbus_info; | 1802 | struct sbus_dma_info *base = &dma_cont->sbus_info; |
1887 | 1803 | ||
1888 | return sbus_readl(base->regs + base->dir + APCVA); | 1804 | return sbus_readl(base->regs + base->dir + APCVA); |
1889 | } | 1805 | } |
1890 | 1806 | ||
1891 | static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) | 1807 | static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) |
1892 | { | 1808 | { |
1893 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, | 1809 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, |
1894 | snd_dma_sbus_data(chip->dev_u.sdev), | 1810 | snd_dma_sbus_data(chip->dev_u.sdev), |
1895 | 64*1024, 128*1024); | 1811 | 64 * 1024, 128 * 1024); |
1896 | } | 1812 | } |
1897 | 1813 | ||
1898 | /* | 1814 | /* |
@@ -1907,8 +1823,6 @@ static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) | |||
1907 | if (chip->port) | 1823 | if (chip->port) |
1908 | sbus_iounmap(chip->port, chip->regs_size); | 1824 | sbus_iounmap(chip->port, chip->regs_size); |
1909 | 1825 | ||
1910 | kfree(chip); | ||
1911 | |||
1912 | return 0; | 1826 | return 0; |
1913 | } | 1827 | } |
1914 | 1828 | ||
@@ -1925,23 +1839,16 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = { | |||
1925 | 1839 | ||
1926 | static int __init snd_cs4231_sbus_create(struct snd_card *card, | 1840 | static int __init snd_cs4231_sbus_create(struct snd_card *card, |
1927 | struct sbus_dev *sdev, | 1841 | struct sbus_dev *sdev, |
1928 | int dev, | 1842 | int dev) |
1929 | struct snd_cs4231 **rchip) | ||
1930 | { | 1843 | { |
1931 | struct snd_cs4231 *chip; | 1844 | struct snd_cs4231 *chip = card->private_data; |
1932 | int err; | 1845 | int err; |
1933 | 1846 | ||
1934 | *rchip = NULL; | ||
1935 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
1936 | if (chip == NULL) | ||
1937 | return -ENOMEM; | ||
1938 | |||
1939 | spin_lock_init(&chip->lock); | 1847 | spin_lock_init(&chip->lock); |
1940 | spin_lock_init(&chip->c_dma.sbus_info.lock); | 1848 | spin_lock_init(&chip->c_dma.sbus_info.lock); |
1941 | spin_lock_init(&chip->p_dma.sbus_info.lock); | 1849 | spin_lock_init(&chip->p_dma.sbus_info.lock); |
1942 | mutex_init(&chip->mce_mutex); | 1850 | mutex_init(&chip->mce_mutex); |
1943 | mutex_init(&chip->open_mutex); | 1851 | mutex_init(&chip->open_mutex); |
1944 | chip->card = card; | ||
1945 | chip->dev_u.sdev = sdev; | 1852 | chip->dev_u.sdev = sdev; |
1946 | chip->regs_size = sdev->reg_addrs[0].reg_size; | 1853 | chip->regs_size = sdev->reg_addrs[0].reg_size; |
1947 | memcpy(&chip->image, &snd_cs4231_original_image, | 1854 | memcpy(&chip->image, &snd_cs4231_original_image, |
@@ -1992,14 +1899,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, | |||
1992 | return err; | 1899 | return err; |
1993 | } | 1900 | } |
1994 | 1901 | ||
1995 | *rchip = chip; | ||
1996 | return 0; | 1902 | return 0; |
1997 | } | 1903 | } |
1998 | 1904 | ||
1999 | static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | 1905 | static int __init cs4231_sbus_attach(struct sbus_dev *sdev) |
2000 | { | 1906 | { |
2001 | struct resource *rp = &sdev->resource[0]; | 1907 | struct resource *rp = &sdev->resource[0]; |
2002 | struct snd_cs4231 *cp; | ||
2003 | struct snd_card *card; | 1908 | struct snd_card *card; |
2004 | int err; | 1909 | int err; |
2005 | 1910 | ||
@@ -2013,25 +1918,28 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev) | |||
2013 | (unsigned long long)rp->start, | 1918 | (unsigned long long)rp->start, |
2014 | sdev->irqs[0]); | 1919 | sdev->irqs[0]); |
2015 | 1920 | ||
2016 | if ((err = snd_cs4231_sbus_create(card, sdev, dev, &cp)) < 0) { | 1921 | err = snd_cs4231_sbus_create(card, sdev, dev); |
1922 | if (err < 0) { | ||
2017 | snd_card_free(card); | 1923 | snd_card_free(card); |
2018 | return err; | 1924 | return err; |
2019 | } | 1925 | } |
2020 | 1926 | ||
2021 | return cs4231_attach_finish(card, cp); | 1927 | return cs4231_attach_finish(card); |
2022 | } | 1928 | } |
2023 | #endif | 1929 | #endif |
2024 | 1930 | ||
2025 | #ifdef EBUS_SUPPORT | 1931 | #ifdef EBUS_SUPPORT |
2026 | 1932 | ||
2027 | static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie) | 1933 | static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, |
1934 | void *cookie) | ||
2028 | { | 1935 | { |
2029 | struct snd_cs4231 *chip = cookie; | 1936 | struct snd_cs4231 *chip = cookie; |
2030 | 1937 | ||
2031 | snd_cs4231_play_callback(chip); | 1938 | snd_cs4231_play_callback(chip); |
2032 | } | 1939 | } |
2033 | 1940 | ||
2034 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie) | 1941 | static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, |
1942 | int event, void *cookie) | ||
2035 | { | 1943 | { |
2036 | struct snd_cs4231 *chip = cookie; | 1944 | struct snd_cs4231 *chip = cookie; |
2037 | 1945 | ||
@@ -2042,7 +1950,8 @@ static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, | |||
2042 | * EBUS DMA wrappers | 1950 | * EBUS DMA wrappers |
2043 | */ | 1951 | */ |
2044 | 1952 | ||
2045 | static int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len) | 1953 | static int _ebus_dma_request(struct cs4231_dma_control *dma_cont, |
1954 | dma_addr_t bus_addr, size_t len) | ||
2046 | { | 1955 | { |
2047 | return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len); | 1956 | return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len); |
2048 | } | 1957 | } |
@@ -2087,8 +1996,6 @@ static int snd_cs4231_ebus_free(struct snd_cs4231 *chip) | |||
2087 | if (chip->port) | 1996 | if (chip->port) |
2088 | iounmap(chip->port); | 1997 | iounmap(chip->port); |
2089 | 1998 | ||
2090 | kfree(chip); | ||
2091 | |||
2092 | return 0; | 1999 | return 0; |
2093 | } | 2000 | } |
2094 | 2001 | ||
@@ -2105,24 +2012,17 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = { | |||
2105 | 2012 | ||
2106 | static int __init snd_cs4231_ebus_create(struct snd_card *card, | 2013 | static int __init snd_cs4231_ebus_create(struct snd_card *card, |
2107 | struct linux_ebus_device *edev, | 2014 | struct linux_ebus_device *edev, |
2108 | int dev, | 2015 | int dev) |
2109 | struct snd_cs4231 **rchip) | ||
2110 | { | 2016 | { |
2111 | struct snd_cs4231 *chip; | 2017 | struct snd_cs4231 *chip = card->private_data; |
2112 | int err; | 2018 | int err; |
2113 | 2019 | ||
2114 | *rchip = NULL; | ||
2115 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
2116 | if (chip == NULL) | ||
2117 | return -ENOMEM; | ||
2118 | |||
2119 | spin_lock_init(&chip->lock); | 2020 | spin_lock_init(&chip->lock); |
2120 | spin_lock_init(&chip->c_dma.ebus_info.lock); | 2021 | spin_lock_init(&chip->c_dma.ebus_info.lock); |
2121 | spin_lock_init(&chip->p_dma.ebus_info.lock); | 2022 | spin_lock_init(&chip->p_dma.ebus_info.lock); |
2122 | mutex_init(&chip->mce_mutex); | 2023 | mutex_init(&chip->mce_mutex); |
2123 | mutex_init(&chip->open_mutex); | 2024 | mutex_init(&chip->open_mutex); |
2124 | chip->flags |= CS4231_FLAG_EBUS; | 2025 | chip->flags |= CS4231_FLAG_EBUS; |
2125 | chip->card = card; | ||
2126 | chip->dev_u.pdev = edev->bus->self; | 2026 | chip->dev_u.pdev = edev->bus->self; |
2127 | memcpy(&chip->image, &snd_cs4231_original_image, | 2027 | memcpy(&chip->image, &snd_cs4231_original_image, |
2128 | sizeof(snd_cs4231_original_image)); | 2028 | sizeof(snd_cs4231_original_image)); |
@@ -2152,7 +2052,8 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, | |||
2152 | chip->port = ioremap(edev->resource[0].start, 0x10); | 2052 | chip->port = ioremap(edev->resource[0].start, 0x10); |
2153 | chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); | 2053 | chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); |
2154 | chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); | 2054 | chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); |
2155 | if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) { | 2055 | if (!chip->port || !chip->p_dma.ebus_info.regs || |
2056 | !chip->c_dma.ebus_info.regs) { | ||
2156 | snd_cs4231_ebus_free(chip); | 2057 | snd_cs4231_ebus_free(chip); |
2157 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); | 2058 | snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); |
2158 | return -EIO; | 2059 | return -EIO; |
@@ -2160,18 +2061,21 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, | |||
2160 | 2061 | ||
2161 | if (ebus_dma_register(&chip->c_dma.ebus_info)) { | 2062 | if (ebus_dma_register(&chip->c_dma.ebus_info)) { |
2162 | snd_cs4231_ebus_free(chip); | 2063 | snd_cs4231_ebus_free(chip); |
2163 | snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev); | 2064 | snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", |
2065 | dev); | ||
2164 | return -EBUSY; | 2066 | return -EBUSY; |
2165 | } | 2067 | } |
2166 | if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) { | 2068 | if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) { |
2167 | snd_cs4231_ebus_free(chip); | 2069 | snd_cs4231_ebus_free(chip); |
2168 | snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev); | 2070 | snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", |
2071 | dev); | ||
2169 | return -EBUSY; | 2072 | return -EBUSY; |
2170 | } | 2073 | } |
2171 | 2074 | ||
2172 | if (ebus_dma_register(&chip->p_dma.ebus_info)) { | 2075 | if (ebus_dma_register(&chip->p_dma.ebus_info)) { |
2173 | snd_cs4231_ebus_free(chip); | 2076 | snd_cs4231_ebus_free(chip); |
2174 | snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev); | 2077 | snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", |
2078 | dev); | ||
2175 | return -EBUSY; | 2079 | return -EBUSY; |
2176 | } | 2080 | } |
2177 | if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) { | 2081 | if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) { |
@@ -2192,14 +2096,12 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, | |||
2192 | return err; | 2096 | return err; |
2193 | } | 2097 | } |
2194 | 2098 | ||
2195 | *rchip = chip; | ||
2196 | return 0; | 2099 | return 0; |
2197 | } | 2100 | } |
2198 | 2101 | ||
2199 | static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) | 2102 | static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) |
2200 | { | 2103 | { |
2201 | struct snd_card *card; | 2104 | struct snd_card *card; |
2202 | struct snd_cs4231 *chip; | ||
2203 | int err; | 2105 | int err; |
2204 | 2106 | ||
2205 | err = cs4231_attach_begin(&card); | 2107 | err = cs4231_attach_begin(&card); |
@@ -2211,12 +2113,13 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) | |||
2211 | edev->resource[0].start, | 2113 | edev->resource[0].start, |
2212 | edev->irqs[0]); | 2114 | edev->irqs[0]); |
2213 | 2115 | ||
2214 | if ((err = snd_cs4231_ebus_create(card, edev, dev, &chip)) < 0) { | 2116 | err = snd_cs4231_ebus_create(card, edev, dev); |
2117 | if (err < 0) { | ||
2215 | snd_card_free(card); | 2118 | snd_card_free(card); |
2216 | return err; | 2119 | return err; |
2217 | } | 2120 | } |
2218 | 2121 | ||
2219 | return cs4231_attach_finish(card, chip); | 2122 | return cs4231_attach_finish(card); |
2220 | } | 2123 | } |
2221 | #endif | 2124 | #endif |
2222 | 2125 | ||
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index e07085a7cfc3..376b98691c96 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -8,18 +8,18 @@ | |||
8 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) | 8 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) |
9 | * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org) | 9 | * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org) |
10 | * | 10 | * |
11 | * This is the lowlevel driver for the DBRI & MMCODEC duo used for ISDN & AUDIO | 11 | * This is the low level driver for the DBRI & MMCODEC duo used for ISDN & AUDIO |
12 | * on Sun SPARCstation 10, 20, LX and Voyager models. | 12 | * on Sun SPARCStation 10, 20, LX and Voyager models. |
13 | * | 13 | * |
14 | * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel | 14 | * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel |
15 | * data time multiplexer with ISDN support (aka T7259) | 15 | * data time multiplexer with ISDN support (aka T7259) |
16 | * Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel. | 16 | * Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel. |
17 | * CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?). | 17 | * CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?). |
18 | * Documentation: | 18 | * Documentation: |
19 | * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Tranceiver" from | 19 | * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Transceiver" from |
20 | * Sparc Technology Business (courtesy of Sun Support) | 20 | * Sparc Technology Business (courtesy of Sun Support) |
21 | * - Data sheet of the T7903, a newer but very similar ISA bus equivalent | 21 | * - Data sheet of the T7903, a newer but very similar ISA bus equivalent |
22 | * available from the Lucent (formarly AT&T microelectronics) home | 22 | * available from the Lucent (formerly AT&T microelectronics) home |
23 | * page. | 23 | * page. |
24 | * - http://www.freesoft.org/Linux/DBRI/ | 24 | * - http://www.freesoft.org/Linux/DBRI/ |
25 | * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec | 25 | * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec |
@@ -27,21 +27,21 @@ | |||
27 | * Documentation: from the Crystal Semiconductor home page. | 27 | * Documentation: from the Crystal Semiconductor home page. |
28 | * | 28 | * |
29 | * The DBRI is a 32 pipe machine, each pipe can transfer some bits between | 29 | * The DBRI is a 32 pipe machine, each pipe can transfer some bits between |
30 | * memory and a serial device (long pipes, nr 0-15) or between two serial | 30 | * memory and a serial device (long pipes, no. 0-15) or between two serial |
31 | * devices (short pipes, nr 16-31), or simply send a fixed data to a serial | 31 | * devices (short pipes, no. 16-31), or simply send a fixed data to a serial |
32 | * device (short pipes). | 32 | * device (short pipes). |
33 | * A timeslot defines the bit-offset and nr of bits read from a serial device. | 33 | * A timeslot defines the bit-offset and no. of bits read from a serial device. |
34 | * The timeslots are linked to 6 circular lists, one for each direction for | 34 | * The timeslots are linked to 6 circular lists, one for each direction for |
35 | * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes | 35 | * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes |
36 | * (the second one is a monitor/tee pipe, valid only for serial input). | 36 | * (the second one is a monitor/tee pipe, valid only for serial input). |
37 | * | 37 | * |
38 | * The mmcodec is connected via the CHI bus and needs the data & some | 38 | * The mmcodec is connected via the CHI bus and needs the data & some |
39 | * parameters (volume, output selection) timemultiplexed in 8 byte | 39 | * parameters (volume, output selection) time multiplexed in 8 byte |
40 | * chunks. It also has a control mode, which serves for audio format setting. | 40 | * chunks. It also has a control mode, which serves for audio format setting. |
41 | * | 41 | * |
42 | * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on | 42 | * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on |
43 | * the same CHI bus, so I thought perhaps it is possible to use the onboard | 43 | * the same CHI bus, so I thought perhaps it is possible to use the on-board |
44 | * & the speakerbox codec simultanously, giving 2 (not very independent :-) | 44 | * & the speakerbox codec simultaneously, giving 2 (not very independent :-) |
45 | * audio devices. But the SUN HW group decided against it, at least on my | 45 | * audio devices. But the SUN HW group decided against it, at least on my |
46 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly | 46 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly |
47 | * connected. | 47 | * connected. |
@@ -56,6 +56,8 @@ | |||
56 | #include <sound/driver.h> | 56 | #include <sound/driver.h> |
57 | #include <linux/interrupt.h> | 57 | #include <linux/interrupt.h> |
58 | #include <linux/delay.h> | 58 | #include <linux/delay.h> |
59 | #include <linux/irq.h> | ||
60 | #include <linux/io.h> | ||
59 | 61 | ||
60 | #include <sound/core.h> | 62 | #include <sound/core.h> |
61 | #include <sound/pcm.h> | 63 | #include <sound/pcm.h> |
@@ -64,8 +66,7 @@ | |||
64 | #include <sound/control.h> | 66 | #include <sound/control.h> |
65 | #include <sound/initval.h> | 67 | #include <sound/initval.h> |
66 | 68 | ||
67 | #include <asm/irq.h> | 69 | #include <linux/of.h> |
68 | #include <asm/io.h> | ||
69 | #include <asm/sbus.h> | 70 | #include <asm/sbus.h> |
70 | #include <asm/atomic.h> | 71 | #include <asm/atomic.h> |
71 | 72 | ||
@@ -76,7 +77,8 @@ MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}"); | |||
76 | 77 | ||
77 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 78 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
78 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 79 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
79 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 80 | /* Enable this card */ |
81 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
80 | 82 | ||
81 | module_param_array(index, int, NULL, 0444); | 83 | module_param_array(index, int, NULL, 0444); |
82 | MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard."); | 84 | MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard."); |
@@ -104,7 +106,7 @@ static char *cmds[] = { | |||
104 | "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV" | 106 | "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV" |
105 | }; | 107 | }; |
106 | 108 | ||
107 | #define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x) | 109 | #define dprintk(a, x...) if (dbri_debug & a) printk(KERN_DEBUG x) |
108 | 110 | ||
109 | #else | 111 | #else |
110 | #define dprintk(a, x...) do { } while (0) | 112 | #define dprintk(a, x...) do { } while (0) |
@@ -131,7 +133,7 @@ struct cs4215 { | |||
131 | }; | 133 | }; |
132 | 134 | ||
133 | /* | 135 | /* |
134 | * Control mode first | 136 | * Control mode first |
135 | */ | 137 | */ |
136 | 138 | ||
137 | /* Time Slot 1, Status register */ | 139 | /* Time Slot 1, Status register */ |
@@ -219,7 +221,7 @@ static struct { | |||
219 | /* Time Slot 7, Input Setting */ | 221 | /* Time Slot 7, Input Setting */ |
220 | #define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */ | 222 | #define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */ |
221 | #define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */ | 223 | #define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */ |
222 | #define CS4215_OVR (1<<5) /* 1: Overrange condition occurred */ | 224 | #define CS4215_OVR (1<<5) /* 1: Over range condition occurred */ |
223 | #define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */ | 225 | #define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */ |
224 | #define CS4215_PIO1 (1<<7) | 226 | #define CS4215_PIO1 (1<<7) |
225 | 227 | ||
@@ -232,12 +234,12 @@ static struct { | |||
232 | ****************************************************************************/ | 234 | ****************************************************************************/ |
233 | 235 | ||
234 | /* DBRI main registers */ | 236 | /* DBRI main registers */ |
235 | #define REG0 0x00UL /* Status and Control */ | 237 | #define REG0 0x00 /* Status and Control */ |
236 | #define REG1 0x04UL /* Mode and Interrupt */ | 238 | #define REG1 0x04 /* Mode and Interrupt */ |
237 | #define REG2 0x08UL /* Parallel IO */ | 239 | #define REG2 0x08 /* Parallel IO */ |
238 | #define REG3 0x0cUL /* Test */ | 240 | #define REG3 0x0c /* Test */ |
239 | #define REG8 0x20UL /* Command Queue Pointer */ | 241 | #define REG8 0x20 /* Command Queue Pointer */ |
240 | #define REG9 0x24UL /* Interrupt Queue Pointer */ | 242 | #define REG9 0x24 /* Interrupt Queue Pointer */ |
241 | 243 | ||
242 | #define DBRI_NO_CMDS 64 | 244 | #define DBRI_NO_CMDS 64 |
243 | #define DBRI_INT_BLK 64 | 245 | #define DBRI_INT_BLK 64 |
@@ -285,7 +287,7 @@ struct dbri_pipe { | |||
285 | /* Per stream (playback or record) information */ | 287 | /* Per stream (playback or record) information */ |
286 | struct dbri_streaminfo { | 288 | struct dbri_streaminfo { |
287 | struct snd_pcm_substream *substream; | 289 | struct snd_pcm_substream *substream; |
288 | u32 dvma_buffer; /* Device view of Alsa DMA buffer */ | 290 | u32 dvma_buffer; /* Device view of ALSA DMA buffer */ |
289 | int size; /* Size of DMA buffer */ | 291 | int size; /* Size of DMA buffer */ |
290 | size_t offset; /* offset in user buffer */ | 292 | size_t offset; /* offset in user buffer */ |
291 | int pipe; /* Data pipe used */ | 293 | int pipe; /* Data pipe used */ |
@@ -295,8 +297,6 @@ struct dbri_streaminfo { | |||
295 | 297 | ||
296 | /* This structure holds the information for both chips (DBRI & CS4215) */ | 298 | /* This structure holds the information for both chips (DBRI & CS4215) */ |
297 | struct snd_dbri { | 299 | struct snd_dbri { |
298 | struct snd_card *card; /* ALSA card */ | ||
299 | |||
300 | int regs_size, irq; /* Needed for unload */ | 300 | int regs_size, irq; /* Needed for unload */ |
301 | struct sbus_dev *sdev; /* SBUS device info */ | 301 | struct sbus_dev *sdev; /* SBUS device info */ |
302 | spinlock_t lock; | 302 | spinlock_t lock; |
@@ -317,8 +317,6 @@ struct snd_dbri { | |||
317 | struct cs4215 mm; /* mmcodec special info */ | 317 | struct cs4215 mm; /* mmcodec special info */ |
318 | /* per stream (playback/record) info */ | 318 | /* per stream (playback/record) info */ |
319 | struct dbri_streaminfo stream_info[DBRI_NO_STREAMS]; | 319 | struct dbri_streaminfo stream_info[DBRI_NO_STREAMS]; |
320 | |||
321 | struct snd_dbri *next; | ||
322 | }; | 320 | }; |
323 | 321 | ||
324 | #define DBRI_MAX_VOLUME 63 /* Output volume */ | 322 | #define DBRI_MAX_VOLUME 63 /* Output volume */ |
@@ -341,11 +339,11 @@ struct snd_dbri { | |||
341 | /* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */ | 339 | /* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */ |
342 | #define D_LITTLE_END (1<<8) /* Byte Order */ | 340 | #define D_LITTLE_END (1<<8) /* Byte Order */ |
343 | #define D_BIG_END (0<<8) /* Byte Order */ | 341 | #define D_BIG_END (0<<8) /* Byte Order */ |
344 | #define D_MRR (1<<4) /* Multiple Error Ack on SBus (readonly) */ | 342 | #define D_MRR (1<<4) /* Multiple Error Ack on SBus (read only) */ |
345 | #define D_MLE (1<<3) /* Multiple Late Error on SBus (readonly) */ | 343 | #define D_MLE (1<<3) /* Multiple Late Error on SBus (read only) */ |
346 | #define D_LBG (1<<2) /* Lost Bus Grant on SBus (readonly) */ | 344 | #define D_LBG (1<<2) /* Lost Bus Grant on SBus (read only) */ |
347 | #define D_MBE (1<<1) /* Burst Error on SBus (readonly) */ | 345 | #define D_MBE (1<<1) /* Burst Error on SBus (read only) */ |
348 | #define D_IR (1<<0) /* Interrupt Indicator (readonly) */ | 346 | #define D_IR (1<<0) /* Interrupt Indicator (read only) */ |
349 | 347 | ||
350 | /* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */ | 348 | /* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */ |
351 | #define D_ENPIO3 (1<<7) /* Enable Pin 3 */ | 349 | #define D_ENPIO3 (1<<7) /* Enable Pin 3 */ |
@@ -376,11 +374,11 @@ struct snd_dbri { | |||
376 | #define D_CDM 0xe /* CHI Data mode command */ | 374 | #define D_CDM 0xe /* CHI Data mode command */ |
377 | 375 | ||
378 | /* Special bits for some commands */ | 376 | /* Special bits for some commands */ |
379 | #define D_PIPE(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */ | 377 | #define D_PIPE(v) ((v)<<0) /* Pipe No.: 0-15 long, 16-21 short */ |
380 | 378 | ||
381 | /* Setup Data Pipe */ | 379 | /* Setup Data Pipe */ |
382 | /* IRM */ | 380 | /* IRM */ |
383 | #define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value rcvd */ | 381 | #define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value received */ |
384 | #define D_SDP_CHANGE (2<<18) /* Report any changes */ | 382 | #define D_SDP_CHANGE (2<<18) /* Report any changes */ |
385 | #define D_SDP_EVERY (3<<18) /* Report any changes */ | 383 | #define D_SDP_EVERY (3<<18) /* Report any changes */ |
386 | #define D_SDP_EOL (1<<17) /* EOL interrupt enable */ | 384 | #define D_SDP_EOL (1<<17) /* EOL interrupt enable */ |
@@ -419,7 +417,7 @@ struct snd_dbri { | |||
419 | #define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */ | 417 | #define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */ |
420 | #define D_TS_ANCHOR (7<<10) /* Starting short pipes */ | 418 | #define D_TS_ANCHOR (7<<10) /* Starting short pipes */ |
421 | #define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */ | 419 | #define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */ |
422 | #define D_TS_NEXT(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */ | 420 | #define D_TS_NEXT(v) ((v)<<0) /* Pipe no.: 0-15 long, 16-21 short */ |
423 | 421 | ||
424 | /* Concentration Highway Interface Modes */ | 422 | /* Concentration Highway Interface Modes */ |
425 | #define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */ | 423 | #define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */ |
@@ -435,7 +433,7 @@ struct snd_dbri { | |||
435 | #define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */ | 433 | #define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */ |
436 | #define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */ | 434 | #define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */ |
437 | #define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */ | 435 | #define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */ |
438 | #define D_NT_ISNT (1<<13) /* Configfure interface as NT */ | 436 | #define D_NT_ISNT (1<<13) /* Configure interface as NT */ |
439 | #define D_NT_FT (1<<12) /* Fixed Timing */ | 437 | #define D_NT_FT (1<<12) /* Fixed Timing */ |
440 | #define D_NT_EZ (1<<11) /* Echo Channel is Zeros */ | 438 | #define D_NT_EZ (1<<11) /* Echo Channel is Zeros */ |
441 | #define D_NT_IFA (1<<10) /* Inhibit Final Activation */ | 439 | #define D_NT_IFA (1<<10) /* Inhibit Final Activation */ |
@@ -455,7 +453,7 @@ struct snd_dbri { | |||
455 | #define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */ | 453 | #define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */ |
456 | #define D_TEST_SIZE(v) ((v)<<11) /* */ | 454 | #define D_TEST_SIZE(v) ((v)<<11) /* */ |
457 | #define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */ | 455 | #define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */ |
458 | #define D_TEST_PROC 0x6 /* MicroProcessor test */ | 456 | #define D_TEST_PROC 0x6 /* Microprocessor test */ |
459 | #define D_TEST_SER 0x7 /* Serial-Controller test */ | 457 | #define D_TEST_SER 0x7 /* Serial-Controller test */ |
460 | #define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */ | 458 | #define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */ |
461 | #define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */ | 459 | #define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */ |
@@ -464,12 +462,12 @@ struct snd_dbri { | |||
464 | #define D_TEST_DUMP 0xe /* ROM Dump */ | 462 | #define D_TEST_DUMP 0xe /* ROM Dump */ |
465 | 463 | ||
466 | /* CHI Data Mode */ | 464 | /* CHI Data Mode */ |
467 | #define D_CDM_THI (1<<8) /* Transmit Data on CHIDR Pin */ | 465 | #define D_CDM_THI (1 << 8) /* Transmit Data on CHIDR Pin */ |
468 | #define D_CDM_RHI (1<<7) /* Receive Data on CHIDX Pin */ | 466 | #define D_CDM_RHI (1 << 7) /* Receive Data on CHIDX Pin */ |
469 | #define D_CDM_RCE (1<<6) /* Receive on Rising Edge of CHICK */ | 467 | #define D_CDM_RCE (1 << 6) /* Receive on Rising Edge of CHICK */ |
470 | #define D_CDM_XCE (1<<2) /* Transmit Data on Rising Edge of CHICK */ | 468 | #define D_CDM_XCE (1 << 2) /* Transmit Data on Rising Edge of CHICK */ |
471 | #define D_CDM_XEN (1<<1) /* Transmit Highway Enable */ | 469 | #define D_CDM_XEN (1 << 1) /* Transmit Highway Enable */ |
472 | #define D_CDM_REN (1<<0) /* Receive Highway Enable */ | 470 | #define D_CDM_REN (1 << 0) /* Receive Highway Enable */ |
473 | 471 | ||
474 | /* The Interrupts */ | 472 | /* The Interrupts */ |
475 | #define D_INTR_BRDY 1 /* Buffer Ready for processing */ | 473 | #define D_INTR_BRDY 1 /* Buffer Ready for processing */ |
@@ -493,9 +491,9 @@ struct snd_dbri { | |||
493 | #define D_INTR_CHI 36 | 491 | #define D_INTR_CHI 36 |
494 | #define D_INTR_CMD 38 | 492 | #define D_INTR_CMD 38 |
495 | 493 | ||
496 | #define D_INTR_GETCHAN(v) (((v)>>24) & 0x3f) | 494 | #define D_INTR_GETCHAN(v) (((v) >> 24) & 0x3f) |
497 | #define D_INTR_GETCODE(v) (((v)>>20) & 0xf) | 495 | #define D_INTR_GETCODE(v) (((v) >> 20) & 0xf) |
498 | #define D_INTR_GETCMD(v) (((v)>>16) & 0xf) | 496 | #define D_INTR_GETCMD(v) (((v) >> 16) & 0xf) |
499 | #define D_INTR_GETVAL(v) ((v) & 0xffff) | 497 | #define D_INTR_GETVAL(v) ((v) & 0xffff) |
500 | #define D_INTR_GETRVAL(v) ((v) & 0xfffff) | 498 | #define D_INTR_GETRVAL(v) ((v) & 0xfffff) |
501 | 499 | ||
@@ -533,43 +531,42 @@ struct snd_dbri { | |||
533 | #define D_P_31 31 /* */ | 531 | #define D_P_31 31 /* */ |
534 | 532 | ||
535 | /* Transmit descriptor defines */ | 533 | /* Transmit descriptor defines */ |
536 | #define DBRI_TD_F (1<<31) /* End of Frame */ | 534 | #define DBRI_TD_F (1 << 31) /* End of Frame */ |
537 | #define DBRI_TD_D (1<<30) /* Do not append CRC */ | 535 | #define DBRI_TD_D (1 << 30) /* Do not append CRC */ |
538 | #define DBRI_TD_CNT(v) ((v)<<16) /* Number of valid bytes in the buffer */ | 536 | #define DBRI_TD_CNT(v) ((v) << 16) /* Number of valid bytes in the buffer */ |
539 | #define DBRI_TD_B (1<<15) /* Final interrupt */ | 537 | #define DBRI_TD_B (1 << 15) /* Final interrupt */ |
540 | #define DBRI_TD_M (1<<14) /* Marker interrupt */ | 538 | #define DBRI_TD_M (1 << 14) /* Marker interrupt */ |
541 | #define DBRI_TD_I (1<<13) /* Transmit Idle Characters */ | 539 | #define DBRI_TD_I (1 << 13) /* Transmit Idle Characters */ |
542 | #define DBRI_TD_FCNT(v) (v) /* Flag Count */ | 540 | #define DBRI_TD_FCNT(v) (v) /* Flag Count */ |
543 | #define DBRI_TD_UNR (1<<3) /* Underrun: transmitter is out of data */ | 541 | #define DBRI_TD_UNR (1 << 3) /* Underrun: transmitter is out of data */ |
544 | #define DBRI_TD_ABT (1<<2) /* Abort: frame aborted */ | 542 | #define DBRI_TD_ABT (1 << 2) /* Abort: frame aborted */ |
545 | #define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */ | 543 | #define DBRI_TD_TBC (1 << 0) /* Transmit buffer Complete */ |
546 | #define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */ | 544 | #define DBRI_TD_STATUS(v) ((v) & 0xff) /* Transmit status */ |
547 | /* Maximum buffer size per TD: almost 8Kb */ | 545 | /* Maximum buffer size per TD: almost 8KB */ |
548 | #define DBRI_TD_MAXCNT ((1 << 13) - 4) | 546 | #define DBRI_TD_MAXCNT ((1 << 13) - 4) |
549 | 547 | ||
550 | /* Receive descriptor defines */ | 548 | /* Receive descriptor defines */ |
551 | #define DBRI_RD_F (1<<31) /* End of Frame */ | 549 | #define DBRI_RD_F (1 << 31) /* End of Frame */ |
552 | #define DBRI_RD_C (1<<30) /* Completed buffer */ | 550 | #define DBRI_RD_C (1 << 30) /* Completed buffer */ |
553 | #define DBRI_RD_B (1<<15) /* Final interrupt */ | 551 | #define DBRI_RD_B (1 << 15) /* Final interrupt */ |
554 | #define DBRI_RD_M (1<<14) /* Marker interrupt */ | 552 | #define DBRI_RD_M (1 << 14) /* Marker interrupt */ |
555 | #define DBRI_RD_BCNT(v) (v) /* Buffer size */ | 553 | #define DBRI_RD_BCNT(v) (v) /* Buffer size */ |
556 | #define DBRI_RD_CRC (1<<7) /* 0: CRC is correct */ | 554 | #define DBRI_RD_CRC (1 << 7) /* 0: CRC is correct */ |
557 | #define DBRI_RD_BBC (1<<6) /* 1: Bad Byte received */ | 555 | #define DBRI_RD_BBC (1 << 6) /* 1: Bad Byte received */ |
558 | #define DBRI_RD_ABT (1<<5) /* Abort: frame aborted */ | 556 | #define DBRI_RD_ABT (1 << 5) /* Abort: frame aborted */ |
559 | #define DBRI_RD_OVRN (1<<3) /* Overrun: data lost */ | 557 | #define DBRI_RD_OVRN (1 << 3) /* Overrun: data lost */ |
560 | #define DBRI_RD_STATUS(v) ((v)&0xff) /* Receive status */ | 558 | #define DBRI_RD_STATUS(v) ((v) & 0xff) /* Receive status */ |
561 | #define DBRI_RD_CNT(v) (((v)>>16)&0x1fff) /* Valid bytes in the buffer */ | 559 | #define DBRI_RD_CNT(v) (((v) >> 16) & 0x1fff) /* Valid bytes in the buffer */ |
562 | 560 | ||
563 | /* stream_info[] access */ | 561 | /* stream_info[] access */ |
564 | /* Translate the ALSA direction into the array index */ | 562 | /* Translate the ALSA direction into the array index */ |
565 | #define DBRI_STREAMNO(substream) \ | 563 | #define DBRI_STREAMNO(substream) \ |
566 | (substream->stream == \ | 564 | (substream->stream == \ |
567 | SNDRV_PCM_STREAM_PLAYBACK? DBRI_PLAY: DBRI_REC) | 565 | SNDRV_PCM_STREAM_PLAYBACK ? DBRI_PLAY: DBRI_REC) |
568 | 566 | ||
569 | /* Return a pointer to dbri_streaminfo */ | 567 | /* Return a pointer to dbri_streaminfo */ |
570 | #define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)] | 568 | #define DBRI_STREAM(dbri, substream) \ |
571 | 569 | &dbri->stream_info[DBRI_STREAMNO(substream)] | |
572 | static struct snd_dbri *dbri_list; /* All DBRI devices */ | ||
573 | 570 | ||
574 | /* | 571 | /* |
575 | * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. | 572 | * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. |
@@ -609,21 +606,21 @@ The list is terminated with a WAIT command, which generates a | |||
609 | CPU interrupt to signal completion. | 606 | CPU interrupt to signal completion. |
610 | 607 | ||
611 | Since the DBRI can run in parallel with the CPU, several means of | 608 | Since the DBRI can run in parallel with the CPU, several means of |
612 | synchronization present themselves. The method implemented here is only | 609 | synchronization present themselves. The method implemented here uses |
613 | use of the dbri_cmdwait() to wait for execution of batch of sent commands. | 610 | the dbri_cmdwait() to wait for execution of batch of sent commands. |
614 | 611 | ||
615 | A circular command buffer is used here. A new command is being added | 612 | A circular command buffer is used here. A new command is being added |
616 | while another can be executed. The scheme works by adding two WAIT commands | 613 | while another can be executed. The scheme works by adding two WAIT commands |
617 | after each sent batch of commands. When the next batch is prepared it is | 614 | after each sent batch of commands. When the next batch is prepared it is |
618 | added after the WAIT commands then the WAITs are replaced with single JUMP | 615 | added after the WAIT commands then the WAITs are replaced with single JUMP |
619 | command to the new batch. The the DBRI is forced to reread the last WAIT | 616 | command to the new batch. The the DBRI is forced to reread the last WAIT |
620 | command (replaced by the JUMP by then). If the DBRI is still executing | 617 | command (replaced by the JUMP by then). If the DBRI is still executing |
621 | previous commands the request to reread the WAIT command is ignored. | 618 | previous commands the request to reread the WAIT command is ignored. |
622 | 619 | ||
623 | Every time a routine wants to write commands to the DBRI, it must | 620 | Every time a routine wants to write commands to the DBRI, it must |
624 | first call dbri_cmdlock() and get pointer to a free space in | 621 | first call dbri_cmdlock() and get pointer to a free space in |
625 | dbri->dma->cmd buffer. After this, the commands can be written to | 622 | dbri->dma->cmd buffer. After this, the commands can be written to |
626 | the buffer, and dbri_cmdsend() is called with the final pointer value | 623 | the buffer, and dbri_cmdsend() is called with the final pointer value |
627 | to send them to the DBRI. | 624 | to send them to the DBRI. |
628 | 625 | ||
629 | */ | 626 | */ |
@@ -646,18 +643,17 @@ static void dbri_cmdwait(struct snd_dbri *dbri) | |||
646 | } | 643 | } |
647 | spin_unlock_irqrestore(&dbri->lock, flags); | 644 | spin_unlock_irqrestore(&dbri->lock, flags); |
648 | 645 | ||
649 | if (maxloops == 0) { | 646 | if (maxloops == 0) |
650 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); | 647 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); |
651 | } else { | 648 | else |
652 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", | 649 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", |
653 | MAXLOOPS - maxloops - 1); | 650 | MAXLOOPS - maxloops - 1); |
654 | } | ||
655 | } | 651 | } |
656 | /* | 652 | /* |
657 | * Lock the command queue and returns pointer to a space for len cmd words | 653 | * Lock the command queue and return pointer to space for len cmd words |
658 | * It locks the cmdlock spinlock. | 654 | * It locks the cmdlock spinlock. |
659 | */ | 655 | */ |
660 | static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len) | 656 | static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len) |
661 | { | 657 | { |
662 | /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */ | 658 | /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */ |
663 | len += 2; | 659 | len += 2; |
@@ -680,7 +676,7 @@ static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len) | |||
680 | * | 676 | * |
681 | * Lock must be held before calling this. | 677 | * Lock must be held before calling this. |
682 | */ | 678 | */ |
683 | static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) | 679 | static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len) |
684 | { | 680 | { |
685 | s32 tmp, addr; | 681 | s32 tmp, addr; |
686 | static int wait_id = 0; | 682 | static int wait_id = 0; |
@@ -700,16 +696,17 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) | |||
700 | s32 *ptr; | 696 | s32 *ptr; |
701 | 697 | ||
702 | for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) | 698 | for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) |
703 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 699 | dprintk(D_CMD, "cmd: %lx:%08x\n", |
700 | (unsigned long)ptr, *ptr); | ||
704 | } else { | 701 | } else { |
705 | s32 *ptr = dbri->cmdptr; | 702 | s32 *ptr = dbri->cmdptr; |
706 | 703 | ||
707 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 704 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); |
708 | ptr++; | 705 | ptr++; |
709 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 706 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); |
710 | for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) { | 707 | for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) |
711 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | 708 | dprintk(D_CMD, "cmd: %lx:%08x\n", |
712 | } | 709 | (unsigned long)ptr, *ptr); |
713 | } | 710 | } |
714 | #endif | 711 | #endif |
715 | 712 | ||
@@ -723,7 +720,7 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) | |||
723 | } | 720 | } |
724 | 721 | ||
725 | /* Lock must be held when calling this */ | 722 | /* Lock must be held when calling this */ |
726 | static void dbri_reset(struct snd_dbri * dbri) | 723 | static void dbri_reset(struct snd_dbri *dbri) |
727 | { | 724 | { |
728 | int i; | 725 | int i; |
729 | u32 tmp; | 726 | u32 tmp; |
@@ -746,7 +743,7 @@ static void dbri_reset(struct snd_dbri * dbri) | |||
746 | } | 743 | } |
747 | 744 | ||
748 | /* Lock must not be held before calling this */ | 745 | /* Lock must not be held before calling this */ |
749 | static void dbri_initialize(struct snd_dbri * dbri) | 746 | static void __devinit dbri_initialize(struct snd_dbri *dbri) |
750 | { | 747 | { |
751 | s32 *cmd; | 748 | s32 *cmd; |
752 | u32 dma_addr; | 749 | u32 dma_addr; |
@@ -763,7 +760,7 @@ static void dbri_initialize(struct snd_dbri * dbri) | |||
763 | 760 | ||
764 | spin_lock_init(&dbri->cmdlock); | 761 | spin_lock_init(&dbri->cmdlock); |
765 | /* | 762 | /* |
766 | * Initialize the interrupt ringbuffer. | 763 | * Initialize the interrupt ring buffer. |
767 | */ | 764 | */ |
768 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); | 765 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); |
769 | dbri->dma->intr[0] = dma_addr; | 766 | dbri->dma->intr[0] = dma_addr; |
@@ -801,7 +798,7 @@ list ordering, among other things. The transmit and receive functions | |||
801 | here interface closely with the transmit and receive interrupt code. | 798 | here interface closely with the transmit and receive interrupt code. |
802 | 799 | ||
803 | */ | 800 | */ |
804 | static int pipe_active(struct snd_dbri * dbri, int pipe) | 801 | static inline int pipe_active(struct snd_dbri *dbri, int pipe) |
805 | { | 802 | { |
806 | return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); | 803 | return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); |
807 | } | 804 | } |
@@ -811,20 +808,22 @@ static int pipe_active(struct snd_dbri * dbri, int pipe) | |||
811 | * Called on an in-use pipe to clear anything being transmitted or received | 808 | * Called on an in-use pipe to clear anything being transmitted or received |
812 | * Lock must be held before calling this. | 809 | * Lock must be held before calling this. |
813 | */ | 810 | */ |
814 | static void reset_pipe(struct snd_dbri * dbri, int pipe) | 811 | static void reset_pipe(struct snd_dbri *dbri, int pipe) |
815 | { | 812 | { |
816 | int sdp; | 813 | int sdp; |
817 | int desc; | 814 | int desc; |
818 | s32 *cmd; | 815 | s32 *cmd; |
819 | 816 | ||
820 | if (pipe < 0 || pipe > DBRI_MAX_PIPE) { | 817 | if (pipe < 0 || pipe > DBRI_MAX_PIPE) { |
821 | printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n"); | 818 | printk(KERN_ERR "DBRI: reset_pipe called with " |
819 | "illegal pipe number\n"); | ||
822 | return; | 820 | return; |
823 | } | 821 | } |
824 | 822 | ||
825 | sdp = dbri->pipes[pipe].sdp; | 823 | sdp = dbri->pipes[pipe].sdp; |
826 | if (sdp == 0) { | 824 | if (sdp == 0) { |
827 | printk(KERN_ERR "DBRI: reset_pipe called on uninitialized pipe\n"); | 825 | printk(KERN_ERR "DBRI: reset_pipe called " |
826 | "on uninitialized pipe\n"); | ||
828 | return; | 827 | return; |
829 | } | 828 | } |
830 | 829 | ||
@@ -835,9 +834,10 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe) | |||
835 | dbri_cmdsend(dbri, cmd, 3); | 834 | dbri_cmdsend(dbri, cmd, 3); |
836 | 835 | ||
837 | desc = dbri->pipes[pipe].first_desc; | 836 | desc = dbri->pipes[pipe].first_desc; |
838 | if ( desc >= 0) | 837 | if (desc >= 0) |
839 | do { | 838 | do { |
840 | dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; | 839 | dbri->dma->desc[desc].ba = 0; |
840 | dbri->dma->desc[desc].nda = 0; | ||
841 | desc = dbri->next_desc[desc]; | 841 | desc = dbri->next_desc[desc]; |
842 | } while (desc != -1 && desc != dbri->pipes[pipe].first_desc); | 842 | } while (desc != -1 && desc != dbri->pipes[pipe].first_desc); |
843 | 843 | ||
@@ -848,15 +848,17 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe) | |||
848 | /* | 848 | /* |
849 | * Lock must be held before calling this. | 849 | * Lock must be held before calling this. |
850 | */ | 850 | */ |
851 | static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp) | 851 | static void setup_pipe(struct snd_dbri *dbri, int pipe, int sdp) |
852 | { | 852 | { |
853 | if (pipe < 0 || pipe > DBRI_MAX_PIPE) { | 853 | if (pipe < 0 || pipe > DBRI_MAX_PIPE) { |
854 | printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n"); | 854 | printk(KERN_ERR "DBRI: setup_pipe called " |
855 | "with illegal pipe number\n"); | ||
855 | return; | 856 | return; |
856 | } | 857 | } |
857 | 858 | ||
858 | if ((sdp & 0xf800) != sdp) { | 859 | if ((sdp & 0xf800) != sdp) { |
859 | printk(KERN_ERR "DBRI: setup_pipe called with strange SDP value\n"); | 860 | printk(KERN_ERR "DBRI: setup_pipe called " |
861 | "with strange SDP value\n"); | ||
860 | /* sdp &= 0xf800; */ | 862 | /* sdp &= 0xf800; */ |
861 | } | 863 | } |
862 | 864 | ||
@@ -877,25 +879,26 @@ static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp) | |||
877 | /* | 879 | /* |
878 | * Lock must be held before calling this. | 880 | * Lock must be held before calling this. |
879 | */ | 881 | */ |
880 | static void link_time_slot(struct snd_dbri * dbri, int pipe, | 882 | static void link_time_slot(struct snd_dbri *dbri, int pipe, |
881 | int prevpipe, int nextpipe, | 883 | int prevpipe, int nextpipe, |
882 | int length, int cycle) | 884 | int length, int cycle) |
883 | { | 885 | { |
884 | s32 *cmd; | 886 | s32 *cmd; |
885 | int val; | 887 | int val; |
886 | 888 | ||
887 | if (pipe < 0 || pipe > DBRI_MAX_PIPE | 889 | if (pipe < 0 || pipe > DBRI_MAX_PIPE |
888 | || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE | 890 | || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE |
889 | || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) { | 891 | || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) { |
890 | printk(KERN_ERR | 892 | printk(KERN_ERR |
891 | "DBRI: link_time_slot called with illegal pipe number\n"); | 893 | "DBRI: link_time_slot called with illegal pipe number\n"); |
892 | return; | 894 | return; |
893 | } | 895 | } |
894 | 896 | ||
895 | if (dbri->pipes[pipe].sdp == 0 | 897 | if (dbri->pipes[pipe].sdp == 0 |
896 | || dbri->pipes[prevpipe].sdp == 0 | 898 | || dbri->pipes[prevpipe].sdp == 0 |
897 | || dbri->pipes[nextpipe].sdp == 0) { | 899 | || dbri->pipes[nextpipe].sdp == 0) { |
898 | printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n"); | 900 | printk(KERN_ERR "DBRI: link_time_slot called " |
901 | "on uninitialized pipe\n"); | ||
899 | return; | 902 | return; |
900 | } | 903 | } |
901 | 904 | ||
@@ -935,17 +938,17 @@ static void link_time_slot(struct snd_dbri * dbri, int pipe, | |||
935 | /* | 938 | /* |
936 | * Lock must be held before calling this. | 939 | * Lock must be held before calling this. |
937 | */ | 940 | */ |
938 | static void unlink_time_slot(struct snd_dbri * dbri, int pipe, | 941 | static void unlink_time_slot(struct snd_dbri *dbri, int pipe, |
939 | enum in_or_out direction, int prevpipe, | 942 | enum in_or_out direction, int prevpipe, |
940 | int nextpipe) | 943 | int nextpipe) |
941 | { | 944 | { |
942 | s32 *cmd; | 945 | s32 *cmd; |
943 | int val; | 946 | int val; |
944 | 947 | ||
945 | if (pipe < 0 || pipe > DBRI_MAX_PIPE | 948 | if (pipe < 0 || pipe > DBRI_MAX_PIPE |
946 | || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE | 949 | || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE |
947 | || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) { | 950 | || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) { |
948 | printk(KERN_ERR | 951 | printk(KERN_ERR |
949 | "DBRI: unlink_time_slot called with illegal pipe number\n"); | 952 | "DBRI: unlink_time_slot called with illegal pipe number\n"); |
950 | return; | 953 | return; |
951 | } | 954 | } |
@@ -985,7 +988,7 @@ static void unlink_time_slot(struct snd_dbri * dbri, int pipe, | |||
985 | * | 988 | * |
986 | * Lock must not be held before calling it. | 989 | * Lock must not be held before calling it. |
987 | */ | 990 | */ |
988 | static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) | 991 | static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data) |
989 | { | 992 | { |
990 | s32 *cmd; | 993 | s32 *cmd; |
991 | unsigned long flags; | 994 | unsigned long flags; |
@@ -996,7 +999,8 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) | |||
996 | } | 999 | } |
997 | 1000 | ||
998 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { | 1001 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { |
999 | printk(KERN_ERR "DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); | 1002 | printk(KERN_ERR "DBRI: xmit_fixed: " |
1003 | "Uninitialized pipe %d\n", pipe); | ||
1000 | return; | 1004 | return; |
1001 | } | 1005 | } |
1002 | 1006 | ||
@@ -1006,7 +1010,8 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) | |||
1006 | } | 1010 | } |
1007 | 1011 | ||
1008 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { | 1012 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { |
1009 | printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); | 1013 | printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", |
1014 | pipe); | ||
1010 | return; | 1015 | return; |
1011 | } | 1016 | } |
1012 | 1017 | ||
@@ -1028,20 +1033,23 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data) | |||
1028 | 1033 | ||
1029 | } | 1034 | } |
1030 | 1035 | ||
1031 | static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr) | 1036 | static void recv_fixed(struct snd_dbri *dbri, int pipe, volatile __u32 *ptr) |
1032 | { | 1037 | { |
1033 | if (pipe < 16 || pipe > DBRI_MAX_PIPE) { | 1038 | if (pipe < 16 || pipe > DBRI_MAX_PIPE) { |
1034 | printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n"); | 1039 | printk(KERN_ERR "DBRI: recv_fixed called with " |
1040 | "illegal pipe number\n"); | ||
1035 | return; | 1041 | return; |
1036 | } | 1042 | } |
1037 | 1043 | ||
1038 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | 1044 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { |
1039 | printk(KERN_ERR "DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); | 1045 | printk(KERN_ERR "DBRI: recv_fixed called on " |
1046 | "non-fixed pipe %d\n", pipe); | ||
1040 | return; | 1047 | return; |
1041 | } | 1048 | } |
1042 | 1049 | ||
1043 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { | 1050 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { |
1044 | printk(KERN_ERR "DBRI: recv_fixed called on transmit pipe %d\n", pipe); | 1051 | printk(KERN_ERR "DBRI: recv_fixed called on " |
1052 | "transmit pipe %d\n", pipe); | ||
1045 | return; | 1053 | return; |
1046 | } | 1054 | } |
1047 | 1055 | ||
@@ -1064,7 +1072,7 @@ static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr) | |||
1064 | * | 1072 | * |
1065 | * Lock must be held before calling this. | 1073 | * Lock must be held before calling this. |
1066 | */ | 1074 | */ |
1067 | static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period) | 1075 | static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period) |
1068 | { | 1076 | { |
1069 | struct dbri_streaminfo *info = &dbri->stream_info[streamno]; | 1077 | struct dbri_streaminfo *info = &dbri->stream_info[streamno]; |
1070 | __u32 dvma_buffer; | 1078 | __u32 dvma_buffer; |
@@ -1089,21 +1097,23 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1089 | 1097 | ||
1090 | if (streamno == DBRI_PLAY) { | 1098 | if (streamno == DBRI_PLAY) { |
1091 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { | 1099 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { |
1092 | printk(KERN_ERR "DBRI: setup_descs: Called on receive pipe %d\n", | 1100 | printk(KERN_ERR "DBRI: setup_descs: " |
1093 | info->pipe); | 1101 | "Called on receive pipe %d\n", info->pipe); |
1094 | return -2; | 1102 | return -2; |
1095 | } | 1103 | } |
1096 | } else { | 1104 | } else { |
1097 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { | 1105 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { |
1098 | printk(KERN_ERR | 1106 | printk(KERN_ERR |
1099 | "DBRI: setup_descs: Called on transmit pipe %d\n", | 1107 | "DBRI: setup_descs: Called on transmit pipe %d\n", |
1100 | info->pipe); | 1108 | info->pipe); |
1101 | return -2; | 1109 | return -2; |
1102 | } | 1110 | } |
1103 | /* Should be able to queue multiple buffers to receive on a pipe */ | 1111 | /* Should be able to queue multiple buffers |
1112 | * to receive on a pipe | ||
1113 | */ | ||
1104 | if (pipe_active(dbri, info->pipe)) { | 1114 | if (pipe_active(dbri, info->pipe)) { |
1105 | printk(KERN_ERR "DBRI: recv_on_pipe: Called on active pipe %d\n", | 1115 | printk(KERN_ERR "DBRI: recv_on_pipe: " |
1106 | info->pipe); | 1116 | "Called on active pipe %d\n", info->pipe); |
1107 | return -2; | 1117 | return -2; |
1108 | } | 1118 | } |
1109 | 1119 | ||
@@ -1113,11 +1123,13 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1113 | 1123 | ||
1114 | /* Free descriptors if pipe has any */ | 1124 | /* Free descriptors if pipe has any */ |
1115 | desc = dbri->pipes[info->pipe].first_desc; | 1125 | desc = dbri->pipes[info->pipe].first_desc; |
1116 | if ( desc >= 0) | 1126 | if (desc >= 0) |
1117 | do { | 1127 | do { |
1118 | dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; | 1128 | dbri->dma->desc[desc].ba = 0; |
1129 | dbri->dma->desc[desc].nda = 0; | ||
1119 | desc = dbri->next_desc[desc]; | 1130 | desc = dbri->next_desc[desc]; |
1120 | } while (desc != -1 && desc != dbri->pipes[info->pipe].first_desc); | 1131 | } while (desc != -1 && |
1132 | desc != dbri->pipes[info->pipe].first_desc); | ||
1121 | 1133 | ||
1122 | dbri->pipes[info->pipe].desc = -1; | 1134 | dbri->pipes[info->pipe].desc = -1; |
1123 | dbri->pipes[info->pipe].first_desc = -1; | 1135 | dbri->pipes[info->pipe].first_desc = -1; |
@@ -1130,6 +1142,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1130 | if (!dbri->dma->desc[desc].ba) | 1142 | if (!dbri->dma->desc[desc].ba) |
1131 | break; | 1143 | break; |
1132 | } | 1144 | } |
1145 | |||
1133 | if (desc == DBRI_NO_DESCS) { | 1146 | if (desc == DBRI_NO_DESCS) { |
1134 | printk(KERN_ERR "DBRI: setup_descs: No descriptors\n"); | 1147 | printk(KERN_ERR "DBRI: setup_descs: No descriptors\n"); |
1135 | return -1; | 1148 | return -1; |
@@ -1150,8 +1163,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1150 | if (streamno == DBRI_PLAY) { | 1163 | if (streamno == DBRI_PLAY) { |
1151 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); | 1164 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); |
1152 | dbri->dma->desc[desc].word4 = 0; | 1165 | dbri->dma->desc[desc].word4 = 0; |
1153 | dbri->dma->desc[desc].word1 |= | 1166 | dbri->dma->desc[desc].word1 |= DBRI_TD_F | DBRI_TD_B; |
1154 | DBRI_TD_F | DBRI_TD_B; | ||
1155 | } else { | 1167 | } else { |
1156 | dbri->dma->desc[desc].word1 = 0; | 1168 | dbri->dma->desc[desc].word1 = 0; |
1157 | dbri->dma->desc[desc].word4 = | 1169 | dbri->dma->desc[desc].word4 = |
@@ -1172,7 +1184,8 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1172 | } | 1184 | } |
1173 | 1185 | ||
1174 | if (first_desc == -1 || last_desc == -1) { | 1186 | if (first_desc == -1 || last_desc == -1) { |
1175 | printk(KERN_ERR "DBRI: setup_descs: Not enough descriptors available\n"); | 1187 | printk(KERN_ERR "DBRI: setup_descs: " |
1188 | " Not enough descriptors available\n"); | ||
1176 | return -1; | 1189 | return -1; |
1177 | } | 1190 | } |
1178 | 1191 | ||
@@ -1183,14 +1196,14 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1183 | dbri->pipes[info->pipe].desc = first_desc; | 1196 | dbri->pipes[info->pipe].desc = first_desc; |
1184 | 1197 | ||
1185 | #ifdef DBRI_DEBUG | 1198 | #ifdef DBRI_DEBUG |
1186 | for (desc = first_desc; desc != -1; ) { | 1199 | for (desc = first_desc; desc != -1;) { |
1187 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", | 1200 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", |
1188 | desc, | 1201 | desc, |
1189 | dbri->dma->desc[desc].word1, | 1202 | dbri->dma->desc[desc].word1, |
1190 | dbri->dma->desc[desc].ba, | 1203 | dbri->dma->desc[desc].ba, |
1191 | dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); | 1204 | dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); |
1192 | desc = dbri->next_desc[desc]; | 1205 | desc = dbri->next_desc[desc]; |
1193 | if ( desc == first_desc ) | 1206 | if (desc == first_desc) |
1194 | break; | 1207 | break; |
1195 | } | 1208 | } |
1196 | #endif | 1209 | #endif |
@@ -1213,7 +1226,8 @@ enum master_or_slave { CHImaster, CHIslave }; | |||
1213 | /* | 1226 | /* |
1214 | * Lock must not be held before calling it. | 1227 | * Lock must not be held before calling it. |
1215 | */ | 1228 | */ |
1216 | static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave, | 1229 | static void reset_chi(struct snd_dbri *dbri, |
1230 | enum master_or_slave master_or_slave, | ||
1217 | int bits_per_frame) | 1231 | int bits_per_frame) |
1218 | { | 1232 | { |
1219 | s32 *cmd; | 1233 | s32 *cmd; |
@@ -1222,7 +1236,7 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla | |||
1222 | /* Set CHI Anchor: Pipe 16 */ | 1236 | /* Set CHI Anchor: Pipe 16 */ |
1223 | 1237 | ||
1224 | cmd = dbri_cmdlock(dbri, 4); | 1238 | cmd = dbri_cmdlock(dbri, 4); |
1225 | val = D_DTS_VO | D_DTS_VI | D_DTS_INS | 1239 | val = D_DTS_VO | D_DTS_VI | D_DTS_INS |
1226 | | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16); | 1240 | | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16); |
1227 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | 1241 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); |
1228 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); | 1242 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); |
@@ -1246,15 +1260,16 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla | |||
1246 | } else { | 1260 | } else { |
1247 | /* Setup DBRI for CHI Master - generate clock, FS | 1261 | /* Setup DBRI for CHI Master - generate clock, FS |
1248 | * | 1262 | * |
1249 | * BPF = bits per 8 kHz frame | 1263 | * BPF = bits per 8 kHz frame |
1250 | * 12.288 MHz / CHICM_divisor = clock rate | 1264 | * 12.288 MHz / CHICM_divisor = clock rate |
1251 | * FD = 1 - drive CHIFS on rising edge of CHICK | 1265 | * FD = 1 - drive CHIFS on rising edge of CHICK |
1252 | */ | 1266 | */ |
1253 | int clockrate = bits_per_frame * 8; | 1267 | int clockrate = bits_per_frame * 8; |
1254 | int divisor = 12288 / clockrate; | 1268 | int divisor = 12288 / clockrate; |
1255 | 1269 | ||
1256 | if (divisor > 255 || divisor * clockrate != 12288) | 1270 | if (divisor > 255 || divisor * clockrate != 12288) |
1257 | printk(KERN_ERR "DBRI: illegal bits_per_frame in setup_chi\n"); | 1271 | printk(KERN_ERR "DBRI: illegal bits_per_frame " |
1272 | "in setup_chi\n"); | ||
1258 | 1273 | ||
1259 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD | 1274 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD |
1260 | | D_CHI_BPF(bits_per_frame)); | 1275 | | D_CHI_BPF(bits_per_frame)); |
@@ -1288,7 +1303,7 @@ to the DBRI via the CHI interface and few of the DBRI's PIO pins. | |||
1288 | * Lock must not be held before calling it. | 1303 | * Lock must not be held before calling it. |
1289 | 1304 | ||
1290 | */ | 1305 | */ |
1291 | static void cs4215_setup_pipes(struct snd_dbri * dbri) | 1306 | static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri) |
1292 | { | 1307 | { |
1293 | unsigned long flags; | 1308 | unsigned long flags; |
1294 | 1309 | ||
@@ -1303,9 +1318,9 @@ static void cs4215_setup_pipes(struct snd_dbri * dbri) | |||
1303 | * not relevant for us (only for doublechecking). | 1318 | * not relevant for us (only for doublechecking). |
1304 | * | 1319 | * |
1305 | * Control mode: | 1320 | * Control mode: |
1306 | * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly) | 1321 | * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only) |
1307 | * Pipe 18: Receive timeslot 1 (clb). | 1322 | * Pipe 18: Receive timeslot 1 (clb). |
1308 | * Pipe 19: Receive timeslot 7 (version). | 1323 | * Pipe 19: Receive timeslot 7 (version). |
1309 | */ | 1324 | */ |
1310 | 1325 | ||
1311 | setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB); | 1326 | setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB); |
@@ -1321,7 +1336,7 @@ static void cs4215_setup_pipes(struct snd_dbri * dbri) | |||
1321 | dbri_cmdwait(dbri); | 1336 | dbri_cmdwait(dbri); |
1322 | } | 1337 | } |
1323 | 1338 | ||
1324 | static int cs4215_init_data(struct cs4215 *mm) | 1339 | static __devinit int cs4215_init_data(struct cs4215 *mm) |
1325 | { | 1340 | { |
1326 | /* | 1341 | /* |
1327 | * No action, memory resetting only. | 1342 | * No action, memory resetting only. |
@@ -1355,7 +1370,7 @@ static int cs4215_init_data(struct cs4215 *mm) | |||
1355 | return 0; | 1370 | return 0; |
1356 | } | 1371 | } |
1357 | 1372 | ||
1358 | static void cs4215_setdata(struct snd_dbri * dbri, int muted) | 1373 | static void cs4215_setdata(struct snd_dbri *dbri, int muted) |
1359 | { | 1374 | { |
1360 | if (muted) { | 1375 | if (muted) { |
1361 | dbri->mm.data[0] |= 63; | 1376 | dbri->mm.data[0] |= 63; |
@@ -1387,7 +1402,7 @@ static void cs4215_setdata(struct snd_dbri * dbri, int muted) | |||
1387 | /* | 1402 | /* |
1388 | * Set the CS4215 to data mode. | 1403 | * Set the CS4215 to data mode. |
1389 | */ | 1404 | */ |
1390 | static void cs4215_open(struct snd_dbri * dbri) | 1405 | static void cs4215_open(struct snd_dbri *dbri) |
1391 | { | 1406 | { |
1392 | int data_width; | 1407 | int data_width; |
1393 | u32 tmp; | 1408 | u32 tmp; |
@@ -1452,7 +1467,7 @@ static void cs4215_open(struct snd_dbri * dbri) | |||
1452 | /* | 1467 | /* |
1453 | * Send the control information (i.e. audio format) | 1468 | * Send the control information (i.e. audio format) |
1454 | */ | 1469 | */ |
1455 | static int cs4215_setctrl(struct snd_dbri * dbri) | 1470 | static int cs4215_setctrl(struct snd_dbri *dbri) |
1456 | { | 1471 | { |
1457 | int i, val; | 1472 | int i, val; |
1458 | u32 tmp; | 1473 | u32 tmp; |
@@ -1502,9 +1517,9 @@ static int cs4215_setctrl(struct snd_dbri * dbri) | |||
1502 | 1517 | ||
1503 | /* | 1518 | /* |
1504 | * Control mode: | 1519 | * Control mode: |
1505 | * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly) | 1520 | * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only) |
1506 | * Pipe 18: Receive timeslot 1 (clb). | 1521 | * Pipe 18: Receive timeslot 1 (clb). |
1507 | * Pipe 19: Receive timeslot 7 (version). | 1522 | * Pipe 19: Receive timeslot 7 (version). |
1508 | */ | 1523 | */ |
1509 | 1524 | ||
1510 | link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset); | 1525 | link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset); |
@@ -1522,9 +1537,9 @@ static int cs4215_setctrl(struct snd_dbri * dbri) | |||
1522 | sbus_writel(tmp, dbri->regs + REG0); | 1537 | sbus_writel(tmp, dbri->regs + REG0); |
1523 | spin_unlock_irqrestore(&dbri->lock, flags); | 1538 | spin_unlock_irqrestore(&dbri->lock, flags); |
1524 | 1539 | ||
1525 | for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) { | 1540 | for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) |
1526 | msleep_interruptible(1); | 1541 | msleep_interruptible(1); |
1527 | } | 1542 | |
1528 | if (i == 0) { | 1543 | if (i == 0) { |
1529 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", | 1544 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", |
1530 | dbri->mm.status); | 1545 | dbri->mm.status); |
@@ -1556,7 +1571,7 @@ static int cs4215_setctrl(struct snd_dbri * dbri) | |||
1556 | * As part of the process we resend the settings for the data | 1571 | * As part of the process we resend the settings for the data |
1557 | * timeslots as well. | 1572 | * timeslots as well. |
1558 | */ | 1573 | */ |
1559 | static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate, | 1574 | static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate, |
1560 | snd_pcm_format_t format, unsigned int channels) | 1575 | snd_pcm_format_t format, unsigned int channels) |
1561 | { | 1576 | { |
1562 | int freq_idx; | 1577 | int freq_idx; |
@@ -1613,7 +1628,7 @@ static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate, | |||
1613 | /* | 1628 | /* |
1614 | * | 1629 | * |
1615 | */ | 1630 | */ |
1616 | static int cs4215_init(struct snd_dbri * dbri) | 1631 | static __devinit int cs4215_init(struct snd_dbri *dbri) |
1617 | { | 1632 | { |
1618 | u32 reg2 = sbus_readl(dbri->regs + REG2); | 1633 | u32 reg2 = sbus_readl(dbri->regs + REG2); |
1619 | dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); | 1634 | dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); |
@@ -1674,7 +1689,7 @@ interrupts are disabled. | |||
1674 | 1689 | ||
1675 | /* xmit_descs() | 1690 | /* xmit_descs() |
1676 | * | 1691 | * |
1677 | * Starts transmiting the current TD's for recording/playing. | 1692 | * Starts transmitting the current TD's for recording/playing. |
1678 | * For playback, ALSA has filled the DMA memory with new data (we hope). | 1693 | * For playback, ALSA has filled the DMA memory with new data (we hope). |
1679 | */ | 1694 | */ |
1680 | static void xmit_descs(struct snd_dbri *dbri) | 1695 | static void xmit_descs(struct snd_dbri *dbri) |
@@ -1701,7 +1716,8 @@ static void xmit_descs(struct snd_dbri *dbri) | |||
1701 | *(cmd++) = DBRI_CMD(D_SDP, 0, | 1716 | *(cmd++) = DBRI_CMD(D_SDP, 0, |
1702 | dbri->pipes[info->pipe].sdp | 1717 | dbri->pipes[info->pipe].sdp |
1703 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | 1718 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); |
1704 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); | 1719 | *(cmd++) = dbri->dma_dvma + |
1720 | dbri_dma_off(desc, first_td); | ||
1705 | dbri_cmdsend(dbri, cmd, 2); | 1721 | dbri_cmdsend(dbri, cmd, 2); |
1706 | 1722 | ||
1707 | /* Reset our admin of the pipe. */ | 1723 | /* Reset our admin of the pipe. */ |
@@ -1722,7 +1738,8 @@ static void xmit_descs(struct snd_dbri *dbri) | |||
1722 | *(cmd++) = DBRI_CMD(D_SDP, 0, | 1738 | *(cmd++) = DBRI_CMD(D_SDP, 0, |
1723 | dbri->pipes[info->pipe].sdp | 1739 | dbri->pipes[info->pipe].sdp |
1724 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | 1740 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); |
1725 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); | 1741 | *(cmd++) = dbri->dma_dvma + |
1742 | dbri_dma_off(desc, first_td); | ||
1726 | dbri_cmdsend(dbri, cmd, 2); | 1743 | dbri_cmdsend(dbri, cmd, 2); |
1727 | 1744 | ||
1728 | /* Reset our admin of the pipe. */ | 1745 | /* Reset our admin of the pipe. */ |
@@ -1747,15 +1764,12 @@ static void xmit_descs(struct snd_dbri *dbri) | |||
1747 | * | 1764 | * |
1748 | */ | 1765 | */ |
1749 | 1766 | ||
1750 | static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | 1767 | static void transmission_complete_intr(struct snd_dbri *dbri, int pipe) |
1751 | { | 1768 | { |
1752 | struct dbri_streaminfo *info; | 1769 | struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY]; |
1753 | int td; | 1770 | int td = dbri->pipes[pipe].desc; |
1754 | int status; | 1771 | int status; |
1755 | 1772 | ||
1756 | info = &dbri->stream_info[DBRI_PLAY]; | ||
1757 | |||
1758 | td = dbri->pipes[pipe].desc; | ||
1759 | while (td >= 0) { | 1773 | while (td >= 0) { |
1760 | if (td >= DBRI_NO_DESCS) { | 1774 | if (td >= DBRI_NO_DESCS) { |
1761 | printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe); | 1775 | printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe); |
@@ -1763,9 +1777,8 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1763 | } | 1777 | } |
1764 | 1778 | ||
1765 | status = DBRI_TD_STATUS(dbri->dma->desc[td].word4); | 1779 | status = DBRI_TD_STATUS(dbri->dma->desc[td].word4); |
1766 | if (!(status & DBRI_TD_TBC)) { | 1780 | if (!(status & DBRI_TD_TBC)) |
1767 | break; | 1781 | break; |
1768 | } | ||
1769 | 1782 | ||
1770 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); | 1783 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); |
1771 | 1784 | ||
@@ -1777,15 +1790,12 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1777 | } | 1790 | } |
1778 | 1791 | ||
1779 | /* Notify ALSA */ | 1792 | /* Notify ALSA */ |
1780 | if (spin_is_locked(&dbri->lock)) { | 1793 | spin_unlock(&dbri->lock); |
1781 | spin_unlock(&dbri->lock); | 1794 | snd_pcm_period_elapsed(info->substream); |
1782 | snd_pcm_period_elapsed(info->substream); | 1795 | spin_lock(&dbri->lock); |
1783 | spin_lock(&dbri->lock); | ||
1784 | } else | ||
1785 | snd_pcm_period_elapsed(info->substream); | ||
1786 | } | 1796 | } |
1787 | 1797 | ||
1788 | static void reception_complete_intr(struct snd_dbri * dbri, int pipe) | 1798 | static void reception_complete_intr(struct snd_dbri *dbri, int pipe) |
1789 | { | 1799 | { |
1790 | struct dbri_streaminfo *info; | 1800 | struct dbri_streaminfo *info; |
1791 | int rd = dbri->pipes[pipe].desc; | 1801 | int rd = dbri->pipes[pipe].desc; |
@@ -1809,15 +1819,12 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1809 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); | 1819 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); |
1810 | 1820 | ||
1811 | /* Notify ALSA */ | 1821 | /* Notify ALSA */ |
1812 | if (spin_is_locked(&dbri->lock)) { | 1822 | spin_unlock(&dbri->lock); |
1813 | spin_unlock(&dbri->lock); | 1823 | snd_pcm_period_elapsed(info->substream); |
1814 | snd_pcm_period_elapsed(info->substream); | 1824 | spin_lock(&dbri->lock); |
1815 | spin_lock(&dbri->lock); | ||
1816 | } else | ||
1817 | snd_pcm_period_elapsed(info->substream); | ||
1818 | } | 1825 | } |
1819 | 1826 | ||
1820 | static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x) | 1827 | static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x) |
1821 | { | 1828 | { |
1822 | int val = D_INTR_GETVAL(x); | 1829 | int val = D_INTR_GETVAL(x); |
1823 | int channel = D_INTR_GETCHAN(x); | 1830 | int channel = D_INTR_GETCHAN(x); |
@@ -1889,7 +1896,7 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x) | |||
1889 | * right now). Non-zero words require processing and are handed off | 1896 | * right now). Non-zero words require processing and are handed off |
1890 | * to dbri_process_one_interrupt AFTER advancing the pointer. | 1897 | * to dbri_process_one_interrupt AFTER advancing the pointer. |
1891 | */ | 1898 | */ |
1892 | static void dbri_process_interrupt_buffer(struct snd_dbri * dbri) | 1899 | static void dbri_process_interrupt_buffer(struct snd_dbri *dbri) |
1893 | { | 1900 | { |
1894 | s32 x; | 1901 | s32 x; |
1895 | 1902 | ||
@@ -1965,20 +1972,20 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id) | |||
1965 | PCM Interface | 1972 | PCM Interface |
1966 | ****************************************************************************/ | 1973 | ****************************************************************************/ |
1967 | static struct snd_pcm_hardware snd_dbri_pcm_hw = { | 1974 | static struct snd_pcm_hardware snd_dbri_pcm_hw = { |
1968 | .info = (SNDRV_PCM_INFO_MMAP | | 1975 | .info = SNDRV_PCM_INFO_MMAP | |
1969 | SNDRV_PCM_INFO_INTERLEAVED | | 1976 | SNDRV_PCM_INFO_INTERLEAVED | |
1970 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1977 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1971 | SNDRV_PCM_INFO_MMAP_VALID), | 1978 | SNDRV_PCM_INFO_MMAP_VALID, |
1972 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | | 1979 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | |
1973 | SNDRV_PCM_FMTBIT_A_LAW | | 1980 | SNDRV_PCM_FMTBIT_A_LAW | |
1974 | SNDRV_PCM_FMTBIT_U8 | | 1981 | SNDRV_PCM_FMTBIT_U8 | |
1975 | SNDRV_PCM_FMTBIT_S16_BE, | 1982 | SNDRV_PCM_FMTBIT_S16_BE, |
1976 | .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512, | 1983 | .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512, |
1977 | .rate_min = 5512, | 1984 | .rate_min = 5512, |
1978 | .rate_max = 48000, | 1985 | .rate_max = 48000, |
1979 | .channels_min = 1, | 1986 | .channels_min = 1, |
1980 | .channels_max = 2, | 1987 | .channels_max = 2, |
1981 | .buffer_bytes_max = (64 * 1024), | 1988 | .buffer_bytes_max = 64 * 1024, |
1982 | .period_bytes_min = 1, | 1989 | .period_bytes_min = 1, |
1983 | .period_bytes_max = DBRI_TD_MAXCNT, | 1990 | .period_bytes_max = DBRI_TD_MAXCNT, |
1984 | .periods_min = 1, | 1991 | .periods_min = 1, |
@@ -2011,7 +2018,8 @@ static int snd_hw_rule_channels(struct snd_pcm_hw_params *params, | |||
2011 | 2018 | ||
2012 | snd_interval_any(&ch); | 2019 | snd_interval_any(&ch); |
2013 | if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) { | 2020 | if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) { |
2014 | ch.min = ch.max = 1; | 2021 | ch.min = 1; |
2022 | ch.max = 1; | ||
2015 | ch.integer = 1; | 2023 | ch.integer = 1; |
2016 | return snd_interval_refine(c, &ch); | 2024 | return snd_interval_refine(c, &ch); |
2017 | } | 2025 | } |
@@ -2035,14 +2043,14 @@ static int snd_dbri_open(struct snd_pcm_substream *substream) | |||
2035 | info->pipe = -1; | 2043 | info->pipe = -1; |
2036 | spin_unlock_irqrestore(&dbri->lock, flags); | 2044 | spin_unlock_irqrestore(&dbri->lock, flags); |
2037 | 2045 | ||
2038 | snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_CHANNELS, | 2046 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
2039 | snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT, | 2047 | snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT, |
2040 | -1); | 2048 | -1); |
2041 | snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_FORMAT, | 2049 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, |
2042 | snd_hw_rule_channels, NULL, | 2050 | snd_hw_rule_channels, NULL, |
2043 | SNDRV_PCM_HW_PARAM_CHANNELS, | 2051 | SNDRV_PCM_HW_PARAM_CHANNELS, |
2044 | -1); | 2052 | -1); |
2045 | 2053 | ||
2046 | cs4215_open(dbri); | 2054 | cs4215_open(dbri); |
2047 | 2055 | ||
2048 | return 0; | 2056 | return 0; |
@@ -2145,7 +2153,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream) | |||
2145 | spin_lock_irq(&dbri->lock); | 2153 | spin_lock_irq(&dbri->lock); |
2146 | info->offset = 0; | 2154 | info->offset = 0; |
2147 | 2155 | ||
2148 | /* Setup the all the transmit/receive desciptors to cover the | 2156 | /* Setup the all the transmit/receive descriptors to cover the |
2149 | * whole DMA buffer. | 2157 | * whole DMA buffer. |
2150 | */ | 2158 | */ |
2151 | ret = setup_descs(dbri, DBRI_STREAMNO(substream), | 2159 | ret = setup_descs(dbri, DBRI_STREAMNO(substream), |
@@ -2205,12 +2213,12 @@ static struct snd_pcm_ops snd_dbri_ops = { | |||
2205 | .pointer = snd_dbri_pointer, | 2213 | .pointer = snd_dbri_pointer, |
2206 | }; | 2214 | }; |
2207 | 2215 | ||
2208 | static int __devinit snd_dbri_pcm(struct snd_dbri * dbri) | 2216 | static int __devinit snd_dbri_pcm(struct snd_card *card) |
2209 | { | 2217 | { |
2210 | struct snd_pcm *pcm; | 2218 | struct snd_pcm *pcm; |
2211 | int err; | 2219 | int err; |
2212 | 2220 | ||
2213 | if ((err = snd_pcm_new(dbri->card, | 2221 | if ((err = snd_pcm_new(card, |
2214 | /* ID */ "sun_dbri", | 2222 | /* ID */ "sun_dbri", |
2215 | /* device */ 0, | 2223 | /* device */ 0, |
2216 | /* playback count */ 1, | 2224 | /* playback count */ 1, |
@@ -2221,16 +2229,15 @@ static int __devinit snd_dbri_pcm(struct snd_dbri * dbri) | |||
2221 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops); | 2229 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops); |
2222 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops); | 2230 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops); |
2223 | 2231 | ||
2224 | pcm->private_data = dbri; | 2232 | pcm->private_data = card->private_data; |
2225 | pcm->info_flags = 0; | 2233 | pcm->info_flags = 0; |
2226 | strcpy(pcm->name, dbri->card->shortname); | 2234 | strcpy(pcm->name, card->shortname); |
2227 | 2235 | ||
2228 | if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, | 2236 | if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, |
2229 | SNDRV_DMA_TYPE_CONTINUOUS, | 2237 | SNDRV_DMA_TYPE_CONTINUOUS, |
2230 | snd_dma_continuous_data(GFP_KERNEL), | 2238 | snd_dma_continuous_data(GFP_KERNEL), |
2231 | 64 * 1024, 64 * 1024)) < 0) { | 2239 | 64 * 1024, 64 * 1024)) < 0) |
2232 | return err; | 2240 | return err; |
2233 | } | ||
2234 | 2241 | ||
2235 | return 0; | 2242 | return 0; |
2236 | } | 2243 | } |
@@ -2245,11 +2252,10 @@ static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol, | |||
2245 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2252 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2246 | uinfo->count = 2; | 2253 | uinfo->count = 2; |
2247 | uinfo->value.integer.min = 0; | 2254 | uinfo->value.integer.min = 0; |
2248 | if (kcontrol->private_value == DBRI_PLAY) { | 2255 | if (kcontrol->private_value == DBRI_PLAY) |
2249 | uinfo->value.integer.max = DBRI_MAX_VOLUME; | 2256 | uinfo->value.integer.max = DBRI_MAX_VOLUME; |
2250 | } else { | 2257 | else |
2251 | uinfo->value.integer.max = DBRI_MAX_GAIN; | 2258 | uinfo->value.integer.max = DBRI_MAX_GAIN; |
2252 | } | ||
2253 | return 0; | 2259 | return 0; |
2254 | } | 2260 | } |
2255 | 2261 | ||
@@ -2271,7 +2277,8 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol, | |||
2271 | struct snd_ctl_elem_value *ucontrol) | 2277 | struct snd_ctl_elem_value *ucontrol) |
2272 | { | 2278 | { |
2273 | struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); | 2279 | struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol); |
2274 | struct dbri_streaminfo *info = &dbri->stream_info[kcontrol->private_value]; | 2280 | struct dbri_streaminfo *info = |
2281 | &dbri->stream_info[kcontrol->private_value]; | ||
2275 | int changed = 0; | 2282 | int changed = 0; |
2276 | 2283 | ||
2277 | if (info->left_gain != ucontrol->value.integer.value[0]) { | 2284 | if (info->left_gain != ucontrol->value.integer.value[0]) { |
@@ -2282,7 +2289,7 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol, | |||
2282 | info->right_gain = ucontrol->value.integer.value[1]; | 2289 | info->right_gain = ucontrol->value.integer.value[1]; |
2283 | changed = 1; | 2290 | changed = 1; |
2284 | } | 2291 | } |
2285 | if (changed == 1) { | 2292 | if (changed) { |
2286 | /* First mute outputs, and wait 1/8000 sec (125 us) | 2293 | /* First mute outputs, and wait 1/8000 sec (125 us) |
2287 | * to make sure this takes. This avoids clicking noises. | 2294 | * to make sure this takes. This avoids clicking noises. |
2288 | */ | 2295 | */ |
@@ -2316,18 +2323,16 @@ static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol, | |||
2316 | int invert = (kcontrol->private_value >> 24) & 1; | 2323 | int invert = (kcontrol->private_value >> 24) & 1; |
2317 | snd_assert(dbri != NULL, return -EINVAL); | 2324 | snd_assert(dbri != NULL, return -EINVAL); |
2318 | 2325 | ||
2319 | if (elem < 4) { | 2326 | if (elem < 4) |
2320 | ucontrol->value.integer.value[0] = | 2327 | ucontrol->value.integer.value[0] = |
2321 | (dbri->mm.data[elem] >> shift) & mask; | 2328 | (dbri->mm.data[elem] >> shift) & mask; |
2322 | } else { | 2329 | else |
2323 | ucontrol->value.integer.value[0] = | 2330 | ucontrol->value.integer.value[0] = |
2324 | (dbri->mm.ctrl[elem - 4] >> shift) & mask; | 2331 | (dbri->mm.ctrl[elem - 4] >> shift) & mask; |
2325 | } | ||
2326 | 2332 | ||
2327 | if (invert == 1) { | 2333 | if (invert == 1) |
2328 | ucontrol->value.integer.value[0] = | 2334 | ucontrol->value.integer.value[0] = |
2329 | mask - ucontrol->value.integer.value[0]; | 2335 | mask - ucontrol->value.integer.value[0]; |
2330 | } | ||
2331 | return 0; | 2336 | return 0; |
2332 | } | 2337 | } |
2333 | 2338 | ||
@@ -2378,11 +2383,12 @@ static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol, | |||
2378 | timeslots. Shift is the bit offset in the timeslot, mask defines the | 2383 | timeslots. Shift is the bit offset in the timeslot, mask defines the |
2379 | number of bits. invert is a boolean for use with attenuation. | 2384 | number of bits. invert is a boolean for use with attenuation. |
2380 | */ | 2385 | */ |
2381 | #define CS4215_SINGLE(xname, entry, shift, mask, invert) \ | 2386 | #define CS4215_SINGLE(xname, entry, shift, mask, invert) \ |
2382 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 2387 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
2383 | .info = snd_cs4215_info_single, \ | 2388 | .info = snd_cs4215_info_single, \ |
2384 | .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \ | 2389 | .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \ |
2385 | .private_value = entry | (shift << 8) | (mask << 16) | (invert << 24) }, | 2390 | .private_value = (entry) | ((shift) << 8) | ((mask) << 16) | \ |
2391 | ((invert) << 24) }, | ||
2386 | 2392 | ||
2387 | static struct snd_kcontrol_new dbri_controls[] __devinitdata = { | 2393 | static struct snd_kcontrol_new dbri_controls[] __devinitdata = { |
2388 | { | 2394 | { |
@@ -2411,19 +2417,20 @@ static struct snd_kcontrol_new dbri_controls[] __devinitdata = { | |||
2411 | CS4215_SINGLE("Mic boost", 4, 4, 1, 1) | 2417 | CS4215_SINGLE("Mic boost", 4, 4, 1, 1) |
2412 | }; | 2418 | }; |
2413 | 2419 | ||
2414 | static int __init snd_dbri_mixer(struct snd_dbri * dbri) | 2420 | static int __devinit snd_dbri_mixer(struct snd_card *card) |
2415 | { | 2421 | { |
2416 | struct snd_card *card; | ||
2417 | int idx, err; | 2422 | int idx, err; |
2423 | struct snd_dbri *dbri; | ||
2418 | 2424 | ||
2419 | snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL); | 2425 | snd_assert(card != NULL && card->private_data != NULL, return -EINVAL); |
2426 | dbri = card->private_data; | ||
2420 | 2427 | ||
2421 | card = dbri->card; | ||
2422 | strcpy(card->mixername, card->shortname); | 2428 | strcpy(card->mixername, card->shortname); |
2423 | 2429 | ||
2424 | for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) { | 2430 | for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) { |
2425 | if ((err = snd_ctl_add(card, | 2431 | err = snd_ctl_add(card, |
2426 | snd_ctl_new1(&dbri_controls[idx], dbri))) < 0) | 2432 | snd_ctl_new1(&dbri_controls[idx], dbri)); |
2433 | if (err < 0) | ||
2427 | return err; | 2434 | return err; |
2428 | } | 2435 | } |
2429 | 2436 | ||
@@ -2438,7 +2445,8 @@ static int __init snd_dbri_mixer(struct snd_dbri * dbri) | |||
2438 | /**************************************************************************** | 2445 | /**************************************************************************** |
2439 | /proc interface | 2446 | /proc interface |
2440 | ****************************************************************************/ | 2447 | ****************************************************************************/ |
2441 | static void dbri_regs_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer) | 2448 | static void dbri_regs_read(struct snd_info_entry *entry, |
2449 | struct snd_info_buffer *buffer) | ||
2442 | { | 2450 | { |
2443 | struct snd_dbri *dbri = entry->private_data; | 2451 | struct snd_dbri *dbri = entry->private_data; |
2444 | 2452 | ||
@@ -2449,7 +2457,7 @@ static void dbri_regs_read(struct snd_info_entry * entry, struct snd_info_buffer | |||
2449 | } | 2457 | } |
2450 | 2458 | ||
2451 | #ifdef DBRI_DEBUG | 2459 | #ifdef DBRI_DEBUG |
2452 | static void dbri_debug_read(struct snd_info_entry * entry, | 2460 | static void dbri_debug_read(struct snd_info_entry *entry, |
2453 | struct snd_info_buffer *buffer) | 2461 | struct snd_info_buffer *buffer) |
2454 | { | 2462 | { |
2455 | struct snd_dbri *dbri = entry->private_data; | 2463 | struct snd_dbri *dbri = entry->private_data; |
@@ -2463,7 +2471,8 @@ static void dbri_debug_read(struct snd_info_entry * entry, | |||
2463 | "Pipe %d: %s SDP=0x%x desc=%d, " | 2471 | "Pipe %d: %s SDP=0x%x desc=%d, " |
2464 | "len=%d next %d\n", | 2472 | "len=%d next %d\n", |
2465 | pipe, | 2473 | pipe, |
2466 | ((pptr->sdp & D_SDP_TO_SER) ? "output" : "input"), | 2474 | (pptr->sdp & D_SDP_TO_SER) ? "output" : |
2475 | "input", | ||
2467 | pptr->sdp, pptr->desc, | 2476 | pptr->sdp, pptr->desc, |
2468 | pptr->length, pptr->nextpipe); | 2477 | pptr->length, pptr->nextpipe); |
2469 | } | 2478 | } |
@@ -2471,15 +2480,16 @@ static void dbri_debug_read(struct snd_info_entry * entry, | |||
2471 | } | 2480 | } |
2472 | #endif | 2481 | #endif |
2473 | 2482 | ||
2474 | void snd_dbri_proc(struct snd_dbri * dbri) | 2483 | void __devinit snd_dbri_proc(struct snd_card *card) |
2475 | { | 2484 | { |
2485 | struct snd_dbri *dbri = card->private_data; | ||
2476 | struct snd_info_entry *entry; | 2486 | struct snd_info_entry *entry; |
2477 | 2487 | ||
2478 | if (! snd_card_proc_new(dbri->card, "regs", &entry)) | 2488 | if (!snd_card_proc_new(card, "regs", &entry)) |
2479 | snd_info_set_text_ops(entry, dbri, dbri_regs_read); | 2489 | snd_info_set_text_ops(entry, dbri, dbri_regs_read); |
2480 | 2490 | ||
2481 | #ifdef DBRI_DEBUG | 2491 | #ifdef DBRI_DEBUG |
2482 | if (! snd_card_proc_new(dbri->card, "debug", &entry)) { | 2492 | if (!snd_card_proc_new(card, "debug", &entry)) { |
2483 | snd_info_set_text_ops(entry, dbri, dbri_debug_read); | 2493 | snd_info_set_text_ops(entry, dbri, dbri_debug_read); |
2484 | entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ | 2494 | entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ |
2485 | } | 2495 | } |
@@ -2491,19 +2501,18 @@ void snd_dbri_proc(struct snd_dbri * dbri) | |||
2491 | **************************** Initialization ******************************** | 2501 | **************************** Initialization ******************************** |
2492 | **************************************************************************** | 2502 | **************************************************************************** |
2493 | */ | 2503 | */ |
2494 | static void snd_dbri_free(struct snd_dbri * dbri); | 2504 | static void snd_dbri_free(struct snd_dbri *dbri); |
2495 | 2505 | ||
2496 | static int __init snd_dbri_create(struct snd_card *card, | 2506 | static int __devinit snd_dbri_create(struct snd_card *card, |
2497 | struct sbus_dev *sdev, | 2507 | struct sbus_dev *sdev, |
2498 | struct linux_prom_irqs *irq, int dev) | 2508 | int irq, int dev) |
2499 | { | 2509 | { |
2500 | struct snd_dbri *dbri = card->private_data; | 2510 | struct snd_dbri *dbri = card->private_data; |
2501 | int err; | 2511 | int err; |
2502 | 2512 | ||
2503 | spin_lock_init(&dbri->lock); | 2513 | spin_lock_init(&dbri->lock); |
2504 | dbri->card = card; | ||
2505 | dbri->sdev = sdev; | 2514 | dbri->sdev = sdev; |
2506 | dbri->irq = irq->pri; | 2515 | dbri->irq = irq; |
2507 | 2516 | ||
2508 | dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), | 2517 | dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), |
2509 | &dbri->dma_dvma); | 2518 | &dbri->dma_dvma); |
@@ -2541,13 +2550,10 @@ static int __init snd_dbri_create(struct snd_card *card, | |||
2541 | return err; | 2550 | return err; |
2542 | } | 2551 | } |
2543 | 2552 | ||
2544 | dbri->next = dbri_list; | ||
2545 | dbri_list = dbri; | ||
2546 | |||
2547 | return 0; | 2553 | return 0; |
2548 | } | 2554 | } |
2549 | 2555 | ||
2550 | static void snd_dbri_free(struct snd_dbri * dbri) | 2556 | static void snd_dbri_free(struct snd_dbri *dbri) |
2551 | { | 2557 | { |
2552 | dprintk(D_GEN, "snd_dbri_free\n"); | 2558 | dprintk(D_GEN, "snd_dbri_free\n"); |
2553 | dbri_reset(dbri); | 2559 | dbri_reset(dbri); |
@@ -2563,20 +2569,19 @@ static void snd_dbri_free(struct snd_dbri * dbri) | |||
2563 | (void *)dbri->dma, dbri->dma_dvma); | 2569 | (void *)dbri->dma, dbri->dma_dvma); |
2564 | } | 2570 | } |
2565 | 2571 | ||
2566 | static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | 2572 | static int __devinit dbri_probe(struct of_device *of_dev, |
2573 | const struct of_device_id *match) | ||
2567 | { | 2574 | { |
2575 | struct sbus_dev *sdev = to_sbus_device(&of_dev->dev); | ||
2568 | struct snd_dbri *dbri; | 2576 | struct snd_dbri *dbri; |
2569 | struct linux_prom_irqs irq; | 2577 | int irq; |
2570 | struct resource *rp; | 2578 | struct resource *rp; |
2571 | struct snd_card *card; | 2579 | struct snd_card *card; |
2572 | static int dev = 0; | 2580 | static int dev = 0; |
2573 | int err; | 2581 | int err; |
2574 | 2582 | ||
2575 | if (sdev->prom_name[9] < 'e') { | 2583 | dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n", |
2576 | printk(KERN_ERR "DBRI: unsupported chip version %c found.\n", | 2584 | sdev->prom_name, sdev->slot); |
2577 | sdev->prom_name[9]); | ||
2578 | return -EIO; | ||
2579 | } | ||
2580 | 2585 | ||
2581 | if (dev >= SNDRV_CARDS) | 2586 | if (dev >= SNDRV_CARDS) |
2582 | return -ENODEV; | 2587 | return -ENODEV; |
@@ -2585,9 +2590,9 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2585 | return -ENOENT; | 2590 | return -ENOENT; |
2586 | } | 2591 | } |
2587 | 2592 | ||
2588 | err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); | 2593 | irq = sdev->irqs[0]; |
2589 | if (err < 0) { | 2594 | if (irq <= 0) { |
2590 | printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", dev); | 2595 | printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); |
2591 | return -ENODEV; | 2596 | return -ENODEV; |
2592 | } | 2597 | } |
2593 | 2598 | ||
@@ -2601,24 +2606,29 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2601 | rp = &sdev->resource[0]; | 2606 | rp = &sdev->resource[0]; |
2602 | sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", | 2607 | sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", |
2603 | card->shortname, | 2608 | card->shortname, |
2604 | rp->flags & 0xffL, (unsigned long long)rp->start, irq.pri); | 2609 | rp->flags & 0xffL, (unsigned long long)rp->start, irq); |
2605 | 2610 | ||
2606 | if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) { | 2611 | err = snd_dbri_create(card, sdev, irq, dev); |
2612 | if (err < 0) { | ||
2607 | snd_card_free(card); | 2613 | snd_card_free(card); |
2608 | return err; | 2614 | return err; |
2609 | } | 2615 | } |
2610 | 2616 | ||
2611 | dbri = card->private_data; | 2617 | dbri = card->private_data; |
2612 | if ((err = snd_dbri_pcm(dbri)) < 0) | 2618 | err = snd_dbri_pcm(card); |
2619 | if (err < 0) | ||
2613 | goto _err; | 2620 | goto _err; |
2614 | 2621 | ||
2615 | if ((err = snd_dbri_mixer(dbri)) < 0) | 2622 | err = snd_dbri_mixer(card); |
2623 | if (err < 0) | ||
2616 | goto _err; | 2624 | goto _err; |
2617 | 2625 | ||
2618 | /* /proc file handling */ | 2626 | /* /proc file handling */ |
2619 | snd_dbri_proc(dbri); | 2627 | snd_dbri_proc(card); |
2628 | dev_set_drvdata(&of_dev->dev, card); | ||
2620 | 2629 | ||
2621 | if ((err = snd_card_register(card)) < 0) | 2630 | err = snd_card_register(card); |
2631 | if (err < 0) | ||
2622 | goto _err; | 2632 | goto _err; |
2623 | 2633 | ||
2624 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", | 2634 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", |
@@ -2628,49 +2638,52 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2628 | 2638 | ||
2629 | return 0; | 2639 | return 0; |
2630 | 2640 | ||
2631 | _err: | 2641 | _err: |
2632 | snd_dbri_free(dbri); | 2642 | snd_dbri_free(dbri); |
2633 | snd_card_free(card); | 2643 | snd_card_free(card); |
2634 | return err; | 2644 | return err; |
2635 | } | 2645 | } |
2636 | 2646 | ||
2637 | /* Probe for the dbri chip and then attach the driver. */ | 2647 | static int __devexit dbri_remove(struct of_device *dev) |
2638 | static int __init dbri_init(void) | ||
2639 | { | 2648 | { |
2640 | struct sbus_bus *sbus; | 2649 | struct snd_card *card = dev_get_drvdata(&dev->dev); |
2641 | struct sbus_dev *sdev; | ||
2642 | int found = 0; | ||
2643 | |||
2644 | /* Probe each SBUS for the DBRI chip(s). */ | ||
2645 | for_all_sbusdev(sdev, sbus) { | ||
2646 | /* | ||
2647 | * The version is coded in the last character | ||
2648 | */ | ||
2649 | if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) { | ||
2650 | dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n", | ||
2651 | sdev->prom_name, sdev->slot); | ||
2652 | 2650 | ||
2653 | if (dbri_attach(sdev->prom_node, sdev) == 0) | 2651 | snd_dbri_free(card->private_data); |
2654 | found++; | 2652 | snd_card_free(card); |
2655 | } | 2653 | |
2656 | } | 2654 | dev_set_drvdata(&dev->dev, NULL); |
2655 | |||
2656 | return 0; | ||
2657 | } | ||
2658 | |||
2659 | static struct of_device_id dbri_match[] = { | ||
2660 | { | ||
2661 | .name = "SUNW,DBRIe", | ||
2662 | }, | ||
2663 | { | ||
2664 | .name = "SUNW,DBRIf", | ||
2665 | }, | ||
2666 | {}, | ||
2667 | }; | ||
2668 | |||
2669 | MODULE_DEVICE_TABLE(of, dbri_match); | ||
2670 | |||
2671 | static struct of_platform_driver dbri_sbus_driver = { | ||
2672 | .name = "dbri", | ||
2673 | .match_table = dbri_match, | ||
2674 | .probe = dbri_probe, | ||
2675 | .remove = __devexit_p(dbri_remove), | ||
2676 | }; | ||
2657 | 2677 | ||
2658 | return (found > 0) ? 0 : -EIO; | 2678 | /* Probe for the dbri chip and then attach the driver. */ |
2679 | static int __init dbri_init(void) | ||
2680 | { | ||
2681 | return of_register_driver(&dbri_sbus_driver, &sbus_bus_type); | ||
2659 | } | 2682 | } |
2660 | 2683 | ||
2661 | static void __exit dbri_exit(void) | 2684 | static void __exit dbri_exit(void) |
2662 | { | 2685 | { |
2663 | struct snd_dbri *this = dbri_list; | 2686 | of_unregister_driver(&dbri_sbus_driver); |
2664 | |||
2665 | while (this != NULL) { | ||
2666 | struct snd_dbri *next = this->next; | ||
2667 | struct snd_card *card = this->card; | ||
2668 | |||
2669 | snd_dbri_free(this); | ||
2670 | snd_card_free(card); | ||
2671 | this = next; | ||
2672 | } | ||
2673 | dbri_list = NULL; | ||
2674 | } | 2687 | } |
2675 | 2688 | ||
2676 | module_init(dbri_init); | 2689 | module_init(dbri_init); |