Commit 9c0df338 authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] Remove spinlock in callbacks

AC97 Codec Core,AK4531 codec
Removed spinlocks in callback, use sempahore instead since all ac97
callbacks are supposed to be non-atomic.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 394bc516
......@@ -480,8 +480,8 @@ struct _snd_ac97 {
snd_info_entry_t *proc_regs;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
spinlock_t reg_lock;
struct semaphore mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */
struct semaphore reg_mutex;
struct semaphore page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */
unsigned short num; /* number of codec: 0 = primary, 1 = secondary */
unsigned short addr; /* physical address of codec [0-3] */
unsigned int id; /* identification of codec */
......
......@@ -72,7 +72,7 @@ struct _snd_ak4531 {
void (*private_free) (ak4531_t *ak4531);
/* --- */
unsigned char regs[0x20];
spinlock_t reg_lock;
struct semaphore reg_mutex;
};
int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531);
......
......@@ -333,11 +333,11 @@ void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value
{
if (!snd_ac97_valid_reg(ac97, reg))
return;
spin_lock(&ac97->reg_lock);
down(&ac97->reg_mutex);
ac97->regs[reg] = value;
spin_unlock(&ac97->reg_lock);
ac97->bus->ops->write(ac97, reg, value);
set_bit(reg, ac97->reg_accessed);
up(&ac97->reg_mutex);
}
/**
......@@ -358,14 +358,13 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
if (!snd_ac97_valid_reg(ac97, reg))
return -EINVAL;
spin_lock(&ac97->reg_lock);
down(&ac97->reg_mutex);
change = ac97->regs[reg] != value;
if (change) {
ac97->regs[reg] = value;
spin_unlock(&ac97->reg_lock);
ac97->bus->ops->write(ac97, reg, value);
} else
spin_unlock(&ac97->reg_lock);
}
up(&ac97->reg_mutex);
return change;
}
......@@ -385,20 +384,29 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
{
int change;
unsigned short old, new;
if (!snd_ac97_valid_reg(ac97, reg))
return -EINVAL;
spin_lock(&ac97->reg_lock);
down(&ac97->reg_mutex);
change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
up(&ac97->reg_mutex);
return change;
}
/* no lock version - see snd_ac97_updat_bits() */
int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
unsigned short mask, unsigned short value)
{
int change;
unsigned short old, new;
old = snd_ac97_read_cache(ac97, reg);
new = (old & ~mask) | value;
change = old != new;
if (change) {
ac97->regs[reg] = new;
spin_unlock(&ac97->reg_lock);
ac97->bus->ops->write(ac97, reg, new);
} else
spin_unlock(&ac97->reg_lock);
}
return change;
}
......@@ -407,15 +415,14 @@ static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned sho
int change;
unsigned short old, new, cfg;
down(&ac97->mutex);
spin_lock(&ac97->reg_lock);
down(&ac97->page_mutex);
old = ac97->spec.ad18xx.pcmreg[codec];
new = (old & ~mask) | value;
cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
change = old != new;
if (change) {
down(&ac97->reg_mutex);
cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG);
ac97->spec.ad18xx.pcmreg[codec] = new;
spin_unlock(&ac97->reg_lock);
/* select single codec */
ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
(cfg & ~0x7000) |
......@@ -425,9 +432,9 @@ static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned sho
/* select all codecs */
ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG,
cfg | 0x7000);
} else
spin_unlock(&ac97->reg_lock);
up(&ac97->mutex);
up(&ac97->reg_mutex);
}
up(&ac97->page_mutex);
return change;
}
......@@ -611,12 +618,12 @@ static int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *
(reg >= 0x60 && reg < 0x70)) {
unsigned short page_save;
unsigned short page = (kcontrol->private_value >> 25) & 0x0f;
down(&ac97->mutex); /* lock paging */
down(&ac97->page_mutex); /* lock paging */
page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
err = func(kcontrol, ucontrol);
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
up(&ac97->mutex); /* unlock paging */
up(&ac97->page_mutex); /* unlock paging */
} else
err = func(kcontrol, ucontrol);
return err;
......@@ -760,12 +767,12 @@ static int snd_ac97_spdif_default_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
{
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
spin_lock(&ac97->reg_lock);
down(&ac97->reg_mutex);
ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff;
ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff;
ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff;
ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff;
spin_unlock(&ac97->reg_lock);
up(&ac97->reg_mutex);
return 0;
}
......@@ -776,7 +783,6 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
unsigned short val = 0;
int change;
spin_lock(&ac97->reg_lock);
new = val = ucontrol->value.iec958.status[0] & (IEC958_AES0_PROFESSIONAL|IEC958_AES0_NONAUDIO);
if (ucontrol->value.iec958.status[0] & IEC958_AES0_PROFESSIONAL) {
new |= ucontrol->value.iec958.status[0] & (IEC958_AES0_PRO_FS|IEC958_AES0_PRO_EMPHASIS_5015);
......@@ -805,9 +811,9 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
}
}
down(&ac97->reg_mutex);
change = ac97->spdif_status != new;
ac97->spdif_status = new;
spin_unlock(&ac97->reg_lock);
if (ac97->flags & AC97_CS_SPDIF) {
int x = (val >> 12) & 0x03;
......@@ -816,23 +822,24 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
case 2: x = 0; break; // 48.0
default: x = 0; break; // illegal.
}
change |= snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
change |= snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
} else if (ac97->flags & AC97_CX_SPDIF) {
int v;
v = new & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
v |= new & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
change |= snd_ac97_update_bits(ac97, AC97_CXR_AUDIO_MISC,
AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
v);
change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC,
AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
v);
} else {
unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
change |= snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val);
change |= snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val);
if (extst & AC97_EA_SPDIF) {
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
}
}
up(&ac97->reg_mutex);
return change;
}
......@@ -841,30 +848,30 @@ static int snd_ac97_put_spsa(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uco
{
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 8) & 0x0f; /* single only */
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
// int invert = (kcontrol->private_value >> 24) & 0xff;
unsigned short value, old, new;
int change;
value = (ucontrol->value.integer.value[0] & mask);
down(&ac97->reg_mutex);
mask <<= shift;
value <<= shift;
spin_lock(&ac97->reg_lock);
old = snd_ac97_read_cache(ac97, reg);
new = (old & ~mask) | value;
spin_unlock(&ac97->reg_lock);
change = old != new;
if (old != new) {
int change;
if (change) {
unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
change = snd_ac97_update_bits(ac97, reg, mask, value);
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
change = snd_ac97_update_bits_nolock(ac97, reg, mask, value);
if (extst & AC97_EA_SPDIF)
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
return change;
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */
}
return 0;
up(&ac97->reg_mutex);
return change;
}
const snd_kcontrol_new_t snd_ac97_controls_spdif[5] = {
......@@ -974,10 +981,10 @@ static int snd_ac97_ad18xx_pcm_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_ele
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
int codec = kcontrol->private_value & 3;
spin_lock(&ac97->reg_lock);
down(&ac97->page_mutex);
ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
spin_unlock(&ac97->reg_lock);
up(&ac97->page_mutex);
return 0;
}
......@@ -1902,8 +1909,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
ac97->limited_regs = template->limited_regs;
memcpy(ac97->reg_accessed, template->reg_accessed, sizeof(ac97->reg_accessed));
bus->codec[ac97->num] = ac97;
spin_lock_init(&ac97->reg_lock);
init_MUTEX(&ac97->mutex);
init_MUTEX(&ac97->reg_mutex);
init_MUTEX(&ac97->page_mutex);
if (ac97->pci) {
pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_VENDOR_ID, &ac97->subsystem_vendor);
......
......@@ -52,6 +52,9 @@ void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
void snd_ac97_restore_status(ac97_t *ac97);
void snd_ac97_restore_iec958(ac97_t *ac97);
int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
unsigned short mask, unsigned short value);
/* ac97_proc.c */
#ifdef CONFIG_PROC_FS
void snd_ac97_bus_proc_init(ac97_bus_t * ac97);
......
......@@ -55,12 +55,12 @@ static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned shor
unsigned short page_save;
int ret;
down(&ac97->mutex);
down(&ac97->page_mutex);
page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
ret = snd_ac97_update_bits(ac97, reg, mask, value);
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
up(&ac97->mutex); /* unlock paging */
up(&ac97->page_mutex); /* unlock paging */
return ret;
}
......
......@@ -206,14 +206,12 @@ static int set_spdif_rate(ac97_t *ac97, unsigned short rate)
mask = AC97_SC_SPSR_MASK;
}
spin_lock(&ac97->reg_lock);
down(&ac97->reg_mutex);
old = snd_ac97_read(ac97, reg) & mask;
spin_unlock(&ac97->reg_lock);
if (old != bits) {
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
snd_ac97_update_bits(ac97, reg, mask, bits);
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0);
snd_ac97_update_bits_nolock(ac97, reg, mask, bits);
/* update the internal spdif bits */
spin_lock(&ac97->reg_lock);
sbits = ac97->spdif_status;
if (sbits & IEC958_AES0_PROFESSIONAL) {
sbits &= ~IEC958_AES0_PRO_FS;
......@@ -231,9 +229,9 @@ static int set_spdif_rate(ac97_t *ac97, unsigned short rate)
}
}
ac97->spdif_status = sbits;
spin_unlock(&ac97->reg_lock);
}
snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF);
up(&ac97->reg_mutex);
return 0;
}
......
......@@ -296,7 +296,7 @@ static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buff
{
ac97_t *ac97 = entry->private_data;
down(&ac97->mutex);
down(&ac97->page_mutex);
if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
int idx;
for (idx = 0; idx < 3; idx++)
......@@ -322,7 +322,7 @@ static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buff
} else {
snd_ac97_proc_read_main(ac97, buffer, 0);
}
up(&ac97->mutex);
up(&ac97->page_mutex);
}
#ifdef CONFIG_SND_DEBUG
......@@ -332,7 +332,7 @@ static void snd_ac97_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t
ac97_t *ac97 = entry->private_data;
char line[64];
unsigned int reg, val;
down(&ac97->mutex);
down(&ac97->page_mutex);
while (!snd_info_get_line(buffer, line, sizeof(line))) {
if (sscanf(line, "%x %x", &reg, &val) != 2)
continue;
......@@ -340,7 +340,7 @@ static void snd_ac97_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t
if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff)
snd_ac97_write_cache(ac97, reg, val);
}
up(&ac97->mutex);
up(&ac97->page_mutex);
}
#endif
......@@ -359,7 +359,7 @@ static void snd_ac97_proc_regs_read(snd_info_entry_t *entry,
{
ac97_t *ac97 = entry->private_data;
down(&ac97->mutex);
down(&ac97->page_mutex);
if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86
int idx;
......@@ -375,7 +375,7 @@ static void snd_ac97_proc_regs_read(snd_info_entry_t *entry,
} else {
snd_ac97_proc_regs_read_main(ac97, buffer, 0);
}
up(&ac97->mutex);
up(&ac97->page_mutex);
}
void snd_ac97_proc_init(ac97_t * ac97)
......
......@@ -72,16 +72,15 @@ static int snd_ak4531_info_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t
static int snd_ak4531_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0x07;
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
int val;
spin_lock_irqsave(&ak4531->reg_lock, flags);
down(&ak4531->reg_mutex);
val = (ak4531->regs[reg] >> shift) & mask;
spin_unlock_irqrestore(&ak4531->reg_lock, flags);
up(&ak4531->reg_mutex);
if (invert) {
val = mask - val;
}
......@@ -92,7 +91,6 @@ static int snd_ak4531_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
static int snd_ak4531_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg = kcontrol->private_value & 0xff;
int shift = (kcontrol->private_value >> 16) & 0x07;
int mask = (kcontrol->private_value >> 24) & 0xff;
......@@ -105,11 +103,11 @@ static int snd_ak4531_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
val = mask - val;
}
val <<= shift;
spin_lock_irqsave(&ak4531->reg_lock, flags);
down(&ak4531->reg_mutex);
val = (ak4531->regs[reg] & ~(mask << shift)) | val;
change = val != ak4531->regs[reg];
ak4531->write(ak4531, reg, ak4531->regs[reg] = val);
spin_unlock_irqrestore(&ak4531->reg_lock, flags);
up(&ak4531->reg_mutex);
return change;
}
......@@ -133,7 +131,6 @@ static int snd_ak4531_info_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t
static int snd_ak4531_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int left_shift = (kcontrol->private_value >> 16) & 0x07;
......@@ -142,10 +139,10 @@ static int snd_ak4531_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
int invert = (kcontrol->private_value >> 22) & 1;
int left, right;
spin_lock_irqsave(&ak4531->reg_lock, flags);
down(&ak4531->reg_mutex);
left = (ak4531->regs[left_reg] >> left_shift) & mask;
right = (ak4531->regs[right_reg] >> right_shift) & mask;
spin_unlock_irqrestore(&ak4531->reg_lock, flags);
up(&ak4531->reg_mutex);
if (invert) {
left = mask - left;
right = mask - right;
......@@ -158,7 +155,6 @@ static int snd_ak4531_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
static int snd_ak4531_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int left_reg = kcontrol->private_value & 0xff;
int right_reg = (kcontrol->private_value >> 8) & 0xff;
int left_shift = (kcontrol->private_value >> 16) & 0x07;
......@@ -176,7 +172,7 @@ static int snd_ak4531_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
}
left <<= left_shift;
right <<= right_shift;
spin_lock_irqsave(&ak4531->reg_lock, flags);
down(&ak4531->reg_mutex);
if (left_reg == right_reg) {
left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right;
change = left != ak4531->regs[left_reg];
......@@ -188,7 +184,7 @@ static int snd_ak4531_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right);
}
spin_unlock_irqrestore(&ak4531->reg_lock, flags);
up(&ak4531->reg_mutex);
return change;
}
......@@ -210,25 +206,23 @@ static int snd_ak4531_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info
static int snd_ak4531_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg1 = kcontrol->private_value & 0xff;
int reg2 = (kcontrol->private_value >> 8) & 0xff;
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
int right_shift = (kcontrol->private_value >> 24) & 0x0f;
spin_lock_irqsave(&ak4531->reg_lock, flags);
down(&ak4531->reg_mutex);
ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1;
ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1;
ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1;
ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1;
spin_unlock_irqrestore(&ak4531->reg_lock, flags);
up(&ak4531->reg_mutex);
return 0;
}
static int snd_ak4531_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
unsigned long flags;
int reg1 = kcontrol->private_value & 0xff;
int reg2 = (kcontrol->private_value >> 8) & 0xff;
int left_shift = (kcontrol->private_value >> 16) & 0x0f;
......@@ -236,7 +230,7 @@ static int snd_ak4531_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
int change;
int val1, val2;
spin_lock_irqsave(&ak4531->reg_lock, flags);
down(&ak4531->reg_mutex);
val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift));
val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift));
val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
......@@ -246,7 +240,7 @@ static int snd_ak4531_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value
change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2];
ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1);
ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2);
spin_unlock_irqrestore(&ak4531->reg_lock, flags);
up(&ak4531->reg_mutex);
return change;
}
......@@ -367,7 +361,7 @@ int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531)
if (ak4531 == NULL)
return -ENOMEM;
*ak4531 = *_ak4531;
spin_lock_init(&ak4531->reg_lock);
init_MUTEX(&ak4531->reg_mutex);
if ((err = snd_component_add(card, "AK4531")) < 0) {
snd_ak4531_free(ak4531);
return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment