Beispiel #1
0
static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *value)
{
	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
	int changed;

	if (value->value.enumerated.item[0] > 1)
		return -EINVAL;

	changed = value->value.enumerated.item[0] != dummy->iobox;
	if (changed) {
		dummy->iobox = value->value.enumerated.item[0];

		if (dummy->iobox) {
			dummy->cd_volume_ctl->vd[0].access &=
				~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
			dummy->cd_switch_ctl->vd[0].access &=
				~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		} else {
			dummy->cd_volume_ctl->vd[0].access |=
				SNDRV_CTL_ELEM_ACCESS_INACTIVE;
			dummy->cd_switch_ctl->vd[0].access |=
				SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		}

		snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
			       &dummy->cd_volume_ctl->id);
		snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
			       &dummy->cd_switch_ctl->id);
	}

	return changed;
}
Beispiel #2
0
static int loopback_check_format(struct loopback_cable *cable, int stream)
{
	struct snd_pcm_runtime *runtime, *cruntime;
	struct loopback_setup *setup;
	struct snd_card *card;
	int check;

	if (cable->valid != CABLE_VALID_BOTH) {
		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
			goto __notify;
		return 0;
	}
	runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
							substream->runtime;
	cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
							substream->runtime;
	check = runtime->format != cruntime->format ||
		runtime->rate != cruntime->rate ||
		runtime->channels != cruntime->channels;
	if (!check)
		return 0;
	if (stream == SNDRV_PCM_STREAM_CAPTURE) {
		return -EIO;
	} else {
		snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
					substream, SNDRV_PCM_STATE_DRAINING);
	      __notify:
		runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
							substream->runtime;
		setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
		card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
		if (setup->format != runtime->format) {
			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
							&setup->format_id);
			setup->format = runtime->format;
		}
		if (setup->rate != runtime->rate) {
			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
							&setup->rate_id);
			setup->rate = runtime->rate;
		}
		if (setup->channels != runtime->channels) {
			snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
							&setup->channels_id);
			setup->channels = runtime->channels;
		}
	}
	return 0;
}
static void oxygen_spdif_input_bits_changed(struct work_struct *work)
{
	struct oxygen *chip = container_of(work, struct oxygen,
					   spdif_input_bits_work);
	u32 reg;

	/*
	 * This function gets called when there is new activity on the SPDIF
	 * input, or when we lose lock on the input signal, or when the rate
	 * changes.
	 */
	msleep(1);
	spin_lock_irq(&chip->reg_lock);
	reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
	if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
		    OXYGEN_SPDIF_LOCK_STATUS))
	    == OXYGEN_SPDIF_SENSE_STATUS) {
		/*
		 * If we detect activity on the SPDIF input but cannot lock to
		 * a signal, the clock bit is likely to be wrong.
		 */
		reg ^= OXYGEN_SPDIF_IN_CLOCK_MASK;
		oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
		spin_unlock_irq(&chip->reg_lock);
		msleep(1);
		spin_lock_irq(&chip->reg_lock);
		reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
		if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
			    OXYGEN_SPDIF_LOCK_STATUS))
		    == OXYGEN_SPDIF_SENSE_STATUS) {
			/* nothing detected with either clock; give up */
			if ((reg & OXYGEN_SPDIF_IN_CLOCK_MASK)
			    == OXYGEN_SPDIF_IN_CLOCK_192) {
				/*
				 * Reset clock to <= 96 kHz because this is
				 * more likely to be received next time.
				 */
				reg &= ~OXYGEN_SPDIF_IN_CLOCK_MASK;
				reg |= OXYGEN_SPDIF_IN_CLOCK_96;
				oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
			}
		}
	}
	spin_unlock_irq(&chip->reg_lock);

	if (chip->controls[CONTROL_SPDIF_INPUT_BITS]) {
		spin_lock_irq(&chip->reg_lock);
		chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
		oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
			       chip->interrupt_mask);
		spin_unlock_irq(&chip->reg_lock);

		/*
		 * We don't actually know that any channel status bits have
		 * changed, but let's send a notification just to be sure.
		 */
		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &chip->controls[CONTROL_SPDIF_INPUT_BITS]->id);
	}
}
Beispiel #4
0
void snd_kctl_jack_report(struct snd_card *card,
			  struct snd_kcontrol *kctl, bool status)
{
	if (kctl->private_value == status)
		return;
	kctl->private_value = status;
	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
}
Beispiel #5
0
static void vortex_notify_pcm_vol_change(struct snd_card *card,
			struct snd_kcontrol *kctl, int activate)
{
	if (activate)
		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
	else
		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
				SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
}
Beispiel #6
0
static irqreturn_t tt_hpdetect_irq(int irq, void *dev_id)
{
	if (tt_context.ops && tt_context.ops->hpdetect_callback) {
		tt_hpdetect	=  tt_context.ops->hpdetect_callback(&tt_context);

		if ((tt_hpdetect_card) && (tt_hpdetect_elem_id))
		{
		  snd_ctl_notify(tt_hpdetect_card, SNDRV_CTL_EVENT_MASK_VALUE, tt_hpdetect_elem_id);
		}
	}

	return IRQ_HANDLED;
}
Beispiel #7
0
int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
{
	struct cs8427 *chip;

	if (snd_BUG_ON(!cs8427))
		return -ENXIO;
	chip = cs8427->private_data;
	if (active)
		memcpy(chip->playback.pcm_status,
		       chip->playback.def_status, 24);
	chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
	snd_ctl_notify(cs8427->bus->card,
		       SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
		       &chip->playback.pcm_ctl->id);
	return 0;
}
Beispiel #8
0
/*
 * snd_ubi32_cs4384_set_channels
 *	Mute unused channels
 */
static int snd_ubi32_cs4384_set_channels(struct ubi32_snd_priv *priv, int channels)
{
	struct i2c_client *client = (struct i2c_client *)priv->client;
	struct snd_ubi32_cs4384_priv *cs4384_priv;
	unsigned char send[2];
	int ret;
	int i;
	unsigned long flags;

	/*
	 * Only support 0, 2, 4, 6, 8 channels
	 */
	if ((channels > 8) || (channels & 1)) {
		return -EINVAL;
	}

	cs4384_priv = snd_ubi32_priv_get_drv(priv);
	spin_lock_irqsave(&cs4384_priv->lock, flags);

	/*
	 * Address 09h, Mute control
	 */
	send[0] = 0x09;
	send[1] = (unsigned char)(0xFF << channels);

	ret = i2c_master_send(client, send, 2);

	spin_unlock_irqrestore(&cs4384_priv->lock, flags);

	/*
	 * Notify the system that we changed the mutes
	 */
	cs4384_priv->mute = (unsigned char)(0xFF << channels);

	for (i = SND_UBI32_MUTE_CTL_START; i < SND_UBI32_MUTE_CTL_END; i++) {
		snd_ctl_notify(priv->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &cs4384_priv->kctls[i]->id);
	}

	if (ret != 2) {
		return -ENXIO;
	}

	return 0;
}
static void oxygen_spdif_input_bits_changed(struct work_struct *work)
{
	struct oxygen *chip = container_of(work, struct oxygen,
					   spdif_input_bits_work);
	u32 reg;

	msleep(1);
	spin_lock_irq(&chip->reg_lock);
	reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
	if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
		    OXYGEN_SPDIF_LOCK_STATUS))
	    == OXYGEN_SPDIF_SENSE_STATUS) {
		reg ^= OXYGEN_SPDIF_IN_CLOCK_MASK;
		oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
		spin_unlock_irq(&chip->reg_lock);
		msleep(1);
		spin_lock_irq(&chip->reg_lock);
		reg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
		if ((reg & (OXYGEN_SPDIF_SENSE_STATUS |
			    OXYGEN_SPDIF_LOCK_STATUS))
		    == OXYGEN_SPDIF_SENSE_STATUS) {
			
			if ((reg & OXYGEN_SPDIF_IN_CLOCK_MASK)
			    == OXYGEN_SPDIF_IN_CLOCK_192) {
				reg &= ~OXYGEN_SPDIF_IN_CLOCK_MASK;
				reg |= OXYGEN_SPDIF_IN_CLOCK_96;
				oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, reg);
			}
		}
	}
	spin_unlock_irq(&chip->reg_lock);

	if (chip->controls[CONTROL_SPDIF_INPUT_BITS]) {
		spin_lock_irq(&chip->reg_lock);
		chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT;
		oxygen_write16(chip, OXYGEN_INTERRUPT_MASK,
			       chip->interrupt_mask);
		spin_unlock_irq(&chip->reg_lock);

		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &chip->controls[CONTROL_SPDIF_INPUT_BITS]->id);
	}
}
Beispiel #10
0
static int oxygen_close(struct snd_pcm_substream *substream)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	unsigned int channel = oxygen_substream_channel(substream);

	mutex_lock(&chip->mutex);
	chip->pcm_active &= ~(1 << channel);
	if (channel == PCM_SPDIF) {
		chip->controls[CONTROL_SPDIF_PCM]->vd[0].access |=
			SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
			       SNDRV_CTL_EVENT_MASK_INFO,
			       &chip->controls[CONTROL_SPDIF_PCM]->id);
	}
	if (channel == PCM_SPDIF || channel == PCM_MULTICH)
		oxygen_update_spdif_source(chip);
	mutex_unlock(&chip->mutex);

	chip->streams[channel] = NULL;
	return 0;
}
Beispiel #11
0
int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
{
	struct cs8427 *chip;
	char *status;
	int err, reset;

	if (snd_BUG_ON(!cs8427))
		return -ENXIO;
	chip = cs8427->private_data;
	status = chip->playback.pcm_status;
	snd_i2c_lock(cs8427->bus);
	if (status[0] & IEC958_AES0_PROFESSIONAL) {
		status[0] &= ~IEC958_AES0_PRO_FS;
		switch (rate) {
		case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break;
		case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break;
		case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break;
		default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break;
		}
	} else {
		status[3] &= ~IEC958_AES3_CON_FS;
		switch (rate) {
		case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break;
		case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break;
		case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break;
		}
	}
	err = snd_cs8427_send_corudata(cs8427, 0, status, 24);
	if (err > 0)
		snd_ctl_notify(cs8427->bus->card,
			       SNDRV_CTL_EVENT_MASK_VALUE,
			       &chip->playback.pcm_ctl->id);
	reset = chip->rate != rate;
	chip->rate = rate;
	snd_i2c_unlock(cs8427->bus);
	if (reset)
		snd_cs8427_reset(cs8427);
	return err < 0 ? err : 0;
}
Beispiel #12
0
/* set up */
static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
{
	unsigned long flags;
	unsigned int tmp;
	int change;

	spin_lock_irqsave(&ice->reg_lock, flags);
	tmp = ice->spdif.cs8403_stream_bits;
	if (tmp & 0x01)		/* consumer */
		tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
	switch (rate) {
	case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
	case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
	case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
	default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
	}
	change = ice->spdif.cs8403_stream_bits != tmp;
	ice->spdif.cs8403_stream_bits = tmp;
	spin_unlock_irqrestore(&ice->reg_lock, flags);
	if (change)
		snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
	snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
}
Beispiel #13
0
static int oxygen_open(struct snd_pcm_substream *substream,
		       unsigned int channel)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int err;

	runtime->private_data = (void *)(uintptr_t)channel;
	if (channel == PCM_B && chip->has_ac97_1 &&
	    (chip->model.device_config & CAPTURE_2_FROM_AC97_1))
		runtime->hw = oxygen_ac97_hardware;
	else
		runtime->hw = *oxygen_hardware[channel];
	switch (channel) {
	case PCM_C:
		runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
				       SNDRV_PCM_RATE_64000);
		runtime->hw.rate_min = 44100;
		break;
	case PCM_MULTICH:
		runtime->hw.channels_max = chip->model.dac_channels_pcm;
		break;
	}
	if (chip->model.pcm_hardware_filter)
		chip->model.pcm_hardware_filter(channel, &runtime->hw);
	err = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
	if (err < 0)
		return err;
	err = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
	if (err < 0)
		return err;
	if (runtime->hw.formats & SNDRV_PCM_FMTBIT_S32_LE) {
		err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
		if (err < 0)
			return err;
	}
	if (runtime->hw.channels_max > 2) {
		err = snd_pcm_hw_constraint_step(runtime, 0,
						 SNDRV_PCM_HW_PARAM_CHANNELS,
						 2);
		if (err < 0)
			return err;
	}
	if (channel == PCM_MULTICH) {
		err = snd_pcm_hw_constraint_minmax
			(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
		if (err < 0)
			return err;
	}
	snd_pcm_set_sync(substream);
	chip->streams[channel] = substream;

	mutex_lock(&chip->mutex);
	chip->pcm_active |= 1 << channel;
	if (channel == PCM_SPDIF) {
		chip->spdif_pcm_bits = chip->spdif_bits;
		chip->controls[CONTROL_SPDIF_PCM]->vd[0].access &=
			~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
			       SNDRV_CTL_EVENT_MASK_INFO,
			       &chip->controls[CONTROL_SPDIF_PCM]->id);
	}
	mutex_unlock(&chip->mutex);

	return 0;
}
Beispiel #14
0
static void loopback_active_notify(struct loopback_pcm *dpcm)
{
	snd_ctl_notify(dpcm->loopback->card,
		       SNDRV_CTL_EVENT_MASK_VALUE,
		       &get_setup(dpcm)->active_id);
}
Beispiel #15
0
/* notify kcontrols if any parameters are changed */
static void ak4114_notify(struct ak4114 *ak4114,
			  unsigned char rcs0, unsigned char rcs1,
			  unsigned char c0, unsigned char c1)
{
	if (!ak4114->kctls[0])
		return;

	if (rcs0 & AK4114_PAR)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[0]->id);
	if (rcs0 & AK4114_V)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[1]->id);
	if (rcs1 & AK4114_CCRC)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[2]->id);
	if (rcs1 & AK4114_QCRC)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[3]->id);

	/* rate change */
	if (c1 & 0xf0)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[4]->id);

	if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[9]->id);
	if (c0 & AK4114_QINT)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[10]->id);

	if (c0 & AK4114_AUDION)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[11]->id);
	if (c0 & AK4114_AUTO)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[12]->id);
	if (c0 & AK4114_DTSCD)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[13]->id);
	if (c0 & AK4114_UNLCK)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
			       &ak4114->kctls[14]->id);
}
Beispiel #16
0
int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags)
{
	struct snd_pcm_runtime *runtime = ak4117->substream ? ak4117->substream->runtime : NULL;
	unsigned long _flags;
	int res = 0;
	unsigned char rcs0, rcs1, rcs2;
	unsigned char c0, c1;

	rcs1 = reg_read(ak4117, AK4117_REG_RCS1);
	if (flags & AK4117_CHECK_NO_STAT)
		goto __rate;
	rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
	rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
	// printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
	spin_lock_irqsave(&ak4117->lock, _flags);
	if (rcs0 & AK4117_PAR)
		ak4117->parity_errors++;
	if (rcs0 & AK4117_V)
		ak4117->v_bit_errors++;
	if (rcs2 & AK4117_CCRC)
		ak4117->ccrc_errors++;
	if (rcs2 & AK4117_QCRC)
		ak4117->qcrc_errors++;
	c0 = (ak4117->rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK)) ^
                     (rcs0 & (AK4117_QINT | AK4117_CINT | AK4117_STC | AK4117_AUDION | AK4117_AUTO | AK4117_UNLCK));
	c1 = (ak4117->rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f)) ^
	             (rcs1 & (AK4117_DTSCD | AK4117_NPCM | AK4117_PEM | 0x0f));
	ak4117->rcs0 = rcs0 & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
	ak4117->rcs1 = rcs1;
	ak4117->rcs2 = rcs2;
	spin_unlock_irqrestore(&ak4117->lock, _flags);

	if (rcs0 & AK4117_PAR)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[0]->id);
	if (rcs0 & AK4117_V)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[1]->id);
	if (rcs2 & AK4117_CCRC)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[2]->id);
	if (rcs2 & AK4117_QCRC)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[3]->id);

	/* rate change */
	if (c1 & 0x0f)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[4]->id);

	if ((c1 & AK4117_PEM) | (c0 & AK4117_CINT))
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[6]->id);
	if (c0 & AK4117_QINT)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[8]->id);

	if (c0 & AK4117_AUDION)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[9]->id);
	if (c1 & AK4117_NPCM)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[10]->id);
	if (c1 & AK4117_DTSCD)
		snd_ctl_notify(ak4117->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4117->kctls[11]->id);
		
	if (ak4117->change_callback && (c0 | c1) != 0)
		ak4117->change_callback(ak4117, c0, c1);

      __rate:
	/* compare rate */
	res = external_rate(rcs1);
	if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
		snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
		if (snd_pcm_running(ak4117->substream)) {
			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
			snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
			wake_up(&runtime->sleep);
			res = 1;
		}
		snd_pcm_stream_unlock_irqrestore(ak4117->substream, _flags);
	}
	return res;
}
Beispiel #17
0
int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags)
{
	snd_pcm_runtime_t *runtime = ak4114->capture_substream ? ak4114->capture_substream->runtime : NULL;
	unsigned long _flags;
	int res = 0;
	unsigned char rcs0, rcs1;
	unsigned char c0, c1;

	rcs1 = reg_read(ak4114, AK4114_REG_RCS1);
	if (flags & AK4114_CHECK_NO_STAT)
		goto __rate;
	rcs0 = reg_read(ak4114, AK4114_REG_RCS0);
	spin_lock_irqsave(&ak4114->lock, _flags);
	if (rcs0 & AK4114_PAR)
		ak4114->parity_errors++;
	if (rcs1 & AK4114_V)
		ak4114->v_bit_errors++;
	if (rcs1 & AK4114_CCRC)
		ak4114->ccrc_errors++;
	if (rcs1 & AK4114_QCRC)
		ak4114->qcrc_errors++;
	c0 = (ak4114->rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK)) ^
                     (rcs0 & (AK4114_QINT | AK4114_CINT | AK4114_PEM | AK4114_AUDION | AK4114_AUTO | AK4114_UNLCK));
	c1 = (ak4114->rcs1 & 0xf0) ^ (rcs1 & 0xf0);
	ak4114->rcs0 = rcs0 & ~(AK4114_QINT | AK4114_CINT);
	ak4114->rcs1 = rcs1;
	spin_unlock_irqrestore(&ak4114->lock, _flags);

	if (rcs0 & AK4114_PAR)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id);
	if (rcs0 & AK4114_V)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id);
	if (rcs1 & AK4114_CCRC)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id);
	if (rcs1 & AK4114_QCRC)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id);

	/* rate change */
	if (c1 & 0xf0)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id);

	if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id);
	if (c0 & AK4114_QINT)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id);

	if (c0 & AK4114_AUDION)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id);
	if (c0 & AK4114_AUTO)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id);
	if (c0 & AK4114_DTSCD)
		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id);

	if (ak4114->change_callback && (c0 | c1) != 0)
		ak4114->change_callback(ak4114, c0, c1);

      __rate:
	/* compare rate */
	res = external_rate(rcs1);
	if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {
		snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);
		if (snd_pcm_running(ak4114->capture_substream)) {
			// printk("rate changed (%i <- %i)\n", runtime->rate, res);
			snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
			res = 1;
		}
		snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags);
	}
	return res;
}