summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Carlsson <md1ulfc@mdstud.chalmers.se>1999-01-27 19:33:48 +0000
committerUlf Carlsson <md1ulfc@mdstud.chalmers.se>1999-01-27 19:33:48 +0000
commitc2a115bbbcb298d8571ebd34c1002b16ea524156 (patch)
treeea5fb780bdb914feef9f55d5a7e7f5046cdccaa5
parent6ec7ec2c243af0cc68f59776cc2fe50f2637ed6f (diff)
I'm pretty bored of writing this now since it's about the tenth time I'm doing
it, but ok: I have fixed some bugs. The driver should now also make sure the indirect registers work as they are supposed to. If this is ok should the next step be the DMA. There are about +1000 bugs in that part of the code.
-rw-r--r--drivers/sgi/audio/hal2.c55
-rw-r--r--drivers/sgi/audio/hal2.h122
2 files changed, 103 insertions, 74 deletions
diff --git a/drivers/sgi/audio/hal2.c b/drivers/sgi/audio/hal2.c
index 25b122698..4d931d24f 100644
--- a/drivers/sgi/audio/hal2.c
+++ b/drivers/sgi/audio/hal2.c
@@ -1,7 +1,8 @@
-/*
+/* $Id$
+ *
* drivers/sgi/audio/hal2.c
*
- * Copyright (C) 1998 Ulf Carlsson (ulfc@bun.falkenberg.se)
+ * Copyright (C) 1998-1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
*
*/
@@ -110,25 +111,24 @@ static unsigned short ireg_read(unsigned short address)
int tmp;
h2_ctrl->iar = address;
- tmp = h2_ctrl->idr0;
INDIRECT_WAIT(h2_ctrl);
+ tmp = h2_ctrl->idr0;
return tmp;
}
static void ireg_write(unsigned short address, unsigned short val)
{
- h2_ctrl->iar = address;
h2_ctrl->idr0 = val;
+ h2_ctrl->iar = address;
INDIRECT_WAIT(h2_ctrl);
}
static void ireg_write2(unsigned short address,
unsigned short val0, unsigned short val1)
{
- h2_ctrl->iar = address;
h2_ctrl->idr0 = val0;
- INDIRECT_WAIT(h2_ctrl);
h2_ctrl->idr1 = val1;
+ h2_ctrl->iar = address;
INDIRECT_WAIT(h2_ctrl);
}
@@ -137,10 +137,10 @@ static void ireg_setbit(unsigned short write_address, unsigned short
int tmp;
h2_ctrl->iar = read_address;
- tmp = h2_ctrl->idr0;
INDIRECT_WAIT(h2_ctrl);
- h2_ctrl->iar = write_address;
+ tmp = h2_ctrl->idr0;
h2_ctrl->idr0 = tmp | bit;
+ h2_ctrl->iar = write_address;
INDIRECT_WAIT(h2_ctrl);
}
@@ -150,10 +150,10 @@ static void ireg_clearbit(unsigned short write_address, unsigned short
int tmp;
h2_ctrl->iar = read_address;
- tmp = h2_ctrl->idr0;
INDIRECT_WAIT(h2_ctrl);
- h2_ctrl->iar = write_address;
+ tmp = h2_ctrl->idr0;
h2_ctrl->idr0 = tmp & ~bit;
+ h2_ctrl->iar = write_address;
INDIRECT_WAIT(h2_ctrl);
}
@@ -161,7 +161,7 @@ static int hal2_probe(void)
{
unsigned short board, major, minor;
- if (!(!h2_ctrl->rev & H2_REV_AUDIO_PRESENT)) {
+ if (h2_ctrl->rev & H2_REV_AUDIO_PRESENT) {
printk("hal2: there was no device?\n");
return -ENODEV;
@@ -169,9 +169,38 @@ static int hal2_probe(void)
board = (h2_ctrl->rev & H2_REV_BOARD_M) >> 12;
major = (h2_ctrl->rev & H2_REV_MAJOR_CHIP_M) >> 4;
minor = (h2_ctrl->rev & H2_REV_MINOR_CHIP_M);
+
printk("SGI HAL2 Processor, Revision %i.%i.%i\n",
board, major, minor);
+ if (board != 4 || major != 1 || minor != 0) {
+ printk("hal2: Other revision than 4.1.0 detected\n");
+ printk("hal2: Your card is probably not supported\n");
+ }
+
+#ifdef DEBUG
+ printk("hal2: checking registers\n");
+#endif
+
+ /* check that the indirect registers are working by writing some bogus
+ * stuff and then reading it back */
+
+ ireg_write(H2IW_DAC_C1, 0x23); /* 16 bit register */
+ ireg_write2(H2IW_DAC_C2, 0x123, 0x321); /* 32 bit register */
+
+ if (ireg_read(H2IR_ADC_C1) != 0x23) {
+ printk("hal2: Didn't pass register check #1\n");
+ return -ENODEV;
+ }
+ if (ireg_read(H2IR_DAC_C2_0) != 0x123) {
+ printk("hal2: Didn't pass register check #2\n");
+ return -ENODEV;
+ }
+ if (ireg_read(H2IR_DAC_C2_1) != 0x321) {
+ printk("hal2: Didn't pass register check #3\n");
+ return -ENODEV;
+ }
+
#ifdef DEBUG
printk("hal2: card found\n");
#endif
@@ -208,7 +237,6 @@ static int hal2_init(struct sgiaudio *sa)
printk("hal2: resetting chip\n");
#endif
-
/* do a global reset */
h2_ctrl->isr = 0;
@@ -610,8 +638,7 @@ static void hal2_configure_bres##clock(struct hal2_private *hp, \
int inc = 4; \
\
ireg_write(H2IW_BRES##clock##_C1 , master); \
- ireg_write2(H2IW_BRES##clock##_C2_0 , inc, \
- mod); \
+ ireg_write2(H2IW_BRES##clock##_C2 , inc, mod); \
} \
__BUILD_CONF_BRESN_CLOCK(1)
diff --git a/drivers/sgi/audio/hal2.h b/drivers/sgi/audio/hal2.h
index 928a4fac0..bfbd74f9b 100644
--- a/drivers/sgi/audio/hal2.h
+++ b/drivers/sgi/audio/hal2.h
@@ -58,11 +58,12 @@ struct hal2_vol_regs {
/*
* Address of indirect internal register to be accessed. A write to this
* register initiates read or write access to the indirect registers in the
- * HAL2. Note that there af four indirect data registers.
+ * HAL2. Note that there af four indirect data registers for write access to
+ * registers larger than 16 byte.
*/
#define H2_IAR_TYPE_M 0xF000 /* bits 15:12, type of functional */
- /* block the register resides in */
+ /* block the register resides in */
/* 1=DMA Port */
/* 9=Global DMA Control */
/* 2=Bresenham */
@@ -95,24 +96,28 @@ struct hal2_vol_regs {
/*
* HAL2 internal addressing
*
- * The HAL2 has "indirect registers" which are accessed by writing the register
- * number into the Indirect Address register. And then reading or writing to the
- * Indirect Data registers as appropriate.
+ * The HAL2 has "indirect registers" (idr) which are accessed by writing to the
+ * Indirect Data registers. Write the address to the Indirect Address register
+ * to transfer the data.
*
- * The indirect registers always differ with 0x80 however we explicity give the
- * two addresses here. We define the H2IR_* to the read address and H2IW_* to
- * the write address and H2I_* to be fields in whatever register is referred to.
+ * We define the H2IR_* to the read address and H2IW_* to the write address and
+ * H2I_* to be fields in whatever register is referred to.
+ *
+ * When we write to indirect registers which are larger than one word (16 bit)
+ * we have to fill more than one indirect register before writing. When we read
+ * back however we have to read several times, each time with different Read
+ * Back Indexes (there are defs for doing this easily).
*/
/*
* Relay Control
*/
-#define H2IW_RELAY_C 0x09100 /* state of RELAY pin signal */
-#define H2IR_RELAY_C 0x09180 /* state of RELAY pin signal */
+#define H2IW_RELAY_C 0x9100 /* state of RELAY pin signal */
+#define H2IR_RELAY_C 0x9180 /* state of RELAY pin signal */
#define H2I_RELAY_C_STATE 0x01 /* state of RELAY pin signal */
#define H2IW_DMA_PORT_EN 0x09104 /* dma port enable */
-#define H2IR_DMA_PORT_EN 0x09184 /* dma port enable */
+#define H2IR_DMA_PORT_EN 0x9184 /* dma port enable */
#define H2I_DMA_PORT_EN_SY_IN 0x01 /* synth_in dma port */
#define H2I_DMA_PORT_EN_AESRX 0x02 /* aes receiver dma port */
#define H2I_DMA_PORT_EN_AESTX 0x04 /* aes transmitter dma port */
@@ -120,8 +125,8 @@ struct hal2_vol_regs {
#define H2I_DMA_PORT_EN_CODECR 0x10 /* codec receive dma port */
/* 0=disable 1=enable */
-#define H2IW_DMA_END 0x09108 /* global dma endian select */
-#define H2IR_DMA_END 0x09188 /* global dma endian select */
+#define H2IW_DMA_END 0x9108 /* global dma endian select */
+#define H2IR_DMA_END 0x9188 /* global dma endian select */
#define H2I_DMA_END_SY_IN 0x01 /* synth_in dma port */
#define H2I_DMA_END_AESRX 0x02 /* aes receiver dma port */
#define H2I_DMA_END_AESTX 0x04 /* aes transmitter dma port */
@@ -129,21 +134,21 @@ struct hal2_vol_regs {
#define H2I_DMA_END_CODECR 0x10 /* codec receive dma port */
/* 0=big endian 1=little endian */
-#define H2IW_DMA_DRV 0x0910C /* global dma bus drive enable */
-#define H2IR_DMA_DRV 0x0918C /* global dma bus drive enable */
+#define H2IW_DMA_DRV 0x910C /* global dma bus drive enable */
+#define H2IR_DMA_DRV 0x918C /* global dma bus drive enable */
-#define H2IW_SYNTH_C 0x01104 /* synth dma control write */
-#define H2IR_SYNTH_C 0x01184 /* synth dma control read */
+#define H2IW_SYNTH_C 0x1104 /* synth dma control write */
+#define H2IR_SYNTH_C 0x1184 /* synth dma control read */
-#define H2IW_AESRX_C 0x01204 /* aes rx dma control write */
-#define H2IR_AESRX_C 0x01284 /* aes rx dma control read */
+#define H2IW_AESRX_C 0x1204 /* aes rx dma control write */
+#define H2IR_AESRX_C 0x1284 /* aes rx dma control read */
#define H2I_AESRX_C_TS_EN 0x20 /* timestamp enable 0=no 1=yes */
#define H2I_AESRX_C_TS_FMT 0x40 /* timestamp format */
#define H2I_AESRX_C_NAUDIO 0x80 /* pbus dma data format */
/* 0=sign_ext 1=pass_non_audio */
-#define H2IW_AESTX_C 0x01304 /* aes tx dma control write */
-#define H2IR_AESTX_C 0x01384 /* aes tx dma control read */
+#define H2IW_AESTX_C 0x1304 /* aes tx dma control write */
+#define H2IR_AESTX_C 0x1384 /* aes tx dma control read */
#define H2I_AESTX_C_CLKID_M 0x18 /* bits 4:3, clockid */
/* 1=Bresenham Clock Gen 1 */
/* 2=Bresenham Clock Gen 2 */
@@ -153,8 +158,8 @@ struct hal2_vol_regs {
/* DAC */
-#define H2IW_DAC_C1 0x01404 /* dac tx dma control 1 write */
-#define H2IR_DAC_C1 0x01484 /* dac tx dma control 1 read */
+#define H2IW_DAC_C1 0x1404 /* dac tx dma control 1 write */
+#define H2IR_DAC_C1 0x1484 /* dac tx dma control 1 read */
#define H2I_DAC_C1_CLKID 0x18 /* bits 4:3, clockid */
/* 1=Bresenham Clock Gen 1 */
/* 2=Bresenham Clock Gen 2 */
@@ -162,16 +167,17 @@ struct hal2_vol_regs {
#define H2I_DAC_C1_DTYPE 0x300 /* bits 9:8 datatype */
/* 1=mono 2=stereo 3=quad */
-#define H2IW_DAC_C2_0 0x01408 /* dac control 2 write word 0 */
-#define H2IR_DAC_C2_0 0x01488 /* dac control 2 read word 0 */
+#define H2IW_DAC_C2 0x1408 /* dac control 2 write word 0 */
+ /* both words have to be written at */
+ /* the same time, fill idr[0-1] */
+#define H2IR_DAC_C2_0 0x1488 /* dac control 2 read word 0 */
+#define H2IR_DAC_C2_1 0x1489 /* dac control 2 read word 1 */
+ /* XXX: The spec says 0x1488 */
#define H2I_DAC_C2_0_R_GAIN 0x0f /* right a/d input gain bit 0-3 */
#define H2I_DAC_C2_0_L_GAIN 0xf0 /* left a/d input gain bit 0-3 */
#define H2I_DAC_C2_0_R_SEL 0x100 /* right a/d input select */
#define H2I_DAC_C2_0_L_SEL 0x200 /* left a/d input select */
#define H2I_DAC_C2_0_MUTE 0x400 /* 1=mute */
-
-#define H2IW_DAC_C2_1 0x01409 /* dac control 2 write word 1 */
-#define H2IR_DAC_C2_1 0x01488 /* dac control 2 read word 1 */
#define H2I_DAC_C2_1_DO1 0x01 /* digital output port bit 1 */
#define H2I_DAC_C2_1_DO2 0x02 /* digital output port bit 0 */
#define H2I_DAC_C2_1_R_ATTEN 0x7c /* bits 6:2 right a/d output */
@@ -180,8 +186,8 @@ struct hal2_vol_regs {
/* attenuation, bit 0-4 (4=msb) */
/* ADC */
-#define H2IW_ADC_C1 0x01504 /* adc tx dma control 1 write */
-#define H2IR_ADC_C1 0x01584 /* adc tx dma control 1 read */
+#define H2IW_ADC_C1 0x1504 /* adc tx dma control 1 write */
+#define H2IR_ADC_C1 0x1584 /* adc tx dma control 1 read */
#define H2I_ADC_C1_CLKID 0x18 /* bits 4:3, clockid */
/* 1=Bresenham Clock Gen 1 */
/* 2=Bresenham Clock Gen 2 */
@@ -189,16 +195,17 @@ struct hal2_vol_regs {
#define H2I_ADC_C1_DTYPE 0x300 /* bits 9:8, datatype */
/* 1=mono 2=stereo 3=quad */
-#define H2IW_ADC_C2_0 0x01508 /* adc control 2 write word 0 */
-#define H2IR_ADC_C2_0 0x01588 /* adc control 2 read word 0 */
+#define H2IW_ADC_C2 0x1508 /* adc control 2 write word 0-1 */
+ /* both words have to be written at */
+ /* the same time, fill idr[0-1] */
+#define H2IR_ADC_C2_0 0x1588 /* adc control 2 read word 0 */
+#define H2IR_ADC_C2_1 0x1589 /* adc control 2 read word 1 */
+ /* XXX: The spec says 0x1588 */
#define H2I_ADC_C2_0_R_GAIN 0x0f /* right a/d input gain bit 0-3 */
#define H2I_ADC_C2_0_L_GAIN 0xf0 /* left a/d input gain bit 0-3 */
#define H2I_ADC_C2_0_R_SEL 0x100 /* right a/d input select */
#define H2I_ADC_C2_0_L_SEL 0x200 /* left a/d input select */
#define H2I_ADC_C2_0_MUTE 0x400 /* 1=mute */
-
-#define H2IW_ADC_C2_1 0x01509 /* adc control 2 write word 1 */
-#define H2IR_ADC_C2_1 0x01588 /* adc control 2 read word 1 */
#define H2I_ADC_C2_1_DO1 0x01 /* digital output port bit 1 */
#define H2I_ADC_C2_1_DO2 0x02 /* digital output port bit 0 */
#define H2I_ADC_C2_1_R_ATTEN 0x7c /* bits 6:2, right a/d output */
@@ -206,53 +213,48 @@ struct hal2_vol_regs {
#define H2I_ADC_C2_1_L_ATTEN 0xf80 /* bits 11:7, left a/d output */
/* attenuation, bit 0-4 (4=msb) */
-#define H2IW_SYNTH_MAP_C 0x01104 /* synth dma handshake ctrl write */
-#define H2IR_SYNTH_MAP_C 0x01184 /* synth dma handshake ctrl read */
+#define H2IW_SYNTH_MAP_C 0x1104 /* synth dma handshake ctrl write */
+#define H2IR_SYNTH_MAP_C 0x1184 /* synth dma handshake ctrl read */
-#define H2IW_BRES1_C1 0x02104 /* clock gen 1 ctrl 1 write */
-#define H2IR_BRES1_C1 0x02184 /* clock gen 1 ctrl 1 read */
+#define H2IW_BRES1_C1 0x2104 /* clock gen 1 ctrl 1 write */
+#define H2IR_BRES1_C1 0x2184 /* clock gen 1 ctrl 1 read */
#define H2I_BRES1_C1_FSRSEL 0x03 /* master clock source */
/* 0=48.0 1=44.1 2=aes_rx */
-#define H2IW_BRES1_C2_0 0x02108 /* clock gen 1 ctrl 2 write word 0 */
-#define H2IR_BRES1_C2_0 0x02188 /* clock gen 1 ctrl 2 write word 0 */
+#define H2IW_BRES1_C2 0x2108 /* clock gen 1 ctrl 2 write word 0-1 */
+#define H2IR_BRES1_C2_0 0x2188 /* clock gen 1 ctrl 2 read word 0 */
+#define H2IR_BRES1_C2_1 0x2189 /* clock gen 1 ctrl 2 read word 1 */
+ /* XXX: The spec says 0x2188 */
#define H2I_BRES1_C2_0_INC 0xffff /* increment value, inc <= mod */
-
-#define H2IW_BRES1_C2_1 0x02108 /* clock gen 1 ctrl 2 write word 1 */
-#define H2IR_BRES1_C2_1 0x02188 /* clock gen 1 ctrl 2 write word 1 */
#define H2I_BRES1_C2_1_INC 0xffff /* modcontrol value, */
/* modctrl=0x00ffff & (modinc-1) */
-#define H2IW_BRES2_C1 0x02204 /* clock gen 2 ctrl 1 write */
-#define H2IR_BRES2_C1 0x02284 /* clock gen 2 ctrl 1 read */
+#define H2IW_BRES2_C1 0x2204 /* clock gen 2 ctrl 1 write */
+#define H2IR_BRES2_C1 0x2284 /* clock gen 2 ctrl 1 read */
#define H2I_BRES2_C1_FSRSEL 0x03 /* master clock source */
/* 0=48.0 1=44.1 2=aes_rx */
-#define H2IW_BRES2_C2_0 0x02208 /* clock gen 2 ctrl 2 write word 0 */
-#define H2IR_BRES2_C2_0 0x02288 /* clock gen 2 ctrl 2 write word 0 */
+#define H2IW_BRES2_C2 0x2208 /* clock gen 2 ctrl 2 write word 0-1 */
+#define H2IR_BRES2_C2_0 0x2288 /* clock gen 2 ctrl 2 read word 0 */
+#define H2IR_BRES2_C2_1 0x2289 /* clock gen 2 ctrl 2 read word 1 */
#define H2I_BRES2_C2_0_INC 0xffff /* increment value, inc <= mod */
-
-#define H2IW_BRES2_C2_1 0x02208 /* clock gen 2 ctrl 2 write word 1 */
-#define H2IR_BRES2_C2_1 0x02289 /* clock gen 2 ctrl 2 write word 1 */
#define H2I_BRES2_C2_1_INC 0xffff /* modcontrol value, */
/* modctrl=0x00ffff & (modinc-1) */
-#define H2IW_BRES3_C1 0x02304 /* clock gen 3 ctrl 1 write */
-#define H2IR_BRES3_C1 0x02384 /* clock gen 3 ctrl 1 read */
+#define H2IW_BRES3_C1 0x2304 /* clock gen 3 ctrl 1 write */
+#define H2IR_BRES3_C1 0x2384 /* clock gen 3 ctrl 1 read */
#define H2I_BRES3_C1_FSRSEL 0x03 /* master clock source */
/* 0=48.0 1=44.1 2=aes_rx */
-#define H2IW_BRES3_C2_0 0x02308 /* clock gen 3 ctrl 2 write word 0 */
-#define H2IR_BRES3_C2_0 0x02388 /* clock gen 3 ctrl 2 write word 0 */
+#define H2IW_BRES3_C2 0x2308 /* clock gen 3 ctrl 2 write word 0-1 */
+#define H2IR_BRES3_C2_0 0x2388 /* clock gen 3 ctrl 2 read word 0 */
+#define H2IR_BRES3_C2_1 0x2389 /* clock gen 3 ctrl 2 read word 1 */
#define H2I_BRES3_C2_0_INC 0xffff /* increment value, inc <= mod */
-
-#define H2IW_BRES3_C2_1 0x02308 /* clock gen 3 ctrl 2 write word 1 */
-#define H2IR_BRES3_C2_1 0x02389 /* clock gen 3 ctrl 2 write word 1 */
#define H2I_BRES3_C2_1_INC 0xffff /* modcontrol value, */
/* modctrl=0x00ffff & (modinc-1) */
-#define H2IW_UTIME 0x03104 /* unix timer write (preload time) */
-#define H2IR_UTIME 0x03184 /* unix timer read */
+#define H2IW_UTIME 0x3104 /* unix timer write (preload time) */
+#define H2IR_UTIME 0x3184 /* unix timer read */
#define H2I_UTIME_0_LD 0xffff /* microseconds, LSB's */
#define H2I_UTIME_1_LD0 0x0f /* microseconds, MSB's */
#define H2I_UTIME_1_LD1 0xf0 /* tenths of microseconds */