示例#1
0
文件: cs4236_lib.c 项目: 274914765/C
static void snd_cs4236_resume(struct snd_cs4231 *chip)
{
    int reg;
    unsigned long flags;
    
    snd_cs4231_mce_up(chip);
    spin_lock_irqsave(&chip->reg_lock, flags);
    for (reg = 0; reg < 32; reg++) {
        switch (reg) {
        case CS4236_EXT_REG:
        case CS4231_VERSION:
        case 27:    /* why? CS4235 - master left */
        case 29:    /* why? CS4235 - master right */
            break;
        default:
            snd_cs4231_out(chip, reg, chip->image[reg]);
            break;
        }
    }
    for (reg = 0; reg < 18; reg++)
        snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), chip->eimage[reg]);
    for (reg = 2; reg < 9; reg++) {
        switch (reg) {
        case 7:
            break;
        default:
            snd_cs4236_ctrl_out(chip, reg, chip->cimage[reg]);
        }
    }
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    snd_cs4231_mce_down(chip);
}
示例#2
0
文件: cs4236_lib.c 项目: 274914765/C
static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
    unsigned long flags;
    int left_reg = kcontrol->private_value & 0xff;
    int right_reg = (kcontrol->private_value >> 8) & 0xff;
    int shift_left = (kcontrol->private_value >> 16) & 0x07;
    int shift_right = (kcontrol->private_value >> 19) & 0x07;
    int mask = (kcontrol->private_value >> 24) & 0xff;
    int invert = (kcontrol->private_value >> 22) & 1;
    int change;
    unsigned short val1, val2;
    
    val1 = ucontrol->value.integer.value[0] & mask;
    val2 = ucontrol->value.integer.value[1] & mask;
    if (invert) {
        val1 = mask - val1;
        val2 = mask - val2;
    }
    val1 <<= shift_left;
    val2 <<= shift_right;
    spin_lock_irqsave(&chip->reg_lock, flags);
    val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
    val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2;
    change = val1 != chip->image[left_reg] || val2 != chip->eimage[CS4236_REG(right_reg)];
    snd_cs4231_out(chip, left_reg, val1);
    snd_cs4236_ext_out(chip, right_reg, val2);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    return change;
}
示例#3
0
文件: cs4236_lib.c 项目: 274914765/C
static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
    unsigned long flags;
    int change;
    unsigned short val1, val2;
    
    val1 = snd_cs4236_mixer_master_digital_invert_volume(ucontrol->value.integer.value[0] & 0x7f);
    val2 = snd_cs4236_mixer_master_digital_invert_volume(ucontrol->value.integer.value[1] & 0x7f);
    spin_lock_irqsave(&chip->reg_lock, flags);
    val1 = (chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] & ~0x7f) | val1;
    val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2;
    change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)];
    snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1);
    snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    return change;
}
示例#4
0
文件: cs4236_lib.c 项目: 274914765/C
static void snd_cs4236_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char cdfr)
{
    unsigned long flags;
    unsigned char rate = divisor_to_rate_register(params->rate_den);
    
    spin_lock_irqsave(&chip->reg_lock, flags);
    /* set fast capture format change and clean capture FIFO */
    snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x20);
    snd_cs4231_out(chip, CS4231_REC_FORMAT, cdfr & 0xf0);
    snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] & ~0x20);
    snd_cs4236_ext_out(chip, CS4236_ADC_RATE, rate);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
}
示例#5
0
文件: cs4236_lib.c 项目: 274914765/C
static void snd_cs4236_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char pdfr)
{
    unsigned long flags;
    unsigned char rate = divisor_to_rate_register(params->rate_den);
    
    spin_lock_irqsave(&chip->reg_lock, flags);
    /* set fast playback format change and clean playback FIFO */
    snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] | 0x10);
    snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, pdfr & 0xf0);
    snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] & ~0x10);
    snd_cs4236_ext_out(chip, CS4236_DAC_RATE, rate);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
}
示例#6
0
文件: cs4236_lib.c 项目: 274914765/C
static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
    struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
    unsigned long flags;
    int reg = kcontrol->private_value & 0xff;
    int shift = (kcontrol->private_value >> 8) & 0xff;
    int mask = (kcontrol->private_value >> 16) & 0xff;
    int invert = (kcontrol->private_value >> 24) & 0xff;
    int change;
    unsigned short val;
    
    val = (ucontrol->value.integer.value[0] & mask);
    if (invert)
        val = mask - val;
    val <<= shift;
    spin_lock_irqsave(&chip->reg_lock, flags);
    val = (chip->eimage[CS4236_REG(reg)] & ~(mask << shift)) | val;
    change = val != chip->eimage[CS4236_REG(reg)];
    snd_cs4236_ext_out(chip, reg, val);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    return change;
}
示例#7
0
文件: cs4236_lib.c 项目: 274914765/C
int snd_cs4236_create(struct snd_card *card,
              unsigned long port,
              unsigned long cport,
              int irq, int dma1, int dma2,
              unsigned short hardware,
              unsigned short hwshare,
              struct snd_cs4231 ** rchip)
{
    struct snd_cs4231 *chip;
    unsigned char ver1, ver2;
    unsigned int reg;
    int err;

    *rchip = NULL;
    if (hardware == CS4231_HW_DETECT)
        hardware = CS4231_HW_DETECT3;
    if (cport < 0x100) {
        snd_printk("please, specify control port for CS4236+ chips\n");
        return -ENODEV;
    }
    if ((err = snd_cs4231_create(card, port, cport, irq, dma1, dma2, hardware, hwshare, &chip)) < 0)
        return err;

    if (!(chip->hardware & CS4231_HW_CS4236B_MASK)) {
            snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware);
        snd_device_free(card, chip);
        return -ENODEV;
    }
#if 0
    {
        int idx;
        for (idx = 0; idx < 8; idx++)
            snd_printk("CD%i = 0x%x\n", idx, inb(chip->cport + idx));
        for (idx = 0; idx < 9; idx++)
            snd_printk("C%i = 0x%x\n", idx, snd_cs4236_ctrl_in(chip, idx));
    }
#endif
    ver1 = snd_cs4236_ctrl_in(chip, 1);
    ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
    snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2);
    if (ver1 != ver2) {
        snd_printk("CS4236+ chip detected, but control port 0x%lx is not valid\n", cport);
        snd_device_free(card, chip);
        return -ENODEV;
    }
    snd_cs4236_ctrl_out(chip, 0, 0x00);
    snd_cs4236_ctrl_out(chip, 2, 0xff);
    snd_cs4236_ctrl_out(chip, 3, 0x00);
    snd_cs4236_ctrl_out(chip, 4, 0x80);
    snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE);
    snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
    snd_cs4236_ctrl_out(chip, 7, 0x00);
    /* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */
    /* is working with this setup, other hardware should have */
    /* different signal paths and this value should be selectable */
    /* in the future */
    snd_cs4236_ctrl_out(chip, 8, 0x8c);
    chip->rate_constraint = snd_cs4236_xrate;
    chip->set_playback_format = snd_cs4236_playback_format;
    chip->set_capture_format = snd_cs4236_capture_format;
#ifdef CONFIG_PM
    chip->suspend = snd_cs4236_suspend;
    chip->resume = snd_cs4236_resume;
#endif

    /* initialize extended registers */
    for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
        snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]);

        /* initialize compatible but more featured registers */
    snd_cs4231_out(chip, CS4231_LEFT_INPUT, 0x40);
    snd_cs4231_out(chip, CS4231_RIGHT_INPUT, 0x40);
    snd_cs4231_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
    snd_cs4231_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff);
    snd_cs4231_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf);
    snd_cs4231_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf);
    snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
    snd_cs4231_out(chip, CS4231_LEFT_LINE_IN, 0xff);
    snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
    switch (chip->hardware) {
    case CS4231_HW_CS4235:
    case CS4231_HW_CS4239:
        snd_cs4231_out(chip, CS4235_LEFT_MASTER, 0xff);
        snd_cs4231_out(chip, CS4235_RIGHT_MASTER, 0xff);
        break;
    }

    *rchip = chip;
    return 0;
}
int snd_cs4236_create(struct snd_card *card,
		      unsigned long port,
		      unsigned long cport,
		      int irq, int dma1, int dma2,
		      unsigned short hardware,
		      unsigned short hwshare,
		      struct snd_wss **rchip)
{
	struct snd_wss *chip;
	unsigned char ver1, ver2;
	unsigned int reg;
	int err;

	*rchip = NULL;
	if (hardware == WSS_HW_DETECT)
		hardware = WSS_HW_DETECT3;

	err = snd_wss_create(card, port, cport,
			     irq, dma1, dma2, hardware, hwshare, &chip);
	if (err < 0)
		return err;

	if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
		snd_printd("chip is not CS4236+, hardware=0x%x\n",
			   chip->hardware);
		*rchip = chip;
		return 0;
	}
#if 0
	{
		int idx;
		for (idx = 0; idx < 8; idx++)
			snd_printk(KERN_DEBUG "CD%i = 0x%x\n",
				   idx, inb(chip->cport + idx));
		for (idx = 0; idx < 9; idx++)
			snd_printk(KERN_DEBUG "C%i = 0x%x\n",
				   idx, snd_cs4236_ctrl_in(chip, idx));
	}
#endif
	if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
		snd_printk(KERN_ERR "please, specify control port "
			   "for CS4236+ chips\n");
		snd_device_free(card, chip);
		return -ENODEV;
	}
	ver1 = snd_cs4236_ctrl_in(chip, 1);
	ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
	snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
			cport, ver1, ver2);
	if (ver1 != ver2) {
		snd_printk(KERN_ERR "CS4236+ chip detected, but "
			   "control port 0x%lx is not valid\n", cport);
		snd_device_free(card, chip);
		return -ENODEV;
	}
	snd_cs4236_ctrl_out(chip, 0, 0x00);
	snd_cs4236_ctrl_out(chip, 2, 0xff);
	snd_cs4236_ctrl_out(chip, 3, 0x00);
	snd_cs4236_ctrl_out(chip, 4, 0x80);
	reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
	      IEC958_AES0_CON_EMPHASIS_NONE;
	snd_cs4236_ctrl_out(chip, 5, reg);
	snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
	snd_cs4236_ctrl_out(chip, 7, 0x00);
	snd_cs4236_ctrl_out(chip, 8, 0x8c);
	chip->rate_constraint = snd_cs4236_xrate;
	chip->set_playback_format = snd_cs4236_playback_format;
	chip->set_capture_format = snd_cs4236_capture_format;
#ifdef CONFIG_PM
	chip->suspend = snd_cs4236_suspend;
	chip->resume = snd_cs4236_resume;
#endif

	
	for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
		snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
				   snd_cs4236_ext_map[reg]);

	
	snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
	snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
	snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
	snd_wss_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff);
	snd_wss_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf);
	snd_wss_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf);
	snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
	snd_wss_out(chip, CS4231_LEFT_LINE_IN, 0xff);
	snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
	switch (chip->hardware) {
	case WSS_HW_CS4235:
	case WSS_HW_CS4239:
		snd_wss_out(chip, CS4235_LEFT_MASTER, 0xff);
		snd_wss_out(chip, CS4235_RIGHT_MASTER, 0xff);
		break;
	}

	*rchip = chip;
	return 0;
}