static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift_left = (kcontrol->private_value >> 8) & 0x0f; int shift_right = (kcontrol->private_value >> 12) & 0x0f; int mask = (kcontrol->private_value >> 16) & 0xff; int invert = (kcontrol->private_value >> 24) & 0xff; int change; unsigned short old_val, 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->lock, flags); old_val = snd_ad1816a_read(chip, reg); val1 = (old_val & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2; change = val1 != old_val; snd_ad1816a_write(chip, reg, val1); spin_unlock_irqrestore(&chip->lock, flags); return change; }
void snd_ad1816a_suspend(struct snd_ad1816a *chip) { int reg; unsigned long flags; snd_pcm_suspend_all(chip->pcm); spin_lock_irqsave(&chip->lock, flags); for (reg = 0; reg < 48; reg++) chip->image[reg] = snd_ad1816a_read(chip, reg); spin_unlock_irqrestore(&chip->lock, flags); }
static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned short val; spin_lock_irqsave(&chip->lock, flags); val = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL); spin_unlock_irqrestore(&chip->lock, flags); ucontrol->value.enumerated.item[0] = (val >> 12) & 7; ucontrol->value.enumerated.item[1] = (val >> 4) & 7; return 0; }
static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; unsigned short val; int change; if (ucontrol->value.enumerated.item[0] > 6 || ucontrol->value.enumerated.item[1] > 6) return -EINVAL; val = (ucontrol->value.enumerated.item[0] << 12) | (ucontrol->value.enumerated.item[1] << 4); spin_lock_irqsave(&chip->lock, flags); change = snd_ad1816a_read(chip, AD1816A_ADC_SOURCE_SEL) != val; snd_ad1816a_write(chip, AD1816A_ADC_SOURCE_SEL, val); spin_unlock_irqrestore(&chip->lock, flags); return change; }
static int snd_ad1816a_timer_start(struct snd_timer *timer) { unsigned short bits; unsigned long flags; struct snd_ad1816a *chip = snd_timer_chip(timer); spin_lock_irqsave(&chip->lock, flags); bits = snd_ad1816a_read(chip, AD1816A_INTERRUPT_ENABLE); if (!(bits & AD1816A_TIMER_ENABLE)) { snd_ad1816a_write(chip, AD1816A_TIMER_BASE_COUNT, timer->sticks & 0xffff); snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE, AD1816A_TIMER_ENABLE, 0xffff); } spin_unlock_irqrestore(&chip->lock, flags); return 0; }
static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int reg = kcontrol->private_value & 0xff; int shift_left = (kcontrol->private_value >> 8) & 0x0f; int shift_right = (kcontrol->private_value >> 12) & 0x0f; int mask = (kcontrol->private_value >> 16) & 0xff; int invert = (kcontrol->private_value >> 24) & 0xff; unsigned short val; spin_lock_irqsave(&chip->lock, flags); val = snd_ad1816a_read(chip, reg); ucontrol->value.integer.value[0] = (val >> shift_left) & mask; ucontrol->value.integer.value[1] = (val >> shift_right) & mask; spin_unlock_irqrestore(&chip->lock, flags); if (invert) { ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; } return 0; }
static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ad1816a *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 old_val, val; val = (ucontrol->value.integer.value[0] & mask); if (invert) val = mask - val; val <<= shift; spin_lock_irqsave(&chip->lock, flags); old_val = snd_ad1816a_read(chip, reg); val = (old_val & ~(mask << shift)) | val; change = val != old_val; snd_ad1816a_write(chip, reg, val); spin_unlock_irqrestore(&chip->lock, flags); return change; }
static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip) { unsigned long flags; spin_lock_irqsave(&chip->lock, flags); switch (chip->version = snd_ad1816a_read(chip, AD1816A_VERSION_ID)) { case 0: chip->hardware = AD1816A_HW_AD1815; break; case 1: chip->hardware = AD1816A_HW_AD18MAX10; break; case 3: chip->hardware = AD1816A_HW_AD1816A; break; default: chip->hardware = AD1816A_HW_AUTO; } spin_unlock_irqrestore(&chip->lock, flags); return 0; }
static void snd_ad1816a_write_mask(struct snd_ad1816a *chip, unsigned char reg, unsigned short mask, unsigned short value) { snd_ad1816a_write(chip, reg, (value & mask) | (snd_ad1816a_read(chip, reg) & ~mask)); }