示例#1
0
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;
}
示例#2
0
文件: multi.c 项目: mmanley/Antares
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);
}
示例#3
0
static status_t
ice1712_setup(ice1712 *ice)
{
	int result, i;
	uint8 reg8 = 0;
	uint16 mute;

	ice->irq			= ice->info.u.h0.interrupt_line;
	ice->Controller		= ice->info.u.h0.base_registers[0];
	ice->DDMA			= ice->info.u.h0.base_registers[1];
	ice->DMA_Path		= ice->info.u.h0.base_registers[2];
	ice->Multi_Track	= ice->info.u.h0.base_registers[3];

	// Soft Reset
	write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x81);
	snooze(200000);
	write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x01);
	snooze(200000);

	result = read_eeprom(ice, ice->eeprom_data);

/*	TRACE("EEprom -> ");
	for (i = 0; i < 32; i++)
		TRACE("%x, ", eeprom_data[i]);
	TRACE("<- EEprom\n");*/

	write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01);

	//Write all configurations register from EEProm
	ice->info.device_id = ice->eeprom_data[E2PROM_MAP_SUBVENDOR_HIGH] << 8
		| ice->eeprom_data[E2PROM_MAP_SUBVENDOR_LOW];
	ice->info.vendor_id = ice->eeprom_data[E2PROM_MAP_SUBDEVICE_HIGH] << 8
		| ice->eeprom_data[E2PROM_MAP_SUBDEVICE_LOW];
	ice->product = ice->info.vendor_id << 16 | ice->info.device_id;
	TRACE("Product ID : 0x%x\n", ice->product);

	write_cci_uint8(ice, CCI_GPIO_WRITE_MASK,
		ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
	write_cci_uint8(ice, CCI_GPIO_DATA,
		ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
	write_cci_uint8(ice, CCI_GPIO_DIRECTION_CONTROL,
		ice->eeprom_data[E2PROM_MAP_GPIODIR]);

	TRACE("CCI_GPIO_WRITE_MASK : 0x%x\n",
		ice->eeprom_data[E2PROM_MAP_GPIOMASK]);
	TRACE("CCI_GPIO_DATA : 0x%x\n",
		ice->eeprom_data[E2PROM_MAP_GPIOSTATE]);
	TRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n",
		ice->eeprom_data[E2PROM_MAP_GPIODIR]);


	//Write Configuration in the PCI configuration Register
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]);
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x61, 1, ice->eeprom_data[E2PROM_MAP_ACL]);
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x62, 1, ice->eeprom_data[E2PROM_MAP_I2S]);
	(pci->write_pci_config)(ice->info.bus, ice->info.device,
		ice->info.function, 0x63, 1, ice->eeprom_data[E2PROM_MAP_SPDIF]);

	TRACE("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG]);
	reg8 = ice->eeprom_data[E2PROM_MAP_CONFIG];
	//Bits signification for E2PROM_MAP_CONFIG Byte
	//
	// 8   7   6   5   4   3   2   1   0
	//           |-D-|-C-|---B---|---A---
	//
	// D : MPU401 number minus 1
	// C : AC'97
	// B : Stereo ADC number minus 1 (=> 1 to 4)
	// A : Stereo DAC number minus 1 (=> 1 to 4)

	ice->config.nb_DAC = ((reg8 & 0x03) + 1) * 2;
	reg8 >>= 2;
	ice->config.nb_ADC = ((reg8 & 0x03) + 1) * 2;
	reg8 >>= 2;

	if ((reg8 & 0x01) != 0) {//Consumer AC'97 Exist
		TRACE("Consumer AC'97 does exist\n");
		//For now do nothing
/*		write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x40);
		snooze(10000);
		write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x00);
		snooze(20000);
*/	} else {
		TRACE("Consumer AC'97 does NOT exist\n");
	}
	reg8 >>= 1;
	ice->config.nb_MPU401 = (reg8 & 0x1) + 1;

	if (ice->config.nb_MPU401 > 0) {
		sprintf(ice->midi_interf[0].name, "midi/ice1712/%ld/1",
			ice - cards + 1);

		(*mpu401->create_device)(ice->Controller + CCS_MIDI_1_DATA,
			&ice->midi_interf[0].mpu401device,
			0x14121712,
			ice_1712_midi_interrupt_op,
			&ice->midi_interf[0]);

		names[num_names++] = ice->midi_interf[0].name;
		ice->midi_interf[0].card = ice;
		ice->midi_interf[0].int_mask = CCS_INTERRUPT_MIDI_1;
	}

	if (ice->config.nb_MPU401 > 1) {
		sprintf(ice->midi_interf[1].name, "midi/ice1712/%ld/2",
			ice - cards + 1);

		(*mpu401->create_device)(ice->Controller + CCS_MIDI_2_DATA,
			&ice->midi_interf[1].mpu401device,
			0x14121712,
			ice_1712_midi_interrupt_op,
			&ice->midi_interf[1]);

		names[num_names++] = ice->midi_interf[1].name;
		ice->midi_interf[1].card = ice;
		ice->midi_interf[1].int_mask = CCS_INTERRUPT_MIDI_2;
	}

	TRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]);
	ice->config.spdif = ice->eeprom_data[E2PROM_MAP_SPDIF];

	switch (ice->product) {
		case ICE1712_SUBDEVICE_DELTA66 :
		case ICE1712_SUBDEVICE_DELTA44 :
			ice->CommLines.clock = DELTA66_CLK;
			ice->CommLines.data_in = 0;
			ice->CommLines.data_out = DELTA66_DOUT;
			ice->CommLines.cs_mask = DELTA66_CLK | DELTA66_DOUT
				| DELTA66_CODEC_CS_0 | DELTA66_CODEC_CS_1;
			break;
		case ICE1712_SUBDEVICE_DELTA410 :
		case ICE1712_SUBDEVICE_AUDIOPHILE_2496 :
		case ICE1712_SUBDEVICE_DELTADIO2496 :
			ice->CommLines.clock = AP2496_CLK;
			ice->CommLines.data_in = AP2496_DIN;
			ice->CommLines.data_out = AP2496_DOUT;
			ice->CommLines.cs_mask = AP2496_CLK | AP2496_DIN
				| AP2496_DOUT | AP2496_SPDIF_CS | AP2496_CODEC_CS;
			break;
		case ICE1712_SUBDEVICE_DELTA1010 :
		case ICE1712_SUBDEVICE_DELTA1010LT :
			ice->CommLines.clock = DELTA1010LT_CLK;
			ice->CommLines.data_in = DELTA1010LT_DIN;
			ice->CommLines.data_out = DELTA1010LT_DOUT;
			ice->CommLines.cs_mask = DELTA1010LT_CLK | DELTA1010LT_DIN
				| DELTA1010LT_DOUT | DELTA1010LT_CS_NONE;
			break;
		case ICE1712_SUBDEVICE_VX442 :
			ice->CommLines.clock = VX442_CLK;
			ice->CommLines.data_in = VX442_DIN;
			ice->CommLines.data_out = VX442_DOUT;
			ice->CommLines.cs_mask = VX442_SPDIF_CS | VX442_CODEC_CS_0
				| VX442_CODEC_CS_1;
			break;
	}

	sprintf(ice->name, "%s/%ld", HMULTI_AUDIO_DEV_PATH, ice - cards + 1);
	names[num_names++] = ice->name;
	names[num_names] = NULL;

	ice->buffer_ready_sem = create_sem(0, "Buffer Exchange");
	if (ice->buffer_ready_sem < B_OK) {
		return ice->buffer_ready_sem;
	}

//	TRACE("installing interrupt : %0x\n", ice->irq);
	install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0);

	ice->mem_id_pb = alloc_mem(&ice->phys_addr_pb, &ice->log_addr_pb,
								PLAYBACK_BUFFER_TOTAL_SIZE,
								"playback buffer");
	if (ice->mem_id_pb < B_OK) {
		remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
		delete_sem(ice->buffer_ready_sem);
		return ice->mem_id_pb;
	}

	ice->mem_id_rec = alloc_mem(&ice->phys_addr_rec, &ice->log_addr_rec,
								RECORD_BUFFER_TOTAL_SIZE,
								"record buffer");
	if (ice->mem_id_rec < B_OK) {
		remove_io_interrupt_handler(ice->irq, ice_1712_int, ice);
		delete_sem(ice->buffer_ready_sem);
		delete_area(ice->mem_id_pb);
		return(ice->mem_id_rec);
	}

	memset(ice->log_addr_pb, 0, PLAYBACK_BUFFER_TOTAL_SIZE);
	memset(ice->log_addr_rec, 0, RECORD_BUFFER_TOTAL_SIZE);

	ice->sampling_rate = 0x08;
	ice->buffer = 0;
	ice->frames_count = 0;
	ice->buffer_size = MAX_BUFFER_FRAMES;

	ice->total_output_channels = ice->config.nb_DAC;
	if (ice->config.spdif & SPDIF_OUT_PRESENT)
		ice->total_output_channels += 2;

	ice->total_input_channels = ice->config.nb_ADC + 2;
	if (ice->config.spdif & SPDIF_IN_PRESENT)
		ice->total_input_channels += 2;

	//Write bits in the GPIO
	write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->CommLines.cs_mask));
	//Deselect CS
	write_cci_uint8(ice, CCI_GPIO_DATA, ice->CommLines.cs_mask);

	//Set the rampe volume to a faster one
	write_mt_uint16(ice, MT_VOLUME_CONTROL_RATE, 0x01);

	//All Analog outputs from DMA
	write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT,	0x0000);
	//All Digital output from DMA
	write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT,	0x0000);

	//Just to route all input to all output
//	write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT,	0xAAAA);
//	write_mt_uint32(ice, MT_CAPTURED_DATA,	0x76543210);

	//Just to route SPDIF Input to DAC 0
//	write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT,	0xAAAF);
//	write_mt_uint32(ice, MT_CAPTURED_DATA,	0x76543280);

	//Mute all input
	mute = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8);
	for (i = 0; i < 2 * ICE1712_HARDWARE_VOLUME; i++) {
		write_mt_uint8(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, i);
		write_mt_uint16(ice, MT_VOLUME_CONTROL_CHANNEL_INDEX, mute);
	}

	//Unmask Interrupt
	write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x41);

	reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK);
	TRACE("-----CCS----- = %x\n", reg8);
	write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0xEF);

/*	reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK);
	TRACE("-----DS_DMA----- = %x\n", reg16);
	write_ds_uint16(ice, DS_DMA_INT_MASK, 0x0000);
*/
	reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS);
	TRACE("-----MT_DMA----- = %x\n", reg8);
	write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, 0x00);

	return B_OK;
};