예제 #1
0
/*
 * change the rate of AK4524 on Delta 44/66, AP, 1010LT
 */
static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
{
	unsigned char tmp, tmp2;
	struct snd_ice1712 *ice = ak->private_data[0];

	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
		return;

	/* check before reset ak4524 to avoid unnecessary clicks */
	mutex_lock(&ice->gpio_mutex);
	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
	mutex_unlock(&ice->gpio_mutex);
	tmp2 = tmp & ~ICE1712_DELTA_DFS; 
	if (rate > 48000)
		tmp2 |= ICE1712_DELTA_DFS;
	if (tmp == tmp2)
		return;

	/* do it again */
	snd_akm4xxx_reset(ak, 1);
	mutex_lock(&ice->gpio_mutex);
	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
	if (rate > 48000)
		tmp |= ICE1712_DELTA_DFS;
	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
	mutex_unlock(&ice->gpio_mutex);
	snd_akm4xxx_reset(ak, 0);
}
예제 #2
0
/* assert chip select */
static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
{
	unsigned char tmp;
	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
	switch (ice->eeprom.subvendor) {
	case ICE1712_SUBDEVICE_DELTA1010E:
	case ICE1712_SUBDEVICE_DELTA1010LT:
		tmp &= ~ICE1712_DELTA_1010LT_CS;
		tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427;
		break;
	case ICE1712_SUBDEVICE_AUDIOPHILE:
	case ICE1712_SUBDEVICE_DELTA410:
		tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
		tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
		break;
	case ICE1712_SUBDEVICE_DELTA66E:
		tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
		       ICE1712_DELTA_66E_CS_CHIP_B;
		tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
		break;
	case ICE1712_SUBDEVICE_VX442:
		tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
		tmp &= ~ICE1712_VX442_CS_DIGITAL;
		break;
	}
	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
	udelay(5);
	return tmp;
}
예제 #3
0
/*
 * change the DFS bit according rate for Delta1010
 */
static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
{
	unsigned char tmp, tmp2;

	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
		return;

	mutex_lock(&ice->gpio_mutex);
	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
	tmp2 = tmp & ~ICE1712_DELTA_DFS;
	if (rate > 48000)
		tmp2 |= ICE1712_DELTA_DFS;
	if (tmp != tmp2)
		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2);
	mutex_unlock(&ice->gpio_mutex);
}
예제 #4
0
파일: ice1712.c 프로젝트: goooooodman/linux
static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
				       int cmd)
{
	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
	int result = 0;
	u8 tmp;

	spin_lock(&ice->reg_lock);
	tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
	if (cmd == SNDRV_PCM_TRIGGER_START) {
		tmp |= 1;
	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
		tmp &= ~1;
	} else {
		result = -EINVAL;
	}
	sn
예제 #5
0
/* read 8 bits */
static unsigned char ap_cs8427_read_byte(struct snd_ice1712 *ice, unsigned char tmp)
{
	unsigned char data = 0;
	int idx;
	
	for (idx = 7; idx >= 0; idx--) {
		tmp &= ~ICE1712_DELTA_AP_CCLK;
		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
		udelay(5);
		if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN)
			data |= 1 << idx;
		tmp |= ICE1712_DELTA_AP_CCLK;
		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
		udelay(5);
	}
	return data;
}
예제 #6
0
static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
{
	unsigned char tmp, mask1, mask2;
	int idx;
	/* send byte to transmitter */
	mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
	mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
	mutex_lock(&ice->gpio_mutex);
	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
	for (idx = 7; idx >= 0; idx--) {
		tmp &= ~(mask1 | mask2);
		if (bits & (1 << idx))
			tmp |= mask2;
		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
		udelay(100);
		tmp |= mask1;
		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
		udelay(100);
	}
	tmp &= ~mask1;
	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
	mutex_unlock(&ice->gpio_mutex);
}
예제 #7
0
파일: ice1712.c 프로젝트: goooooodman/linux
static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
					int cmd)
{
	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
	int result = 0;
	u32 tmp;

	spin_lock(&ice->reg_lock);
	tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
	if (cmd == SNDRV_PCM_TRIGGER_START) {
		tmp |= 1;
	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
		tmp &= ~1;
	} else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
		tmp |= 2;
	} else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
		tmp &= ~2;
	} else {
		result = -EINVAL;
	}
	snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
	spin_unlock(&ice->reg_lock);
	return result;
}
예제 #8
0
파일: ice1712.c 프로젝트: goooooodman/linux
static unsigned int snd_ice1712_get_gpio_data(struct snd_ice1712 *ice)
{
	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
}
예제 #9
0
파일: ice1712.c 프로젝트: goooooodman/linux
static unsigned int snd_ice1712_get_gpio_mask(struct snd_ice1712 *ice)
{
	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK);
}
예제 #10
0
파일: ice1712.c 프로젝트: goooooodman/linux
static unsigned int snd_ice1712_get_gpio_dir(struct snd_ice1712 *ice)
{
	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION);
}
예제 #11
0
static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
{
	int err;
	struct snd_akm4xxx *ak;
	unsigned char tmp;

	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 &&
	    ice->eeprom.gpiodir == 0x7b)
		ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA1010E;

	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA66 &&
	    ice->eeprom.gpiodir == 0xfb)
	    	ice->eeprom.subvendor = ICE1712_SUBDEVICE_DELTA66E;

	/* determine I2C, DACs and ADCs */
	switch (ice->eeprom.subvendor) {
	case ICE1712_SUBDEVICE_AUDIOPHILE:
		ice->num_total_dacs = 2;
		ice->num_total_adcs = 2;
		break;
	case ICE1712_SUBDEVICE_DELTA410:
		ice->num_total_dacs = 8;
		ice->num_total_adcs = 2;
		break;
	case ICE1712_SUBDEVICE_DELTA44:
	case ICE1712_SUBDEVICE_DELTA66:
		ice->num_total_dacs = ice->omni ? 8 : 4;
		ice->num_total_adcs = ice->omni ? 8 : 4;
		break;
	case ICE1712_SUBDEVICE_DELTA1010:
	case ICE1712_SUBDEVICE_DELTA1010E:
	case ICE1712_SUBDEVICE_DELTA1010LT:
	case ICE1712_SUBDEVICE_MEDIASTATION:
	case ICE1712_SUBDEVICE_EDIROLDA2496:
		ice->num_total_dacs = 8;
		ice->num_total_adcs = 8;
		break;
	case ICE1712_SUBDEVICE_DELTADIO2496:
		ice->num_total_dacs = 4;	/* two AK4324 codecs */
		break;
	case ICE1712_SUBDEVICE_VX442:
	case ICE1712_SUBDEVICE_DELTA66E:	/* omni not suported yet */
		ice->num_total_dacs = 4;
		ice->num_total_adcs = 4;
		break;
	}

	/* initialize the SPI clock to high */
	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
	tmp |= ICE1712_DELTA_AP_CCLK;
	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
	udelay(5);

	/* initialize spdif */
	switch (ice->eeprom.subvendor) {
	case ICE1712_SUBDEVICE_AUDIOPHILE:
	case ICE1712_SUBDEVICE_DELTA410:
	case ICE1712_SUBDEVICE_DELTA1010E:
	case ICE1712_SUBDEVICE_DELTA1010LT:
	case ICE1712_SUBDEVICE_VX442:
	case ICE1712_SUBDEVICE_DELTA66E:
		if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
			snd_printk(KERN_ERR "unable to create I2C bus\n");
			return err;
		}
		ice->i2c->private_data = ice;
		ice->i2c->ops = &ap_cs8427_i2c_ops;
		if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
			return err;
		break;
	case ICE1712_SUBDEVICE_DELTA1010:
	case ICE1712_SUBDEVICE_MEDIASTATION:
		ice->gpio.set_pro_rate = delta_1010_set_rate_val;
		break;
	case ICE1712_SUBDEVICE_DELTADIO2496:
		ice->gpio.set_pro_rate = delta_1010_set_rate_val;
		/* fall thru */
	case ICE1712_SUBDEVICE_DELTA66:
		ice->spdif.ops.open = delta_open_spdif;
		ice->spdif.ops.setup_rate = delta_setup_spdif;
		ice->spdif.ops.default_get = delta_spdif_default_get;
		ice->spdif.ops.default_put = delta_spdif_default_put;
		ice->spdif.ops.stream_get = delta_spdif_stream_get;
		ice->spdif.ops.stream_put = delta_spdif_stream_put;
		/* Set spdif defaults */
		snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits);
		break;
	}

	/* no analog? */
	switch (ice->eeprom.subvendor) {
	case ICE1712_SUBDEVICE_DELTA1010:
	case ICE1712_SUBDEVICE_DELTA1010E:
	case ICE1712_SUBDEVICE_DELTADIO2496:
	case ICE1712_SUBDEVICE_MEDIASTATION:
		return 0;
	}

	/* second stage of initialization, analog parts and others */
	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
	if (! ak)
		return -ENOMEM;
	ice->akm_codecs = 1;

	switch (ice->eeprom.subvendor) {
	case ICE1712_SUBDEVICE_AUDIOPHILE:
		err = snd_ice1712_akm4xxx_init(ak, &akm_audiophile, &akm_audiophile_priv, ice);
		break;
	case ICE1712_SUBDEVICE_DELTA410:
		err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
		break;
	case ICE1712_SUBDEVICE_DELTA1010LT:
	case ICE1712_SUBDEVICE_EDIROLDA2496:
		err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
		break;
	case ICE1712_SUBDEVICE_DELTA66:
	case ICE1712_SUBDEVICE_DELTA44:
		err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
		break;
	case ICE1712_SUBDEVICE_VX442:
		err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
		break;
	case ICE1712_SUBDEVICE_DELTA66E:
		err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}

	return err;
}