1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Purpose: Definitions for the CMedia 8788 driver.
*/
/*
* This file is part of Open Sound System
*
* Copyright (C) 4Front Technologies 1996-2011.
*
* This software is released under CDDL 1.0 source license.
* See the COPYING file included in the main directory of this source
* distribution for the license terms and conditions.
*/
#ifndef CMEDIAHD_H
#define CMEDIAHD_H
#define CMEDIAHD_NAME "audiocmihd"
#define CMEDIAHD_NUM_PORTC 2
#define CMEDIAHD_PLAY 0
#define CMEDIAHD_REC 1
/*
* Number of fragments must be multiple of 2 because the
* hardware supports only full and half buffer interrupts. In
* addition it looks like 8 fragments is the minimum.
*/
#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
/*
* PCI registers
*/
#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)
/* Device IDs */
#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
/* Xonar specific */
#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
/* defs for AKM 4396 DAC */
#define AK4396_CTL1 0x00
#define AK4396_CTL2 0x01
#define AK4396_CTL3 0x02
#define AK4396_LchATTCtl 0x03
#define AK4396_RchATTCtl 0x04
/* defs for CS4398 DAC */
#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) /* Obvious */
#define CS4398_CPEN (1<<6) /* Control Port Enable */
#define CS4398_FREEZE (1<<5) /* Freezes registers, unfreeze to */
/* accept changed registers */
#define CS4398_MCLKDIV2 (1<<4) /* Divide MCLK by 2 */
#define CS4398_MCLKDIV3 (1<<3) /* Divive MCLK by 3 */
#define CS4398_I2S (1<<4) /* Set I2S mode */
/* defs for CS4362A DAC */
#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
/* CS4362A Reg 01h */
#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)
/* CS4362A Reg 02h */
#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
/* CS4362A Reg 03h */
#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
/* CS4362A Reg 04h */
#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
/* CS4362A Reg 05h */
#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)
/* CS4362A Reg 06h, 09h, 0Ch */
/* ATAPI crap, does anyone still use analog CD playback? */
/* CS4362A Reg 07h, 08h, 0Ah, 0Bh, 0Dh, 0Eh */
/* Volume registers */
#define CS4362A_VOL_MUTE 0x80
/* 0-100. Start at -96dB. */
#define CS4398_VOL(x) \
((x) == 0 ? 0xFF : (0xC0 - ((x)*192/100)))
/* 0-100. Start at -96dB. Bit 7 is mute. */
#define CS4362A_VOL(x) \
(char)((x) == 0 ? 0xFF : (0x60 - ((x)*96/100)))
/* Xonar D2/D2X codec remap */
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 /* must be last */
} 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; /* base address */
caddr_t size; /* current count */
caddr_t frag; /* terminal count */
caddr_t i2s; /* i2s reg */
int chan; /* rec a/b/c, play spdif/multi/front */
#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; /* dma for buffers */
ddi_acc_handle_t buf_acch;
uint32_t paddr;
caddr_t kaddr;
size_t buf_size;
size_t buf_frames; /* Buffer size in 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; /* For normal locking */
kmutex_t low_mutex; /* For low level routines */
cmediahd_regs_t rec_eng; /* which rec engine to use */
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 /* CMEDIAHD_H */
|