#ifndef _AUDIO_4231_H
#define _AUDIO_4231_H
#ifdef __cplusplus
extern "C" {
#endif
#define CS_DEV_NAME "SUNW,CS4231"
#define CS_DEV_CONFIG_ONBRD1 "onboard1"
#define CS_DEV_VERSION "a"
#define CS_DEV_VERSION_A CS_DEV_VERSION
#define CS_DEV_VERSION_B "b"
#define CS_DEV_VERSION_C "c"
#define CS_DEV_VERSION_D "d"
#define CS_DEV_VERSION_E "e"
#define CS_DEV_VERSION_F "f"
#define CS_DEV_VERSION_G "g"
#define CS_DEV_VERSION_H "h"
#define CS4231_NAME "audiocs"
#define CS4231_MOD_NAME "CS4231 audio driver"
#ifdef _KERNEL
enum {
CTL_VOLUME = 0,
CTL_IGAIN,
CTL_MGAIN,
CTL_INPUTS,
CTL_OUTPUTS,
CTL_MICBOOST,
CTL_NUM
};
typedef struct CS_engine CS_engine_t;
typedef struct CS_ctrl CS_ctrl_t;
typedef struct CS_state CS_state_t;
struct cs4231_apc {
uint32_t dmacsr;
uint32_t lpad[3];
uint32_t dmacva;
uint32_t dmacc;
uint32_t dmacnva;
uint32_t dmacnc;
uint32_t dmapva;
uint32_t dmapc;
uint32_t dmapnva;
uint32_t dmapnc;
};
typedef struct cs4231_apc cs4231_apc_t;
#define APC_DMACSR state->cs_regs->apc.dmacsr
#define APC_DMACVA state->cs_regs->apc.dmacva
#define APC_DMACC state->cs_regs->apc.dmacc
#define APC_DMACNVA state->cs_regs->apc.dmacnva
#define APC_DMACNC state->cs_regs->apc.dmacnc
#define APC_DMAPVA state->cs_regs->apc.dmapva
#define APC_DMAPC state->cs_regs->apc.dmapc
#define APC_DMAPNVA state->cs_regs->apc.dmapnva
#define APC_DMAPNC state->cs_regs->apc.dmapnc
#define APC_RESET 0x00000001u
#define APC_CDMA_GO 0x00000004u
#define APC_PDMA_GO 0x00000008u
#define APC_LOOP_BACK 0x00000010u
#define APC_COD_PDWN 0x00000020u
#define APC_C_ABORT 0x00000040u
#define APC_P_ABORT 0x00000080u
#define APC_CXI_EN 0x00000100u
#define APC_CXI 0x00000200u
#define APC_CD 0x00000400u
#define APC_CX 0x00000800u
#define APC_PMI_EN 0x00001000u
#define APC_PD 0x00002000u
#define APC_PM 0x00004000u
#define APC_PMI 0x00008000u
#define APC_EIE 0x00010000u
#define APC_CIE 0x00020000u
#define APC_PIE 0x00040000u
#define APC_IE 0x00080000u
#define APC_EI 0x00100000u
#define APC_CI 0x00200000u
#define APC_PI 0x00400000u
#define APC_IP 0x00800000u
#define APC_ID 0xff000000u
#define APC_ID_VALUE 0x7E000000u
#define APC_CLEAR_RESET_VALUE 0x00
#define APC_PINTR_MASK (APC_PI|APC_PMI)
#define APC_CINTR_MASK (APC_CI|APC_CXI)
#define APC_COMMON_MASK (APC_IP|APC_EI)
#define APC_PINTR_ENABLE (APC_PIE|APC_PMI_EN)
#define APC_CINTR_ENABLE (APC_CIE|APC_CXI_EN)
#define APC_COMMON_ENABLE (APC_IE|APC_EIE)
#define APC_PLAY_ENABLE (APC_PDMA_GO)
#define APC_PLAY_DISABLE (APC_PDMA_GO)
#define APC_CAP_ENABLE (APC_CDMA_GO)
#define APC_CAP_DISABLE (APC_CDMA_GO)
struct cs4231_eb2regs {
uint32_t eb2csr;
uint32_t eb2acr;
uint32_t eb2bcr;
};
typedef struct cs4231_eb2regs cs4231_eb2regs_t;
#define EB2_PLAY_CSR state->cs_eb2_regs.play->eb2csr
#define EB2_PLAY_ACR state->cs_eb2_regs.play->eb2acr
#define EB2_PLAY_BCR state->cs_eb2_regs.play->eb2bcr
#define EB2_REC_CSR state->cs_eb2_regs.record->eb2csr
#define EB2_REC_ACR state->cs_eb2_regs.record->eb2acr
#define EB2_REC_BCR state->cs_eb2_regs.record->eb2bcr
#define EB2_AUXIO_REG state->cs_eb2_regs.auxio
#define EB2_AUXIO_COD_PDWN 0x00000001u
#define EB2_INT_PEND 0x00000001u
#define EB2_ERR_PEND 0x00000002u
#define EB2_DRAIN 0x00000004u
#define EB2_INT_EN 0x00000010u
#define EB2_RESET 0x00000080u
#define EB2_WRITE 0x00000100u
#define EB2_READ 0x00000000u
#define EB2_EN_DMA 0x00000200u
#define EB2_CYC_PENDING 0x00000400u
#define EB2_DIAG_RD_DONE 0x00000800u
#define EB2_DIAG_WR_DONE 0x00001000u
#define EB2_EN_CNT 0x00002000u
#define EB2_TC 0x00004000u
#define EB2_DIS_CSR_DRN 0x00010000u
#define EB2_16 0x00000000u
#define EB2_32 0x00040000u
#define EB2_4 0x00080000u
#define EB2_64 0x000C0000u
#define EB2_DIAG_EN 0x00100000u
#define EB2_DIS_ERR_PEND 0x00400000u
#define EB2_TCI_DIS 0x00800000u
#define EB2_EN_NEXT 0x01000000u
#define EB2_DMA_ON 0x02000000u
#define EB2_A_LOADED 0x04000000u
#define EB2_NA_LOADED 0x08000000u
#define EB2_DEV_ID 0xf0000000u
#define EB2_ID_VALUE 0xC0000000u
#define EB2_PCLEAR_RESET_VALUE (EB2_READ|EB2_EN_NEXT|EB2_EN_CNT)
#define EB2_RCLEAR_RESET_VALUE (EB2_WRITE|EB2_EN_NEXT|EB2_EN_CNT)
#define EB2_PLAY_ENABLE (EB2_EN_DMA|EB2_EN_CNT|EB2_64|\
EB2_PCLEAR_RESET_VALUE)
#define EB2_REC_ENABLE (EB2_EN_DMA|EB2_EN_CNT|EB2_64|\
EB2_RCLEAR_RESET_VALUE)
#define EB2_FIFO_DRAIN (EB2_DRAIN|EB2_CYC_PENDING)
#define CS4231_REGS (32)
#define CS4231_NCOMPONENTS (1)
#define CS4231_COMPONENT (0)
#define CS4231_PWR_OFF (0)
#define CS4231_PWR_ON (1)
#define CS4231_TIMEOUT (100000)
#define CS4231_300MS (300*1000)
#define CS4231_PLAY 0
#define CS4231_REC 1
#define CS4231_NFRAMES 4096
#define CS4231_NFRAGS 2
#define CS4231_FRAGSZ ((CS4231_NFRAMES / CS4231_NFRAGS) * 4)
#define CS4231_BUFSZ (CS4231_NFRAMES * 4)
enum cs_dmae_types {APC_DMA, EB2_DMA};
typedef enum cs_dmae_types cs_dmae_types_e;
struct cs4231_pioregs {
uint8_t iar;
uint8_t pad1[3];
uint8_t idr;
uint8_t pad2[3];
uint8_t statr;
uint8_t pad3[3];
uint8_t piodr;
uint8_t pad4[3];
};
typedef struct cs4231_pioregs cs4231_pioregs_t;
struct cs4231_eb2 {
cs4231_eb2regs_t *play;
cs4231_eb2regs_t *record;
uint_t *auxio;
};
typedef struct cs4231_eb2 cs4231_eb2_t;
struct cs4231_regs {
cs4231_pioregs_t codec;
cs4231_apc_t apc;
};
typedef struct cs4231_regs cs4231_regs_t;
#define CS4231_IAR state->cs_regs->codec.iar
#define CS4231_IDR state->cs_regs->codec.idr
#define CS4231_STATUS state->cs_regs->codec.statr
#define CS4231_PIODR state->cs_regs->codec.piodr
struct cs4231_handle {
ddi_acc_handle_t cs_codec_hndl;
ddi_acc_handle_t cs_eb2_play_hndl;
ddi_acc_handle_t cs_eb2_rec_hndl;
ddi_acc_handle_t cs_eb2_auxio_hndl;
};
typedef struct cs4231_handle cs4231_handle_t;
#define CODEC_HANDLE state->cs_handles.cs_codec_hndl
#define APC_HANDLE state->cs_handles.cs_codec_hndl
#define EB2_PLAY_HNDL state->cs_handles.cs_eb2_play_hndl
#define EB2_REC_HNDL state->cs_handles.cs_eb2_rec_hndl
#define EB2_AUXIO_HNDL state->cs_handles.cs_eb2_auxio_hndl
struct CS_engine {
CS_state_t *ce_state;
audio_engine_t *ce_engine;
int ce_num;
unsigned ce_syncdir;
boolean_t ce_started;
uint64_t ce_count;
caddr_t ce_kaddr;
ddi_dma_handle_t ce_dmah;
ddi_acc_handle_t ce_acch;
uint32_t ce_paddr;
uint32_t ce_curoff;
int ce_curidx;
ddi_acc_handle_t ce_regsh;
cs4231_eb2regs_t *ce_eb2regs;
uint8_t ce_codec_en;
};
struct CS_ctrl {
CS_state_t *cc_state;
audio_ctrl_t *cc_ctrl;
uint32_t cc_num;
uint64_t cc_val;
};
struct CS_state {
kmutex_t cs_lock;
kcondvar_t cs_cv;
dev_info_t *cs_dip;
audio_dev_t *cs_adev;
cs_dmae_types_e cs_dma_engine;
struct cs4231_dma_ops *cs_dma_ops;
cs4231_regs_t *cs_regs;
cs4231_eb2_t cs_eb2_regs;
cs4231_handle_t cs_handles;
boolean_t cs_suspended;
boolean_t cs_powered;
CS_engine_t *cs_engines[2];
boolean_t cs_revA;
uint8_t cs_save[CS4231_REGS];
uint64_t cs_imask;
uint64_t cs_omask;
uint64_t cs_omod;
CS_ctrl_t *cs_ogain;
CS_ctrl_t *cs_igain;
CS_ctrl_t *cs_micboost;
CS_ctrl_t *cs_mgain;
CS_ctrl_t *cs_outputs;
CS_ctrl_t *cs_inputs;
};
struct cs4231_dma_ops {
char *dma_device;
ddi_dma_attr_t *cs_dma_attr;
int (*cs_dma_map_regs)(CS_state_t *);
void (*cs_dma_unmap_regs)(CS_state_t *);
void (*cs_dma_reset)(CS_state_t *);
int (*cs_dma_start)(CS_engine_t *);
void (*cs_dma_stop)(CS_engine_t *);
void (*cs_dma_power)(CS_state_t *, int);
void (*cs_dma_reload)(CS_engine_t *);
uint32_t (*cs_dma_addr)(CS_engine_t *);
};
typedef struct cs4231_dma_ops cs4231_dma_ops_t;
extern cs4231_dma_ops_t cs4231_apcdma_ops;
extern cs4231_dma_ops_t cs4231_eb2dma_ops;
#define CS4231_DMA_MAP_REGS(S) ((S)->cs_dma_ops->cs_dma_map_regs)(S)
#define CS4231_DMA_UNMAP_REGS(S) ((S)->cs_dma_ops->cs_dma_unmap_regs)(S)
#define CS4231_DMA_RESET(S) ((S)->cs_dma_ops->cs_dma_reset)(S)
#define CS4231_DMA_START(S, E) ((S)->cs_dma_ops->cs_dma_start)(E)
#define CS4231_DMA_STOP(S, E) ((S)->cs_dma_ops->cs_dma_stop)(E)
#define CS4231_DMA_POWER(S, L) ((S)->cs_dma_ops->cs_dma_power)(S, L)
#define CS4231_DMA_ATTR(S) ((S)->cs_dma_ops->cs_dma_attr)
#define CS4231_DMA_RELOAD(S, E) ((S)->cs_dma_ops->cs_dma_reload)(E)
#define CS4231_DMA_ADDR(S, E) ((S)->cs_dma_ops->cs_dma_addr)(E)
#define CS4231_RETRIES 10
#define OR_SET_WORD(handle, addr, val) \
ddi_put32((handle), (uint_t *)(addr), \
(ddi_get32((handle), (uint_t *)(addr)) | (uint_t)(val)))
#define AND_SET_WORD(handle, addr, val) \
ddi_put32((handle), (uint_t *)(addr), \
(ddi_get32((handle), (uint_t *)(addr)) & (uint_t)(val)))
#define IAR_ADDRESS_MASK 0x1f
#define IAR_TRD 0x20
#define IAR_MCE 0x40
#define IAR_INIT 0x80
#define STATUS_INT 0x01
#define STATUS_PRDY 0x02
#define STATUS_PLR 0x04
#define STATUS_PUL 0x08
#define STATUS_SER 0x10
#define STATUS_CRDY 0x20
#define STATUS_CLR 0x40
#define STATUS_CUL 0x80
#define STATUS_RESET 0x00
#define LADCI_REG 0x00
#define LADCI_GAIN_MASK 0x0f
#define LADCI_LMGE 0x20
#define LADCI_LLINE 0x00
#define LADCI_LAUX1 0x40
#define LADCI_LMIC 0x80
#define LADCI_LLOOP 0xc0
#define LADCI_IN_MASK 0xc0
#define LADCI_VALID_MASK 0xef
#define RADCI_REG 0x01
#define RADCI_GAIN_MASK 0x0f
#define RADCI_RMGE 0x20
#define RADCI_RLINE 0x00
#define RADCI_RAUX1 0x40
#define RADCI_RMIC 0x80
#define RADCI_RLOOP 0xc0
#define RADCI_IN_MASK 0xc0
#define RADCI_VALID_MASK 0xef
#define LAUX1_REG 0x02
#define LAUX1_GAIN_MASK 0x1f
#define LAUX1_LX1M 0x80
#define LAUX1_UNITY_GAIN 0x08
#define LAUX1_VALID_MASK 0x9f
#define RAUX1_REG 0x03
#define RAUX1_GAIN_MASK 0x1f
#define RAUX1_RX1M 0x80
#define RAUX1_UNITY_GAIN 0x08
#define RAUX1_VALID_MASK 0x9f
#define LAUX2_REG 0x04
#define LAUX2_GAIN_MASK 0x1f
#define LAUX2_LX2M 0x80
#define LAUX2_UNITY_GAIN 0x08
#define LAUX2_VALID_MASK 0x9f
#define RAUX2_REG 0x05
#define RAUX2_GAIN_MASK 0x1f
#define RAUX2_RX2M 0x80
#define RAUX2_UNITY_GAIN 0x08
#define RAUX2_VALID_MASK 0x9f
#define LDACO_REG 0x06
#define LDACO_ATTEN_MASK 0x3f
#define LDACO_LDM 0x80
#define LDACO_MID_GAIN 0x11
#define LDAC0_VALID_MASK 0xbf
#define RDACO_REG 0x07
#define RDACO_ATTEN_MASK 0x3f
#define RDACO_RDM 0x80
#define RDACO_MID_GAIN 0x11
#define RDAC0_VALID_MASK 0xbf
#define FSDF_REG 0x08
#define FS_5510 0x01
#define FS_6620 0x0f
#define FS_8000 0x00
#define FS_9600 0x0e
#define FS_11025 0x03
#define FS_16000 0x02
#define FS_18900 0x05
#define FS_22050 0x07
#define FS_27420 0x04
#define FS_32000 0x06
#define FS_33075 0x0d
#define FS_37800 0x09
#define FS_44100 0x0b
#define FS_48000 0x0c
#define PDF_STEREO 0x10
#define PDF_MONO 0x00
#define PDF_LINEAR8 0x00
#define PDF_ULAW8 0x20
#define PDF_LINEAR16LE 0x40
#define PDF_ALAW8 0x60
#define PDF_ADPCM4 0xa0
#define PDF_LINEAR16BE 0xc0
#define FSDF_VALID_MASK 0xff
#ifdef _BIG_ENDIAN
#define PDF_LINEAR16NE PDF_LINEAR16BE
#else
#define PDF_LINEAR16NE PDF_LINEAR16LE
#endif
#define INTC_REG 0x09
#define INTC_PEN 0x01
#define INTC_CEN 0x02
#define INTC_SDC 0x04
#define INTC_DDC 0x00
#define INTC_ACAL 0x08
#define INTC_PPIO 0x40
#define INTC_PDMA 0x00
#define INTC_CPIO 0x80
#define INTC_CDMA 0x00
#define INTC_VALID_MASK 0xcf
#define PC_REG 0x0a
#define PC_IEN 0x02
#define PC_DEN 0x04
#define PC_XCTL0 0x40
#define PC_LINE_OUT_MUTE 0x40
#define PC_XCTL1 0x80
#define PC_HEADPHONE_MUTE 0x80
#define PC_VALID_MASK 0xca
#define ESI_REG 0x0b
#define ESI_ORL_MASK 0x03
#define ESI_ORR_MASK 0x0c
#define ESI_DRS 0x10
#define ESI_ACI 0x20
#define ESI_PUR 0x40
#define ESI_COR 0x80
#define ESI_VALID_MASK 0xff
#define MID_REG 0x0c
#define MID_ID_MASK 0x0f
#define MID_MODE2 0x40
#define MID_VALID_MASK 0xcf
#define LC_REG 0x0d
#define LC_LBE 0x01
#define LC_ATTEN_MASK 0xfc
#define LC_OFF 0x00
#define LC_VALID_MASK 0xfd
#define PUB_REG 0x0e
#define PUB_VALID_MASK 0xff
#define PLB_REG 0x0f
#define PLB_VALID_MASK 0xff
#define AFE1_REG 0x10
#define AFE1_DACZ 0x01
#define AFE1_TE 0x40
#define AFE1_OLB 0x80
#define AFE1_VALID_MASK 0xc1
#define AFE2_REG 0x11
#define AFE2_HPF 0x01
#define AFE2_VALID_MASK 0x01
#define LLIC_REG 0x12
#define LLIC_MIX_GAIN_MASK 0x1f
#define LLIC_LLM 0x80
#define LLIC_UNITY_GAIN 0x08
#define LLIC_VALID_MASK 0x9f
#define RLIC_REG 0x13
#define RLIC_MIX_GAIN_MASK 0x1f
#define RLIC_RLM 0x80
#define RLIC_UNITY_GAIN 0x08
#define RLIC_VALID_MASK 0x9f
#define TLB_REG 0x14
#define TLB_VALID_MASK 0xff
#define TUB_REG 0x15
#define TUB_VALID_MASK 0xff
#define AFS_REG 0x18
#define AFS_PU 0x01
#define AFS_PO 0x02
#define AFS_CO 0x04
#define AFS_CU 0x08
#define AFS_PI 0x10
#define AFS_CI 0x20
#define AFS_TI 0x40
#define AFS_RESET_STATUS 0x00
#define AFS_VALID_MASK 0x7f
#define VID_REG 0x19
#define VID_CID_MASK 0x07
#define VID_VERSION_MASK 0xe0
#define VID_A 0x20
#define VID_CDE 0x80
#define VID_VALID_MASK 0xe7
#define MIOC_REG 0x1a
#define MIOC_MI_ATTEN_MASK 0x0f
#define MIOC_MOM 0x40
#define MIOC_MONO_SPKR_MUTE 0x40
#define MIOC_MIM 0x80
#define MIOC_VALID_MASK 0xcf
#define CDF_REG 0x1c
#define CDF_STEREO 0x10
#define CDF_MONO 0x00
#define CDF_LINEAR8 0x00
#define CDF_ULAW8 0x20
#define CDF_LINEAR16LE 0x40
#define CDF_ALAW8 0x60
#define CDF_ADPCM4 0xa0
#define CDF_LINEAR16BE 0xc0
#define CDF_VALID_MASK 0xf0
#ifdef _BIG_ENDIAN
#define CDF_LINEAR16NE CDF_LINEAR16BE
#else
#define CDF_LINEAR16NE CDF_LINEAR16LE
#endif
#define CUB_REG 0x1e
#define CUB_VALID_MASK 0xff
#define CLB_REG 0x1f
#define CLB_VALID_MASK 0xff
#endif
#ifdef __cplusplus
}
#endif
#endif