1 /*
2 * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Jérôme Duval, jerome.duval@free.fr
7 * Marcus Overhagen, marcus@overhagen.de
8 * Jérôme Lévêque, leveque.jerome@gmail.com
9 */
10
11
12 #include "io.h"
13 #include "ice1712_reg.h"
14 #include "debug.h"
15
16 extern pci_module_info *pci;
17
18 static void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr,
19 uint8 data, uint8 chip_select, uint8 invert_cs);
20
21 static void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr,
22 uint8 data, uint8 chip_select, uint8 invert_cs);
23
ak45xx_read_gpio(ice1712 * ice,uint8 reg_addr,uint8 chip_select,uint8 invert_cs)24 static uint8 ak45xx_read_gpio(ice1712 *ice, uint8 reg_addr,
25 uint8 chip_select, uint8 invert_cs)
26 {return 0;} //Unimplemented
27
28 static uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr,
29 uint8 chip_select, uint8 invert_cs);
30
31 static void write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data);
32 static uint8 read_gpio_byte(ice1712 *ice, uint8 gpio_data);
33
34
35 //Address are [PCI_10] + xx
36 uint8
read_ccs_uint8(ice1712 * ice,int8 regno)37 read_ccs_uint8(ice1712 *ice, int8 regno)
38 {
39 return pci->read_io_8(ice->Controller + regno);
40 };
41
42
43 uint16
read_ccs_uint16(ice1712 * ice,int8 regno)44 read_ccs_uint16(ice1712 *ice, int8 regno)
45 {
46 return pci->read_io_16(ice->Controller + regno);
47 };
48
49
50 uint32
read_ccs_uint32(ice1712 * ice,int8 regno)51 read_ccs_uint32(ice1712 *ice, int8 regno)
52 {
53 return pci->read_io_32(ice->Controller + regno);
54 };
55
56
57 void
write_ccs_uint8(ice1712 * ice,int8 regno,uint8 value)58 write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value)
59 {
60 pci->write_io_8(ice->Controller + regno, value);
61 };
62
63
64 void
write_ccs_uint16(ice1712 * ice,int8 regno,uint16 value)65 write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value)
66 {
67 pci->write_io_16(ice->Controller + regno, value);
68 };
69
70
71 void
write_ccs_uint32(ice1712 * ice,int8 regno,uint32 value)72 write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value)
73 {
74 pci->write_io_32(ice->Controller + regno, value);
75 };
76
77
78 uint8
read_cci_uint8(ice1712 * ice,int8 index)79 read_cci_uint8(ice1712 *ice, int8 index)
80 {
81 write_ccs_uint8(ice, CCS_CCI_INDEX, index);
82 return read_ccs_uint8(ice, CCS_CCI_DATA);
83 };
84
85
86 void
write_cci_uint8(ice1712 * ice,int8 index,uint8 value)87 write_cci_uint8(ice1712 *ice, int8 index, uint8 value)
88 {
89 write_ccs_uint8(ice, CCS_CCI_INDEX, index);
90 write_ccs_uint8(ice, CCS_CCI_DATA, value);
91 };
92
93
94 //Address are [PCI_14] + xx
95 uint8
read_ddma_uint8(ice1712 * ice,int8 regno)96 read_ddma_uint8(ice1712 *ice, int8 regno)
97 {
98 return pci->read_io_8(ice->DDMA + regno);
99 };
100
101
102 uint16
read_ddma_uint16(ice1712 * ice,int8 regno)103 read_ddma_uint16(ice1712 *ice, int8 regno)
104 {
105 return pci->read_io_16(ice->DDMA + regno);
106 };
107
108
109 uint32
read_ddma_uint32(ice1712 * ice,int8 regno)110 read_ddma_uint32(ice1712 *ice, int8 regno)
111 {
112 return pci->read_io_32(ice->DDMA + regno);
113 };
114
115
116 void
write_ddma_uint8(ice1712 * ice,int8 regno,uint8 value)117 write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value)
118 {
119 pci->write_io_8(ice->DDMA + regno, value);
120 };
121
122
123 void
write_ddma_uint16(ice1712 * ice,int8 regno,uint16 value)124 write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value)
125 {
126 pci->write_io_16(ice->DDMA + regno, value);
127 };
128
129
130 void
write_ddma_uint32(ice1712 * ice,int8 regno,uint32 value)131 write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value)
132 {
133 pci->write_io_32(ice->DDMA + regno, value);
134 };
135
136
137 //Address are [PCI_18] + x
138 uint8
read_ds_uint8(ice1712 * ice,int8 regno)139 read_ds_uint8(ice1712 *ice, int8 regno)
140 {
141 return pci->read_io_8(ice->DMA_Path + regno);
142 };
143
144
145 uint16
read_ds_uint16(ice1712 * ice,int8 regno)146 read_ds_uint16(ice1712 *ice, int8 regno)
147 {
148 return pci->read_io_16(ice->DMA_Path + regno);
149 };
150
151
152 uint32
read_ds_uint32(ice1712 * ice,int8 regno)153 read_ds_uint32(ice1712 *ice, int8 regno)
154 {
155 return pci->read_io_32(ice->DMA_Path + regno);
156 };
157
158
159 void
write_ds_uint8(ice1712 * ice,int8 regno,uint8 value)160 write_ds_uint8(ice1712 *ice, int8 regno, uint8 value)
161 {
162 pci->write_io_8(ice->DMA_Path + regno, value);
163 };
164
165
166 void
write_ds_uint16(ice1712 * ice,int8 regno,uint16 value)167 write_ds_uint16(ice1712 *ice, int8 regno, uint16 value)
168 {
169 pci->write_io_16(ice->DMA_Path + regno, value);
170 };
171
172
173 void
write_ds_uint32(ice1712 * ice,int8 regno,uint32 value)174 write_ds_uint32(ice1712 *ice, int8 regno, uint32 value)
175 {
176 pci->write_io_32(ice->DMA_Path + regno, value);
177 };
178
179
180 uint32
read_ds_channel_data(ice1712 * ice,uint8 channel,ds8_register index)181 read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index)
182 {
183 uint8 ds8_channel_index = channel << 4 | index;
184
185 write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index);
186 return read_ds_uint32(ice, DS_CHANNEL_DATA);
187 }
188
189
190 void
write_ds_channel_data(ice1712 * ice,uint8 channel,ds8_register index,uint32 data)191 write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index,
192 uint32 data)
193 {
194 uint8 ds8_channel_index = channel << 4 | index;
195
196 write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index);
197 write_ds_uint32(ice, DS_CHANNEL_DATA, data);
198 }
199
200
201 //Address are [PCI_1C] + xx
202 uint8
read_mt_uint8(ice1712 * ice,int8 regno)203 read_mt_uint8(ice1712 *ice, int8 regno)
204 {
205 return pci->read_io_8(ice->Multi_Track + regno);
206 };
207
208
209 uint16
read_mt_uint16(ice1712 * ice,int8 regno)210 read_mt_uint16(ice1712 *ice, int8 regno)
211 {
212 return pci->read_io_16(ice->Multi_Track + regno);
213 };
214
215
216 uint32
read_mt_uint32(ice1712 * ice,int8 regno)217 read_mt_uint32(ice1712 *ice, int8 regno)
218 {
219 return pci->read_io_32(ice->Multi_Track + regno);
220 };
221
222
223 void
write_mt_uint8(ice1712 * ice,int8 regno,uint8 value)224 write_mt_uint8(ice1712 *ice, int8 regno, uint8 value)
225 {
226 pci->write_io_8(ice->Multi_Track + regno, value);
227 };
228
229
230 void
write_mt_uint16(ice1712 * ice,int8 regno,uint16 value)231 write_mt_uint16(ice1712 *ice, int8 regno, uint16 value)
232 {
233 pci->write_io_16(ice->Multi_Track + regno, value);
234 };
235
236
237 void
write_mt_uint32(ice1712 * ice,int8 regno,uint32 value)238 write_mt_uint32(ice1712 *ice, int8 regno, uint32 value)
239 {
240 pci->write_io_32(ice->Multi_Track + regno, value);
241 };
242
243
244 /*
245 * return -1 if error else return an uint8
246 */
247 int16
read_i2c(ice1712 * ice,uint8 dev_addr,uint8 byte_addr)248 read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr)
249 {
250 if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
251 return -1;
252 write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
253 write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
254 snooze(1000);
255 return read_ccs_uint8(ice, CCS_I2C_DATA);
256 }
257
258
259 /*
260 * return -1 if error else return 0
261 */
262 int16
write_i2c(ice1712 * ice,uint8 dev_addr,uint8 byte_addr,uint8 value)263 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value)
264 {
265 if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
266 return -1;
267
268 write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
269 write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
270 write_ccs_uint8(ice, CCS_I2C_DATA, value);
271 return 0;
272 }
273
274
read_eeprom(ice1712 * ice,uint8 eeprom[32])275 int16 read_eeprom(ice1712 *ice, uint8 eeprom[32])
276 {
277 int i;
278 int16 tmp;
279
280 for (i = 0; i < 6; i++) {
281 tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
282 if (tmp >= 0)
283 eeprom[i] = (uint8)tmp;
284 else
285 return -1;
286 }
287 if (eeprom[4] > 32)
288 return -1;
289 for (i = 6; i < eeprom[4]; i++) {
290 tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
291 if (tmp >= 0)
292 eeprom[i] = (uint8)tmp;
293 else
294 return -1;
295 }
296 return eeprom[4];
297 }
298
299
300 void
codec_write(ice1712 * ice,uint8 reg_addr,uint8 data)301 codec_write(ice1712 *ice, uint8 reg_addr, uint8 data)
302 {
303 switch (ice->config.product) {
304 case ICE1712_SUBDEVICE_DELTA66:
305 case ICE1712_SUBDEVICE_DELTA44:
306 ak45xx_write_gpio(ice, reg_addr, data,
307 DELTA66_CODEC_CS_0, 0);
308 ak45xx_write_gpio(ice, reg_addr, data,
309 DELTA66_CODEC_CS_1, 0);
310 break;
311 case ICE1712_SUBDEVICE_DELTA410:
312 case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
313 case ICE1712_SUBDEVICE_DELTADIO2496:
314 ak45xx_write_gpio(ice, reg_addr, data, AP2496_CODEC_CS, 0);
315 break;
316 case ICE1712_SUBDEVICE_DELTA1010:
317 case ICE1712_SUBDEVICE_DELTA1010LT:
318 ak45xx_write_gpio(ice, reg_addr, data,
319 DELTA1010LT_CODEC_CS_0, DELTA1010LT_CS_NONE);
320 ak45xx_write_gpio(ice, reg_addr, data,
321 DELTA1010LT_CODEC_CS_1, DELTA1010LT_CS_NONE);
322 ak45xx_write_gpio(ice, reg_addr, data,
323 DELTA1010LT_CODEC_CS_2, DELTA1010LT_CS_NONE);
324 ak45xx_write_gpio(ice, reg_addr, data,
325 DELTA1010LT_CODEC_CS_3, DELTA1010LT_CS_NONE);
326 break;
327 case ICE1712_SUBDEVICE_VX442:
328 ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0, 0);
329 ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1, 0);
330 break;
331 }
332 }
333
334
335 void
spdif_write(ice1712 * ice,uint8 reg_addr,uint8 data)336 spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data)
337 {
338 switch (ice->config.product) {
339 case ICE1712_SUBDEVICE_DELTA1010:
340 break;
341 case ICE1712_SUBDEVICE_DELTADIO2496:
342 break;
343 case ICE1712_SUBDEVICE_DELTA66:
344 break;
345 case ICE1712_SUBDEVICE_DELTA44:
346 break;
347 case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
348 cs84xx_write_gpio(ice, reg_addr, data, AP2496_SPDIF_CS, 0);
349 break;
350 case ICE1712_SUBDEVICE_DELTA410:
351 break;
352 case ICE1712_SUBDEVICE_DELTA1010LT:
353 cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS,
354 DELTA1010LT_CS_NONE);
355 break;
356 case ICE1712_SUBDEVICE_VX442:
357 cs84xx_write_gpio(ice, reg_addr, data, VX442_SPDIF_CS, 0);
358 break;
359 }
360 }
361
362
363 uint8
codec_read(ice1712 * ice,uint8 reg_addr)364 codec_read(ice1712 *ice, uint8 reg_addr)
365 {
366 uint8 val = 0xFF;
367 switch (ice->config.product) {
368 case ICE1712_SUBDEVICE_DELTA66:
369 case ICE1712_SUBDEVICE_DELTA44:
370 val = ak45xx_read_gpio(ice, reg_addr, DELTA66_CODEC_CS_0, 0);
371 break;
372 case ICE1712_SUBDEVICE_DELTA410:
373 case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
374 case ICE1712_SUBDEVICE_DELTADIO2496:
375 val = ak45xx_read_gpio(ice, reg_addr, AP2496_CODEC_CS, 0);
376 break;
377 case ICE1712_SUBDEVICE_DELTA1010:
378 case ICE1712_SUBDEVICE_DELTA1010LT:
379 val = ak45xx_read_gpio(ice, reg_addr, DELTA1010LT_CODEC_CS_0,
380 DELTA1010LT_CS_NONE);
381 break;
382 case ICE1712_SUBDEVICE_VX442:
383 val = ak45xx_read_gpio(ice, reg_addr, VX442_CODEC_CS_0, 0);
384 break;
385 }
386
387 return val;
388 }
389
390
391 uint8
spdif_read(ice1712 * ice,uint8 reg_addr)392 spdif_read(ice1712 *ice, uint8 reg_addr)
393 {
394 uint8 val = 0xFF;
395 switch (ice->config.product) {
396 case ICE1712_SUBDEVICE_DELTA1010:
397 break;
398 case ICE1712_SUBDEVICE_DELTADIO2496:
399 break;
400 case ICE1712_SUBDEVICE_DELTA66:
401 break;
402 case ICE1712_SUBDEVICE_DELTA44:
403 break;
404 case ICE1712_SUBDEVICE_AUDIOPHILE_2496:
405 val = cs84xx_read_gpio(ice, reg_addr, AP2496_SPDIF_CS, 0);
406 break;
407 case ICE1712_SUBDEVICE_DELTA410:
408 break;
409 case ICE1712_SUBDEVICE_DELTA1010LT:
410 val = cs84xx_read_gpio(ice, reg_addr, DELTA1010LT_SPDIF_CS,
411 DELTA1010LT_CS_NONE);
412 break;
413 case ICE1712_SUBDEVICE_VX442:
414 val = cs84xx_read_gpio(ice, reg_addr, VX442_SPDIF_CS, 0);
415 break;
416 }
417
418 return val;
419 }
420
421
422 void
write_gpio_byte(ice1712 * ice,uint8 data,uint8 gpio_data)423 write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data)
424 {
425 int i;
426
427 for (i = 7; i >= 0; i--) {
428 // drop clock and data bits
429 gpio_data &= ~(ice->CommLines.clock | ice->CommLines.data_out);
430
431 // set data bit if needed
432 if (data & (1 << i))
433 gpio_data |= ice->CommLines.data_out;
434
435 write_gpio(ice, gpio_data);
436 snooze(GPIO_I2C_DELAY);
437
438 // raise clock
439 gpio_data |= ice->CommLines.clock;
440 write_gpio(ice, gpio_data);
441 snooze(GPIO_I2C_DELAY);
442 }
443 }
444
445
446 uint8
read_gpio_byte(ice1712 * ice,uint8 gpio_data)447 read_gpio_byte(ice1712 *ice, uint8 gpio_data)
448 {
449 int i;
450 uint8 data = 0;
451
452 for (i = 7; i >= 0; i--) {
453 // drop clock
454 gpio_data &= ~(ice->CommLines.clock);
455 write_gpio(ice, gpio_data);
456 snooze(GPIO_I2C_DELAY);
457
458 if (read_gpio(ice) &ice->CommLines.data_in)
459 data |= 1 << i;
460
461 gpio_data |= ice->CommLines.clock;
462
463 write_gpio(ice, gpio_data);
464 snooze(GPIO_I2C_DELAY);
465 }
466
467 return data;
468 }
469
470
471 void
ak45xx_write_gpio(ice1712 * ice,uint8 reg_addr,uint8 data,uint8 chip_select,uint8 invert_cs)472 ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
473 uint8 chip_select, uint8 invert_cs)
474 {
475 uint8 tmp;
476
477 tmp = read_gpio(ice);
478 tmp |= ice->CommLines.cs_mask;
479
480 if (invert_cs != 0) {
481 tmp &= ~invert_cs;
482 tmp |= chip_select;
483 } else {
484 tmp &= ~chip_select;
485 }
486
487 write_gpio(ice, tmp);
488 snooze(GPIO_I2C_DELAY);
489
490 write_gpio_byte(ice, ((AK45xx_CHIP_ADDRESS & 0x03) << 6) | 0x20
491 | (reg_addr & 0x1F), tmp);
492 write_gpio_byte(ice, data, tmp);
493
494 if (invert_cs != 0) {
495 tmp |= invert_cs;
496 } else {
497 tmp |= chip_select;
498 }
499 write_gpio(ice, tmp);
500 snooze(GPIO_I2C_DELAY);
501 }
502
503
504 void
cs84xx_write_gpio(ice1712 * ice,uint8 reg_addr,uint8 data,uint8 chip_select,uint8 invert_cs)505 cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
506 uint8 chip_select, uint8 invert_cs)
507 {
508 uint8 tmp;
509
510 tmp = read_gpio(ice);
511 tmp |= ice->CommLines.cs_mask;
512
513 if (invert_cs != 0) {
514 tmp &= ~invert_cs;
515 tmp |= chip_select;
516 } else {
517 tmp &= ~chip_select;
518 }
519
520 write_gpio(ice, tmp);
521 snooze(GPIO_I2C_DELAY);
522
523 write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1, tmp);
524 write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
525 write_gpio_byte(ice, data, tmp);
526
527 if (invert_cs != 0) {
528 tmp |= invert_cs;
529 } else {
530 tmp |= chip_select;
531 }
532 write_gpio(ice, tmp);
533 snooze(GPIO_I2C_DELAY);
534 }
535
536
537 uint8
cs84xx_read_gpio(ice1712 * ice,uint8 reg_addr,uint8 chip_select,uint8 invert_cs)538 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select,
539 uint8 invert_cs)
540 {
541 uint8 tmp, data;
542
543 tmp = read_gpio(ice);
544 tmp |= ice->CommLines.cs_mask;
545
546 if (invert_cs != 0) {
547 tmp &= ~invert_cs;
548 tmp |= chip_select;
549 } else {
550 tmp &= ~chip_select;
551 }
552
553 write_gpio(ice, tmp);
554 snooze(GPIO_I2C_DELAY);
555
556 write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1,
557 tmp); //For writing the MAP
558 write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
559
560 //Deselect the chip
561 if (invert_cs != 0) {
562 tmp |= invert_cs;
563 } else {
564 tmp |= chip_select;
565 }
566 write_gpio(ice, tmp);
567 snooze(GPIO_I2C_DELAY);
568
569 if (invert_cs != 0) {
570 tmp &= ~invert_cs;
571 tmp |= chip_select;
572 } else {
573 tmp &= ~chip_select;
574 }
575 write_gpio(ice, tmp);
576 snooze(GPIO_I2C_DELAY);
577
578 write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1 | 1,
579 tmp); //For writing the MAP
580 data = read_gpio_byte(ice, tmp); //For reading
581
582 //Deselect the chip
583 if (invert_cs != 0) {
584 tmp |= invert_cs;
585 } else {
586 tmp |= chip_select;
587 }
588 write_gpio(ice, tmp);
589
590 return data;
591 }
592
593
594 /*
595 * return -1 if error else return an uint8
596 */
597 uint8
read_gpio(ice1712 * ice)598 read_gpio(ice1712 *ice)
599 {
600 return read_cci_uint8(ice, CCI_GPIO_DATA);
601 }
602
603
604 /*
605 * return -1 if error else return 0
606 */
607 void
write_gpio(ice1712 * ice,uint8 value)608 write_gpio(ice1712 *ice, uint8 value)
609 {
610 write_cci_uint8(ice, CCI_GPIO_DATA, value);
611 }
612