2 * Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
4 * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
6 * Original code : BeOS Driver for Intel ICH AC'97 Link interface
7 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de>
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <KernelExport.h>
35 #include "emuxkireg.h"
37 extern pci_module_info
*pci
;
40 emuxki_reg_read_8(device_config
*config
, int regno
)
42 return pci
->read_io_8(config
->nabmbar
+ regno
);
46 emuxki_reg_read_16(device_config
*config
, int regno
)
48 return pci
->read_io_16(config
->nabmbar
+ regno
);
52 emuxki_reg_read_32(device_config
*config
, int regno
)
54 return pci
->read_io_32(config
->nabmbar
+ regno
);
58 emuxki_reg_write_8(device_config
*config
, int regno
, uint8 value
)
60 pci
->write_io_8(config
->nabmbar
+ regno
, value
);
64 emuxki_reg_write_16(device_config
*config
, int regno
, uint16 value
)
66 pci
->write_io_16(config
->nabmbar
+ regno
, value
);
70 emuxki_reg_write_32(device_config
*config
, int regno
, uint32 value
)
72 pci
->write_io_32(config
->nabmbar
+ regno
, value
);
75 /* Emu10k1 Low level */
78 emuxki_chan_read(device_config
*config
, uint16 chano
, uint32 reg
)
80 uint32 ptr
, mask
= 0xFFFFFFFF;
81 uint8 size
, offset
= 0;
83 ptr
= ((((uint32
) reg
) << 16) &
84 (IS_AUDIGY(config
) ? EMU_A_PTR_ADDR_MASK
: EMU_PTR_ADDR_MASK
)) |
85 (chano
& EMU_PTR_CHNO_MASK
);
86 if (reg
& 0xff000000) {
87 size
= (reg
>> 24) & 0x3f;
88 offset
= (reg
>> 16) & 0x1f;
89 mask
= ((1 << size
) - 1) << offset
;
91 pci
->write_io_32(config
->nabmbar
+ EMU_PTR
, ptr
);
92 ptr
= (pci
->read_io_32(config
->nabmbar
+ EMU_DATA
) & mask
) >> offset
;
97 emuxki_chan_write(device_config
*config
, uint16 chano
,
98 uint32 reg
, uint32 data
)
103 ptr
= ((((uint32
) reg
) << 16) &
104 (IS_AUDIGY(config
) ? EMU_A_PTR_ADDR_MASK
: EMU_PTR_ADDR_MASK
)) |
105 (chano
& EMU_PTR_CHNO_MASK
);
106 if (reg
& 0xff000000) {
107 size
= (reg
>> 24) & 0x3f;
108 offset
= (reg
>> 16) & 0x1f;
109 mask
= ((1 << size
) - 1) << offset
;
110 data
= ((data
<< offset
) & mask
) |
111 (emuxki_chan_read(config
, chano
, reg
& 0xFFFF) & ~mask
);
113 pci
->write_io_32(config
->nabmbar
+ EMU_PTR
, ptr
);
114 pci
->write_io_32(config
->nabmbar
+ EMU_DATA
, data
);
120 emuxki_write_micro(device_config
*config
, uint32 pc
, uint32 data
)
122 emuxki_chan_write(config
, 0, (IS_AUDIGY(config
) ? EMU_A_MICROCODEBASE
:
123 EMU_MICROCODEBASE
) + pc
, data
);
127 emuxki_read_micro(device_config
*config
, uint32 pc
)
129 return emuxki_chan_read(config
, 0, (IS_AUDIGY(config
) ? EMU_A_MICROCODEBASE
:
130 EMU_MICROCODEBASE
) + pc
);
134 emuxki_dsp_addop(device_config
*config
, uint16
*pc
, uint8 op
,
135 uint16 r
, uint16 a
, uint16 x
, uint16 y
)
137 if(IS_AUDIGY(config
)) {
138 emuxki_write_micro(config
, *pc
<< 1,
139 ((x
<< 12) & EMU_A_DSP_LOWORD_OPX_MASK
) |
140 (y
& EMU_A_DSP_LOWORD_OPY_MASK
));
141 emuxki_write_micro(config
, (*pc
<< 1) + 1,
142 ((op
<< 24) & EMU_A_DSP_HIWORD_OPCODE_MASK
) |
143 ((r
<< 12) & EMU_A_DSP_HIWORD_RESULT_MASK
) |
144 (a
& EMU_A_DSP_HIWORD_OPA_MASK
));
146 emuxki_write_micro(config
, *pc
<< 1,
147 ((x
<< 10) & EMU_DSP_LOWORD_OPX_MASK
) |
148 (y
& EMU_DSP_LOWORD_OPY_MASK
));
149 emuxki_write_micro(config
, (*pc
<< 1) + 1,
150 ((op
<< 20) & EMU_DSP_HIWORD_OPCODE_MASK
) |
151 ((r
<< 10) & EMU_DSP_HIWORD_RESULT_MASK
) |
152 (a
& EMU_DSP_HIWORD_OPA_MASK
));
158 emuxki_dsp_getop(device_config
*config
, uint16
*pc
, uint8
*op
,
159 uint16
*r
, uint16
*a
, uint16
*x
, uint16
*y
)
162 if(IS_AUDIGY(config
)) {
163 value
= emuxki_read_micro(config
, *pc
<< 1);
164 *x
= (value
& EMU_A_DSP_LOWORD_OPX_MASK
) >> 12;
165 *y
= value
& EMU_A_DSP_LOWORD_OPY_MASK
;
166 value
= emuxki_read_micro(config
, (*pc
<< 1) + 1);
167 *op
= (value
& EMU_A_DSP_HIWORD_OPCODE_MASK
) >> 24;
168 *r
= (value
& EMU_A_DSP_HIWORD_RESULT_MASK
) >> 12;
169 *a
= value
& EMU_A_DSP_HIWORD_OPA_MASK
;
171 value
= emuxki_read_micro(config
, *pc
<< 1);
172 *x
= (value
& EMU_DSP_LOWORD_OPX_MASK
) >> 10;
173 *y
= value
& EMU_DSP_LOWORD_OPY_MASK
;
174 value
= emuxki_read_micro(config
, (*pc
<< 1) + 1);
175 *op
= (value
& EMU_DSP_HIWORD_OPCODE_MASK
) >> 20;
176 *r
= (value
& EMU_DSP_HIWORD_RESULT_MASK
) >> 10;
177 *a
= value
& EMU_DSP_HIWORD_OPA_MASK
;
185 emuxki_write_gpr(device_config
*config
, uint32 pc
, uint32 data
)
187 emuxki_chan_write(config
, 0, IS_AUDIGY(config
) ? EMU_A_DSP_GPR(pc
) :
188 EMU_DSP_GPR(pc
), data
);
192 emuxki_read_gpr(device_config
*config
, uint32 pc
)
194 return emuxki_chan_read(config
, 0, IS_AUDIGY(config
) ? EMU_A_DSP_GPR(pc
) :
201 emuxki_codec_read(device_config
*config
, int regno
)
203 pci
->write_io_8(config
->nabmbar
+ EMU_AC97ADDR
, regno
);
204 return pci
->read_io_16(config
->nabmbar
+ EMU_AC97DATA
);
208 emuxki_codec_write(device_config
*config
, int regno
, uint16 value
)
210 pci
->write_io_8(config
->nabmbar
+ EMU_AC97ADDR
, regno
);
211 pci
->write_io_16(config
->nabmbar
+ EMU_AC97DATA
, value
);
217 emuxki_inte_enable(device_config
*config
, uint32 value
)
219 emuxki_reg_write_32(config
, EMU_INTE
,
220 emuxki_reg_read_32(config
, EMU_INTE
) | value
);
224 emuxki_inte_disable(device_config
*config
, uint32 value
)
226 emuxki_reg_write_32(config
, EMU_INTE
,
227 emuxki_reg_read_32(config
, EMU_INTE
) & ~value
);
232 emuxki_p16v_read(device_config
*config
, uint16 chano
, uint16 reg
)
234 emuxki_reg_write_32(config
, EMU_A2_PTR
, reg
<< 16 | chano
);
235 return emuxki_reg_read_32(config
, EMU_A2_DATA
);
240 emuxki_p16v_write(device_config
*config
, uint16 chano
, uint16 reg
, uint32 data
)
242 emuxki_reg_write_32(config
, EMU_A2_PTR
, reg
<< 16 | chano
);
243 emuxki_reg_write_32(config
, EMU_A2_DATA
, data
);