aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/sparc/cs4231.c195
1 files changed, 42 insertions, 153 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 96051dca1e6b..4f515a64e03f 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -135,129 +135,10 @@ static struct snd_cs4231 *cs4231_list;
135 */ 135 */
136 136
137/* IO ports */ 137/* IO ports */
138 138#include <sound/cs4231-regs.h>
139#define CS4231P(chip, x) ((chip)->port + c_d_c_CS4231##x)
140 139
141/* XXX offsets are different than PC ISA chips... */ 140/* XXX offsets are different than PC ISA chips... */
142#define c_d_c_CS4231REGSEL 0x0 141#define CS4231U(chip, x) ((chip)->port + ((c_d_c_CS4231##x) << 2))
143#define c_d_c_CS4231REG 0x4
144#define c_d_c_CS4231STATUS 0x8
145#define c_d_c_CS4231PIO 0xc
146
147/* codec registers */
148
149#define CS4231_LEFT_INPUT 0x00 /* left input control */
150#define CS4231_RIGHT_INPUT 0x01 /* right input control */
151#define CS4231_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */
152#define CS4231_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */
153#define CS4231_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */
154#define CS4231_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */
155#define CS4231_LEFT_OUTPUT 0x06 /* left output control register */
156#define CS4231_RIGHT_OUTPUT 0x07 /* right output control register */
157#define CS4231_PLAYBK_FORMAT 0x08 /* clock and data format - playback - bits 7-0 MCE */
158#define CS4231_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */
159#define CS4231_PIN_CTRL 0x0a /* pin control */
160#define CS4231_TEST_INIT 0x0b /* test and initialization */
161#define CS4231_MISC_INFO 0x0c /* miscellaneaous information */
162#define CS4231_LOOPBACK 0x0d /* loopback control */
163#define CS4231_PLY_UPR_CNT 0x0e /* playback upper base count */
164#define CS4231_PLY_LWR_CNT 0x0f /* playback lower base count */
165#define CS4231_ALT_FEATURE_1 0x10 /* alternate #1 feature enable */
166#define CS4231_ALT_FEATURE_2 0x11 /* alternate #2 feature enable */
167#define CS4231_LEFT_LINE_IN 0x12 /* left line input control */
168#define CS4231_RIGHT_LINE_IN 0x13 /* right line input control */
169#define CS4231_TIMER_LOW 0x14 /* timer low byte */
170#define CS4231_TIMER_HIGH 0x15 /* timer high byte */
171#define CS4231_LEFT_MIC_INPUT 0x16 /* left MIC input control register (InterWave only) */
172#define CS4231_RIGHT_MIC_INPUT 0x17 /* right MIC input control register (InterWave only) */
173#define CS4236_EXT_REG 0x17 /* extended register access */
174#define CS4231_IRQ_STATUS 0x18 /* irq status register */
175#define CS4231_LINE_LEFT_OUTPUT 0x19 /* left line output control register (InterWave only) */
176#define CS4231_VERSION 0x19 /* CS4231(A) - version values */
177#define CS4231_MONO_CTRL 0x1a /* mono input/output control */
178#define CS4231_LINE_RIGHT_OUTPUT 0x1b /* right line output control register (InterWave only) */
179#define CS4235_LEFT_MASTER 0x1b /* left master output control */
180#define CS4231_REC_FORMAT 0x1c /* clock and data format - record - bits 7-0 MCE */
181#define CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */
182#define CS4235_RIGHT_MASTER 0x1d /* right master output control */
183#define CS4231_REC_UPR_CNT 0x1e /* record upper count */
184#define CS4231_REC_LWR_CNT 0x1f /* record lower count */
185
186/* definitions for codec register select port - CODECP( REGSEL ) */
187
188#define CS4231_INIT 0x80 /* CODEC is initializing */
189#define CS4231_MCE 0x40 /* mode change enable */
190#define CS4231_TRD 0x20 /* transfer request disable */
191
192/* definitions for codec status register - CODECP( STATUS ) */
193
194#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
195
196/* definitions for codec irq status - CS4231_IRQ_STATUS */
197
198#define CS4231_PLAYBACK_IRQ 0x10
199#define CS4231_RECORD_IRQ 0x20
200#define CS4231_TIMER_IRQ 0x40
201#define CS4231_ALL_IRQS 0x70
202#define CS4231_REC_UNDERRUN 0x08
203#define CS4231_REC_OVERRUN 0x04
204#define CS4231_PLY_OVERRUN 0x02
205#define CS4231_PLY_UNDERRUN 0x01
206
207/* definitions for CS4231_LEFT_INPUT and CS4231_RIGHT_INPUT registers */
208
209#define CS4231_ENABLE_MIC_GAIN 0x20
210
211#define CS4231_MIXS_LINE 0x00
212#define CS4231_MIXS_AUX1 0x40
213#define CS4231_MIXS_MIC 0x80
214#define CS4231_MIXS_ALL 0xc0
215
216/* definitions for clock and data format register - CS4231_PLAYBK_FORMAT */
217
218#define CS4231_LINEAR_8 0x00 /* 8-bit unsigned data */
219#define CS4231_ALAW_8 0x60 /* 8-bit A-law companded */
220#define CS4231_ULAW_8 0x20 /* 8-bit U-law companded */
221#define CS4231_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */
222#define CS4231_LINEAR_16_BIG 0xc0 /* 16-bit twos complement data - big endian */
223#define CS4231_ADPCM_16 0xa0 /* 16-bit ADPCM */
224#define CS4231_STEREO 0x10 /* stereo mode */
225/* bits 3-1 define frequency divisor */
226#define CS4231_XTAL1 0x00 /* 24.576 crystal */
227#define CS4231_XTAL2 0x01 /* 16.9344 crystal */
228
229/* definitions for interface control register - CS4231_IFACE_CTRL */
230
231#define CS4231_RECORD_PIO 0x80 /* record PIO enable */
232#define CS4231_PLAYBACK_PIO 0x40 /* playback PIO enable */
233#define CS4231_CALIB_MODE 0x18 /* calibration mode bits */
234#define CS4231_AUTOCALIB 0x08 /* auto calibrate */
235#define CS4231_SINGLE_DMA 0x04 /* use single DMA channel */
236#define CS4231_RECORD_ENABLE 0x02 /* record enable */
237#define CS4231_PLAYBACK_ENABLE 0x01 /* playback enable */
238
239/* definitions for pin control register - CS4231_PIN_CTRL */
240
241#define CS4231_IRQ_ENABLE 0x02 /* enable IRQ */
242#define CS4231_XCTL1 0x40 /* external control #1 */
243#define CS4231_XCTL0 0x80 /* external control #0 */
244
245/* definitions for test and init register - CS4231_TEST_INIT */
246
247#define CS4231_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */
248#define CS4231_DMA_REQUEST 0x10 /* DMA request in progress */
249
250/* definitions for misc control register - CS4231_MISC_INFO */
251
252#define CS4231_MODE2 0x40 /* MODE 2 */
253#define CS4231_IW_MODE3 0x6c /* MODE 3 - InterWave enhanced mode */
254#define CS4231_4236_MODE3 0xe0 /* MODE 3 - CS4236+ enhanced mode */
255
256/* definitions for alternate feature 1 register - CS4231_ALT_FEATURE_1 */
257
258#define CS4231_DACZ 0x01 /* zero DAC when underrun */
259#define CS4231_TIMER_ENABLE 0x40 /* codec timer enable */
260#define CS4231_OLB 0x80 /* output level bit */
261 142
262/* SBUS DMA register defines. */ 143/* SBUS DMA register defines. */
263 144
@@ -418,10 +299,12 @@ static void snd_cs4231_ready(struct snd_cs4231 *chip)
418{ 299{
419 int timeout; 300 int timeout;
420 301
421 for (timeout = 250; 302 for (timeout = 250; timeout > 0; timeout--) {
422 timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); 303 int val = __cs4231_readb(chip, CS4231U(chip, REGSEL));
423 timeout--) 304 if ((val & CS4231_INIT) == 0)
424 udelay(100); 305 break;
306 udelay(100);
307 }
425} 308}
426 309
427static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, 310static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg,
@@ -429,14 +312,14 @@ static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg,
429{ 312{
430 snd_cs4231_ready(chip); 313 snd_cs4231_ready(chip);
431#ifdef CONFIG_SND_DEBUG 314#ifdef CONFIG_SND_DEBUG
432 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 315 if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
433 snd_printdd("out: auto calibration time out - reg = 0x%x, " 316 snd_printdd("out: auto calibration time out - reg = 0x%x, "
434 "value = 0x%x\n", 317 "value = 0x%x\n",
435 reg, value); 318 reg, value);
436#endif 319#endif
437 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); 320 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL));
438 wmb(); 321 wmb();
439 __cs4231_writeb(chip, value, CS4231P(chip, REG)); 322 __cs4231_writeb(chip, value, CS4231U(chip, REG));
440 mb(); 323 mb();
441} 324}
442 325
@@ -462,13 +345,13 @@ static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
462{ 345{
463 snd_cs4231_ready(chip); 346 snd_cs4231_ready(chip);
464#ifdef CONFIG_SND_DEBUG 347#ifdef CONFIG_SND_DEBUG
465 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 348 if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
466 snd_printdd("in: auto calibration time out - reg = 0x%x\n", 349 snd_printdd("in: auto calibration time out - reg = 0x%x\n",
467 reg); 350 reg);
468#endif 351#endif
469 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL)); 352 __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL));
470 mb(); 353 mb();
471 return __cs4231_readb(chip, CS4231P(chip, REG)); 354 return __cs4231_readb(chip, CS4231U(chip, REG));
472} 355}
473 356
474/* 357/*
@@ -481,13 +364,15 @@ static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
481 364
482 /* looks like this sequence is proper for CS4231A chip (GUS MAX) */ 365 /* looks like this sequence is proper for CS4231A chip (GUS MAX) */
483 for (timeout = 5; timeout > 0; timeout--) 366 for (timeout = 5; timeout > 0; timeout--)
484 __cs4231_readb(chip, CS4231P(chip, REGSEL)); 367 __cs4231_readb(chip, CS4231U(chip, REGSEL));
485 368
486 /* end of cleanup sequence */ 369 /* end of cleanup sequence */
487 for (timeout = 500; 370 for (timeout = 500; timeout > 0; timeout--) {
488 timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); 371 int val = __cs4231_readb(chip, CS4231U(chip, REGSEL));
489 timeout--) 372 if ((val & CS4231_INIT) == 0)
373 break;
490 msleep(1); 374 msleep(1);
375 }
491} 376}
492 377
493static void snd_cs4231_mce_up(struct snd_cs4231 *chip) 378static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
@@ -498,17 +383,18 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
498 spin_lock_irqsave(&chip->lock, flags); 383 spin_lock_irqsave(&chip->lock, flags);
499 snd_cs4231_ready(chip); 384 snd_cs4231_ready(chip);
500#ifdef CONFIG_SND_DEBUG 385#ifdef CONFIG_SND_DEBUG
501 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 386 if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
502 snd_printdd("mce_up - auto calibration time out (0)\n"); 387 snd_printdd("mce_up - auto calibration time out (0)\n");
503#endif 388#endif
504 chip->mce_bit |= CS4231_MCE; 389 chip->mce_bit |= CS4231_MCE;
505 timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL)); 390 timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
506 if (timeout == 0x80) 391 if (timeout == 0x80)
507 snd_printdd("mce_up [%p]: serious init problem - " 392 snd_printdd("mce_up [%p]: serious init problem - "
508 "codec still busy\n", 393 "codec still busy\n",
509 chip->port); 394 chip->port);
510 if (!(timeout & CS4231_MCE)) 395 if (!(timeout & CS4231_MCE))
511 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); 396 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
397 CS4231U(chip, REGSEL));
512 spin_unlock_irqrestore(&chip->lock, flags); 398 spin_unlock_irqrestore(&chip->lock, flags);
513} 399}
514 400
@@ -520,12 +406,14 @@ static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
520 spin_lock_irqsave(&chip->lock, flags); 406 spin_lock_irqsave(&chip->lock, flags);
521 snd_cs4231_busy_wait(chip); 407 snd_cs4231_busy_wait(chip);
522#ifdef CONFIG_SND_DEBUG 408#ifdef CONFIG_SND_DEBUG
523 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 409 if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
524 snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL)); 410 snd_printdd("mce_down [%p] - auto calibration time out (0)\n",
411 CS4231U(chip, REGSEL));
525#endif 412#endif
526 chip->mce_bit &= ~CS4231_MCE; 413 chip->mce_bit &= ~CS4231_MCE;
527 timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL)); 414 timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
528 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); 415 __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
416 CS4231U(chip, REGSEL));
529 if (timeout == 0x80) 417 if (timeout == 0x80)
530 snd_printdd("mce_down [%p]: serious init problem - " 418 snd_printdd("mce_down [%p]: serious init problem - "
531 "codec still busy\n", 419 "codec still busy\n",
@@ -564,7 +452,7 @@ static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
564 452
565 /* in 10ms increments, check condition, up to 100ms */ 453 /* in 10ms increments, check condition, up to 100ms */
566 timeout = 10; 454 timeout = 10;
567 while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) { 455 while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) {
568 spin_unlock_irqrestore(&chip->lock, flags); 456 spin_unlock_irqrestore(&chip->lock, flags);
569 if (--timeout < 0) { 457 if (--timeout < 0) {
570 snd_printk("mce_down - " 458 snd_printk("mce_down - "
@@ -944,8 +832,8 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
944 CS4231_RECORD_IRQ | 832 CS4231_RECORD_IRQ |
945 CS4231_TIMER_IRQ); 833 CS4231_TIMER_IRQ);
946 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); 834 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
947 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ 835 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
948 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ 836 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
949 837
950 snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | 838 snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
951 CS4231_RECORD_IRQ | 839 CS4231_RECORD_IRQ |
@@ -974,8 +862,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
974 /* disable IRQ */ 862 /* disable IRQ */
975 spin_lock_irqsave(&chip->lock, flags); 863 spin_lock_irqsave(&chip->lock, flags);
976 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); 864 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
977 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ 865 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
978 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ 866 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
979 867
980 /* now disable record & playback */ 868 /* now disable record & playback */
981 869
@@ -997,8 +885,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
997 885
998 /* clear IRQ again */ 886 /* clear IRQ again */
999 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); 887 snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
1000 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ 888 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
1001 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */ 889 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
1002 spin_unlock_irqrestore(&chip->lock, flags); 890 spin_unlock_irqrestore(&chip->lock, flags);
1003 891
1004 snd_cs4231_calibrate_mute(chip, 0); 892 snd_cs4231_calibrate_mute(chip, 0);
@@ -1187,7 +1075,7 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
1187 1075
1188 for (i = 0; i < 50; i++) { 1076 for (i = 0; i < 50; i++) {
1189 mb(); 1077 mb();
1190 if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) 1078 if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
1191 msleep(2); 1079 msleep(2);
1192 else { 1080 else {
1193 spin_lock_irqsave(&chip->lock, flags); 1081 spin_lock_irqsave(&chip->lock, flags);
@@ -1205,8 +1093,9 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
1205 1093
1206 spin_lock_irqsave(&chip->lock, flags); 1094 spin_lock_irqsave(&chip->lock, flags);
1207 1095
1208 __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */ 1096 /* clear any pendings IRQ */
1209 __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); 1097 __cs4231_readb(chip, CS4231U(chip, STATUS));
1098 __cs4231_writeb(chip, 0, CS4231U(chip, STATUS));
1210 mb(); 1099 mb();
1211 1100
1212 spin_unlock_irqrestore(&chip->lock, flags); 1101 spin_unlock_irqrestore(&chip->lock, flags);
@@ -1784,7 +1673,7 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
1784 struct snd_cs4231 *chip = dev_id; 1673 struct snd_cs4231 *chip = dev_id;
1785 1674
1786 /*This is IRQ is not raised by the cs4231*/ 1675 /*This is IRQ is not raised by the cs4231*/
1787 if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ)) 1676 if (!(__cs4231_readb(chip, CS4231U(chip, STATUS)) & CS4231_GLOBALIRQ))
1788 return IRQ_NONE; 1677 return IRQ_NONE;
1789 1678
1790 /* ACK the APC interrupt. */ 1679 /* ACK the APC interrupt. */