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 * Purpose: Driver for CMEDIA CM8738 PCI audio controller. 27 */ 28 /* 29 * This file is part of Open Sound System 30 * 31 * Copyright (C) 4Front Technologies 1996-2008. 32 * 33 * This software is released under CDDL 1.0 source license. 34 * See the COPYING file included in the main directory of this source 35 * distribution for the license terms and conditions. 36 */ 37 38 #ifndef _AUDIOCMI_H 39 #define _AUDIOCMI_H 40 41 #define CMEDIA_VENDOR_ID 0x13F6 42 #define CMEDIA_CM8738 0x0111 43 #define CMEDIA_CM8338A 0x0100 44 #define CMEDIA_CM8338B 0x0101 45 46 /* 47 * CM8338 registers definition 48 */ 49 50 #define REG_FUNCTRL0 0x00 51 #define REG_FUNCTRL1 0x04 52 #define REG_CHFORMAT 0x08 53 #define REG_INTCTRL 0x0C 54 #define REG_INTSTAT 0x10 55 #define REG_LEGACY 0x14 56 #define REG_MISC 0x18 57 #define REG_TDMAPOS 0x1C 58 #define REG_SBVER 0x20 /* 8 bit access only */ 59 #define REG_IDXDATA 0x22 /* 8 bit access only */ 60 #define REG_IDXADDR 0x23 /* 8 bit access only */ 61 #define REG_MIX2 0x24 62 #define REG_MIX3 0x25 63 #define REG_VAUX 0x26 64 #define REG_CH0_PADDR 0x80 /* buffer address (32b) */ 65 #define REG_CH0_BUFSZ 0x84 /* buffer size in samples (16b) */ 66 #define REG_CH0_FRAGSZ 0x86 /* fragment size in samples (16b) */ 67 #define REG_CH1_PADDR 0x88 68 #define REG_CH1_BUFSZ 0x8C 69 #define REG_CH1_FRAGSZ 0x8E 70 #define REG_SPDIF_STAT 0x90 71 #define REG_MISC2 0x92 72 73 #define FUNCTRL0_CH1_RST BIT(19) 74 #define FUNCTRL0_CH0_RST BIT(18) 75 #define FUNCTRL0_CH1_EN BIT(17) 76 #define FUNCTRL0_CH0_EN BIT(16) 77 #define FUNCTRL0_CH1_PAUSE BIT(3) 78 #define FUNCTRL0_CH0_PAUSE BIT(2) 79 #define FUNCTRL0_CH1_REC BIT(1) 80 #define FUNCTRL0_CH0_REC BIT(0) 81 82 #define FUNCTRL1_DAC_RATE_MASK (0x7 << 13) 83 #define FUNCTRL1_DAC_RATE_48K (0x7 << 13) 84 #define FUNCTRL1_DAC_RATE_32K (0x6 << 13) 85 #define FUNCTRL1_DAC_RATE_16K (0x5 << 13) 86 #define FUNCTRL1_DAC_RATE_8K (0x4 << 13) 87 #define FUNCTRL1_DAC_RATE_44K (0x3 << 13) 88 #define FUNCTRL1_DAC_RATE_22K (0x2 << 13) 89 #define FUNCTRL1_DAC_RATE_11K (0x1 << 13) 90 #define FUNCTRL1_DAC_RATE_5K (0x0 << 13) 91 #define FUNCTRL1_ADC_RATE_MASK (0x7 << 10) 92 #define FUNCTRL1_ADC_RATE_48K (0x7 << 10) 93 #define FUNCTRL1_ADC_RATE_32K (0x6 << 10) 94 #define FUNCTRL1_ADC_RATE_16K (0x5 << 10) 95 #define FUNCTRL1_ADC_RATE_8K (0x4 << 10) 96 #define FUNCTRL1_ADC_RATE_44K (0x3 << 10) 97 #define FUNCTRL1_ADC_RATE_22K (0x2 << 10) 98 #define FUNCTRL1_ADC_RATE_11K (0x1 << 10) 99 #define FUNCTRL1_ADC_RATE_5K (0x0 << 10) 100 #define FUNCTRL1_INTRM BIT(5) /* enable MCB intr */ 101 #define FUNCTRL1_BREQ BIT(4) /* bus master enable */ 102 #define FUNCTRL1_VOICE_EN BIT(3) 103 #define FUNCTRL1_UART_EN BIT(2) 104 #define FUNCTRL1_JYSTK_EN BIT(1) 105 106 #define CHFORMAT_CHB3D5C BIT(31) /* 5 channel surround */ 107 #define CHFORMAT_CHB3D BIT(29) /* 4 channel surround */ 108 #define CHFORMAT_VER_MASK (0x1f << 24) 109 #define CHFORMAT_VER_033 0 110 #define CHFORMAT_VER_037 1 111 #define CHFORMAT_CH1_MASK (0x3 << 2) 112 #define CHFORMAT_CH1_16ST (0x3 << 2) 113 #define CHFORMAT_CH1_16MO (0x2 << 2) 114 #define CHFORMAT_CH1_8ST (0x1 << 2) 115 #define CHFORMAT_CH1_8MO (0x0 << 2) 116 #define CHFORMAT_CH0_MASK (0x3 << 0) 117 #define CHFORMAT_CH0_16ST (0x3 << 0) 118 #define CHFORMAT_CH0_16MO (0x2 << 0) 119 #define CHFORMAT_CH0_8ST (0x1 << 0) 120 #define CHFORMAT_CH0_8MO (0x0 << 0) 121 122 #define INTCTRL_MDL_MASK (0xffU << 24) 123 #define INTCTRL_MDL_068 (0x28 << 24) 124 #define INTCTRL_MDL_055 (0x8 << 24) 125 #define INTCTRL_MDL_039 (0x4 << 24) 126 #define INTCTRL_TDMA_EN BIT(18) 127 #define INTCTRL_CH1_EN BIT(17) 128 #define INTCTRL_CH0_EN BIT(16) 129 130 #define INTSTAT_INTR BIT(31) 131 #define INTSTAT_MCB_INT BIT(26) 132 #define INTSTAT_UART_INT BIT(16) 133 #define INTSTAT_LTDMA_INT BIT(15) 134 #define INTSTAT_HTDMA_INT BIT(14) 135 #define INTSTAT_LHBTOG BIT(7) 136 #define INTSTAT_LEGDMA BIT(6) 137 #define INTSTAT_LEGHIGH BIT(5) 138 #define INTSTAT_LEGSTEREO BIT(4) 139 #define INTSTAT_CH1_BUSY BIT(3) 140 #define INTSTAT_CH0_BUSY BIT(2) 141 #define INTSTAT_CH1_INT BIT(1) 142 #define INTSTAT_CH0_INT BIT(0) 143 144 #define LEGACY_NXCHG BIT(31) 145 #define LEGACY_CHB3D6C BIT(15) /* 6 channel surround */ 146 #define LEGACY_CENTR2LN BIT(14) /* line in as center out */ 147 #define LEGACY_BASS2LN BIT(13) /* line in as lfe */ 148 #define LEGACY_EXBASSEN BIT(12) /* external bass input enable */ 149 150 #define MISC_PWD BIT(31) /* power down */ 151 #define MISC_RESET BIT(30) 152 #define MISC_N4SPK3D BIT(26) /* 4 channel emulation */ 153 #define MISC_ENDBDAC BIT(23) /* dual dac */ 154 #define MISC_XCHGDAC BIT(22) /* swap front/rear dacs */ 155 #define MISC_SPD32SEL BIT(21) /* 32-bit SPDIF (default 16-bit) */ 156 #define MISC_FM_EN BIT(19) /* enable legacy FM */ 157 #define MISC_SPDF_AC97 BIT(15) /* spdif out 44.1k (0), 48 k (1) */ 158 #define MISC_ENCENTER BIT(7) /* enable center */ 159 #define MISC_REAR2LN BIT(6) /* send rear to line in */ 160 161 #define MIX2_FMMUTE BIT(7) 162 #define MIX2_WSMUTE BIT(6) 163 #define MIX2_SPK4 BIT(5) /* line-in is rear out */ 164 #define MIX2_REAR2FRONT BIT(4) /* swap front and rear */ 165 #define MIX2_WAVEIN_L BIT(3) /* for recording wave out */ 166 #define MIX2_WAVEIN_R BIT(2) /* for recording wave out */ 167 #define MIX2_X3DEN BIT(1) /* 3D surround enable */ 168 #define MIX2_CDPLAY BIT(0) /* spdif-in PCM to DAC */ 169 170 #define MIX3_RAUXREN BIT(7) 171 #define MIX3_RAUXLEN BIT(6) 172 #define MIX3_VAUXRM BIT(5) /* r-aux mute */ 173 #define MIX3_VAUXLM BIT(4) /* l-aux mute */ 174 #define MIX3_VADCMIC_MASK (0x7 << 1) /* rec mic volume */ 175 #define MIX3_CEN2MIC BIT(2) 176 #define MIX3_MICGAINZ BIT(0) /* mic gain */ 177 178 #define VAUX_L_MASK 0xf0 179 #define VAUX_R_MASK 0x0f 180 181 #define MISC2_CHB3D8C BIT(5) /* 8 channel surround */ 182 #define MISC2_SPD32FMT BIT(4) /* spdif at 32 kHz */ 183 #define MISC2_ADC2SPDIF BIT(3) /* send adc to spdif out */ 184 #define MISC2_SHAREADC BIT(2) /* use adc for cen/lfe */ 185 186 /* Indexes via SBINDEX */ 187 #define IDX_MASTER_LEFT 0x30 188 #define IDX_MASTER_RIGHT 0x31 189 #define IDX_VOICE_LEFT 0x32 /* PCM volume */ 190 #define IDX_VOICE_RIGHT 0x33 191 #define IDX_CDDA_LEFT 0x36 192 #define IDX_CDDA_RIGHT 0x37 193 #define IDX_LINEIN_LEFT 0x38 194 #define IDX_LINEIN_RIGHT 0x39 195 #define IDX_MIC 0x3A 196 #define IDX_SPEAKER 0x3B 197 #define IDX_OUTMIX 0x3C 198 #define OUTMIX_MIC 0x01 199 #define OUTMIX_CD_R 0x02 200 #define OUTMIX_CD_L 0x04 201 #define OUTMIX_LINE_R 0x08 202 #define OUTMIX_LINE_L 0x10 203 #define IDX_INMIX_L 0x3D 204 #define IDX_INMIX_R 0x3E 205 #define INMIX_LINE_R 0x08 206 #define INMIX_LINE_L 0x10 207 #define INMIX_CD_R 0x20 208 #define INMIX_CD_L 0x40 209 #define INMIX_MIC 0x01 210 #define IDX_IGAIN_L 0x3F 211 #define IDX_IGAIN_R 0x40 212 #define IDX_OGAIN_L 0x41 213 #define IDX_OGAIN_R 0x42 214 #define IDX_AGC 0x43 215 #define IDX_TREBLE_L 0x44 216 #define IDX_TREBLE_R 0x45 217 #define IDX_BASS_L 0x46 218 #define IDX_BASS_R 0x47 219 220 221 #define IDX_EXTENSION 0xf0 222 223 #define EXTENSION_VPHONE_MASK (0x7 << 5) 224 #define EXTENSION_VPHONE_MUTE BIT(4) 225 #define EXTENSION_BEEPER_MUTE BIT(3) 226 #define EXTENSION_VADCMIC3 BIT(0) 227 228 enum { 229 SRC_MIC = 0, 230 SRC_LINE, 231 SRC_CD, 232 SRC_AUX, 233 SRC_MIX, 234 }; 235 236 enum { 237 CTL_VOLUME = 0, 238 CTL_LINEOUT, 239 CTL_SPEAKER, 240 CTL_MIC, 241 CTL_LINEIN, 242 CTL_CD, 243 CTL_AUX, 244 CTL_RECSRCS, 245 CTL_MONSRCS, 246 CTL_MICBOOST, 247 CTL_NUM 248 }; 249 250 typedef struct cmpci_port cmpci_port_t; 251 typedef struct cmpci_dev cmpci_dev_t; 252 typedef struct cmpci_ctrl cmpci_ctrl_t; 253 254 struct cmpci_ctrl { 255 cmpci_dev_t *dev; 256 audio_ctrl_t *ctrl; 257 uint64_t value; 258 }; 259 260 struct cmpci_port { 261 cmpci_dev_t *dev; 262 audio_engine_t *engine; 263 int num; 264 ddi_acc_handle_t acch; 265 ddi_dma_handle_t dmah; 266 caddr_t kaddr; 267 uint32_t paddr; 268 unsigned fragfr; 269 unsigned nfrags; 270 unsigned nframes; 271 unsigned bufsz; 272 unsigned nchan; 273 274 boolean_t capture; 275 boolean_t open; 276 277 /* registers & bit masks */ 278 uint8_t reg_paddr; 279 uint8_t reg_bufsz; 280 uint8_t reg_fragsz; 281 282 uint32_t fc0_rst_bit; 283 uint32_t fc0_rec_bit; 284 uint32_t fc0_en_bit; 285 uint32_t int_en_bit; 286 uint32_t fc1_rate_mask; 287 uint32_t chformat_mask; 288 int sync_dir; 289 290 uint32_t offset; /* in bytes */ 291 uint64_t count; /* in bytes */ 292 293 void (*callb)(audio_engine_t *); 294 cmpci_ctrl_t controls[CTL_NUM]; 295 }; 296 297 #define PORT_MAX 2 298 299 struct cmpci_dev { 300 audio_dev_t *adev; 301 dev_info_t *dip; 302 ddi_acc_handle_t acch; 303 caddr_t regs; 304 305 int pintrs; 306 int rintrs; 307 ddi_intr_handle_t ihandle; 308 kstat_t *ksp; 309 310 int model; 311 #define MDL_CM8738 1 312 #define MDL_CM8338A 2 313 #define MDL_CM8338B 3 314 #define MDL_CM8768 4 315 316 int maxch; 317 318 boolean_t suspended; 319 320 kmutex_t mutex; 321 cmpci_port_t port[PORT_MAX]; 322 cmpci_ctrl_t controls[CTL_NUM]; 323 }; 324 325 /* 326 * The hardware appears to be able to address up to 16-bits worth of samples, 327 * giving a total address space of 256K. Note, however, that we will restrict 328 * this further when we do fragment and memory allocation. 329 */ 330 #define DEFINTS 175 331 332 #define GET8(dev, offset) \ 333 ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset))) 334 #define GET16(dev, offset) \ 335 ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset))) 336 #define GET32(dev, offset) \ 337 ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset))) 338 #define PUT8(dev, offset, v) \ 339 ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v) 340 #define PUT16(dev, offset, v) \ 341 ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v) 342 #define PUT32(dev, offset, v) \ 343 ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v) 344 345 #define CLR8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) & ~(v)) 346 #define SET8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) | (v)) 347 #define CLR16(dev, offset, v) PUT16(dev, offset, GET16(dev, offset) & ~(v)) 348 #define SET16(dev, offset, v) PUT16(dev, offset, GET16(dev, offset) | (v)) 349 #define CLR32(dev, offset, v) PUT32(dev, offset, GET32(dev, offset) & ~(v)) 350 #define SET32(dev, offset, v) PUT32(dev, offset, GET32(dev, offset) | (v)) 351 352 #define KSINTR(dev) ((kstat_intr_t *)((dev)->ksp->ks_data)) 353 354 #define BIT(n) (1U << (n)) 355 356 #endif /* _AUDIOCMI_H */ 357