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