#ifndef CMEDIAHD_H
#define CMEDIAHD_H
#define CMEDIAHD_NAME "audiocmihd"
#define CMEDIAHD_NUM_PORTC 2
#define CMEDIAHD_PLAY 0
#define CMEDIAHD_REC 1
#define CMEDIAHD_BUF_LEN (65536)
#define PCI_VENDOR_ID_CMEDIA 0x13F6
#define PCI_DEVICE_ID_CMEDIAHD 0x8788
#define CMEDIAHD_MAX_INTRS 512
#define CMEDIAHD_MIN_INTRS 48
#define CMEDIAHD_INTRS 100
#define RECA_ADDR (devc->base+0x00)
#define RECA_SIZE (devc->base+0x04)
#define RECA_FRAG (devc->base+0x06)
#define RECB_ADDR (devc->base+0x08)
#define RECB_SIZE (devc->base+0x0C)
#define RECB_FRAG (devc->base+0x0E)
#define RECC_ADDR (devc->base+0x10)
#define RECC_SIZE (devc->base+0x14)
#define RECC_FRAG (devc->base+0x16)
#define SPDIF_ADDR (devc->base+0x18)
#define SPDIF_SIZE (devc->base+0x1C)
#define SPDIF_FRAG (devc->base+0x1E)
#define MULTICH_ADDR (devc->base+0x20)
#define MULTICH_SIZE (devc->base+0x24)
#define MULTICH_FRAG (devc->base+0x28)
#define FPOUT_ADDR (devc->base+0x30)
#define FPOUT_SIZE (devc->base+0x34)
#define FPOUT_FRAG (devc->base+0x36)
#define DMA_START (devc->base+0x40)
#define CHAN_RESET (devc->base+0x42)
#define MULTICH_MODE (devc->base+0x43)
#define IRQ_MASK (devc->base+0x44)
#define IRQ_STAT (devc->base+0x46)
#define MISC_REG (devc->base+0x48)
#define REC_FORMAT (devc->base+0x4A)
#define PLAY_FORMAT (devc->base+0x4B)
#define REC_MODE (devc->base+0x4C)
#define FUNCTION (devc->base+0x50)
#define I2S_MULTICH_DAC (devc->base+0x60)
#define I2S_ADC1 (devc->base+0x62)
#define I2S_ADC2 (devc->base+0x64)
#define I2S_ADC3 (devc->base+0x66)
#define SPDIF_FUNC (devc->base+0x70)
#define SPDIFOUT_CHAN_STAT (devc->base+0x74)
#define SPDIFIN_CHAN_STAT (devc->base+0x78)
#define TWO_WIRE_ADDR (devc->base+0x90)
#define TWO_WIRE_MAP (devc->base+0x91)
#define TWO_WIRE_DATA (devc->base+0x92)
#define TWO_WIRE_CTRL (devc->base+0x94)
#define SPI_CONTROL (devc->base+0x98)
#define SPI_DATA (devc->base+0x99)
#define MPU401_DATA (devc->base+0xA0)
#define MPU401_COMMAND (devc->base+0xA1)
#define MPU401_CONTROL (devc->base+0xA2)
#define GPI_DATA (devc->base+0xA4)
#define GPI_IRQ_MASK (devc->base+0xA5)
#define GPIO_DATA (devc->base+0xA6)
#define GPIO_CONTROL (devc->base+0xA8)
#define GPIO_IRQ_MASK (devc->base+0xAA)
#define DEVICE_SENSE (devc->base+0xAC)
#define PLAY_ROUTING (devc->base+0xC0)
#define REC_ROUTING (devc->base+0xC2)
#define REC_MONITOR (devc->base+0xC3)
#define MONITOR_ROUTING (devc->base+0xC4)
#define AC97_CTRL (devc->base+0xD0)
#define AC97_INTR_MASK (devc->base+0xD2)
#define AC97_INTR_STAT (devc->base+0xD3)
#define AC97_OUT_CHAN_CONFIG (devc->base+0xD4)
#define AC97_IN_CHAN_CONFIG (devc->base+0xD8)
#define AC97_CMD_DATA (devc->base+0xDC)
#define CODEC_VERSION (devc->base+0xE4)
#define CTRL_VERSION (devc->base+0xE6)
#define ASUS_VENDOR_ID 0x1043
#define SUBID_XONAR_D2 0x8269
#define SUBID_XONAR_D2X 0x82b7
#define SUBID_XONAR_D1 0x834f
#define SUBID_XONAR_DX 0x8275
#define SUBID_XONAR_STX 0x835c
#define SUBID_XONAR_DS 0x838e
#define SUBID_GENERIC 0x0000
#define XONAR_DX_FRONTDAC 0x9e
#define XONAR_DX_SURRDAC 0x30
#define XONAR_STX_FRONTDAC 0x98
#define XONAR_DS_FRONTDAC 0x1
#define XONAR_DS_SURRDAC 0x0
#define AK4396_CTL1 0x00
#define AK4396_CTL2 0x01
#define AK4396_CTL3 0x02
#define AK4396_LchATTCtl 0x03
#define AK4396_RchATTCtl 0x04
#define CS4398_CHIP_ID 0x01
#define CS4398_MODE_CTRL 0x02
#define CS4398_MIXING 0x03
#define CS4398_MUTE_CTRL 0x04
#define CS4398_VOLA 0x05
#define CS4398_VOLB 0x06
#define CS4398_RAMP_CTRL 0x07
#define CS4398_MISC_CTRL 0x08
#define CS4398_MISC2_CTRL 0x09
#define CS4398_POWER_DOWN (1<<7)
#define CS4398_CPEN (1<<6)
#define CS4398_FREEZE (1<<5)
#define CS4398_MCLKDIV2 (1<<4)
#define CS4398_MCLKDIV3 (1<<3)
#define CS4398_I2S (1<<4)
#define CS4362A_MODE1_CTRL 0x01
#define CS4362A_MODE2_CTRL 0x02
#define CS4362A_MODE3_CTRL 0x03
#define CS4362A_FILTER_CTRL 0x04
#define CS4362A_INVERT_CTRL 0x05
#define CS4362A_MIX1_CTRL 0x06
#define CS4362A_VOLA_1 0x07
#define CS4362A_VOLB_1 0x08
#define CS4362A_MIX2_CTRL 0x09
#define CS4362A_VOLA_2 0x0A
#define CS4362A_VOLB_2 0x0B
#define CS4362A_MIX3_CTRL 0x0C
#define CS4362A_VOLA_3 0x0D
#define CS4362A_VOLB_3 0x0E
#define CS4362A_CHIP_REV 0x12
#define CS4362A_CPEN (1<<7)
#define CS4362A_FREEZE (1<<6)
#define CS4362A_MCLKDIV (1<<5)
#define CS4362A_DAC3_ENABLE (1<<3)
#define CS4362A_DAC2_ENABLE (1<<2)
#define CS4362A_DAC1_ENABLE (1<<1)
#define CS4362A_POWER_DOWN (1)
#define CS4362A_DIF_LJUST 0x00
#define CS4362A_DIF_I2S 0x10
#define CS4362A_DIF_RJUST16 0x20
#define CS4362A_DIF_RJUST24 0x30
#define CS4362A_DIF_RJUST20 0x40
#define CS4362A_DIF_RJUST18 0x50
#define CS4362A_RAMP_IMMEDIATE 0x00
#define CS4362A_RAMP_ZEROCROSS 0x40
#define CS4362A_RAMP_SOFT 0x80
#define CS4362A_RAMP_SOFTZERO 0xC0
#define CS4362A_SINGLE_VOL 0x20
#define CS4362A_RAMP_ERROR 0x10
#define CS4362A_MUTEC_POL 0x08
#define CS4362A_AUTOMUTE 0x04
#define CS4362A_SIX_MUTE 0x00
#define CS4362A_ONE_MUTE 0x01
#define CS4362A_THREE_MUTE 0x03
#define CS4362A_FILT_SEL 0x10
#define CS4362A_DEM_NONE 0x00
#define CS4362A_DEM_44KHZ 0x02
#define CS4362A_DEM_48KHZ 0x04
#define CS4362A_DEM_32KHZ 0x06
#define CS4362A_RAMPDOWN 0x01
#define CS4362A_INV_A3 (1<<4)
#define CS4362A_INV_B3 (1<<5)
#define CS4362A_INV_A2 (1<<2)
#define CS4362A_INV_B2 (1<<3)
#define CS4362A_INV_A1 (1)
#define CS4362A_INV_B1 (1<<1)
#define CS4362A_VOL_MUTE 0x80
#define CS4398_VOL(x) \
((x) == 0 ? 0xFF : (0xC0 - ((x)*192/100)))
#define CS4362A_VOL(x) \
(char)((x) == 0 ? 0xFF : (0x60 - ((x)*96/100)))
static const char xd2_codec_map[4] = {
0, 1, 2, 4
};
typedef struct _cmediahd_devc_t cmediahd_devc_t;
typedef struct _cmediahd_portc_t cmediahd_portc_t;
typedef enum {
CTL_VOLUME = 0,
CTL_FRONT,
CTL_REAR,
CTL_CENTER,
CTL_LFE,
CTL_SURROUND,
CTL_MONITOR,
CTL_RECSRC,
CTL_RECGAIN,
CTL_MICVOL,
CTL_AUXVOL,
CTL_CDVOL,
CTL_LOOP,
CTL_SPREAD,
CTL_NUM
} cmediahd_ctrl_num_t;
typedef struct cmediahd_ctrl
{
cmediahd_devc_t *devc;
audio_ctrl_t *ctrl;
cmediahd_ctrl_num_t num;
uint64_t val;
} cmediahd_ctrl_t;
typedef struct cmediahd_regs
{
caddr_t addr;
caddr_t size;
caddr_t frag;
caddr_t i2s;
int chan;
#define REC_A 0
#define REC_B 1
#define REC_C 2
#define PLAY_SPDIF 3
#define PLAY_MULTI 4
#define PLAY_FRONT 5
} cmediahd_regs_t;
struct _cmediahd_portc_t
{
cmediahd_devc_t *devc;
audio_engine_t *engine;
int chans;
int direction;
ddi_dma_handle_t buf_dmah;
ddi_acc_handle_t buf_acch;
uint32_t paddr;
caddr_t kaddr;
size_t buf_size;
size_t buf_frames;
unsigned fragfr;
unsigned nfrags;
unsigned nframes;
unsigned bufsz;
size_t offset;
uint64_t count;
int syncdir;
};
struct _cmediahd_devc_t
{
dev_info_t *dip;
audio_dev_t *adev;
boolean_t has_ac97, has_fp_ac97;
int model;
ac97_t *ac97, *fp_ac97;
boolean_t suspended;
ddi_acc_handle_t pcih;
ddi_acc_handle_t regsh;
caddr_t base;
kmutex_t mutex;
kmutex_t low_mutex;
cmediahd_regs_t rec_eng;
cmediahd_portc_t *portc[CMEDIAHD_NUM_PORTC];
int gpio_mic, gpio_out, gpio_codec, gpio_alt;
cmediahd_ctrl_t controls[CTL_NUM];
};
#define INB(devc, reg) ddi_get8(devc->regsh, (void *)(reg))
#define OUTB(devc, val, reg) ddi_put8(devc->regsh, (void *)(reg), (val))
#define INW(devc, reg) ddi_get16(devc->regsh, (void *)(reg))
#define OUTW(devc, val, reg) ddi_put16(devc->regsh, (void *)(reg), (val))
#define INL(devc, reg) ddi_get32(devc->regsh, (void *)(reg))
#define OUTL(devc, val, reg) ddi_put32(devc->regsh, (void *)(reg), (val))
#endif