- Handle multiple nodes having output volume control.
[AROS.git] / workbench / devs / AHI / Drivers / Envy24 / ak_codec.c
blob95030625ec1fcd7ee27b65abad356222915419f1
1 /*
2 Copyright � 2004-2014, Davy Wentzler. All rights reserved.
3 $Id$
4 */
6 #include <proto/exec.h>
7 #include <proto/dos.h>
8 #include <proto/expansion.h>
9 #include "DriverData.h"
10 #include "Phase88.h"
11 #include "ak_codec.h"
12 #include "regs.h"
13 #include "misc.h"
16 #define snd_akm4xxx_get(ak,chip,reg) (ak)->images[(chip) * 16 + (reg)]
17 #define snd_akm4xxx_set(ak,chip,reg,val) ((ak)->images[(chip) * 16 + (reg)] = (val))
18 #define snd_akm4xxx_get_ipga(ak,chip,reg) (ak)->ipga_gain[chip][(reg)-4]
19 #define snd_akm4xxx_set_ipga(ak,chip,reg,val) ((ak)->ipga_gain[chip][(reg)-4] = (val))
21 #define ice card
22 #define snd_ice1712_gpio_read GetGPIOData
23 #define snd_ice1712_gpio_write SetGPIOData
24 #define udelay MicroDelay
26 void akm4xxx_write(struct CardData *card, struct akm_codec *priv, int chip, unsigned char addr, unsigned char data)
28 unsigned int tmp;
29 int idx;
30 unsigned int addrdata = 0;
31 struct PCIDevice *dev = card->pci_dev;
32 unsigned long base = card->iobase;
34 tmp = snd_ice1712_gpio_read(ice);
35 tmp |= priv->add_flags;
36 tmp &= ~priv->mask_flags;
37 if (priv->cs_mask == priv->cs_addr) {
38 if (priv->cif) {
39 tmp |= priv->cs_mask; /* start without chip select */
40 } else {
41 tmp &= ~priv->cs_mask; /* chip select low */
42 snd_ice1712_gpio_write(ice, tmp);
43 udelay(1);
45 } else {
46 /* doesn't handle cf=1 yet */
47 tmp &= ~priv->cs_mask;
48 tmp |= priv->cs_addr;
49 snd_ice1712_gpio_write(ice, tmp);
50 udelay(1);
53 /* build I2C address + data byte */
54 addrdata = (priv->caddr << 6) | 0x20 | (addr & 0x1f);
55 addrdata = (addrdata << 8) | data;
56 for (idx = 15; idx >= 0; idx--) {
57 /* drop clock */
58 tmp &= ~priv->clk_mask;
59 snd_ice1712_gpio_write(ice, tmp);
60 udelay(1);
61 /* set data */
62 if (addrdata & (1 << idx))
63 tmp |= priv->data_mask;
64 else
65 tmp &= ~priv->data_mask;
66 snd_ice1712_gpio_write(ice, tmp);
67 udelay(1);
68 /* raise clock */
69 tmp |= priv->clk_mask;
70 snd_ice1712_gpio_write(ice, tmp);
71 udelay(1);
74 if (priv->cs_mask == priv->cs_addr) {
75 if (priv->cif) {
76 /* assert a cs pulse to trigger */
77 tmp &= ~priv->cs_mask;
78 snd_ice1712_gpio_write(ice, tmp);
79 udelay(1);
81 tmp |= priv->cs_mask; /* chip select high to trigger */
82 } else {
83 tmp &= ~priv->cs_mask;
84 tmp |= priv->cs_none; /* deselect address */
86 snd_ice1712_gpio_write(ice, tmp);
87 udelay(1);
90 void akm4xxx_write_old(struct CardData *card, struct akm_codec *codec, int chip, unsigned char addr, unsigned char data)
92 unsigned char tmp;
93 int idx;
94 unsigned int addrdata = 0;
95 struct PCIDevice *dev = card->pci_dev;
96 unsigned long base = card->iobase;
98 //IExec->DebugPrintF("m = %x, %x, data = %x\n", dev->InByte(base + 0x1F), dev->InWord(base + 0x16), data);
100 tmp = GetGPIOData(card);
102 //tmp |= codec->clock; // clock hi
103 tmp &= ~codec->cs_mask; // cs down
104 SetGPIOData(card, tmp); // set CS low
105 MicroDelay(1);
108 /* build I2C address + data byte */
109 addrdata = (codec->caddr << 6) | 0x20 | (addr & 0x1f); // Chip Address in C1/C0 | r/w bit on (=write) | address & 5 left over bit positions
110 addrdata = (addrdata << 8) | data;
112 for (idx = 15; idx >= 0; idx--) {
114 /* drop clock */
115 tmp &= ~codec->clk_mask;
116 SetGPIOData(card, tmp);
117 MicroDelay(1);
119 /* set data */
120 if (addrdata & (1 << idx))
121 tmp |= codec->data_mask;
122 else
123 tmp &= ~codec->data_mask;
125 SetGPIOData(card, tmp);
126 MicroDelay(1);
128 /* raise clock */
129 tmp |= codec->clk_mask;
130 SetGPIOData(card, tmp);
131 MicroDelay(1);
134 /* assert a cs pulse to trigger */
135 //tmp &= ~codec->clock;
136 tmp |= codec->cs_mask;
137 SetGPIOData(card, tmp);
138 MicroDelay(1);
140 //tmp |= codec->clock;
141 //SetGPIOData(card, tmp);
142 //MicroDelay(1);
146 static void Phase88_akm4xxx_write(struct CardData *card, int chip, unsigned char addr, unsigned char data)
148 unsigned int tmp;
149 int idx;
150 unsigned int addrdata;
152 if (!(chip >= 0 && chip < 4))
153 return;
155 Phase88_ak4524_lock(card, chip);
157 tmp = ReadCCI(card, CCI_GPIO_DATA);
158 tmp |= PHASE88_RW;
161 /* build I2C address + data byte */
162 addrdata = (2 << 6) | 0x20 | (addr & 0x1f);
163 addrdata = (addrdata << 8) | data;
165 for (idx = 15; idx >= 0; idx--) {
167 /* drop clock */
168 tmp &= ~PHASE88_CLOCK;
169 WriteCCI(card, CCI_GPIO_DATA, tmp);
170 MicroDelay(1);
172 /* set data */
173 if (addrdata & (1 << idx))
174 tmp |= PHASE88_DATA;
175 else
176 tmp &= ~PHASE88_DATA;
177 WriteCCI(card, CCI_GPIO_DATA, tmp);
178 MicroDelay(1);
180 /* raise clock */
181 tmp |= PHASE88_CLOCK;
182 WriteCCI(card, CCI_GPIO_DATA, tmp);
183 MicroDelay(1);
186 /* assert a cs pulse to trigger */
187 WriteCCI(card, CCI_GPIO_DATA, tmp);
188 MicroDelay(1);
190 Phase88_ak4524_unlock(card, chip);
194 static unsigned char inits_ak4524[] = {
195 0x00, 0x07, /* 0: all power up */
196 0x01, 0x00, /* 1: ADC/DAC reset */
197 0x02, 0x60, /* 2: 24bit I2S */
198 0x03, 0x19, /* 3: deemphasis off */
199 0x01, 0x03, /* 1: ADC/DAC enable */
200 0x04, 0x00, /* 4: ADC left muted */
201 0x05, 0x00, /* 5: ADC right muted */
202 0x04, 0x80, /* 4: ADC IPGA gain 0dB */
203 0x05, 0x80, /* 5: ADC IPGA gain 0dB */
204 0x06, 0x7F, /* 6: DAC left full */
205 0x07, 0x7F, /* 7: DAC right full */
206 0xff, 0xff
208 static unsigned char inits_ak4528[] = {
209 0x00, 0x07, /* 0: all power up */
210 0x01, 0x00, /* 1: ADC/DAC reset */
211 0x02, 0x60, /* 2: 24bit I2S */
212 0x03, 0x01, /* 3: no highpass filters */
213 0x01, 0x03, /* 1: ADC/DAC enable */
214 0x04, 0x7F, /* 4: ADC left muted */
215 0x05, 0x7F, /* 5: ADC right muted */
216 0xff, 0xff
218 static unsigned char inits_ak4529[] = {
219 0x09, 0x01, /* 9: ATS=0, RSTN=1 */
220 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
221 0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
222 0x01, 0x00, /* 1: ACKS=0, ADC, loop off */
223 0x02, 0xff, /* 2: LOUT1 muted */
224 0x03, 0xff, /* 3: ROUT1 muted */
225 0x04, 0xff, /* 4: LOUT2 muted */
226 0x05, 0xff, /* 5: ROUT2 muted */
227 0x06, 0xff, /* 6: LOUT3 muted */
228 0x07, 0xff, /* 7: ROUT3 muted */
229 0x0b, 0xff, /* B: LOUT4 muted */
230 0x0c, 0xff, /* C: ROUT4 muted */
231 0x08, 0x55, /* 8: deemphasis all off */
232 0xff, 0xff
234 static unsigned char inits_ak4355[] = {
235 0x01, 0x02, /* 1: reset and soft-mute */
236 0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */
237 0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
238 // 0x02, 0x2e, /* quad speed */
239 0x03, 0x01, /* 3: de-emphasis off */
240 0x04, 0x00, /* 4: LOUT1 volume muted */
241 0x05, 0x00, /* 5: ROUT1 volume muted */
242 0x06, 0x00, /* 6: LOUT2 volume muted */
243 0x07, 0x00, /* 7: ROUT2 volume muted */
244 0x08, 0x00, /* 8: LOUT3 volume muted */
245 0x09, 0x00, /* 9: ROUT3 volume muted */
246 0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
247 0x01, 0x01, /* 1: un-reset, unmute */
248 0xff, 0xff
250 static unsigned char inits_ak4381[] = {
251 0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
252 0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */
253 // 0x01, 0x12, /* quad speed */
254 0x02, 0x00, /* 2: DZF disabled */
255 0x03, 0x00, /* 3: LATT 0 */
256 0x04, 0x00, /* 4: RATT 0 */
257 0x00, 0x0f, /* 0: power-up, un-reset */
258 0xff, 0xff
263 * initialize all the ak4xxx chips
265 void Init_akm4xxx(struct CardData *card, enum akm_types type, enum Model CardModel)
268 int chip, num_chips;
269 unsigned char *ptr, reg, data, *inits;
271 switch (type) {
272 case AKM4524:
273 inits = inits_ak4524;
274 num_chips = 8 / 2;
275 break;
276 case AKM4528:
277 inits = inits_ak4528;
278 num_chips = 1; //8 / 2;
279 break;
280 case AKM4529:
281 inits = inits_ak4529;
282 num_chips = 1;
283 break;
284 case AKM4355:
285 inits = inits_ak4355;
286 num_chips = 1;
287 break;
288 case AKM4381:
289 inits = inits_ak4381;
290 num_chips = 8 / 2;
291 break;
292 default:
293 inits = inits_ak4524;
294 num_chips = 8 / 2;
295 return;
299 if (CardModel == PHASE88)
301 for (chip = 0; chip < num_chips; chip++)
303 ptr = inits;
304 while (*ptr != 0xff)
306 reg = *ptr++;
307 data = *ptr++;
308 Phase88_akm4xxx_write(card, chip, reg, data);
312 else if (CardModel == MAUDIO_2496)
314 ptr = inits;
315 while (*ptr != 0xff)
317 reg = *ptr++;
318 data = *ptr++;
319 akm4xxx_write(card, &(card->codec[0]), 0, reg, data);
322 else if (CardModel == MAUDIO_DELTA44 || CardModel == MAUDIO_DELTA66)
324 ptr = inits;
325 while (*ptr != 0xff)
327 reg = *ptr++;
328 data = *ptr++;
329 akm4xxx_write(card, &(card->codec[0]), 0, reg, data);
332 else if (CardModel == MAUDIO_1010LT)
334 for (chip = 0; chip < num_chips; chip++)
336 ptr = inits;
337 while (*ptr != 0xff)
339 reg = *ptr++;
340 data = *ptr++;
341 akm4xxx_write(card, &card->codec[chip], chip, reg, data);
347 #define AK_GET_CHIP(val) (((val) >> 8) & 0xff)
348 #define AK_GET_ADDR(val) ((val) & 0xff)
349 #define AK_GET_SHIFT(val) (((val) >> 16) & 0x7f)
350 #define AK_GET_INVERT(val) (((val) >> 23) & 1)
351 #define AK_GET_MASK(val) (((val) >> 24) & 0xff)
352 #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
353 #define AK_INVERT (1<<23)