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 2009 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 #define I810_INTS (175) /* default interrupt rate */ 40 #define I810_MIN_INTS (24) /* minimum interrupt rate */ 41 #define I810_MAX_INTS (5000) /* maximum interrupt rate */ 42 #define I810_NFRAGS (8) /* default # fragments */ 43 44 /* 45 * Misc. defines 46 */ 47 48 #define I810_BD_NUMS (32) 49 #define I810_NUM_PORTS (2) 50 #define I810_MOD_SIZE (16) 51 52 #define I810_ROUNDUP(x, algn) (((x) + ((algn) - 1)) & ~((algn) - 1)) 53 #define I810_KIOP(X) ((kstat_intr_t *)(X->ksp->ks_data)) 54 55 /* The size of each entry of "reg" property is 5 integers */ 56 #define I810_INTS_PER_REG_PROP 5 57 58 /* offset from the base of specified DMA engine */ 59 #define I810_OFFSET_BD_BASE (0x00) 60 #define I810_OFFSET_CIV (0x04) 61 #define I810_OFFSET_LVI (0x05) 62 #define I810_OFFSET_SR (0x06) 63 #define I810_OFFSET_PICB (0x08) 64 #define I810_OFFSET_PIV (0x0A) 65 #define I810_OFFSET_CR (0x0B) 66 67 /* DMA engine offset from base */ 68 #define I810_BASE_PCM_IN (0x00) 69 #define I810_BASE_PCM_OUT (0x10) 70 #define I810_BASE_MIC (0x20) 71 72 #define I810_REG_GCR 0x2C 73 #define I810_REG_GSR 0x30 74 #define I810_REG_CASR 0x34 75 #define I810_REG_SISCTL 0x4C /* SiS 7012 control */ 76 77 /* bits of bus master status register */ 78 #define I810_BM_SR_DCH 0x01 79 #define I810_BM_SR_CELV 0x02 80 #define I810_BM_SR_LVBCI 0x04 81 #define I810_BM_SR_BCIS 0x08 82 #define I810_BM_SR_FIFOE 0x10 83 84 /* bits of bus master control register */ 85 #define I810_BM_CR_RUN 0x01 86 #define I810_BM_CR_RST 0x02 87 #define I810_BM_CR_LVBIE 0x04 88 #define I810_BM_CR_FEIE 0x08 89 #define I810_BM_CR_IOCE 0x10 90 91 #define I810_BM_CR_PAUSE 0x00 92 93 /* 94 * Global Control Register 95 */ 96 #define I810_GCR_GPIE 0x00000001 97 #define I810_GCR_COLD_RST 0x00000002 98 #define I810_GCR_WARM_RST 0x00000004 99 #define I810_GCR_ACLINK_OFF 0x00000008 100 #define I810_GCR_PRI_INTR_ENABLE 0x00000010 101 #define I810_GCR_SEC_INTR_ENABLE 0x00000020 102 103 /* For ICH2 or more, bit21:20 is the PCM 4/6-channel enable bits */ 104 #define I810_GCR_2_CHANNELS (0 << 20) 105 #define I810_GCR_4_CHANNELS (1 << 20) 106 #define I810_GCR_6_CHANNELS (2 << 20) 107 #define I810_GCR_CHANNELS_MASK (3 << 20) 108 /* SiS 7012 has its own flags here */ 109 #define I810_GCR_SIS_2_CHANNELS (0 << 6) 110 #define I810_GCR_SIS_4_CHANNELS (1 << 6) 111 #define I810_GCR_SIS_6_CHANNELS (2 << 6) 112 #define I810_GCR_SIS_CHANNELS_MASK (3 << 6) 113 114 115 /* 116 * Global Status Register 117 */ 118 #define I810_GSR_TRI_READY 0x10000000 /* for ICH4/5 */ 119 #define I810_GSR_CAP8CH 0x00400000 120 #define I810_GSR_CAP6CH 0x00200000 121 #define I810_GSR_CAP4CH 0x00100000 122 #define I810_GSR_READ_COMPL 0x00008000 123 #define I810_GSR_INTR_SEC_RESUME 0x00000800 124 #define I810_GSR_INTR_PRI_RESUME 0x00000400 125 #define I810_GSR_SEC_READY 0x00000200 126 #define I810_GSR_PRI_READY 0x00000100 127 #define I810_GSR_INTR_MIC 0x00000080 128 #define I810_GSR_INTR_POUT 0x00000040 129 #define I810_GSR_INTR_PIN 0x00000020 130 #define I810_GSR_INTR_MO 0x00000004 131 #define I810_GSR_INTR_MI 0x00000002 132 #define I810_GSR_INTR_GSI 0x00000001 133 #define I810_GSR_USE_INTR 0x00000060 /* PCM-IN ,PCM-OUT */ 134 135 /* 136 * SiS Control Register 137 */ 138 #define I810_SISCTL_UNMUTE 0x01 139 140 /* 141 * Macro for AD1980 codec 142 */ 143 #define AD1980_VID1 0x4144 144 #define AD1980_VID2 0x5370 145 #define AD1985_VID2 0x5375 146 #define CODEC_AD_REG_MISC 0x76 /* offset of ad1980 misc control reg */ 147 #define AD1980_MISC_LOSEL 0x0020 /* Line-out amplifier output selector */ 148 #define AD1980_MISC_HPSEL 0x0400 /* HP-out amplifier output selector */ 149 #define AD1980_SURR_MUTE 0x8080 /* Mute for surround volume register */ 150 151 #define I810_PCM_IN 0 152 #define I810_PCM_OUT 1 153 154 struct audio810_port { 155 struct audio810_state *statep; 156 int num; 157 ddi_dma_handle_t samp_dmah; 158 ddi_acc_handle_t samp_acch; 159 size_t samp_size; 160 caddr_t samp_kaddr; 161 uint32_t samp_paddr; 162 163 ddi_dma_handle_t bdl_dmah; 164 ddi_acc_handle_t bdl_acch; 165 size_t bdl_size; 166 caddr_t bdl_kaddr; 167 uint32_t bdl_paddr; 168 169 unsigned intrs; 170 unsigned fragfr; 171 unsigned fragsz; 172 uint64_t count; 173 uint8_t nfrag; 174 uint8_t nchan; 175 176 uint8_t regoff; 177 uint8_t stsoff; /* status offset */ 178 uint8_t picboff; /* picb offset */ 179 uint8_t civ; 180 uint16_t picb; 181 unsigned sync_dir; 182 183 boolean_t started; 184 185 audio_engine_t *engine; 186 }; 187 typedef struct audio810_port audio810_port_t; 188 189 /* 190 * buffer descripter list entry, sees datasheet 191 */ 192 struct i810_bd_entry { 193 uint32_t buf_base; /* the address of the buffer */ 194 uint16_t buf_len; /* the number of samples */ 195 uint16_t buf_cmd; 196 }; 197 typedef struct i810_bd_entry i810_bd_entry_t; 198 #define BUF_CMD_BUP 0x4000 199 #define BUF_CMD_IOC 0x8000 200 201 typedef enum i810_quirk { 202 QUIRK_NONE = 0, 203 QUIRK_SIS7012, /* weird registers and such */ 204 } i810_quirk_t; 205 206 /* 207 * audio810_state_t -per instance state and operation data 208 */ 209 struct audio810_state { 210 kmutex_t inst_lock; /* state protection lock */ 211 kmutex_t ac_lock; 212 ddi_iblock_cookie_t iblock; 213 dev_info_t *dip; /* used by audio810_getinfo() */ 214 audio_dev_t *adev; 215 ac97_t *ac97; 216 audio810_port_t *ports[2]; 217 218 ddi_acc_handle_t am_regs_handle; /* for audio mixer register */ 219 ddi_acc_handle_t bm_regs_handle; /* for bus master register */ 220 caddr_t am_regs_base; /* base of audio mixer regs */ 221 caddr_t bm_regs_base; /* base of bus master regs */ 222 223 kstat_t *ksp; /* kernel statistics */ 224 225 boolean_t intr_added; 226 boolean_t suspended; /* suspend/resume state */ 227 uint8_t maxch; 228 i810_quirk_t quirk; 229 }; 230 typedef struct audio810_state audio810_state_t; 231 232 /* 233 * Useful bit twiddlers 234 */ 235 #define I810_BM_GET8(reg) \ 236 ddi_get8(statep->bm_regs_handle, \ 237 (void *)((char *)statep->bm_regs_base + (reg))) 238 239 #define I810_BM_GET16(reg) \ 240 ddi_get16(statep->bm_regs_handle, \ 241 (void *)((char *)statep->bm_regs_base + (reg))) 242 243 #define I810_BM_GET32(reg) \ 244 ddi_get32(statep->bm_regs_handle, \ 245 (void *)((char *)statep->bm_regs_base + (reg))) 246 247 #define I810_BM_PUT8(reg, val) \ 248 ddi_put8(statep->bm_regs_handle, \ 249 (void *)((char *)statep->bm_regs_base + (reg)), (val)) 250 251 #define I810_BM_PUT16(reg, val) \ 252 ddi_put16(statep->bm_regs_handle, \ 253 (void *)((char *)statep->bm_regs_base + (reg)), (val)) 254 255 #define I810_BM_PUT32(reg, val) \ 256 ddi_put32(statep->bm_regs_handle, \ 257 (void *)((char *)statep->bm_regs_base + (reg)), (val)) 258 259 #define I810_AM_GET16(reg) \ 260 ddi_get16(statep->am_regs_handle, \ 261 (void *)((char *)statep->am_regs_base + (reg))) 262 263 #define I810_AM_PUT16(reg, val) \ 264 ddi_put16(statep->am_regs_handle, \ 265 (void *)((char *)statep->am_regs_base + (reg)), (val)) 266 267 #endif /* _AUDIO810_H_ */ 268