示例#1
0
文件: cs4236_lib.c 项目: 274914765/C
static int snd_cs4236_put_iec958_switch(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 enable, val;
    
    enable = ucontrol->value.integer.value[0] & 1;

    mutex_lock(&chip->mce_mutex);
    snd_cs4231_mce_up(chip);
    spin_lock_irqsave(&chip->reg_lock, flags);
    val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
    change = val != chip->image[CS4231_ALT_FEATURE_1];
    snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, val);
    val = snd_cs4236_ctrl_in(chip, 4) | 0xc0;
    snd_cs4236_ctrl_out(chip, 4, val);
    udelay(100);
    val &= ~0x40;
    snd_cs4236_ctrl_out(chip, 4, val);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    snd_cs4231_mce_down(chip);
    mutex_unlock(&chip->mce_mutex);

#if 0
    printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
            snd_cs4231_in(chip, CS4231_ALT_FEATURE_1),
            snd_cs4236_ctrl_in(chip, 3),
            snd_cs4236_ctrl_in(chip, 4),
            snd_cs4236_ctrl_in(chip, 5),
            snd_cs4236_ctrl_in(chip, 6),
            snd_cs4236_ctrl_in(chip, 8));
#endif
    return change;
}
示例#2
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);
}
示例#3
0
/*
 * Create an AD1845 PCM subdevice on the SoundScape. The AD1845
 * is very much like a CS4231, with a few extra bits. We will
 * try to support at least some of the extra bits by overriding
 * some of the CS4231 callback.
 */
static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq, int dma1)
{
	register struct soundscape *sscape = get_card_soundscape(card);
	struct snd_cs4231 *chip;
	int err;

#define CS4231_SHARE_HARDWARE  (CS4231_HWSHARE_DMA1 | CS4231_HWSHARE_DMA2)
	/*
	 * The AD1845 PCM device is only half-duplex, and so
	 * we only give it one DMA channel ...
	 */
	if ((err = snd_cs4231_create(card,
				     port, -1, irq, dma1, dma1,
				     CS4231_HW_DETECT,
				     CS4231_HWSHARE_DMA1, &chip)) == 0) {
		unsigned long flags;
		struct snd_pcm *pcm;

#define AD1845_FREQ_SEL_ENABLE  0x08

#define AD1845_PWR_DOWN_CTRL   0x1b
#define AD1845_CRYS_CLOCK_SEL  0x1d

/*
 * It turns out that the PLAYBACK_ENABLE bit is set
 * by the lowlevel driver ...
 *
#define AD1845_IFACE_CONFIG  \
           (CS4231_AUTOCALIB | CS4231_RECORD_ENABLE | CS4231_PLAYBACK_ENABLE)
    snd_cs4231_mce_up(chip);
    spin_lock_irqsave(&chip->reg_lock, flags);
    snd_cs4231_out(chip, CS4231_IFACE_CTRL, AD1845_IFACE_CONFIG);
    spin_unlock_irqrestore(&chip->reg_lock, flags);
    snd_cs4231_mce_down(chip);
 */

		/*
		 * The input clock frequency on the SoundScape must
		 * be 14.31818 MHz, because we must set this register
		 * to get the playback to sound correct ...
		 */
		snd_cs4231_mce_up(chip);
		spin_lock_irqsave(&chip->reg_lock, flags);
		snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20);
		spin_unlock_irqrestore(&chip->reg_lock, flags);
		snd_cs4231_mce_down(chip);

		/*
		 * More custom configuration:
		 * a) select "mode 2", and provide a current drive of 8 mA
		 * b) enable frequency selection (for capture/playback)
		 */
		spin_lock_irqsave(&chip->reg_lock, flags);
		snd_cs4231_out(chip, CS4231_MISC_INFO, (CS4231_MODE2 | 0x10));
		snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL) | AD1845_FREQ_SEL_ENABLE);
		spin_unlock_irqrestore(&chip->reg_lock, flags);

		if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
			snd_printk(KERN_ERR "sscape: No PCM device for AD1845 chip\n");
			goto _error;
		}

		if ((err = snd_cs4231_mixer(chip)) < 0) {
			snd_printk(KERN_ERR "sscape: No mixer device for AD1845 chip\n");
			goto _error;
		}

		if ((err = snd_ctl_add(card, snd_ctl_new1(&midi_mixer_ctl, chip))) < 0) {
			snd_printk(KERN_ERR "sscape: Could not create MIDI mixer control\n");
			goto _error;
		}

		strcpy(card->driver, "SoundScape");
		strcpy(card->shortname, pcm->name);
		snprintf(card->longname, sizeof(card->longname),
		         "%s at 0x%lx, IRQ %d, DMA %d\n",
		         pcm->name, chip->port, chip->irq, chip->dma1);
		chip->set_playback_format = ad1845_playback_format;
		chip->set_capture_format = ad1845_capture_format;
		sscape->chip = chip;
	}

	_error:
	return err;
}