Loading include/sound/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,8 @@ struct snd_card { int user_ctl_count; /* count of all user controls */ struct list_head controls; /* all controls for this card */ struct list_head ctl_files; /* active control files */ struct mutex user_ctl_lock; /* protects user controls against concurrent access */ struct snd_info_entry *proc_root; /* root for soundcard specific files */ struct snd_info_entry *proc_id; /* the card id */ Loading sound/core/control.c +51 −27 Original line number Diff line number Diff line Loading @@ -288,6 +288,10 @@ static bool snd_ctl_remove_numid_conflict(struct snd_card *card, { struct snd_kcontrol *kctl; /* Make sure that the ids assigned to the control do not wrap around */ if (card->last_numid >= UINT_MAX - count) card->last_numid = 0; list_for_each_entry(kctl, &card->controls, list) { if (kctl->id.numid < card->last_numid + 1 + count && kctl->id.numid + kctl->count > card->last_numid + 1) { Loading Loading @@ -330,6 +334,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { struct snd_ctl_elem_id id; unsigned int idx; unsigned int count; int err = -EINVAL; if (! kcontrol) Loading @@ -337,6 +342,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) if (snd_BUG_ON(!card || !kcontrol->info)) goto error; id = kcontrol->id; if (id.index > UINT_MAX - kcontrol->count) goto error; down_write(&card->controls_rwsem); if (snd_ctl_find_id(card, &id)) { up_write(&card->controls_rwsem); Loading @@ -358,8 +366,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) card->controls_count += kcontrol->count; kcontrol->id.numid = card->last_numid + 1; card->last_numid += kcontrol->count; count = kcontrol->count; up_write(&card->controls_rwsem); for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) for (idx = 0; idx < count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; Loading Loading @@ -388,6 +397,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace) { struct snd_ctl_elem_id id; unsigned int count; unsigned int idx; struct snd_kcontrol *old; int ret; Loading Loading @@ -423,8 +433,9 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, card->controls_count += kcontrol->count; kcontrol->id.numid = card->last_numid + 1; card->last_numid += kcontrol->count; count = kcontrol->count; up_write(&card->controls_rwsem); for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) for (idx = 0; idx < count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; Loading Loading @@ -897,9 +908,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, result = kctl->put(kctl, control); } if (result > 0) { struct snd_ctl_elem_id id = control->id; up_read(&card->controls_rwsem); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); return 0; } } Loading Loading @@ -991,6 +1002,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, struct user_element { struct snd_ctl_elem_info info; struct snd_card *card; void *elem_data; /* element data */ unsigned long elem_data_size; /* size of element data in bytes */ void *tlv_data; /* TLV data */ Loading Loading @@ -1034,7 +1046,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, { struct user_element *ue = kcontrol->private_data; mutex_lock(&ue->card->user_ctl_lock); memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); mutex_unlock(&ue->card->user_ctl_lock); return 0; } Loading @@ -1044,9 +1058,11 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, int change; struct user_element *ue = kcontrol->private_data; mutex_lock(&ue->card->user_ctl_lock); change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; if (change) memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); mutex_unlock(&ue->card->user_ctl_lock); return change; } Loading @@ -1066,19 +1082,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, new_data = memdup_user(tlv, size); if (IS_ERR(new_data)) return PTR_ERR(new_data); mutex_lock(&ue->card->user_ctl_lock); change = ue->tlv_data_size != size; if (!change) change = memcmp(ue->tlv_data, new_data, size); kfree(ue->tlv_data); ue->tlv_data = new_data; ue->tlv_data_size = size; mutex_unlock(&ue->card->user_ctl_lock); } else { if (! ue->tlv_data_size || ! ue->tlv_data) return -ENXIO; if (size < ue->tlv_data_size) return -ENOSPC; int ret = 0; mutex_lock(&ue->card->user_ctl_lock); if (!ue->tlv_data_size || !ue->tlv_data) { ret = -ENXIO; goto err_unlock; } if (size < ue->tlv_data_size) { ret = -ENOSPC; goto err_unlock; } if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) return -EFAULT; ret = -EFAULT; err_unlock: mutex_unlock(&ue->card->user_ctl_lock); if (ret) return ret; } return change; } Loading Loading @@ -1136,8 +1165,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, struct user_element *ue; int idx, err; if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS) return -ENOMEM; if (info->count < 1) return -EINVAL; access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : Loading @@ -1146,21 +1173,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)); info->id.numid = 0; memset(&kctl, 0, sizeof(kctl)); down_write(&card->controls_rwsem); _kctl = snd_ctl_find_id(card, &info->id); err = 0; if (_kctl) { if (replace) err = snd_ctl_remove(card, _kctl); else err = -EBUSY; } else { if (replace) err = -ENOENT; } up_write(&card->controls_rwsem); if (err < 0) if (replace) { err = snd_ctl_remove_user_ctl(file, &info->id); if (err) return err; } if (card->user_ctl_count >= MAX_USER_CONTROLS) return -ENOMEM; memcpy(&kctl.id, &info->id, sizeof(info->id)); kctl.count = info->owner ? info->owner : 1; access |= SNDRV_CTL_ELEM_ACCESS_USER; Loading Loading @@ -1210,6 +1232,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); if (ue == NULL) return -ENOMEM; ue->card = card; ue->info = *info; ue->info.access = 0; ue->elem_data = (char *)ue + sizeof(*ue); Loading Loading @@ -1321,8 +1344,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, } err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); if (err > 0) { struct snd_ctl_elem_id id = kctl->id; up_read(&card->controls_rwsem); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); return 0; } } else { Loading sound/core/init.c +1 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid, INIT_LIST_HEAD(&card->devices); init_rwsem(&card->controls_rwsem); rwlock_init(&card->ctl_files_rwlock); mutex_init(&card->user_ctl_lock); INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); Loading sound/soc/codecs/Kconfig +10 −2 Original line number Diff line number Diff line Loading @@ -225,11 +225,11 @@ config SND_SOC_ADAU1373 config SND_SOC_ADAU1701 tristate "Analog Devices ADAU1701 CODEC" depends on I2C select SND_SOC_SIGMADSP select SND_SOC_SIGMADSP_I2C config SND_SOC_ADAU17X1 tristate select SND_SOC_SIGMADSP select SND_SOC_SIGMADSP_REGMAP config SND_SOC_ADAU1761 tristate Loading Loading @@ -476,6 +476,14 @@ config SND_SOC_SIGMADSP tristate select CRC32 config SND_SOC_SIGMADSP_I2C tristate select SND_SOC_SIGMADSP config SND_SOC_SIGMADSP_REGMAP tristate select SND_SOC_SIGMADSP config SND_SOC_SIRF_AUDIO_CODEC tristate "SiRF SoC internal audio codec" select REGMAP_MMIO Loading sound/soc/codecs/Makefile +4 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o snd-soc-si476x-objs := si476x.o snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o snd-soc-sn95031-objs := sn95031.o Loading Loading @@ -240,6 +242,8 @@ obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o Loading Loading
include/sound/core.h +2 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,8 @@ struct snd_card { int user_ctl_count; /* count of all user controls */ struct list_head controls; /* all controls for this card */ struct list_head ctl_files; /* active control files */ struct mutex user_ctl_lock; /* protects user controls against concurrent access */ struct snd_info_entry *proc_root; /* root for soundcard specific files */ struct snd_info_entry *proc_id; /* the card id */ Loading
sound/core/control.c +51 −27 Original line number Diff line number Diff line Loading @@ -288,6 +288,10 @@ static bool snd_ctl_remove_numid_conflict(struct snd_card *card, { struct snd_kcontrol *kctl; /* Make sure that the ids assigned to the control do not wrap around */ if (card->last_numid >= UINT_MAX - count) card->last_numid = 0; list_for_each_entry(kctl, &card->controls, list) { if (kctl->id.numid < card->last_numid + 1 + count && kctl->id.numid + kctl->count > card->last_numid + 1) { Loading Loading @@ -330,6 +334,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { struct snd_ctl_elem_id id; unsigned int idx; unsigned int count; int err = -EINVAL; if (! kcontrol) Loading @@ -337,6 +342,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) if (snd_BUG_ON(!card || !kcontrol->info)) goto error; id = kcontrol->id; if (id.index > UINT_MAX - kcontrol->count) goto error; down_write(&card->controls_rwsem); if (snd_ctl_find_id(card, &id)) { up_write(&card->controls_rwsem); Loading @@ -358,8 +366,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) card->controls_count += kcontrol->count; kcontrol->id.numid = card->last_numid + 1; card->last_numid += kcontrol->count; count = kcontrol->count; up_write(&card->controls_rwsem); for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) for (idx = 0; idx < count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; Loading Loading @@ -388,6 +397,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace) { struct snd_ctl_elem_id id; unsigned int count; unsigned int idx; struct snd_kcontrol *old; int ret; Loading Loading @@ -423,8 +433,9 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, card->controls_count += kcontrol->count; kcontrol->id.numid = card->last_numid + 1; card->last_numid += kcontrol->count; count = kcontrol->count; up_write(&card->controls_rwsem); for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) for (idx = 0; idx < count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; Loading Loading @@ -897,9 +908,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, result = kctl->put(kctl, control); } if (result > 0) { struct snd_ctl_elem_id id = control->id; up_read(&card->controls_rwsem); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); return 0; } } Loading Loading @@ -991,6 +1002,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, struct user_element { struct snd_ctl_elem_info info; struct snd_card *card; void *elem_data; /* element data */ unsigned long elem_data_size; /* size of element data in bytes */ void *tlv_data; /* TLV data */ Loading Loading @@ -1034,7 +1046,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, { struct user_element *ue = kcontrol->private_data; mutex_lock(&ue->card->user_ctl_lock); memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); mutex_unlock(&ue->card->user_ctl_lock); return 0; } Loading @@ -1044,9 +1058,11 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, int change; struct user_element *ue = kcontrol->private_data; mutex_lock(&ue->card->user_ctl_lock); change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; if (change) memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); mutex_unlock(&ue->card->user_ctl_lock); return change; } Loading @@ -1066,19 +1082,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, new_data = memdup_user(tlv, size); if (IS_ERR(new_data)) return PTR_ERR(new_data); mutex_lock(&ue->card->user_ctl_lock); change = ue->tlv_data_size != size; if (!change) change = memcmp(ue->tlv_data, new_data, size); kfree(ue->tlv_data); ue->tlv_data = new_data; ue->tlv_data_size = size; mutex_unlock(&ue->card->user_ctl_lock); } else { if (! ue->tlv_data_size || ! ue->tlv_data) return -ENXIO; if (size < ue->tlv_data_size) return -ENOSPC; int ret = 0; mutex_lock(&ue->card->user_ctl_lock); if (!ue->tlv_data_size || !ue->tlv_data) { ret = -ENXIO; goto err_unlock; } if (size < ue->tlv_data_size) { ret = -ENOSPC; goto err_unlock; } if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) return -EFAULT; ret = -EFAULT; err_unlock: mutex_unlock(&ue->card->user_ctl_lock); if (ret) return ret; } return change; } Loading Loading @@ -1136,8 +1165,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, struct user_element *ue; int idx, err; if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS) return -ENOMEM; if (info->count < 1) return -EINVAL; access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : Loading @@ -1146,21 +1173,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)); info->id.numid = 0; memset(&kctl, 0, sizeof(kctl)); down_write(&card->controls_rwsem); _kctl = snd_ctl_find_id(card, &info->id); err = 0; if (_kctl) { if (replace) err = snd_ctl_remove(card, _kctl); else err = -EBUSY; } else { if (replace) err = -ENOENT; } up_write(&card->controls_rwsem); if (err < 0) if (replace) { err = snd_ctl_remove_user_ctl(file, &info->id); if (err) return err; } if (card->user_ctl_count >= MAX_USER_CONTROLS) return -ENOMEM; memcpy(&kctl.id, &info->id, sizeof(info->id)); kctl.count = info->owner ? info->owner : 1; access |= SNDRV_CTL_ELEM_ACCESS_USER; Loading Loading @@ -1210,6 +1232,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); if (ue == NULL) return -ENOMEM; ue->card = card; ue->info = *info; ue->info.access = 0; ue->elem_data = (char *)ue + sizeof(*ue); Loading Loading @@ -1321,8 +1344,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, } err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); if (err > 0) { struct snd_ctl_elem_id id = kctl->id; up_read(&card->controls_rwsem); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); return 0; } } else { Loading
sound/core/init.c +1 −0 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid, INIT_LIST_HEAD(&card->devices); init_rwsem(&card->controls_rwsem); rwlock_init(&card->ctl_files_rwlock); mutex_init(&card->user_ctl_lock); INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); Loading
sound/soc/codecs/Kconfig +10 −2 Original line number Diff line number Diff line Loading @@ -225,11 +225,11 @@ config SND_SOC_ADAU1373 config SND_SOC_ADAU1701 tristate "Analog Devices ADAU1701 CODEC" depends on I2C select SND_SOC_SIGMADSP select SND_SOC_SIGMADSP_I2C config SND_SOC_ADAU17X1 tristate select SND_SOC_SIGMADSP select SND_SOC_SIGMADSP_REGMAP config SND_SOC_ADAU1761 tristate Loading Loading @@ -476,6 +476,14 @@ config SND_SOC_SIGMADSP tristate select CRC32 config SND_SOC_SIGMADSP_I2C tristate select SND_SOC_SIGMADSP config SND_SOC_SIGMADSP_REGMAP tristate select SND_SOC_SIGMADSP config SND_SOC_SIRF_AUDIO_CODEC tristate "SiRF SoC internal audio codec" select REGMAP_MMIO Loading
sound/soc/codecs/Makefile +4 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o snd-soc-alc5632-objs := alc5632.o snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o snd-soc-si476x-objs := si476x.o snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o snd-soc-sn95031-objs := sn95031.o Loading Loading @@ -240,6 +242,8 @@ obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o Loading