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
16extern pci_module_info *pci;
17
18static void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr,
19	uint8 data, uint8 chip_select, uint8 invert_cs);
20
21static void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr,
22	uint8 data, uint8 chip_select, uint8 invert_cs);
23
24static uint8 ak45xx_read_gpio(ice1712 *ice, uint8 reg_addr,
25	uint8 chip_select, uint8 invert_cs)
26		{return 0;} //Unimplemented
27
28static uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr,
29	uint8 chip_select, uint8 invert_cs);
30
31static void write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data);
32static uint8 read_gpio_byte(ice1712 *ice, uint8 gpio_data);
33
34
35//Address are [PCI_10] + xx
36uint8
37read_ccs_uint8(ice1712 *ice, int8 regno)
38{
39	return pci->read_io_8(ice->Controller + regno);
40};
41
42
43uint16
44read_ccs_uint16(ice1712 *ice, int8 regno)
45{
46	return pci->read_io_16(ice->Controller + regno);
47};
48
49
50uint32
51read_ccs_uint32(ice1712 *ice, int8 regno)
52{
53	return pci->read_io_32(ice->Controller + regno);
54};
55
56
57void
58write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value)
59{
60	pci->write_io_8(ice->Controller + regno, value);
61};
62
63
64void
65write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value)
66{
67	pci->write_io_16(ice->Controller + regno, value);
68};
69
70
71void
72write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value)
73{
74	pci->write_io_32(ice->Controller + regno, value);
75};
76
77
78uint8
79read_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
86void
87write_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
95uint8
96read_ddma_uint8(ice1712 *ice, int8 regno)
97{
98	return pci->read_io_8(ice->DDMA + regno);
99};
100
101
102uint16
103read_ddma_uint16(ice1712 *ice, int8 regno)
104{
105	return pci->read_io_16(ice->DDMA + regno);
106};
107
108
109uint32
110read_ddma_uint32(ice1712 *ice, int8 regno)
111{
112	return pci->read_io_32(ice->DDMA + regno);
113};
114
115
116void
117write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value)
118{
119	pci->write_io_8(ice->DDMA + regno, value);
120};
121
122
123void
124write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value)
125{
126	pci->write_io_16(ice->DDMA + regno, value);
127};
128
129
130void
131write_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
138uint8
139read_ds_uint8(ice1712 *ice, int8 regno)
140{
141	return pci->read_io_8(ice->DMA_Path + regno);
142};
143
144
145uint16
146read_ds_uint16(ice1712 *ice, int8 regno)
147{
148	return pci->read_io_16(ice->DMA_Path + regno);
149};
150
151
152uint32
153read_ds_uint32(ice1712 *ice, int8 regno)
154{
155	return pci->read_io_32(ice->DMA_Path + regno);
156};
157
158
159void
160write_ds_uint8(ice1712 *ice, int8 regno, uint8 value)
161{
162	pci->write_io_8(ice->DMA_Path + regno, value);
163};
164
165
166void
167write_ds_uint16(ice1712 *ice, int8 regno, uint16 value)
168{
169	pci->write_io_16(ice->DMA_Path + regno, value);
170};
171
172
173void
174write_ds_uint32(ice1712 *ice, int8 regno, uint32 value)
175{
176	pci->write_io_32(ice->DMA_Path + regno, value);
177};
178
179
180uint32
181read_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
190void
191write_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
202uint8
203read_mt_uint8(ice1712 *ice, int8 regno)
204{
205	return pci->read_io_8(ice->Multi_Track + regno);
206};
207
208
209uint16
210read_mt_uint16(ice1712 *ice, int8 regno)
211{
212	return pci->read_io_16(ice->Multi_Track + regno);
213};
214
215
216uint32
217read_mt_uint32(ice1712 *ice, int8 regno)
218{
219	return pci->read_io_32(ice->Multi_Track + regno);
220};
221
222
223void
224write_mt_uint8(ice1712 *ice, int8 regno, uint8 value)
225{
226	pci->write_io_8(ice->Multi_Track + regno, value);
227};
228
229
230void
231write_mt_uint16(ice1712 *ice, int8 regno, uint16 value)
232{
233	pci->write_io_16(ice->Multi_Track + regno, value);
234};
235
236
237void
238write_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 */
247int16
248read_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 */
262int16
263write_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
275int16 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
300void
301codec_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
335void
336spdif_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
363uint8
364codec_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
391uint8
392spdif_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
422void
423write_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
446uint8
447read_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
471void
472ak45xx_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
504void
505cs84xx_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
537uint8
538cs84xx_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 */
597uint8
598read_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 */
607void
608write_gpio(ice1712 *ice, uint8 value)
609{
610	write_cci_uint8(ice, CCI_GPIO_DATA, value);
611}
612