Ejemplo n.º 1
0
static void snd_als300_init(struct snd_als300 *chip)
{
	unsigned long flags;
	u32 tmp;
	
	spin_lock_irqsave(&chip->reg_lock, flags);
	chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16)
								& 0x0000000F;
	/* Setup DRAM */
	tmp = snd_als300_gcr_read(chip->port, DRAM_WRITE_CONTROL);
	snd_als300_gcr_write(chip->port, DRAM_WRITE_CONTROL,
						(tmp | DRAM_MODE_2)
						& ~WRITE_TRANS_START);

	/* Enable IRQ output */
	snd_als300_set_irq_flag(chip, IRQ_ENABLE);

	/* Unmute hardware devices so their outputs get routed to
	 * the onboard mixer */
	tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
	snd_als300_gcr_write(chip->port, MISC_CONTROL,
			tmp | VMUTE_NORMAL | MMUTE_NORMAL);

	/* Reset volumes */
	snd_als300_gcr_write(chip->port, MUS_VOC_VOL, 0);

	/* Make sure playback transfer is stopped */
	tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
	snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL,
			tmp & ~TRANSFER_START);
	spin_unlock_irqrestore(&chip->reg_lock, flags);
}
Ejemplo n.º 2
0
static int snd_als300_capture_prepare(struct snd_pcm_substream *substream)
{
	u32 tmp;
	struct snd_als300 *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	unsigned short period_bytes = snd_pcm_lib_period_bytes(substream);
	unsigned short buffer_bytes = snd_pcm_lib_buffer_bytes(substream);

	spin_lock_irq(&chip->reg_lock);
	tmp = snd_als300_gcr_read(chip->port, RECORD_CONTROL);
	tmp &= ~TRANSFER_START;

	snd_als300_dbgplay("Period bytes: %d Buffer bytes %d\n", period_bytes,
							buffer_bytes);

	/* set block size */
	tmp &= 0xffff0000;
	tmp |= period_bytes - 1;

	/* set dma area */
	snd_als300_gcr_write(chip->port, RECORD_CONTROL, tmp);
	snd_als300_gcr_write(chip->port, RECORD_START,
					runtime->dma_addr);
	snd_als300_gcr_write(chip->port, RECORD_END,
					runtime->dma_addr + buffer_bytes - 1);
	spin_unlock_irq(&chip->reg_lock);
	return 0;
}
Ejemplo n.º 3
0
static void snd_als300_init(struct snd_als300 *chip)
{
	unsigned long flags;
	u32 tmp;
	
	snd_als300_dbgcallenter();
	spin_lock_irqsave(&chip->reg_lock, flags);
	chip->revision = (snd_als300_gcr_read(chip->port, MISC_CONTROL) >> 16)
								& 0x0000000F;
	/*            */
	tmp = snd_als300_gcr_read(chip->port, DRAM_WRITE_CONTROL);
	snd_als300_gcr_write(chip->port, DRAM_WRITE_CONTROL,
						(tmp | DRAM_MODE_2)
						& ~WRITE_TRANS_START);

	/*                   */
	snd_als300_set_irq_flag(chip, IRQ_ENABLE);

	/*                                                       
                      */
	tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
	snd_als300_gcr_write(chip->port, MISC_CONTROL,
			tmp | VMUTE_NORMAL | MMUTE_NORMAL);

	/*               */
	snd_als300_gcr_write(chip->port, MUS_VOC_VOL, 0);

	/*                                        */
	tmp = snd_als300_gcr_read(chip->port, PLAYBACK_CONTROL);
	snd_als300_gcr_write(chip->port, PLAYBACK_CONTROL,
			tmp & ~TRANSFER_START);
	spin_unlock_irqrestore(&chip->reg_lock, flags);
	snd_als300_dbgcallleave();
}
Ejemplo n.º 4
0
static int snd_als300_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_als300 *chip = snd_pcm_substream_chip(substream);
	u32 tmp;
	struct snd_als300_substream_data *data;
	unsigned short reg;
	int ret = 0;

	data = substream->runtime->private_data;
	reg = data->control_register;

	snd_als300_dbgcallenter();
	spin_lock(&chip->reg_lock);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
		tmp = snd_als300_gcr_read(chip->port, reg);
		data->period_flipflop = 1;
		snd_als300_gcr_write(chip->port, reg, tmp | TRANSFER_START);
		snd_als300_dbgplay("TRIGGER START\n");
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		tmp = snd_als300_gcr_read(chip->port, reg);
		snd_als300_gcr_write(chip->port, reg, tmp & ~TRANSFER_START);
		snd_als300_dbgplay("TRIGGER STOP\n");
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		tmp = snd_als300_gcr_read(chip->port, reg);
		snd_als300_gcr_write(chip->port, reg, tmp | FIFO_PAUSE);
		snd_als300_dbgplay("TRIGGER PAUSE\n");
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		tmp = snd_als300_gcr_read(chip->port, reg);
		snd_als300_gcr_write(chip->port, reg, tmp & ~FIFO_PAUSE);
		snd_als300_dbgplay("TRIGGER RELEASE\n");
		break;
	default:
		snd_als300_dbgplay("TRIGGER INVALID\n");
		ret = -EINVAL;
	}
	spin_unlock(&chip->reg_lock);
	snd_als300_dbgcallleave();
	return ret;
}
Ejemplo n.º 5
0
/* Enable/Disable Interrupts */
static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd)
{
	u32 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);

	/* boolean XOR check, since old vs. new hardware have
	   directly reversed bit setting for ENABLE and DISABLE.
	   ALS300+ acts like newer versions of ALS300 */
	if (((chip->revision > 5 || chip->chip_type == DEVICE_ALS300_PLUS) ^
						(cmd == IRQ_ENABLE)) == 0)
		tmp |= IRQ_SET_BIT;
	else
		tmp &= ~IRQ_SET_BIT;
	snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp);
}
Ejemplo n.º 6
0
static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd)
{
	u32 tmp = snd_als300_gcr_read(chip->port, MISC_CONTROL);
	snd_als300_dbgcallenter();

	/*                                                   
                                                         
                                               */
	if (((chip->revision > 5 || chip->chip_type == DEVICE_ALS300_PLUS) ^
						(cmd == IRQ_ENABLE)) == 0)
		tmp |= IRQ_SET_BIT;
	else
		tmp &= ~IRQ_SET_BIT;
	snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp);
	snd_als300_dbgcallleave();
}