示例#1
0
u32 lx_plx_mbox_read(struct lx6464es *chip, int mbox_nr)
{
	int index;

	switch (mbox_nr) {
	case 1:
		index = ePLX_MBOX1;    break;
	case 2:
		index = ePLX_MBOX2;    break;
	case 3:
		index = ePLX_MBOX3;    break;
	case 4:
		index = ePLX_MBOX4;    break;
	case 5:
		index = ePLX_MBOX5;    break;
	case 6:
		index = ePLX_MBOX6;    break;
	case 7:
		index = ePLX_MBOX7;    break;
	case 0:			/* reserved for HF flags */
		snd_BUG();
	default:
		return 0xdeadbeef;
	}

	return lx_plx_reg_read(chip, index);
}
示例#2
0
int lx_plx_mbox_write(struct lx6464es *chip, int mbox_nr, u32 value)
{
	int index = -1;

	switch (mbox_nr) {
	case 1:
		index = ePLX_MBOX1;    break;
	case 3:
		index = ePLX_MBOX3;    break;
	case 4:
		index = ePLX_MBOX4;    break;
	case 5:
		index = ePLX_MBOX5;    break;
	case 6:
		index = ePLX_MBOX6;    break;
	case 7:
		index = ePLX_MBOX7;    break;
	case 0:			/* reserved for HF flags */
	case 2:			/* reserved for Pipe States
				 * the DSP keeps an image of it */
		snd_BUG();
		return -EBADRQC;
	}

	lx_plx_reg_write(chip, index, value);
	return 0;
}
示例#3
0
文件: midirender.c 项目: bkero/hdjmod
int snd_hdjmidi_output_open(snd_rawmidi_substream_t *substream)
#endif
{
	struct snd_hdjmidi* umidi = substream->rmidi->private_data;
	struct hdjmidi_out_port* port = NULL;
	int i, j;
#ifdef RENDER_DUMP_URB_THROTTLE
	render_dump_urb_throttle = 0;
#endif
	snd_printk(KERN_DEBUG"%s()\n",__FUNCTION__);

	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
		if (umidi->endpoints[i].out) {
			for (j = 0; j < 0x10; ++j) {
				if (umidi->endpoints[i].out->ports[j].substream == substream) {
					port = &umidi->endpoints[i].out->ports[j];
#ifdef THROTTLE_MP3_RENDER
					umidi->endpoints[i].out->last_send_time = jiffies + 
							(THROTTLE_MP3_RENDER_RATE*HZ)/1000;
#endif
					break;
				}
			}
		}
	}
	if (!port) {
		snd_BUG();
		return -ENXIO;
	}
	substream->runtime->private_data = port;
	port->state = STATE_UNKNOWN;
	return 0;
}
示例#4
0
/*
 * vxp_load_dsp - load_dsp callback
 */
static int vxp_load_dsp(vx_core_t *vx, int index, const struct firmware *fw)
{
	int err;

	switch (index) {
	case 0:
		/* xilinx boot */
		if ((err = vx_check_magic(vx)) < 0)
			return err;
		if ((err = snd_vx_load_boot_image(vx, fw)) < 0)
			return err;
		return 0;
	case 1:
		/* xilinx image */
		return vxp_load_xilinx_binary(vx, fw);
	case 2:
		/* DSP boot */
		return snd_vx_dsp_boot(vx, fw);
	case 3:
		/* DSP image */
		return snd_vx_dsp_load(vx, fw);
	default:
		snd_BUG();
		return -EINVAL;
	}
}
示例#5
0
static int __devinit phase22_init(struct snd_ice1712 *ice)
{
	struct snd_akm4xxx *ak;
	int err;

	// Configure DAC/ADC description for generic part of ice1724
	switch (ice->eeprom.subvendor) {
	case VT1724_SUBDEVICE_PHASE22:
		ice->num_total_dacs = 2;
		ice->num_total_adcs = 2;
		ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}

	// Initialize analog chips
	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
	if (! ak)
		return -ENOMEM;
	ice->akm_codecs = 1;
	switch (ice->eeprom.subvendor) {
	case VT1724_SUBDEVICE_PHASE22:
		if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0)
			return err;
		break;
	}

	return 0;
}
示例#6
0
/*
 * return the index of the target rate
 */
static int
snd_nm256_fixed_rate(unsigned int rate)
{
	unsigned int i;
	for (i = 0; i < ARRAY_SIZE(samplerates); i++) {
		if (rate == samplerates[i])
			return i;
	}
	snd_BUG();
	return 0;
}
示例#7
0
文件: pmac.c 项目: roysuman/linux
/*
 * get a stream of the opposite direction
 */
static struct pmac_stream *snd_pmac_get_stream(struct snd_pmac *chip, int stream)
{
	switch (stream) {
	case SNDRV_PCM_STREAM_PLAYBACK:
		return &chip->playback;
	case SNDRV_PCM_STREAM_CAPTURE:
		return &chip->capture;
	default:
		snd_BUG();
		return NULL;
	}
}
示例#8
0
文件: cs4236_lib.c 项目: 274914765/C
static unsigned char divisor_to_rate_register(unsigned int divisor)
{
    switch (divisor) {
    case 353:    return 1;
    case 529:    return 2;
    case 617:    return 3;
    case 1058:    return 4;
    case 1764:    return 5;
    case 2117:    return 6;
    case 2558:    return 7;
    default:
        if (divisor < 21 || divisor > 192) {
            snd_BUG();
            return 192;
        }
        return divisor;
    }
}
示例#9
0
/* this is called in atomic context with IRQ disabled.
   Must be as fast as possible and not sleep.
   DMA should be *triggered* by this call.
   The WSMC "WAEN" bit triggers DMA Wave On/Off */
static int
snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
{
	u16 wsmc;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	
	wsmc = ad1889_readw(chip, AD_DS_WSMC);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* enable DMA loop & interrupts */
		ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
		wsmc |= AD_DS_WSMC_WAEN;
		/* 1 to clear CHSS bit */
		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
		ad1889_unmute(chip);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ad1889_mute(chip);
		wsmc &= ~AD_DS_WSMC_WAEN;
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}
	
	chip->wave.reg = wsmc;
	ad1889_writew(chip, AD_DS_WSMC, wsmc);	
	ad1889_readw(chip, AD_DS_WSMC);	/* flush */

	/* reset the chip when STOP - will disable IRQs */
	if (cmd == SNDRV_PCM_TRIGGER_STOP)
		ad1889_channel_reset(chip, AD_CHAN_WAV);

	return 0;
}
static int
snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
{
	u16 wsmc;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	
	wsmc = ad1889_readw(chip, AD_DS_WSMC);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		
		ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
		wsmc |= AD_DS_WSMC_WAEN;
		
		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
		ad1889_unmute(chip);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ad1889_mute(chip);
		wsmc &= ~AD_DS_WSMC_WAEN;
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}
	
	chip->wave.reg = wsmc;
	ad1889_writew(chip, AD_DS_WSMC, wsmc);	
	ad1889_readw(chip, AD_DS_WSMC);	

	
	if (cmd == SNDRV_PCM_TRIGGER_STOP)
		ad1889_channel_reset(chip, AD_CHAN_WAV);

	return 0;
}
/*
 * initialize all the ak4xxx chips
 */
void snd_akm4xxx_init(struct snd_akm4xxx *ak)
{
	static unsigned char inits_ak4524[] = {
		0x00, 0x07, /* 0: all power up */
		0x01, 0x00, /* 1: ADC/DAC reset */
		0x02, 0x60, /* 2: 24bit I2S */
		0x03, 0x19, /* 3: deemphasis off */
		0x01, 0x03, /* 1: ADC/DAC enable */
		0x04, 0x00, /* 4: ADC left muted */
		0x05, 0x00, /* 5: ADC right muted */
		0x04, 0x80, /* 4: ADC IPGA gain 0dB */
		0x05, 0x80, /* 5: ADC IPGA gain 0dB */
		0x06, 0x00, /* 6: DAC left muted */
		0x07, 0x00, /* 7: DAC right muted */
		0xff, 0xff
	};
	static unsigned char inits_ak4528[] = {
		0x00, 0x07, /* 0: all power up */
		0x01, 0x00, /* 1: ADC/DAC reset */
		0x02, 0x60, /* 2: 24bit I2S */
		0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */
		0x01, 0x03, /* 1: ADC/DAC enable */
		0x04, 0x00, /* 4: ADC left muted */
		0x05, 0x00, /* 5: ADC right muted */
		0xff, 0xff
	};
	static unsigned char inits_ak4529[] = {
		0x09, 0x01, /* 9: ATS=0, RSTN=1 */
		0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
		0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
		0x01, 0x00, /* 1: ACKS=0, ADC, loop off */
		0x02, 0xff, /* 2: LOUT1 muted */
		0x03, 0xff, /* 3: ROUT1 muted */
		0x04, 0xff, /* 4: LOUT2 muted */
		0x05, 0xff, /* 5: ROUT2 muted */
		0x06, 0xff, /* 6: LOUT3 muted */
		0x07, 0xff, /* 7: ROUT3 muted */
		0x0b, 0xff, /* B: LOUT4 muted */
		0x0c, 0xff, /* C: ROUT4 muted */
		0x08, 0x55, /* 8: deemphasis all off */
		0xff, 0xff
	};
	static unsigned char inits_ak4355[] = {
		0x01, 0x02, /* 1: reset and soft-mute */
		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */
		0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
		// 0x02, 0x2e, /* quad speed */
		0x03, 0x01, /* 3: de-emphasis off */
		0x04, 0x00, /* 4: LOUT1 volume muted */
		0x05, 0x00, /* 5: ROUT1 volume muted */
		0x06, 0x00, /* 6: LOUT2 volume muted */
		0x07, 0x00, /* 7: ROUT2 volume muted */
		0x08, 0x00, /* 8: LOUT3 volume muted */
		0x09, 0x00, /* 9: ROUT3 volume muted */
		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
		0x01, 0x01, /* 1: un-reset, unmute */
		0xff, 0xff
	};
	static unsigned char inits_ak4358[] = {
		0x01, 0x02, /* 1: reset and soft-mute */
		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect, disable DZF, sharp roll-off, RSTN#=0 */
		0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
		// 0x02, 0x2e, /* quad speed */
		0x03, 0x01, /* 3: de-emphasis off */
		0x04, 0x00, /* 4: LOUT1 volume muted */
		0x05, 0x00, /* 5: ROUT1 volume muted */
		0x06, 0x00, /* 6: LOUT2 volume muted */
		0x07, 0x00, /* 7: ROUT2 volume muted */
		0x08, 0x00, /* 8: LOUT3 volume muted */
		0x09, 0x00, /* 9: ROUT3 volume muted */
		0x0b, 0x00, /* b: LOUT4 volume muted */
		0x0c, 0x00, /* c: ROUT4 volume muted */
		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
		0x01, 0x01, /* 1: un-reset, unmute */
		0xff, 0xff
	};
	static unsigned char inits_ak4381[] = {
		0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
		0x01, 0x02, /* 1: de-emphasis off, normal speed, sharp roll-off, DZF off */
		// 0x01, 0x12, /* quad speed */
		0x02, 0x00, /* 2: DZF disabled */
		0x03, 0x00, /* 3: LATT 0 */
		0x04, 0x00, /* 4: RATT 0 */
		0x00, 0x0f, /* 0: power-up, un-reset */
		0xff, 0xff
	};

	int chip, num_chips;
	unsigned char *ptr, reg, data, *inits;

	switch (ak->type) {
	case SND_AK4524:
		inits = inits_ak4524;
		num_chips = ak->num_dacs / 2;
		break;
	case SND_AK4528:
		inits = inits_ak4528;
		num_chips = ak->num_dacs / 2;
		break;
	case SND_AK4529:
		inits = inits_ak4529;
		num_chips = 1;
		break;
	case SND_AK4355:
		inits = inits_ak4355;
		num_chips = 1;
		break;
	case SND_AK4358:
		inits = inits_ak4358;
		num_chips = 1;
		break;
	case SND_AK4381:
		inits = inits_ak4381;
		num_chips = ak->num_dacs / 2;
		break;
	default:
		snd_BUG();
		return;
	}

	for (chip = 0; chip < num_chips; chip++) {
		ptr = inits;
		while (*ptr != 0xff) {
			reg = *ptr++;
			data = *ptr++;
			snd_akm4xxx_write(ak, chip, reg, data);
		}
	}
}
示例#12
0
/*
 * initialize all the ak4xxx chips
 */
void snd_akm4xxx_init(struct snd_akm4xxx *ak)
{
	static const unsigned char inits_ak4524[] = {
		0x00, 0x07, /* 0: all power up */
		0x01, 0x00, /* 1: ADC/DAC reset */
		0x02, 0x60, /* 2: 24bit I2S */
		0x03, 0x19, /* 3: deemphasis off */
		0x01, 0x03, /* 1: ADC/DAC enable */
		0x04, 0x00, /* 4: ADC left muted */
		0x05, 0x00, /* 5: ADC right muted */
		0x06, 0x00, /* 6: DAC left muted */
		0x07, 0x00, /* 7: DAC right muted */
		0xff, 0xff
	};
	static const unsigned char inits_ak4528[] = {
		0x00, 0x07, /* 0: all power up */
		0x01, 0x00, /* 1: ADC/DAC reset */
		0x02, 0x60, /* 2: 24bit I2S */
		0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */
		0x01, 0x03, /* 1: ADC/DAC enable */
		0x04, 0x00, /* 4: ADC left muted */
		0x05, 0x00, /* 5: ADC right muted */
		0xff, 0xff
	};
	static const unsigned char inits_ak4529[] = {
		0x09, 0x01, /* 9: ATS=0, RSTN=1 */
		0x0a, 0x3f, /* A: all power up, no zero/overflow detection */
		0x00, 0x0c, /* 0: TDM=0, 24bit I2S, SMUTE=0 */
		0x01, 0x00, /* 1: ACKS=0, ADC, loop off */
		0x02, 0xff, /* 2: LOUT1 muted */
		0x03, 0xff, /* 3: ROUT1 muted */
		0x04, 0xff, /* 4: LOUT2 muted */
		0x05, 0xff, /* 5: ROUT2 muted */
		0x06, 0xff, /* 6: LOUT3 muted */
		0x07, 0xff, /* 7: ROUT3 muted */
		0x0b, 0xff, /* B: LOUT4 muted */
		0x0c, 0xff, /* C: ROUT4 muted */
		0x08, 0x55, /* 8: deemphasis all off */
		0xff, 0xff
	};
	static const unsigned char inits_ak4355[] = {
		0x01, 0x02, /* 1: reset and soft-mute */
		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
			     * disable DZF, sharp roll-off, RSTN#=0 */
		0x02, 0x0e, /* 2: DA's power up, normal speed, RSTN#=0 */
		// 0x02, 0x2e, /* quad speed */
		0x03, 0x01, /* 3: de-emphasis off */
		0x04, 0x00, /* 4: LOUT1 volume muted */
		0x05, 0x00, /* 5: ROUT1 volume muted */
		0x06, 0x00, /* 6: LOUT2 volume muted */
		0x07, 0x00, /* 7: ROUT2 volume muted */
		0x08, 0x00, /* 8: LOUT3 volume muted */
		0x09, 0x00, /* 9: ROUT3 volume muted */
		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
		0x01, 0x01, /* 1: un-reset, unmute */
		0xff, 0xff
	};
	static const unsigned char inits_ak4358[] = {
		0x01, 0x02, /* 1: reset and soft-mute */
		0x00, 0x06, /* 0: mode3(i2s), disable auto-clock detect,
			     * disable DZF, sharp roll-off, RSTN#=0 */
		0x02, 0x4e, /* 2: DA's power up, normal speed, RSTN#=0 */
		/* 0x02, 0x6e,*/ /* quad speed */
		0x03, 0x01, /* 3: de-emphasis off */
		0x04, 0x00, /* 4: LOUT1 volume muted */
		0x05, 0x00, /* 5: ROUT1 volume muted */
		0x06, 0x00, /* 6: LOUT2 volume muted */
		0x07, 0x00, /* 7: ROUT2 volume muted */
		0x08, 0x00, /* 8: LOUT3 volume muted */
		0x09, 0x00, /* 9: ROUT3 volume muted */
		0x0b, 0x00, /* b: LOUT4 volume muted */
		0x0c, 0x00, /* c: ROUT4 volume muted */
		0x0a, 0x00, /* a: DATT speed=0, ignore DZF */
		0x01, 0x01, /* 1: un-reset, unmute */
		0xff, 0xff
	};
	static const unsigned char inits_ak4381[] = {
		0x00, 0x0c, /* 0: mode3(i2s), disable auto-clock detect */
		0x01, 0x02, /* 1: de-emphasis off, normal speed,
			     * sharp roll-off, DZF off */
		// 0x01, 0x12, /* quad speed */
		0x02, 0x00, /* 2: DZF disabled */
		0x03, 0x00, /* 3: LATT 0 */
		0x04, 0x00, /* 4: RATT 0 */
		0x00, 0x0f, /* 0: power-up, un-reset */
		0xff, 0xff
	};
	static const unsigned char inits_ak4620[] = {
		0x00, 0x07, /* 0: normal */
		0x01, 0x00, /* 0: reset */
		0x01, 0x02, /* 1: RSTAD */
		0x01, 0x03, /* 1: RSTDA */
		0x01, 0x0f, /* 1: normal */
		0x02, 0x60, /* 2: 24bit I2S */
		0x03, 0x01, /* 3: deemphasis off */
		0x04, 0x00, /* 4: LIN muted */
		0x05, 0x00, /* 5: RIN muted */
		0x06, 0x00, /* 6: LOUT muted */
		0x07, 0x00, /* 7: ROUT muted */
		0xff, 0xff
	};

	int chip;
	const unsigned char *ptr, *inits;
	unsigned char reg, data;

	memset(ak->images, 0, sizeof(ak->images));
	memset(ak->volumes, 0, sizeof(ak->volumes));

	switch (ak->type) {
	case SND_AK4524:
		inits = inits_ak4524;
		ak->num_chips = ak->num_dacs / 2;
		ak->name = "ak4524";
		ak->total_regs = 0x08;
		break;
	case SND_AK4528:
		inits = inits_ak4528;
		ak->num_chips = ak->num_dacs / 2;
		ak->name = "ak4528";
		ak->total_regs = 0x06;
		break;
	case SND_AK4529:
		inits = inits_ak4529;
		ak->num_chips = 1;
		ak->name = "ak4529";
		ak->total_regs = 0x0d;
		break;
	case SND_AK4355:
		inits = inits_ak4355;
		ak->num_chips = 1;
		ak->name = "ak4355";
		ak->total_regs = 0x0b;
		break;
	case SND_AK4358:
		inits = inits_ak4358;
		ak->num_chips = 1;
		ak->name = "ak4358";
		ak->total_regs = 0x10;
		break;
	case SND_AK4381:
		inits = inits_ak4381;
		ak->num_chips = ak->num_dacs / 2;
		ak->name = "ak4381";
		ak->total_regs = 0x05;
		break;
	case SND_AK5365:
		/* FIXME: any init sequence? */
		ak->num_chips = 1;
		ak->name = "ak5365";
		ak->total_regs = 0x08;
		return;
	case SND_AK4620:
		inits = inits_ak4620;
		ak->num_chips = ak->num_dacs / 2;
		ak->name = "ak4620";
		ak->total_regs = 0x08;
		break;
	default:
		snd_BUG();
		return;
	}

	for (chip = 0; chip < ak->num_chips; chip++) {
		ptr = inits;
		while (*ptr != 0xff) {
			reg = *ptr++;
			data = *ptr++;
			snd_akm4xxx_write(ak, chip, reg, data);
			udelay(10);
		}
	}
}
示例#13
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;
}
示例#14
0
static int snd_stm_pcm_player_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *hw_params)
{
	int result;
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int buffer_bytes, frame_bytes, transfer_bytes;
	unsigned int transfer_size;
	struct stm_dma_req_config fdma_req_config = {
		.rw        = REQ_CONFIG_WRITE,
		.opcode    = REQ_CONFIG_OPCODE_4,
		.increment = 0,
		.hold_off  = 0,
		.initiator = pcm_player->info->fdma_initiator,
	};

	snd_stm_printd(1, "snd_stm_pcm_player_hw_params(substream=0x%p,"
			" hw_params=0x%p)\n", substream, hw_params);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));
	BUG_ON(!runtime);

	/* This function may be called many times, so let's be prepared... */
	if (snd_stm_buffer_is_allocated(pcm_player->buffer))
		snd_stm_pcm_player_hw_free(substream);

	/* Allocate buffer */

	buffer_bytes = params_buffer_bytes(hw_params);
	result = snd_stm_buffer_alloc(pcm_player->buffer, substream,
			buffer_bytes);
	if (result != 0) {
		snd_stm_printe("Can't allocate %d bytes buffer for '%s'!\n",
			       buffer_bytes, dev_name(pcm_player->device));
		result = -ENOMEM;
		goto error_buf_alloc;
	}

	/* Set FDMA transfer size (number of opcodes generated
	 * after request line assertion) */

	frame_bytes = snd_pcm_format_physical_width(params_format(hw_params)) *
			params_channels(hw_params) / 8;
	transfer_bytes = snd_stm_pcm_transfer_bytes(frame_bytes,
			pcm_player->fdma_max_transfer_size * 4);
	transfer_size = transfer_bytes / 4;
	snd_stm_printd(1, "FDMA request trigger limit and transfer size set "
			"to %d.\n", transfer_size);

	BUG_ON(buffer_bytes % transfer_bytes != 0);
	BUG_ON(transfer_size > pcm_player->fdma_max_transfer_size);
	fdma_req_config.count = transfer_size;

	BUG_ON(transfer_size != 1 && transfer_size % 2 != 0);
	BUG_ON(transfer_size >
	       mask__AUD_PCMOUT_FMT__DMA_REQ_TRIG_LMT(pcm_player));
	set__AUD_PCMOUT_FMT__DMA_REQ_TRIG_LMT(pcm_player, transfer_size);

	/* Configure FDMA transfer */

	pcm_player->fdma_request = dma_req_config(pcm_player->fdma_channel,
			pcm_player->info->fdma_request_line, &fdma_req_config);
	if (!pcm_player->fdma_request) {
		snd_stm_printe("Can't configure FDMA pacing channel for player"
			       " '%s'!\n", dev_name(pcm_player->device));
		result = -EINVAL;
		goto error_req_config;
	}

	dma_params_init(&pcm_player->fdma_params, MODE_PACED,
			STM_DMA_LIST_CIRC);

	dma_params_DIM_1_x_0(&pcm_player->fdma_params);

	dma_params_req(&pcm_player->fdma_params, pcm_player->fdma_request);

	dma_params_addrs(&pcm_player->fdma_params, runtime->dma_addr,
			pcm_player->fifo_phys_address, buffer_bytes);

	result = dma_compile_list(pcm_player->fdma_channel,
				&pcm_player->fdma_params, GFP_KERNEL);
	if (result < 0) {
		snd_stm_printe("Can't compile FDMA parameters for player"
			       " '%s'!\n", dev_name(pcm_player->device));
		goto error_compile_list;
	}

	return 0;

error_compile_list:
	dma_req_free(pcm_player->fdma_channel,
			pcm_player->fdma_request);
error_req_config:
	snd_stm_buffer_free(pcm_player->buffer);
error_buf_alloc:
	return result;
}

static int snd_stm_pcm_player_prepare(struct snd_pcm_substream *substream)
{
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	unsigned int format, lr_pol;
	int oversampling, bits_in_output_frame;
	int result;

	snd_stm_printd(1, "snd_stm_pcm_player_prepare(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));
	BUG_ON(!runtime);
	BUG_ON(runtime->period_size * runtime->channels >=
	       MAX_SAMPLES_PER_PERIOD);

	/* Configure SPDIF synchronisation */

	/* TODO */

	/* Get format & oversampling value from connected converter */

	if (pcm_player->conv_group) {
		format = snd_stm_conv_get_format(pcm_player->conv_group);
		oversampling = snd_stm_conv_get_oversampling(
				pcm_player->conv_group);
		if (oversampling == 0)
			oversampling = DEFAULT_OVERSAMPLING;
	} else {
		format = DEFAULT_FORMAT;
		oversampling = DEFAULT_OVERSAMPLING;
	}

	snd_stm_printd(1, "Player %s: sampling frequency %d, oversampling %d\n",
			dev_name(pcm_player->device), runtime->rate,
			oversampling);

	BUG_ON(oversampling < 0);

	/* For 32 bits subframe oversampling must be a multiple of 128,
	 * for 16 bits - of 64 */
	BUG_ON((format & SND_STM_FORMAT__SUBFRAME_32_BITS) &&
		(oversampling % 128 != 0));
	BUG_ON(!(format & SND_STM_FORMAT__SUBFRAME_16_BITS) &&
		(oversampling % 64 != 0));

	/* Set up frequency synthesizer */

	result = clk_enable(pcm_player->clock);
	if (result != 0) {
		snd_stm_printe("Can't enable clock for player '%s'!\n",
				dev_name(pcm_player->device));
		return result;
	}

	result = clk_set_rate(pcm_player->clock,
				runtime->rate * oversampling);
	if (result != 0) {
		snd_stm_printe("Can't configure clock for player '%s'!\n",
				dev_name(pcm_player->device));
		clk_disable(pcm_player->clock);
		return result;
	}

	/* Set up player hardware */

	snd_stm_printd(1, "Player %s format configuration:\n",
			dev_name(pcm_player->device));

	/* Number of bits per subframe (which is one channel sample)
	 * on output - it determines serial clock frequency, which is
	 * 64 times sampling rate for 32 bits subframe (2 channels 32
	 * bits each means 64 bits per frame) and 32 times sampling
	 * rate for 16 bits subframe
	 * (you know why, don't you? :-) */

	switch (format & SND_STM_FORMAT__SUBFRAME_MASK) {
	case SND_STM_FORMAT__SUBFRAME_32_BITS:
		snd_stm_printd(1, "- 32 bits per subframe\n");
		set__AUD_PCMOUT_FMT__NBIT__32_BITS(pcm_player);
		if (pcm_player->ver > 5)
			set__AUD_PCMOUT_FMT__DATA_SIZE__32_BITS(pcm_player);
		else
			set__AUD_PCMOUT_FMT__DATA_SIZE__24_BITS(pcm_player);
		bits_in_output_frame = 64; /* frame = 2 * subframe */
		break;
	case SND_STM_FORMAT__SUBFRAME_16_BITS:
		snd_stm_printd(1, "- 16 bits per subframe\n");
		set__AUD_PCMOUT_FMT__NBIT__16_BITS(pcm_player);
		set__AUD_PCMOUT_FMT__DATA_SIZE__16_BITS(pcm_player);
		bits_in_output_frame = 32; /* frame = 2 * subframe */
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}

	/* Serial audio interface format - for detailed explanation
	 * see ie.:
	 * http://www.cirrus.com/en/pubs/appNote/AN282REV1.pdf */

	set__AUD_PCMOUT_FMT__ORDER__MSB_FIRST(pcm_player);

	/* Value FALLING of SCLK_EDGE bit in AUD_PCMOUT_FMT register that
	 * actually means "data clocking (changing) on the falling edge"
	 * (and we usually want this...) - STx7100 and cuts < 3.0 of
	 * STx7109 have this bit inverted comparing to what their
	 * datasheets claim... (specs say 1) */

	set__AUD_PCMOUT_FMT__SCLK_EDGE__FALLING(pcm_player);

	switch (format & SND_STM_FORMAT__MASK) {
	case SND_STM_FORMAT__I2S:
		snd_stm_printd(1, "- I2S\n");
		set__AUD_PCMOUT_FMT__ALIGN__LEFT(pcm_player);
		set__AUD_PCMOUT_FMT__PADDING__1_CYCLE_DELAY(pcm_player);
		lr_pol = value__AUD_PCMOUT_FMT__LR_POL__LEFT_LOW(pcm_player);
		break;
	case SND_STM_FORMAT__LEFT_JUSTIFIED:
		snd_stm_printd(1, "- left justified\n");
		set__AUD_PCMOUT_FMT__ALIGN__LEFT(pcm_player);
		set__AUD_PCMOUT_FMT__PADDING__NO_DELAY(pcm_player);
		lr_pol = value__AUD_PCMOUT_FMT__LR_POL__LEFT_HIGH(pcm_player);
		break;
	case SND_STM_FORMAT__RIGHT_JUSTIFIED:
		snd_stm_printd(1, "- right justified\n");
		set__AUD_PCMOUT_FMT__ALIGN__RIGHT(pcm_player);
		set__AUD_PCMOUT_FMT__PADDING__NO_DELAY(pcm_player);
		lr_pol = value__AUD_PCMOUT_FMT__LR_POL__LEFT_HIGH(pcm_player);
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}

	/* Configure PCM player frequency divider
	 *
	 *             Fdacclk             Fs * oversampling
	 * divider = ----------- = ------------------------------- =
	 *            2 * Fsclk     2 * Fs * bits_in_output_frame
	 *
	 *                  oversampling
	 *         = --------------------------
	 *            2 * bits_in_output_frame
	 * where:
	 *   - Fdacclk - frequency of DAC clock signal, known also as PCMCLK,
	 *               MCLK (master clock), "system clock" etc.
	 *   - Fsclk - frequency of SCLK (serial clock) aka BICK (bit clock)
	 *   - Fs - sampling rate (frequency)
	 *   - bits_in_output_frame - number of bits in output signal _frame_
	 *                (32 or 64, depending on NBIT field of FMT register)
	 */

	set__AUD_PCMOUT_CTRL__CLK_DIV(pcm_player,
			oversampling / (2 * bits_in_output_frame));

	/* Configure data memory format & NSAMPLE interrupt */

	switch (runtime->format) {
	case SNDRV_PCM_FORMAT_S16_LE:
		/* One data word contains two samples */
		set__AUD_PCMOUT_CTRL__MEM_FMT__16_BITS_16_BITS(pcm_player);

		/* Workaround for a problem with L/R channels swap in case of
		 * 16/16 memory model: PCM player expects left channel data in
		 * word's upper two bytes, but due to little endianess
		 * character of our memory there is right channel data there;
		 * the workaround is to invert L/R signal, however it is
		 * cheating, because in such case channel phases are shifted
		 * by one sample...
		 * (ask me for more details if above is not clear ;-)
		 * TODO this somehow better... */
		set__AUD_PCMOUT_FMT__LR_POL(pcm_player, !lr_pol);

		/* One word of data is two samples (two channels...) */
		set__AUD_PCMOUT_CTRL__NSAMPLE(pcm_player,
				runtime->period_size * runtime->channels / 2);
		break;

	case SNDRV_PCM_FORMAT_S32_LE:
		/* Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
		 * on the left than zeros (if less than 32 bites)"... ;-) */
		set__AUD_PCMOUT_CTRL__MEM_FMT__16_BITS_0_BITS(pcm_player);

		/* In x/0 bits memory mode there is no problem with
		 * L/R polarity */
		set__AUD_PCMOUT_FMT__LR_POL(pcm_player, lr_pol);

		/* One word of data is one sample, so period size
		 * times channels */
		set__AUD_PCMOUT_CTRL__NSAMPLE(pcm_player,
				runtime->period_size * runtime->channels);
		break;

	default:
		snd_BUG();
		return -EINVAL;
	}

	/* Number of channels... */

	BUG_ON(runtime->channels % 2 != 0);
	BUG_ON(runtime->channels < 2);
	BUG_ON(runtime->channels > 10);

	set__AUD_PCMOUT_FMT__NUM_CH(pcm_player, runtime->channels / 2);

	return 0;
}

static int snd_stm_pcm_player_start(struct snd_pcm_substream *substream)
{
	int result;
	struct snd_stm_pcm_player *pcm_player =
			snd_pcm_substream_chip(substream);

	snd_stm_printd(1, "snd_stm_pcm_player_start(substream=0x%p)\n",
			substream);

	BUG_ON(!pcm_player);
	BUG_ON(!snd_stm_magic_valid(pcm_player));

	/* Un-reset PCM player */

	set__AUD_PCMOUT_RST__SRSTP__RUNNING(pcm_player);

	/* Launch FDMA transfer */

	result = dma_xfer_list(pcm_player->fdma_channel,
			&pcm_player->fdma_params);
	if (result != 0) {
		snd_stm_printe("Can't launch FDMA transfer for player '%s'!\n",
			       dev_name(pcm_player->device));
		clk_disable(pcm_player->clock);
		return -EINVAL;
	}
	while (dma_get_status(pcm_player->fdma_channel) !=
			DMA_CHANNEL_STATUS_RUNNING)
		udelay(5);

	/* Enable player interrupts (and clear possible stalled ones) */

	enable_irq(pcm_player->irq);
	set__AUD_PCMOUT_ITS_CLR__NSAMPLE__CLEAR(pcm_player);
	set__AUD_PCMOUT_IT_EN_SET__NSAMPLE__SET(pcm_player);
	set__AUD_PCMOUT_ITS_CLR__UNF__CLEAR(pcm_player);
	set__AUD_PCMOUT_IT_EN_SET__UNF__SET(pcm_player);

	/* Launch the player */

	set__AUD_PCMOUT_CTRL__MODE__PCM(pcm_player);

	/* Wake up & unmute DAC */

	if (pcm_player->conv_group) {
		snd_stm_conv_enable(pcm_player->conv_group,
				0, substream->runtime->channels - 1);
		snd_stm_conv_unmute(pcm_player->conv_group);
	}

	return 0;
}