1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _AUDIO810_H_ 27 #define _AUDIO810_H_ 28 29 /* 30 * Header file for the audio810 device driver 31 */ 32 33 /* 34 * Driver supported configuration information 35 */ 36 #define I810_NAME "audio810" 37 #define I810_MOD_NAME "audio810 audio driver" 38 39 /* 40 * Misc. defines 41 */ 42 43 #define I810_BD_NUMS (32) 44 #define I810_NUM_PORTS (2) 45 #define I810_MOD_SIZE (16) 46 47 #define I810_ROUNDUP(x, algn) (((x) + ((algn) - 1)) & ~((algn) - 1)) 48 49 /* The size of each entry of "reg" property is 5 integers */ 50 #define I810_INTS_PER_REG_PROP 5 51 52 /* offset from the base of specified DMA engine */ 53 #define I810_OFFSET_BD_BASE (0x00) 54 #define I810_OFFSET_CIV (0x04) 55 #define I810_OFFSET_LVI (0x05) 56 #define I810_OFFSET_SR (0x06) 57 #define I810_OFFSET_PICB (0x08) 58 #define I810_OFFSET_PIV (0x0A) 59 #define I810_OFFSET_CR (0x0B) 60 61 /* DMA engine offset from base */ 62 #define I810_BASE_PCM_IN (0x00) 63 #define I810_BASE_PCM_OUT (0x10) 64 #define I810_BASE_MIC (0x20) 65 66 #define I810_REG_GCR 0x2C 67 #define I810_REG_GSR 0x30 68 #define I810_REG_CASR 0x34 69 #define I810_REG_SISCTL 0x4C /* SiS 7012 control */ 70 71 /* bits of bus master status register */ 72 #define I810_BM_SR_DCH 0x01 73 #define I810_BM_SR_CELV 0x02 74 #define I810_BM_SR_LVBCI 0x04 75 #define I810_BM_SR_BCIS 0x08 76 #define I810_BM_SR_FIFOE 0x10 77 78 /* bits of bus master control register */ 79 #define I810_BM_CR_RUN 0x01 80 #define I810_BM_CR_RST 0x02 81 #define I810_BM_CR_LVBIE 0x04 82 #define I810_BM_CR_FEIE 0x08 83 #define I810_BM_CR_IOCE 0x10 84 85 #define I810_BM_CR_PAUSE 0x00 86 87 /* 88 * Global Control Register 89 */ 90 #define I810_GCR_GPIE 0x00000001 91 #define I810_GCR_COLD_RST 0x00000002 92 #define I810_GCR_WARM_RST 0x00000004 93 #define I810_GCR_ACLINK_OFF 0x00000008 94 #define I810_GCR_PRI_INTR_ENABLE 0x00000010 95 #define I810_GCR_SEC_INTR_ENABLE 0x00000020 96 97 /* For ICH2 or more, bit21:20 is the PCM 4/6-channel enable bits */ 98 #define I810_GCR_2_CHANNELS (0 << 20) 99 #define I810_GCR_4_CHANNELS (1 << 20) 100 #define I810_GCR_6_CHANNELS (2 << 20) 101 #define I810_GCR_CHANNELS_MASK (3 << 20) 102 /* SiS 7012 has its own flags here */ 103 #define I810_GCR_SIS_2_CHANNELS (0 << 6) 104 #define I810_GCR_SIS_4_CHANNELS (1 << 6) 105 #define I810_GCR_SIS_6_CHANNELS (2 << 6) 106 #define I810_GCR_SIS_CHANNELS_MASK (3 << 6) 107 108 109 /* 110 * Global Status Register 111 */ 112 #define I810_GSR_TRI_READY 0x10000000 /* for ICH4/5 */ 113 #define I810_GSR_CAP8CH 0x00400000 114 #define I810_GSR_CAP6CH 0x00200000 115 #define I810_GSR_CAP4CH 0x00100000 116 #define I810_GSR_READ_COMPL 0x00008000 117 #define I810_GSR_INTR_SEC_RESUME 0x00000800 118 #define I810_GSR_INTR_PRI_RESUME 0x00000400 119 #define I810_GSR_SEC_READY 0x00000200 120 #define I810_GSR_PRI_READY 0x00000100 121 #define I810_GSR_INTR_MIC 0x00000080 122 #define I810_GSR_INTR_POUT 0x00000040 123 #define I810_GSR_INTR_PIN 0x00000020 124 #define I810_GSR_INTR_MO 0x00000004 125 #define I810_GSR_INTR_MI 0x00000002 126 #define I810_GSR_INTR_GSI 0x00000001 127 #define I810_GSR_USE_INTR 0x00000060 /* PCM-IN ,PCM-OUT */ 128 129 /* 130 * SiS Control Register 131 */ 132 #define I810_SISCTL_UNMUTE 0x01 133 134 /* 135 * Macro for AD1980 codec 136 */ 137 #define AD1980_VID1 0x4144 138 #define AD1980_VID2 0x5370 139 #define AD1985_VID2 0x5375 140 #define CODEC_AD_REG_MISC 0x76 /* offset of ad1980 misc control reg */ 141 #define AD1980_MISC_LOSEL 0x0020 /* Line-out amplifier output selector */ 142 #define AD1980_MISC_HPSEL 0x0400 /* HP-out amplifier output selector */ 143 #define AD1980_SURR_MUTE 0x8080 /* Mute for surround volume register */ 144 145 #define I810_PCM_IN 0 146 #define I810_PCM_OUT 1 147 148 struct audio810_port { 149 struct audio810_state *statep; 150 int num; 151 ddi_dma_handle_t samp_dmah; 152 ddi_acc_handle_t samp_acch; 153 uint32_t samp_frames; 154 size_t samp_size; 155 caddr_t samp_kaddr; 156 uint32_t samp_paddr; 157 158 ddi_dma_handle_t bdl_dmah; 159 ddi_acc_handle_t bdl_acch; 160 size_t bdl_size; 161 caddr_t bdl_kaddr; 162 uint32_t bdl_paddr; 163 164 uint32_t offset; 165 uint64_t count; 166 uint8_t nchan; 167 168 uint8_t regoff; 169 uint8_t stsoff; /* status offset */ 170 uint8_t picboff; /* picb offset */ 171 unsigned sync_dir; 172 173 audio_engine_t *engine; 174 }; 175 typedef struct audio810_port audio810_port_t; 176 177 /* 178 * buffer descripter list entry, sees datasheet 179 */ 180 struct i810_bd_entry { 181 uint32_t buf_base; /* the address of the buffer */ 182 uint16_t buf_len; /* the number of samples */ 183 uint16_t buf_cmd; 184 }; 185 typedef struct i810_bd_entry i810_bd_entry_t; 186 #define BUF_CMD_BUP 0x4000 187 #define BUF_CMD_IOC 0x8000 188 189 typedef enum i810_quirk { 190 QUIRK_NONE = 0, 191 QUIRK_OLDICH, /* likely emulated, needs deeper playahead */ 192 QUIRK_SIS7012, /* weird registers and such */ 193 } i810_quirk_t; 194 195 /* 196 * audio810_state_t -per instance state and operation data 197 */ 198 struct audio810_state { 199 dev_info_t *dip; /* used by audio810_getinfo() */ 200 audio_dev_t *adev; 201 ac97_t *ac97; 202 audio810_port_t *ports[2]; 203 204 ddi_acc_handle_t am_regs_handle; /* for audio mixer register */ 205 ddi_acc_handle_t bm_regs_handle; /* for bus master register */ 206 caddr_t am_regs_base; /* base of audio mixer regs */ 207 caddr_t bm_regs_base; /* base of bus master regs */ 208 209 kstat_t *ksp; /* kernel statistics */ 210 211 uint8_t maxch; 212 i810_quirk_t quirk; 213 }; 214 typedef struct audio810_state audio810_state_t; 215 216 /* 217 * Useful bit twiddlers 218 */ 219 #define I810_BM_GET8(reg) \ 220 ddi_get8(statep->bm_regs_handle, \ 221 (void *)((char *)statep->bm_regs_base + (reg))) 222 223 #define I810_BM_GET16(reg) \ 224 ddi_get16(statep->bm_regs_handle, \ 225 (void *)((char *)statep->bm_regs_base + (reg))) 226 227 #define I810_BM_GET32(reg) \ 228 ddi_get32(statep->bm_regs_handle, \ 229 (void *)((char *)statep->bm_regs_base + (reg))) 230 231 #define I810_BM_PUT8(reg, val) \ 232 ddi_put8(statep->bm_regs_handle, \ 233 (void *)((char *)statep->bm_regs_base + (reg)), (val)) 234 235 #define I810_BM_PUT16(reg, val) \ 236 ddi_put16(statep->bm_regs_handle, \ 237 (void *)((char *)statep->bm_regs_base + (reg)), (val)) 238 239 #define I810_BM_PUT32(reg, val) \ 240 ddi_put32(statep->bm_regs_handle, \ 241 (void *)((char *)statep->bm_regs_base + (reg)), (val)) 242 243 #define I810_AM_GET16(reg) \ 244 ddi_get16(statep->am_regs_handle, \ 245 (void *)((char *)statep->am_regs_base + (reg))) 246 247 #define I810_AM_PUT16(reg, val) \ 248 ddi_put16(statep->am_regs_handle, \ 249 (void *)((char *)statep->am_regs_base + (reg)), (val)) 250 251 #endif /* _AUDIO810_H_ */ 252