⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pontis.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* * SPDIF input source */static int cs_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){	static char *texts[] = {		"Coax",		/* RXP0 */		"Optical",	/* RXP1 */		"CD",		/* RXP2 */	};	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;	uinfo->count = 1;	uinfo->value.enumerated.items = 3;	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);	return 0;}static int cs_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	down(&ice->gpio_mutex);	ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];	up(&ice->gpio_mutex);	return 0;}static int cs_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	unsigned char val;	int change = 0;	down(&ice->gpio_mutex);	if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {		ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;		val = 0x80 | (ice->gpio.saved[0] << 3);		spi_write(ice, CS_DEV, 0x04, val);		change = 1;	}	up(&ice->gpio_mutex);	return 0;}/* * GPIO controls */static int pontis_gpio_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;	uinfo->count = 1;	uinfo->value.integer.min = 0;	uinfo->value.integer.max = 0xffff; /* 16bit */	return 0;}static int pontis_gpio_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	down(&ice->gpio_mutex);	/* 4-7 reserved */	ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;	up(&ice->gpio_mutex);	return 0;}	static int pontis_gpio_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	unsigned int val;	int changed;	down(&ice->gpio_mutex);	/* 4-7 reserved */	val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;	changed = val != ice->gpio.write_mask;	ice->gpio.write_mask = val;	up(&ice->gpio_mutex);	return changed;}static int pontis_gpio_dir_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	down(&ice->gpio_mutex);	/* 4-7 reserved */	ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;	up(&ice->gpio_mutex);	return 0;}	static int pontis_gpio_dir_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	unsigned int val;	int changed;	down(&ice->gpio_mutex);	/* 4-7 reserved */	val = ucontrol->value.integer.value[0] & 0xff0f;	changed = (val != ice->gpio.direction);	ice->gpio.direction = val;	up(&ice->gpio_mutex);	return changed;}static int pontis_gpio_data_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	down(&ice->gpio_mutex);	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);	ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;	up(&ice->gpio_mutex);	return 0;}static int pontis_gpio_data_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){	ice1712_t *ice = snd_kcontrol_chip(kcontrol);	unsigned int val, nval;	int changed = 0;	down(&ice->gpio_mutex);	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);	val = snd_ice1712_gpio_read(ice) & 0xffff;	nval = ucontrol->value.integer.value[0] & 0xffff;	if (val != nval) {		snd_ice1712_gpio_write(ice, nval);		changed = 1;	}	up(&ice->gpio_mutex);	return changed;}/* * mixers */static snd_kcontrol_new_t pontis_controls[] __devinitdata = {	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "PCM Playback Volume",		.info = wm_dac_vol_info,		.get = wm_dac_vol_get,		.put = wm_dac_vol_put,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Capture Volume",		.info = wm_adc_vol_info,		.get = wm_adc_vol_get,		.put = wm_adc_vol_put,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "CD Capture Switch",		.info = wm_adc_mux_info,		.get = wm_adc_mux_get,		.put = wm_adc_mux_put,		.private_value = 0,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Line Capture Switch",		.info = wm_adc_mux_info,		.get = wm_adc_mux_get,		.put = wm_adc_mux_put,		.private_value = 1,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Analog Bypass Switch",		.info = wm_bypass_info,		.get = wm_bypass_get,		.put = wm_bypass_put,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "Swap Output Channels",		.info = wm_chswap_info,		.get = wm_chswap_get,		.put = wm_chswap_put,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,		.name = "IEC958 Input Source",		.info = cs_source_info,		.get = cs_source_get,		.put = cs_source_put,	},	/* FIXME: which interface? */	{		.iface = SNDRV_CTL_ELEM_IFACE_CARD,		.name = "GPIO Mask",		.info = pontis_gpio_mask_info,		.get = pontis_gpio_mask_get,		.put = pontis_gpio_mask_put,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_CARD,		.name = "GPIO Direction",		.info = pontis_gpio_mask_info,		.get = pontis_gpio_dir_get,		.put = pontis_gpio_dir_put,	},	{		.iface = SNDRV_CTL_ELEM_IFACE_CARD,		.name = "GPIO Data",		.info = pontis_gpio_mask_info,		.get = pontis_gpio_data_get,		.put = pontis_gpio_data_put,	},};/* * WM codec registers */static void wm_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	ice1712_t *ice = (ice1712_t *)entry->private_data;	char line[64];	unsigned int reg, val;	down(&ice->gpio_mutex);	while (!snd_info_get_line(buffer, line, sizeof(line))) {		if (sscanf(line, "%x %x", &reg, &val) != 2)			continue;		if (reg <= 0x17 && val <= 0xffff)			wm_put(ice, reg, val);	}	up(&ice->gpio_mutex);}static void wm_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	ice1712_t *ice = (ice1712_t *)entry->private_data;	int reg, val;	down(&ice->gpio_mutex);	for (reg = 0; reg <= 0x17; reg++) {		val = wm_get(ice, reg);		snd_iprintf(buffer, "%02x = %04x\n", reg, val);	}	up(&ice->gpio_mutex);}static void wm_proc_init(ice1712_t *ice){	snd_info_entry_t *entry;	if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {		snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read);		entry->mode |= S_IWUSR;		entry->c.text.write_size = 1024;		entry->c.text.write = wm_proc_regs_write;	}}static void cs_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){	ice1712_t *ice = (ice1712_t *)entry->private_data;	int reg, val;	down(&ice->gpio_mutex);	for (reg = 0; reg <= 0x26; reg++) {		val = spi_read(ice, CS_DEV, reg);		snd_iprintf(buffer, "%02x = %02x\n", reg, val);	}	val = spi_read(ice, CS_DEV, 0x7f);	snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);	up(&ice->gpio_mutex);}static void cs_proc_init(ice1712_t *ice){	snd_info_entry_t *entry;	if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) {		snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read);	}}static int __devinit pontis_add_controls(ice1712_t *ice){	unsigned int i;	int err;	for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {		err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));		if (err < 0)			return err;	}	wm_proc_init(ice);	cs_proc_init(ice);	return 0;}/* * initialize the chip */static int __devinit pontis_init(ice1712_t *ice){	static unsigned short wm_inits[] = {		/* These come first to reduce init pop noise */		WM_ADC_MUX,	0x00c0,	/* ADC mute */		WM_DAC_MUTE,	0x0001,	/* DAC softmute */		WM_DAC_CTRL1,	0x0000,	/* DAC mute */		WM_POWERDOWN,	0x0008,	/* All power-up except HP */		WM_RESET,	0x0000,	/* reset */	};	static unsigned short wm_inits2[] = {		WM_MASTER_CTRL,	0x0022,	/* 256fs, slave mode */		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */		WM_OUT_MUX,	0x0001,	/* OUT DAC */		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */		// WM_DAC_MASTER,	0x0100,	/* DAC master muted */		WM_PHASE_SWAP,	0x0000,	/* phase normal */		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */#if 0		WM_ALC_CTRL1,	0x007b,	/* */		WM_ALC_CTRL2,	0x0000,	/* */		WM_ALC_CTRL3,	0x0000,	/* */		WM_NOISE_GATE,	0x0000,	/* */#endif		WM_DAC_MUTE,	0x0000,	/* DAC unmute */		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */	};	static unsigned char cs_inits[] = {		0x04,	0x80,	/* RUN, RXP0 */		0x05,	0x05,	/* slave, 24bit */		0x01,	0x00,		0x02,	0x00,		0x03,	0x00,	};	unsigned int i;	ice->vt1720 = 1;	ice->num_total_dacs = 2;	ice->num_total_adcs = 2;	/* to remeber the register values */	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);	if (! ice->akm)		return -ENOMEM;	ice->akm_codecs = 1;	/* HACK - use this as the SPDIF source.	 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten	 */	ice->gpio.saved[0] = 0;	/* initialize WM8776 codec */	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)		wm_put(ice, wm_inits[i], wm_inits[i+1]);	schedule_timeout_uninterruptible(1);	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);	/* initialize CS8416 codec */	/* assert PRST#; MT05 bit 7 */	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));	mdelay(5);	/* deassert PRST# */	outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));	for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)		spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);	return 0;}/* * Pontis boards don't provide the EEPROM data at all. * hence the driver needs to sets up it properly. */static unsigned char pontis_eeprom[] __devinitdata = {	0x08,	/* SYSCONF: clock 256, mpu401, spdif-in/ADC, 1DAC */	0x80,	/* ACLINK: I2S */	0xf8,	/* I2S: vol, 96k, 24bit, 192k */	0xc3,	/* SPDIF: out-en, out-int, spdif-in */	0x07,	/* GPIO_DIR */	0x00,	/* GPIO_DIR1 */	0x00,	/* GPIO_DIR2 (ignored) */	0x0f,	/* GPIO_MASK (4-7 reserved for CS8416) */	0xff,	/* GPIO_MASK1 */	0x00,	/* GPIO_MASK2 (ignored) */	0x06,	/* GPIO_STATE (0-low, 1-high, 2-high) */	0x00,	/* GPIO_STATE1 */	0x00,	/* GPIO_STATE2 (ignored) */};/* entry point */struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {	{		.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,		.name = "Pontis MS300",		.model = "ms300",		.chip_init = pontis_init,		.build_controls = pontis_add_controls,		.eeprom_size = sizeof(pontis_eeprom),		.eeprom_data = pontis_eeprom,	},	{ } /* terminator */};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -