static void start_DMA(ice1712 *card) { uint16 size = card->buffer_size * MAX_DAC; write_mt_uint8(card, MT_PROF_PB_CONTROL, 0); write_mt_uint32(card, MT_PROF_PB_DMA_BASE_ADDRESS, (uint32)card->phys_addr_pb); write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS, (size * SWAPPING_BUFFERS) - 1); //We want interrupt only from playback write_mt_uint16(card, MT_PROF_PB_DMA_TERM_COUNT, size - 1); TRACE("SIZE DMA PLAYBACK %#x\n", size); size = card->buffer_size * MAX_ADC; write_mt_uint32(card, MT_PROF_REC_DMA_BASE_ADDRESS, (uint32)card->phys_addr_rec); write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS, (size * SWAPPING_BUFFERS) - 1); //We do not want any interrupt from the record write_mt_uint16(card, MT_PROF_REC_DMA_TERM_COUNT, 0); TRACE("SIZE DMA RECORD %#x\n", size); //Enable output AND Input from Analog CODEC switch (card->product) { //TODO: find correct value for all card case ICE1712_SUBDEVICE_DELTA66: case ICE1712_SUBDEVICE_DELTA44: case ICE1712_SUBDEVICE_AUDIOPHILE_2496: case ICE1712_SUBDEVICE_DELTADIO2496: case ICE1712_SUBDEVICE_DELTA410: case ICE1712_SUBDEVICE_DELTA1010LT: case ICE1712_SUBDEVICE_DELTA1010: codec_write(card, AK45xx_CLOCK_FORMAT_REGISTER, 0x69); codec_write(card, AK45xx_RESET_REGISTER, 0x03); break; case ICE1712_SUBDEVICE_VX442: // ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0); // ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1); break; } //Set Data Format for SPDif codec switch (card->product) { //TODO: find correct value for all card case ICE1712_SUBDEVICE_DELTA1010: break; case ICE1712_SUBDEVICE_DELTADIO2496: break; case ICE1712_SUBDEVICE_DELTA66: case ICE1712_SUBDEVICE_DELTA44: // ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0); // ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1); break; case ICE1712_SUBDEVICE_AUDIOPHILE_2496: spdif_write(card, CS84xx_SERIAL_INPUT_FORMAT_REG, 0x85); spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x85); // spdif_write(card, CS84xx_SERIAL_OUTPUT_FORMAT_REG, 0x41); break; case ICE1712_SUBDEVICE_DELTA410: break; case ICE1712_SUBDEVICE_DELTA1010LT: // ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_0); // ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_1); // ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_2); // ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_3); break; case ICE1712_SUBDEVICE_VX442: // ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0); // ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1); break; } card->buffer = 1; write_mt_uint8(card, MT_PROF_PB_CONTROL, 5); }
status_t applySettings(ice1712 *card) { int i; uint16 val, mt30 = 0; uint32 mt34 = 0; for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) { //Select the channel write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i); if (card->settings.playback[i].mute == true) { val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8); } else { unsigned char volume = card->settings.playback[i].volume / -1.5; if (i & 1) {//a right channel val = ICE1712_MUTE_VALUE << 0; //Mute left volume val |= volume << 8; } else {//a left channel val = ICE1712_MUTE_VALUE << 8; //Mute right volume val |= volume << 0; } } write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); TRACE_VV("Apply Settings %d : 0x%x\n", i, val); } for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) { //Select the channel write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i + ICE1712_HARDWARE_VOLUME); if (card->settings.record[i].mute == true) { val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8); } else { uint8 volume = card->settings.record[i].volume / -1.5; if (i & 1) {//a right channel val = ICE1712_MUTE_VALUE << 0; //Mute left volume val |= volume << 8; } else {//a left channel val = ICE1712_MUTE_VALUE << 8; //Mute right volume val |= volume << 0; } } write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); TRACE_VV("Apply Settings %d : 0x%x\n", i, val); } //Analog output selection for (i = 0; i < 4; i++) { uint8 out = card->settings.output[i]; if (out == 0) { TRACE_VV("Output %d is haiku output\n", i); //Nothing to do } else if (out <= (card->config.nb_ADC / 2)) { uint8 mt34_c; out--; TRACE_VV("Output %d is input %d\n", i, out); mt34_c = (out * 2); mt34_c |= (out * 2 + 1) << 4; mt30 |= 0x0202 << (2*i); mt30 |= mt34_c << (8*i); } else if (out == ((card->config.nb_ADC / 2) + 1) && (card->config.spdif & SPDIF_IN_PRESENT) != 0) { TRACE_VV("Output %d is digital input\n", i); mt30 |= 0x0303 << (2*i); mt34 |= 0x80 << (8*i); } else { TRACE_VV("Output %d is digital Mixer\n", i); mt30 |= 0x0101; } } write_mt_uint16(card, MT_ROUTING_CONTROL_PSDOUT, mt30); write_mt_uint32(card, MT_CAPTURED_DATA, mt34); //Digital output if ((card->config.spdif & SPDIF_OUT_PRESENT) != 0) { uint16 mt32 = 0; uint8 out = card->settings.output[4]; if (out == 0) { TRACE_VV("Digital output is haiku output\n"); //Nothing to do } else if (out <= (card->config.nb_ADC / 2)) { out--; TRACE_VV("Digital output is input %d\n", out); mt32 |= 0x0202; mt32 |= (out * 2) << 8; mt32 |= (out * 2 + 1) << 12; } else if (out == ((card->config.nb_ADC / 2) + 1) && (card->config.spdif & SPDIF_IN_PRESENT) != 0) { TRACE_VV("Digital output is digital input\n"); mt32 |= 0x800F; } else { TRACE_VV("Digital output is digital Mixer\n"); mt32 |= 0x0005; } write_mt_uint16(card, MT_ROUTING_CONTROL_SPDOUT, mt32); } return B_OK; }