1/*
2 * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller
3 *
4 * Copyright (c) 2002, Jerome Duval		(jerome.duval@free.fr)
5 * Copyright (c) 2003, Marcus Overhagen	(marcus@overhagen.de)
6 * Copyright (c) 2007, Jerome Leveque	(leveque.jerome@neuf.fr)
7 *
8 * All rights reserved
9 * Distributed under the terms of the MIT license.
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
36
37uint8
38read_ccs_uint8(ice1712 *ice, int8 regno)
39{
40	return pci->read_io_8(ice->Controller + regno);
41};
42
43
44uint16
45read_ccs_uint16(ice1712 *ice, int8 regno)
46{
47	return pci->read_io_16(ice->Controller + regno);
48};
49
50
51uint32
52read_ccs_uint32(ice1712 *ice, int8 regno)
53{
54	return pci->read_io_32(ice->Controller + regno);
55};
56
57
58void
59write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value)
60{
61	pci->write_io_8(ice->Controller + regno, value);
62};
63
64
65void
66write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value)
67{
68	pci->write_io_16(ice->Controller + regno, value);
69};
70
71
72void
73write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value)
74{
75	pci->write_io_32(ice->Controller + regno, value);
76};
77
78
79uint8
80read_cci_uint8(ice1712 *ice, int8 index)
81{
82	write_ccs_uint8(ice, CCS_CCI_INDEX, index);
83	return read_ccs_uint8(ice, CCS_CCI_DATA);
84};
85
86
87void
88write_cci_uint8(ice1712 *ice, int8 index, uint8 value)
89{
90	write_ccs_uint8(ice, CCS_CCI_INDEX, index);
91	write_ccs_uint8(ice, CCS_CCI_DATA, value);
92};
93
94//--------------------------------------------------
95//--------------------------------------------------
96//Address are [PCI_14] + xx
97
98uint8
99read_ddma_uint8(ice1712 *ice, int8 regno)
100{
101	return pci->read_io_8(ice->DDMA + regno);
102};
103
104
105uint16
106read_ddma_uint16(ice1712 *ice, int8 regno)
107{
108	return pci->read_io_16(ice->DDMA + regno);
109};
110
111
112uint32
113read_ddma_uint32(ice1712 *ice, int8 regno)
114{
115	return pci->read_io_32(ice->DDMA + regno);
116};
117
118
119void
120write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value)
121{
122	pci->write_io_8(ice->DDMA + regno, value);
123};
124
125
126void
127write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value)
128{
129	pci->write_io_16(ice->DDMA + regno, value);
130};
131
132
133void
134write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value)
135{
136	pci->write_io_32(ice->DDMA + regno, value);
137};
138
139
140//--------------------------------------------------
141//--------------------------------------------------
142//Address are [PCI_18] + x
143uint8
144read_ds_uint8(ice1712 *ice, int8 regno)
145{
146	return pci->read_io_8(ice->DMA_Path + regno);
147};
148
149
150uint16
151read_ds_uint16(ice1712 *ice, int8 regno)
152{
153	return pci->read_io_16(ice->DMA_Path + regno);
154};
155
156
157uint32
158read_ds_uint32(ice1712 *ice, int8 regno)
159{
160	return pci->read_io_32(ice->DMA_Path + regno);
161};
162
163
164void
165write_ds_uint8(ice1712 *ice, int8 regno, uint8 value)
166{
167	pci->write_io_8(ice->DMA_Path + regno, value);
168};
169
170
171void
172write_ds_uint16(ice1712 *ice, int8 regno, uint16 value)
173{
174	pci->write_io_16(ice->DMA_Path + regno, value);
175};
176
177
178void
179write_ds_uint32(ice1712 *ice, int8 regno, uint32 value)
180{
181	pci->write_io_32(ice->DMA_Path + regno, value);
182};
183
184
185uint32
186read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index)
187{
188	uint8 ds8_channel_index = channel << 4 | index;
189
190	write_ds_uint8(ice,	DS_CHANNEL_INDEX, ds8_channel_index);
191	return read_ds_uint32(ice, DS_CHANNEL_DATA);
192}
193
194
195void
196write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index,
197	uint32 data)
198{
199	uint8 ds8_channel_index = channel << 4 | index;
200
201	write_ds_uint8(ice,	DS_CHANNEL_INDEX, ds8_channel_index);
202	write_ds_uint32(ice, DS_CHANNEL_DATA, data);
203}
204
205
206//--------------------------------------------------
207//--------------------------------------------------
208//Address are [PCI_1C] + xx
209
210uint8
211read_mt_uint8(ice1712 *ice,	int8 regno)
212{
213	return 	pci->read_io_8(ice->Multi_Track + regno);
214};
215
216
217uint16
218read_mt_uint16(ice1712 *ice,	int8 regno)
219{
220	return 	pci->read_io_16(ice->Multi_Track + regno);
221};
222
223
224uint32
225read_mt_uint32(ice1712 *ice,	int8 regno)
226{
227	return pci->read_io_32(ice->Multi_Track + regno);
228};
229
230void
231write_mt_uint8(ice1712 *ice,	int8 regno,	uint8 value)
232{
233	pci->write_io_8(ice->Multi_Track + regno, value);
234};
235
236
237void
238write_mt_uint16(ice1712 *ice,	int8 regno,	uint16 value)
239{
240	pci->write_io_16(ice->Multi_Track + regno, value);
241};
242
243
244void
245write_mt_uint32(ice1712 *ice,	int8 regno,	uint32 value)
246{
247	pci->write_io_32(ice->Multi_Track + regno, value);
248};
249
250
251int16
252read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr)
253{//return -1 if error else return an uint8
254
255	if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
256		return -1;
257	write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
258	write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
259	snooze(1000);
260	return read_ccs_uint8(ice, CCS_I2C_DATA);
261}
262
263
264int16
265write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value)
266{//return -1 if error else return 0
267	if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80)
268		return -1;
269
270	write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr);
271	write_ccs_uint8(ice, CCS_I2C_DEV_ADDRESS, dev_addr);
272	write_ccs_uint8(ice, CCS_I2C_DATA, value);
273	return 0;
274}
275
276
277int16 read_eeprom(ice1712 *ice, uint8 eeprom[32])
278{
279	int i;
280	int16 tmp;
281
282	for (i = 0; i < 6; i++) {
283		tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
284		if (tmp >= 0)
285			eeprom[i] = (uint8)tmp;
286		else
287			return -1;
288	}
289	if (eeprom[4] > 32)
290		return -1;
291	for (i = 6; i < eeprom[4]; i++) {
292		tmp = read_i2c(ice, I2C_EEPROM_ADDRESS_READ, i);
293		if (tmp >= 0)
294			eeprom[i] = (uint8)tmp;
295		else
296			return -1;
297	}
298	return eeprom[4];
299}
300
301
302void
303codec_write(ice1712 *ice, uint8 reg_addr, uint8 data)
304{
305	switch (ice->product) {
306		case ICE1712_SUBDEVICE_DELTA66:
307		case ICE1712_SUBDEVICE_DELTA44:
308			ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0, 0);
309			ak45xx_write_gpio(ice, reg_addr, data, 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, DELTA1010LT_CODEC_CS_0,
319					DELTA1010LT_CS_NONE);
320			ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_1,
321					DELTA1010LT_CS_NONE);
322			ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_2,
323					DELTA1010LT_CS_NONE);
324			ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_3,
325					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->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->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->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
421void
422write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data)
423{
424	int i;
425
426	for (i = 7; i >= 0; i--) {
427		// drop clock and data bits
428		gpio_data &= ~(ice->CommLines.clock | ice->CommLines.data_out);
429
430		// set data bit if needed
431		if (data & (1 << i))
432			gpio_data |= ice->CommLines.data_out;
433
434		write_gpio(ice, gpio_data);
435		snooze(GPIO_I2C_DELAY);
436
437		// raise clock
438		gpio_data |= ice->CommLines.clock;
439		write_gpio(ice, gpio_data);
440		snooze(GPIO_I2C_DELAY);
441	}
442}
443
444uint8
445read_gpio_byte(ice1712 *ice, uint8 gpio_data)
446{
447	int i;
448	uint8 data = 0;
449
450	for (i = 7; i >= 0; i--) {
451		// drop clock
452		gpio_data &= ~(ice->CommLines.clock);
453		write_gpio(ice, gpio_data);
454		snooze(GPIO_I2C_DELAY);
455
456		if (read_gpio(ice) &  ice->CommLines.data_in)
457			data |= 1 << i;
458
459		gpio_data |= ice->CommLines.clock;
460
461		write_gpio(ice, gpio_data);
462		snooze(GPIO_I2C_DELAY);
463	}
464
465	return data;
466}
467
468void
469ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
470	uint8 chip_select, uint8 invert_cs)
471{
472	uint8 tmp;
473
474	tmp = read_gpio(ice);
475	tmp |= ice->CommLines.cs_mask;
476
477	if (invert_cs != 0) {
478		tmp &= ~invert_cs;
479		tmp |= chip_select;
480	} else {
481		tmp &= ~chip_select;
482	}
483
484	write_gpio(ice, tmp);
485	snooze(GPIO_I2C_DELAY);
486
487	write_gpio_byte(ice, ((AK45xx_CHIP_ADDRESS & 0x03) << 6) | 0x20
488		| (reg_addr & 0x1F), tmp);
489	write_gpio_byte(ice, data, tmp);
490
491	if (invert_cs != 0) {
492		tmp |= invert_cs;
493	} else {
494		tmp |= chip_select;
495	}
496	write_gpio(ice, tmp);
497	snooze(GPIO_I2C_DELAY);
498}
499
500void
501cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data,
502	uint8 chip_select, uint8 invert_cs)
503{
504	uint8 tmp;
505
506	tmp = read_gpio(ice);
507	tmp |= ice->CommLines.cs_mask;
508
509	if (invert_cs != 0) {
510		tmp &= ~invert_cs;
511		tmp |= chip_select;
512	} else {
513		tmp &= ~chip_select;
514	}
515
516	write_gpio(ice, tmp);
517	snooze(GPIO_I2C_DELAY);
518
519	write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1, tmp);
520	write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
521	write_gpio_byte(ice, data, tmp);
522
523	if (invert_cs != 0) {
524		tmp |= invert_cs;
525	} else {
526		tmp |= chip_select;
527	}
528	write_gpio(ice, tmp);
529	snooze(GPIO_I2C_DELAY);
530}
531
532uint8
533cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select,
534	uint8 invert_cs)
535{
536	uint8 tmp, data;
537
538	tmp = read_gpio(ice);
539	tmp |= ice->CommLines.cs_mask;
540
541	if (invert_cs != 0) {
542		tmp &= ~invert_cs;
543		tmp |= chip_select;
544	} else {
545		tmp &= ~chip_select;
546	}
547
548	write_gpio(ice, tmp);
549	snooze(GPIO_I2C_DELAY);
550
551	write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1,
552		tmp); //For writing the MAP
553	write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment
554
555	//Deselect the chip
556	if (invert_cs != 0) {
557		tmp |= invert_cs;
558	} else {
559		tmp |= chip_select;
560	}
561	write_gpio(ice, tmp);
562	snooze(GPIO_I2C_DELAY);
563
564	if (invert_cs != 0) {
565		tmp &= ~invert_cs;
566		tmp |= chip_select;
567	} else {
568		tmp &= ~chip_select;
569	}
570	write_gpio(ice, tmp);
571	snooze(GPIO_I2C_DELAY);
572
573	write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7F) << 1 | 1,
574		tmp); //For writing the MAP
575	data = read_gpio_byte(ice, tmp); //For reading
576
577	//Deselect the chip
578	if (invert_cs != 0) {
579		tmp |= invert_cs;
580	} else {
581		tmp |= chip_select;
582	}
583	write_gpio(ice, tmp);
584
585	return data;
586}
587
588
589uint8
590read_gpio(ice1712 *ice)
591{//return -1 if error else return an uint8
592	return read_cci_uint8(ice, CCI_GPIO_DATA);
593}
594
595
596void
597write_gpio(ice1712 *ice, uint8 value)
598{//return -1 if error else return 0
599	write_cci_uint8(ice, CCI_GPIO_DATA, value);
600}
601
602