diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-20 00:49:37 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-20 00:49:37 -0400 |
| commit | 4ef61076f849ce13af88670f7362a5c9477c2747 (patch) | |
| tree | 8d1310dc02a00497647852b2f386b8047b447be5 | |
| parent | 0c9bc275304fd1c46584e1e651ce6698e5d61042 (diff) | |
| parent | 8d42fda9ea9820d271a40f0bf7ed436647f2ddb9 (diff) | |
Merge tag 'sound-3.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"The significant part here is a few security fixes for ALSA core
control API by Lars. Besides that, there are a few fixes for ASoC
sigmadsp (again by Lars) for building properly, and small fixes for
ASoC rsnd, MMP, PXA and FSL, in addition to a fix for bogus WARNING in
i915/HD-audio binding"
* tag 'sound-3.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: control: Make sure that id->index does not overflow
ALSA: control: Handle numid overflow
ALSA: control: Don't access controls outside of protected regions
ALSA: control: Fix replacing user controls
ALSA: control: Protect user controls against concurrent access
drm/i915, HD-audio: Don't continue probing when nomodeset is given
ASoC: fsl: Fix build problem
ASoC: rsnd: fixup index of src/dst mod when capture
ASoC: fsl_spdif: Fix integer overflow when calculating divisors
ASoC: fsl_spdif: Fix incorrect usage of regmap_read()
ASoC: dapm: Make sure register value is in sync with DAPM kcontrol state
ASoC: sigmadsp: Split regmap and I2C support into separate modules
ASoC: MMP audio needs sram support
ASoC: pxa: add I2C dependencies as needed
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 14 | ||||
| -rw-r--r-- | include/drm/i915_powerwell.h | 4 | ||||
| -rw-r--r-- | include/sound/core.h | 2 | ||||
| -rw-r--r-- | sound/core/control.c | 78 | ||||
| -rw-r--r-- | sound/core/init.c | 1 | ||||
| -rw-r--r-- | sound/pci/hda/hda_i915.c | 12 | ||||
| -rw-r--r-- | sound/pci/hda/hda_i915.h | 4 | ||||
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 7 | ||||
| -rw-r--r-- | sound/soc/codecs/Kconfig | 12 | ||||
| -rw-r--r-- | sound/soc/codecs/Makefile | 4 | ||||
| -rw-r--r-- | sound/soc/codecs/sigmadsp-i2c.c | 35 | ||||
| -rw-r--r-- | sound/soc/codecs/sigmadsp-regmap.c | 36 | ||||
| -rw-r--r-- | sound/soc/codecs/sigmadsp.c | 65 | ||||
| -rw-r--r-- | sound/soc/codecs/sigmadsp.h | 20 | ||||
| -rw-r--r-- | sound/soc/fsl/fsl_dma.c | 4 | ||||
| -rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 6 | ||||
| -rw-r--r-- | sound/soc/pxa/Kconfig | 11 | ||||
| -rw-r--r-- | sound/soc/sh/rcar/core.c | 2 | ||||
| -rw-r--r-- | sound/soc/soc-dapm.c | 29 |
19 files changed, 213 insertions, 133 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 769caea97c21..54242e4f6f4c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -6019,30 +6019,32 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
| 6019 | static struct i915_power_domains *hsw_pwr; | 6019 | static struct i915_power_domains *hsw_pwr; |
| 6020 | 6020 | ||
| 6021 | /* Display audio driver power well request */ | 6021 | /* Display audio driver power well request */ |
| 6022 | void i915_request_power_well(void) | 6022 | int i915_request_power_well(void) |
| 6023 | { | 6023 | { |
| 6024 | struct drm_i915_private *dev_priv; | 6024 | struct drm_i915_private *dev_priv; |
| 6025 | 6025 | ||
| 6026 | if (WARN_ON(!hsw_pwr)) | 6026 | if (!hsw_pwr) |
| 6027 | return; | 6027 | return -ENODEV; |
| 6028 | 6028 | ||
| 6029 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, | 6029 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, |
| 6030 | power_domains); | 6030 | power_domains); |
| 6031 | intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); | 6031 | intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); |
| 6032 | return 0; | ||
| 6032 | } | 6033 | } |
| 6033 | EXPORT_SYMBOL_GPL(i915_request_power_well); | 6034 | EXPORT_SYMBOL_GPL(i915_request_power_well); |
| 6034 | 6035 | ||
| 6035 | /* Display audio driver power well release */ | 6036 | /* Display audio driver power well release */ |
| 6036 | void i915_release_power_well(void) | 6037 | int i915_release_power_well(void) |
| 6037 | { | 6038 | { |
| 6038 | struct drm_i915_private *dev_priv; | 6039 | struct drm_i915_private *dev_priv; |
| 6039 | 6040 | ||
| 6040 | if (WARN_ON(!hsw_pwr)) | 6041 | if (!hsw_pwr) |
| 6041 | return; | 6042 | return -ENODEV; |
| 6042 | 6043 | ||
| 6043 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, | 6044 | dev_priv = container_of(hsw_pwr, struct drm_i915_private, |
| 6044 | power_domains); | 6045 | power_domains); |
| 6045 | intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); | 6046 | intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); |
| 6047 | return 0; | ||
| 6046 | } | 6048 | } |
| 6047 | EXPORT_SYMBOL_GPL(i915_release_power_well); | 6049 | EXPORT_SYMBOL_GPL(i915_release_power_well); |
| 6048 | 6050 | ||
diff --git a/include/drm/i915_powerwell.h b/include/drm/i915_powerwell.h index cfdc884405b7..2baba9996094 100644 --- a/include/drm/i915_powerwell.h +++ b/include/drm/i915_powerwell.h | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #define _I915_POWERWELL_H_ | 30 | #define _I915_POWERWELL_H_ |
| 31 | 31 | ||
| 32 | /* For use by hda_i915 driver */ | 32 | /* For use by hda_i915 driver */ |
| 33 | extern void i915_request_power_well(void); | 33 | extern int i915_request_power_well(void); |
| 34 | extern void i915_release_power_well(void); | 34 | extern int i915_release_power_well(void); |
| 35 | 35 | ||
| 36 | #endif /* _I915_POWERWELL_H_ */ | 36 | #endif /* _I915_POWERWELL_H_ */ |
diff --git a/include/sound/core.h b/include/sound/core.h index eedda2cdfe57..1df3f2fe5350 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
| @@ -116,6 +116,8 @@ struct snd_card { | |||
| 116 | int user_ctl_count; /* count of all user controls */ | 116 | int user_ctl_count; /* count of all user controls */ |
| 117 | struct list_head controls; /* all controls for this card */ | 117 | struct list_head controls; /* all controls for this card */ |
| 118 | struct list_head ctl_files; /* active control files */ | 118 | struct list_head ctl_files; /* active control files */ |
| 119 | struct mutex user_ctl_lock; /* protects user controls against | ||
| 120 | concurrent access */ | ||
| 119 | 121 | ||
| 120 | struct snd_info_entry *proc_root; /* root for soundcard specific files */ | 122 | struct snd_info_entry *proc_root; /* root for soundcard specific files */ |
| 121 | struct snd_info_entry *proc_id; /* the card id */ | 123 | struct snd_info_entry *proc_id; /* the card id */ |
diff --git a/sound/core/control.c b/sound/core/control.c index f038f5afafe2..f0b0e14497a5 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
| @@ -288,6 +288,10 @@ static bool snd_ctl_remove_numid_conflict(struct snd_card *card, | |||
| 288 | { | 288 | { |
| 289 | struct snd_kcontrol *kctl; | 289 | struct snd_kcontrol *kctl; |
| 290 | 290 | ||
| 291 | /* Make sure that the ids assigned to the control do not wrap around */ | ||
| 292 | if (card->last_numid >= UINT_MAX - count) | ||
| 293 | card->last_numid = 0; | ||
| 294 | |||
| 291 | list_for_each_entry(kctl, &card->controls, list) { | 295 | list_for_each_entry(kctl, &card->controls, list) { |
| 292 | if (kctl->id.numid < card->last_numid + 1 + count && | 296 | if (kctl->id.numid < card->last_numid + 1 + count && |
| 293 | kctl->id.numid + kctl->count > card->last_numid + 1) { | 297 | kctl->id.numid + kctl->count > card->last_numid + 1) { |
| @@ -330,6 +334,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
| 330 | { | 334 | { |
| 331 | struct snd_ctl_elem_id id; | 335 | struct snd_ctl_elem_id id; |
| 332 | unsigned int idx; | 336 | unsigned int idx; |
| 337 | unsigned int count; | ||
| 333 | int err = -EINVAL; | 338 | int err = -EINVAL; |
| 334 | 339 | ||
| 335 | if (! kcontrol) | 340 | if (! kcontrol) |
| @@ -337,6 +342,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
| 337 | if (snd_BUG_ON(!card || !kcontrol->info)) | 342 | if (snd_BUG_ON(!card || !kcontrol->info)) |
| 338 | goto error; | 343 | goto error; |
| 339 | id = kcontrol->id; | 344 | id = kcontrol->id; |
| 345 | if (id.index > UINT_MAX - kcontrol->count) | ||
| 346 | goto error; | ||
| 347 | |||
| 340 | down_write(&card->controls_rwsem); | 348 | down_write(&card->controls_rwsem); |
| 341 | if (snd_ctl_find_id(card, &id)) { | 349 | if (snd_ctl_find_id(card, &id)) { |
| 342 | up_write(&card->controls_rwsem); | 350 | up_write(&card->controls_rwsem); |
| @@ -358,8 +366,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
| 358 | card->controls_count += kcontrol->count; | 366 | card->controls_count += kcontrol->count; |
| 359 | kcontrol->id.numid = card->last_numid + 1; | 367 | kcontrol->id.numid = card->last_numid + 1; |
| 360 | card->last_numid += kcontrol->count; | 368 | card->last_numid += kcontrol->count; |
| 369 | count = kcontrol->count; | ||
| 361 | up_write(&card->controls_rwsem); | 370 | up_write(&card->controls_rwsem); |
| 362 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | 371 | for (idx = 0; idx < count; idx++, id.index++, id.numid++) |
| 363 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | 372 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); |
| 364 | return 0; | 373 | return 0; |
| 365 | 374 | ||
| @@ -388,6 +397,7 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, | |||
| 388 | bool add_on_replace) | 397 | bool add_on_replace) |
| 389 | { | 398 | { |
| 390 | struct snd_ctl_elem_id id; | 399 | struct snd_ctl_elem_id id; |
| 400 | unsigned int count; | ||
| 391 | unsigned int idx; | 401 | unsigned int idx; |
| 392 | struct snd_kcontrol *old; | 402 | struct snd_kcontrol *old; |
| 393 | int ret; | 403 | int ret; |
| @@ -423,8 +433,9 @@ add: | |||
| 423 | card->controls_count += kcontrol->count; | 433 | card->controls_count += kcontrol->count; |
| 424 | kcontrol->id.numid = card->last_numid + 1; | 434 | kcontrol->id.numid = card->last_numid + 1; |
| 425 | card->last_numid += kcontrol->count; | 435 | card->last_numid += kcontrol->count; |
| 436 | count = kcontrol->count; | ||
| 426 | up_write(&card->controls_rwsem); | 437 | up_write(&card->controls_rwsem); |
| 427 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | 438 | for (idx = 0; idx < count; idx++, id.index++, id.numid++) |
| 428 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | 439 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); |
| 429 | return 0; | 440 | return 0; |
| 430 | 441 | ||
| @@ -897,9 +908,9 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, | |||
| 897 | result = kctl->put(kctl, control); | 908 | result = kctl->put(kctl, control); |
| 898 | } | 909 | } |
| 899 | if (result > 0) { | 910 | if (result > 0) { |
| 911 | struct snd_ctl_elem_id id = control->id; | ||
| 900 | up_read(&card->controls_rwsem); | 912 | up_read(&card->controls_rwsem); |
| 901 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, | 913 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); |
| 902 | &control->id); | ||
| 903 | return 0; | 914 | return 0; |
| 904 | } | 915 | } |
| 905 | } | 916 | } |
| @@ -991,6 +1002,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, | |||
| 991 | 1002 | ||
| 992 | struct user_element { | 1003 | struct user_element { |
| 993 | struct snd_ctl_elem_info info; | 1004 | struct snd_ctl_elem_info info; |
| 1005 | struct snd_card *card; | ||
| 994 | void *elem_data; /* element data */ | 1006 | void *elem_data; /* element data */ |
| 995 | unsigned long elem_data_size; /* size of element data in bytes */ | 1007 | unsigned long elem_data_size; /* size of element data in bytes */ |
| 996 | void *tlv_data; /* TLV data */ | 1008 | void *tlv_data; /* TLV data */ |
| @@ -1034,7 +1046,9 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, | |||
| 1034 | { | 1046 | { |
| 1035 | struct user_element *ue = kcontrol->private_data; | 1047 | struct user_element *ue = kcontrol->private_data; |
| 1036 | 1048 | ||
| 1049 | mutex_lock(&ue->card->user_ctl_lock); | ||
| 1037 | memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); | 1050 | memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); |
| 1051 | mutex_unlock(&ue->card->user_ctl_lock); | ||
| 1038 | return 0; | 1052 | return 0; |
| 1039 | } | 1053 | } |
| 1040 | 1054 | ||
| @@ -1043,10 +1057,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, | |||
| 1043 | { | 1057 | { |
| 1044 | int change; | 1058 | int change; |
| 1045 | struct user_element *ue = kcontrol->private_data; | 1059 | struct user_element *ue = kcontrol->private_data; |
| 1046 | 1060 | ||
| 1061 | mutex_lock(&ue->card->user_ctl_lock); | ||
| 1047 | change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; | 1062 | change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; |
| 1048 | if (change) | 1063 | if (change) |
| 1049 | memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); | 1064 | memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); |
| 1065 | mutex_unlock(&ue->card->user_ctl_lock); | ||
| 1050 | return change; | 1066 | return change; |
| 1051 | } | 1067 | } |
| 1052 | 1068 | ||
| @@ -1066,19 +1082,32 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, | |||
| 1066 | new_data = memdup_user(tlv, size); | 1082 | new_data = memdup_user(tlv, size); |
| 1067 | if (IS_ERR(new_data)) | 1083 | if (IS_ERR(new_data)) |
| 1068 | return PTR_ERR(new_data); | 1084 | return PTR_ERR(new_data); |
| 1085 | mutex_lock(&ue->card->user_ctl_lock); | ||
| 1069 | change = ue->tlv_data_size != size; | 1086 | change = ue->tlv_data_size != size; |
| 1070 | if (!change) | 1087 | if (!change) |
| 1071 | change = memcmp(ue->tlv_data, new_data, size); | 1088 | change = memcmp(ue->tlv_data, new_data, size); |
| 1072 | kfree(ue->tlv_data); | 1089 | kfree(ue->tlv_data); |
| 1073 | ue->tlv_data = new_data; | 1090 | ue->tlv_data = new_data; |
| 1074 | ue->tlv_data_size = size; | 1091 | ue->tlv_data_size = size; |
| 1092 | mutex_unlock(&ue->card->user_ctl_lock); | ||
| 1075 | } else { | 1093 | } else { |
| 1076 | if (! ue->tlv_data_size || ! ue->tlv_data) | 1094 | int ret = 0; |
| 1077 | return -ENXIO; | 1095 | |
| 1078 | if (size < ue->tlv_data_size) | 1096 | mutex_lock(&ue->card->user_ctl_lock); |
| 1079 | return -ENOSPC; | 1097 | if (!ue->tlv_data_size || !ue->tlv_data) { |
| 1098 | ret = -ENXIO; | ||
| 1099 | goto err_unlock; | ||
| 1100 | } | ||
| 1101 | if (size < ue->tlv_data_size) { | ||
| 1102 | ret = -ENOSPC; | ||
| 1103 | goto err_unlock; | ||
| 1104 | } | ||
| 1080 | if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) | 1105 | if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) |
| 1081 | return -EFAULT; | 1106 | ret = -EFAULT; |
| 1107 | err_unlock: | ||
| 1108 | mutex_unlock(&ue->card->user_ctl_lock); | ||
| 1109 | if (ret) | ||
| 1110 | return ret; | ||
| 1082 | } | 1111 | } |
| 1083 | return change; | 1112 | return change; |
| 1084 | } | 1113 | } |
| @@ -1136,8 +1165,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1136 | struct user_element *ue; | 1165 | struct user_element *ue; |
| 1137 | int idx, err; | 1166 | int idx, err; |
| 1138 | 1167 | ||
| 1139 | if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS) | ||
| 1140 | return -ENOMEM; | ||
| 1141 | if (info->count < 1) | 1168 | if (info->count < 1) |
| 1142 | return -EINVAL; | 1169 | return -EINVAL; |
| 1143 | access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : | 1170 | access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : |
| @@ -1146,21 +1173,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1146 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)); | 1173 | SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)); |
| 1147 | info->id.numid = 0; | 1174 | info->id.numid = 0; |
| 1148 | memset(&kctl, 0, sizeof(kctl)); | 1175 | memset(&kctl, 0, sizeof(kctl)); |
| 1149 | down_write(&card->controls_rwsem); | 1176 | |
| 1150 | _kctl = snd_ctl_find_id(card, &info->id); | 1177 | if (replace) { |
| 1151 | err = 0; | 1178 | err = snd_ctl_remove_user_ctl(file, &info->id); |
| 1152 | if (_kctl) { | 1179 | if (err) |
| 1153 | if (replace) | 1180 | return err; |
| 1154 | err = snd_ctl_remove(card, _kctl); | ||
| 1155 | else | ||
| 1156 | err = -EBUSY; | ||
| 1157 | } else { | ||
| 1158 | if (replace) | ||
| 1159 | err = -ENOENT; | ||
| 1160 | } | 1181 | } |
| 1161 | up_write(&card->controls_rwsem); | 1182 | |
| 1162 | if (err < 0) | 1183 | if (card->user_ctl_count >= MAX_USER_CONTROLS) |
| 1163 | return err; | 1184 | return -ENOMEM; |
| 1185 | |||
| 1164 | memcpy(&kctl.id, &info->id, sizeof(info->id)); | 1186 | memcpy(&kctl.id, &info->id, sizeof(info->id)); |
| 1165 | kctl.count = info->owner ? info->owner : 1; | 1187 | kctl.count = info->owner ? info->owner : 1; |
| 1166 | access |= SNDRV_CTL_ELEM_ACCESS_USER; | 1188 | access |= SNDRV_CTL_ELEM_ACCESS_USER; |
| @@ -1210,6 +1232,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1210 | ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); | 1232 | ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL); |
| 1211 | if (ue == NULL) | 1233 | if (ue == NULL) |
| 1212 | return -ENOMEM; | 1234 | return -ENOMEM; |
| 1235 | ue->card = card; | ||
| 1213 | ue->info = *info; | 1236 | ue->info = *info; |
| 1214 | ue->info.access = 0; | 1237 | ue->info.access = 0; |
| 1215 | ue->elem_data = (char *)ue + sizeof(*ue); | 1238 | ue->elem_data = (char *)ue + sizeof(*ue); |
| @@ -1321,8 +1344,9 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, | |||
| 1321 | } | 1344 | } |
| 1322 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); | 1345 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); |
| 1323 | if (err > 0) { | 1346 | if (err > 0) { |
| 1347 | struct snd_ctl_elem_id id = kctl->id; | ||
| 1324 | up_read(&card->controls_rwsem); | 1348 | up_read(&card->controls_rwsem); |
| 1325 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); | 1349 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); |
| 1326 | return 0; | 1350 | return 0; |
| 1327 | } | 1351 | } |
| 1328 | } else { | 1352 | } else { |
diff --git a/sound/core/init.c b/sound/core/init.c index 5ee83845c5de..7bdfd19e24a8 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
| @@ -232,6 +232,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid, | |||
| 232 | INIT_LIST_HEAD(&card->devices); | 232 | INIT_LIST_HEAD(&card->devices); |
| 233 | init_rwsem(&card->controls_rwsem); | 233 | init_rwsem(&card->controls_rwsem); |
| 234 | rwlock_init(&card->ctl_files_rwlock); | 234 | rwlock_init(&card->ctl_files_rwlock); |
| 235 | mutex_init(&card->user_ctl_lock); | ||
| 235 | INIT_LIST_HEAD(&card->controls); | 236 | INIT_LIST_HEAD(&card->controls); |
| 236 | INIT_LIST_HEAD(&card->ctl_files); | 237 | INIT_LIST_HEAD(&card->ctl_files); |
| 237 | spin_lock_init(&card->files_lock); | 238 | spin_lock_init(&card->files_lock); |
diff --git a/sound/pci/hda/hda_i915.c b/sound/pci/hda/hda_i915.c index 9d07e4edacdb..e9e8a4a4a9a1 100644 --- a/sound/pci/hda/hda_i915.c +++ b/sound/pci/hda/hda_i915.c | |||
| @@ -22,20 +22,20 @@ | |||
| 22 | #include <drm/i915_powerwell.h> | 22 | #include <drm/i915_powerwell.h> |
| 23 | #include "hda_i915.h" | 23 | #include "hda_i915.h" |
| 24 | 24 | ||
| 25 | static void (*get_power)(void); | 25 | static int (*get_power)(void); |
| 26 | static void (*put_power)(void); | 26 | static int (*put_power)(void); |
| 27 | 27 | ||
| 28 | void hda_display_power(bool enable) | 28 | int hda_display_power(bool enable) |
| 29 | { | 29 | { |
| 30 | if (!get_power || !put_power) | 30 | if (!get_power || !put_power) |
| 31 | return; | 31 | return -ENODEV; |
| 32 | 32 | ||
| 33 | pr_debug("HDA display power %s \n", | 33 | pr_debug("HDA display power %s \n", |
| 34 | enable ? "Enable" : "Disable"); | 34 | enable ? "Enable" : "Disable"); |
| 35 | if (enable) | 35 | if (enable) |
| 36 | get_power(); | 36 | return get_power(); |
| 37 | else | 37 | else |
| 38 | put_power(); | 38 | return put_power(); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | int hda_i915_init(void) | 41 | int hda_i915_init(void) |
diff --git a/sound/pci/hda/hda_i915.h b/sound/pci/hda/hda_i915.h index 5a63da2c53e5..bfd835f8f1aa 100644 --- a/sound/pci/hda/hda_i915.h +++ b/sound/pci/hda/hda_i915.h | |||
| @@ -17,11 +17,11 @@ | |||
| 17 | #define __SOUND_HDA_I915_H | 17 | #define __SOUND_HDA_I915_H |
| 18 | 18 | ||
| 19 | #ifdef CONFIG_SND_HDA_I915 | 19 | #ifdef CONFIG_SND_HDA_I915 |
| 20 | void hda_display_power(bool enable); | 20 | int hda_display_power(bool enable); |
| 21 | int hda_i915_init(void); | 21 | int hda_i915_init(void); |
| 22 | int hda_i915_exit(void); | 22 | int hda_i915_exit(void); |
| 23 | #else | 23 | #else |
| 24 | static inline void hda_display_power(bool enable) {} | 24 | static inline int hda_display_power(bool enable) { return 0; } |
| 25 | static inline int hda_i915_init(void) | 25 | static inline int hda_i915_init(void) |
| 26 | { | 26 | { |
| 27 | return -ENODEV; | 27 | return -ENODEV; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bb65a124e006..23fd6b9aecca 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -1656,8 +1656,13 @@ static int azx_probe_continue(struct azx *chip) | |||
| 1656 | "Error request power-well from i915\n"); | 1656 | "Error request power-well from i915\n"); |
| 1657 | goto out_free; | 1657 | goto out_free; |
| 1658 | } | 1658 | } |
| 1659 | err = hda_display_power(true); | ||
| 1660 | if (err < 0) { | ||
| 1661 | dev_err(chip->card->dev, | ||
| 1662 | "Cannot turn on display power on i915\n"); | ||
| 1663 | goto out_free; | ||
| 1664 | } | ||
| 1659 | #endif | 1665 | #endif |
| 1660 | hda_display_power(true); | ||
| 1661 | } | 1666 | } |
| 1662 | 1667 | ||
| 1663 | err = azx_first_init(chip); | 1668 | err = azx_first_init(chip); |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index cbfa1e18f651..0b9571c858f8 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
| @@ -225,11 +225,11 @@ config SND_SOC_ADAU1373 | |||
| 225 | config SND_SOC_ADAU1701 | 225 | config SND_SOC_ADAU1701 |
| 226 | tristate "Analog Devices ADAU1701 CODEC" | 226 | tristate "Analog Devices ADAU1701 CODEC" |
| 227 | depends on I2C | 227 | depends on I2C |
| 228 | select SND_SOC_SIGMADSP | 228 | select SND_SOC_SIGMADSP_I2C |
| 229 | 229 | ||
| 230 | config SND_SOC_ADAU17X1 | 230 | config SND_SOC_ADAU17X1 |
| 231 | tristate | 231 | tristate |
| 232 | select SND_SOC_SIGMADSP | 232 | select SND_SOC_SIGMADSP_REGMAP |
| 233 | 233 | ||
| 234 | config SND_SOC_ADAU1761 | 234 | config SND_SOC_ADAU1761 |
| 235 | tristate | 235 | tristate |
| @@ -476,6 +476,14 @@ config SND_SOC_SIGMADSP | |||
| 476 | tristate | 476 | tristate |
| 477 | select CRC32 | 477 | select CRC32 |
| 478 | 478 | ||
| 479 | config SND_SOC_SIGMADSP_I2C | ||
| 480 | tristate | ||
| 481 | select SND_SOC_SIGMADSP | ||
| 482 | |||
| 483 | config SND_SOC_SIGMADSP_REGMAP | ||
| 484 | tristate | ||
| 485 | select SND_SOC_SIGMADSP | ||
| 486 | |||
| 479 | config SND_SOC_SIRF_AUDIO_CODEC | 487 | config SND_SOC_SIRF_AUDIO_CODEC |
| 480 | tristate "SiRF SoC internal audio codec" | 488 | tristate "SiRF SoC internal audio codec" |
| 481 | select REGMAP_MMIO | 489 | select REGMAP_MMIO |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index be3377b8d73f..1bd6e1cf6f82 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
| @@ -77,6 +77,8 @@ snd-soc-sgtl5000-objs := sgtl5000.o | |||
| 77 | snd-soc-alc5623-objs := alc5623.o | 77 | snd-soc-alc5623-objs := alc5623.o |
| 78 | snd-soc-alc5632-objs := alc5632.o | 78 | snd-soc-alc5632-objs := alc5632.o |
| 79 | snd-soc-sigmadsp-objs := sigmadsp.o | 79 | snd-soc-sigmadsp-objs := sigmadsp.o |
| 80 | snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o | ||
| 81 | snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o | ||
| 80 | snd-soc-si476x-objs := si476x.o | 82 | snd-soc-si476x-objs := si476x.o |
| 81 | snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o | 83 | snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o |
| 82 | snd-soc-sn95031-objs := sn95031.o | 84 | snd-soc-sn95031-objs := sn95031.o |
| @@ -240,6 +242,8 @@ obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o | |||
| 240 | obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o | 242 | obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o |
| 241 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 243 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
| 242 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o | 244 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o |
| 245 | obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o | ||
| 246 | obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o | ||
| 243 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o | 247 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o |
| 244 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o | 248 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o |
| 245 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o | 249 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o |
diff --git a/sound/soc/codecs/sigmadsp-i2c.c b/sound/soc/codecs/sigmadsp-i2c.c new file mode 100644 index 000000000000..246081aae8ca --- /dev/null +++ b/sound/soc/codecs/sigmadsp-i2c.c | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | * Load Analog Devices SigmaStudio firmware files | ||
| 3 | * | ||
| 4 | * Copyright 2009-2011 Analog Devices Inc. | ||
| 5 | * | ||
| 6 | * Licensed under the GPL-2 or later. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/i2c.h> | ||
| 10 | #include <linux/export.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | |||
| 13 | #include "sigmadsp.h" | ||
| 14 | |||
| 15 | static int sigma_action_write_i2c(void *control_data, | ||
| 16 | const struct sigma_action *sa, size_t len) | ||
| 17 | { | ||
| 18 | return i2c_master_send(control_data, (const unsigned char *)&sa->addr, | ||
| 19 | len); | ||
| 20 | } | ||
| 21 | |||
| 22 | int process_sigma_firmware(struct i2c_client *client, const char *name) | ||
| 23 | { | ||
| 24 | struct sigma_firmware ssfw; | ||
| 25 | |||
| 26 | ssfw.control_data = client; | ||
| 27 | ssfw.write = sigma_action_write_i2c; | ||
| 28 | |||
| 29 | return _process_sigma_firmware(&client->dev, &ssfw, name); | ||
| 30 | } | ||
| 31 | EXPORT_SYMBOL(process_sigma_firmware); | ||
| 32 | |||
| 33 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
| 34 | MODULE_DESCRIPTION("SigmaDSP I2C firmware loader"); | ||
| 35 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/sigmadsp-regmap.c b/sound/soc/codecs/sigmadsp-regmap.c new file mode 100644 index 000000000000..f78ed8d2cfb2 --- /dev/null +++ b/sound/soc/codecs/sigmadsp-regmap.c | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* | ||
| 2 | * Load Analog Devices SigmaStudio firmware files | ||
| 3 | * | ||
| 4 | * Copyright 2009-2011 Analog Devices Inc. | ||
| 5 | * | ||
| 6 | * Licensed under the GPL-2 or later. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/regmap.h> | ||
| 10 | #include <linux/export.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | |||
| 13 | #include "sigmadsp.h" | ||
| 14 | |||
| 15 | static int sigma_action_write_regmap(void *control_data, | ||
| 16 | const struct sigma_action *sa, size_t len) | ||
| 17 | { | ||
| 18 | return regmap_raw_write(control_data, be16_to_cpu(sa->addr), | ||
| 19 | sa->payload, len - 2); | ||
| 20 | } | ||
| 21 | |||
| 22 | int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap, | ||
| 23 | const char *name) | ||
| 24 | { | ||
| 25 | struct sigma_firmware ssfw; | ||
| 26 | |||
| 27 | ssfw.control_data = regmap; | ||
| 28 | ssfw.write = sigma_action_write_regmap; | ||
| 29 | |||
| 30 | return _process_sigma_firmware(dev, &ssfw, name); | ||
| 31 | } | ||
| 32 | EXPORT_SYMBOL(process_sigma_firmware_regmap); | ||
| 33 | |||
| 34 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
| 35 | MODULE_DESCRIPTION("SigmaDSP regmap firmware loader"); | ||
| 36 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 4068f2491232..f2de7e049bc6 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c | |||
| @@ -34,23 +34,6 @@ enum { | |||
| 34 | SIGMA_ACTION_END, | 34 | SIGMA_ACTION_END, |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | struct sigma_action { | ||
| 38 | u8 instr; | ||
| 39 | u8 len_hi; | ||
| 40 | __le16 len; | ||
| 41 | __be16 addr; | ||
| 42 | unsigned char payload[]; | ||
| 43 | } __packed; | ||
| 44 | |||
| 45 | struct sigma_firmware { | ||
| 46 | const struct firmware *fw; | ||
| 47 | size_t pos; | ||
| 48 | |||
| 49 | void *control_data; | ||
| 50 | int (*write)(void *control_data, const struct sigma_action *sa, | ||
| 51 | size_t len); | ||
| 52 | }; | ||
| 53 | |||
| 54 | static inline u32 sigma_action_len(struct sigma_action *sa) | 37 | static inline u32 sigma_action_len(struct sigma_action *sa) |
| 55 | { | 38 | { |
| 56 | return (sa->len_hi << 16) | le16_to_cpu(sa->len); | 39 | return (sa->len_hi << 16) | le16_to_cpu(sa->len); |
| @@ -138,7 +121,7 @@ process_sigma_actions(struct sigma_firmware *ssfw) | |||
| 138 | return 0; | 121 | return 0; |
| 139 | } | 122 | } |
| 140 | 123 | ||
| 141 | static int _process_sigma_firmware(struct device *dev, | 124 | int _process_sigma_firmware(struct device *dev, |
| 142 | struct sigma_firmware *ssfw, const char *name) | 125 | struct sigma_firmware *ssfw, const char *name) |
| 143 | { | 126 | { |
| 144 | int ret; | 127 | int ret; |
| @@ -197,50 +180,6 @@ static int _process_sigma_firmware(struct device *dev, | |||
| 197 | 180 | ||
| 198 | return ret; | 181 | return ret; |
| 199 | } | 182 | } |
| 200 | 183 | EXPORT_SYMBOL_GPL(_process_sigma_firmware); | |
| 201 | #if IS_ENABLED(CONFIG_I2C) | ||
| 202 | |||
| 203 | static int sigma_action_write_i2c(void *control_data, | ||
| 204 | const struct sigma_action *sa, size_t len) | ||
| 205 | { | ||
| 206 | return i2c_master_send(control_data, (const unsigned char *)&sa->addr, | ||
| 207 | len); | ||
| 208 | } | ||
| 209 | |||
| 210 | int process_sigma_firmware(struct i2c_client *client, const char *name) | ||
| 211 | { | ||
| 212 | struct sigma_firmware ssfw; | ||
| 213 | |||
| 214 | ssfw.control_data = client; | ||
| 215 | ssfw.write = sigma_action_write_i2c; | ||
| 216 | |||
| 217 | return _process_sigma_firmware(&client->dev, &ssfw, name); | ||
| 218 | } | ||
| 219 | EXPORT_SYMBOL(process_sigma_firmware); | ||
| 220 | |||
| 221 | #endif | ||
| 222 | |||
| 223 | #if IS_ENABLED(CONFIG_REGMAP) | ||
| 224 | |||
| 225 | static int sigma_action_write_regmap(void *control_data, | ||
| 226 | const struct sigma_action *sa, size_t len) | ||
| 227 | { | ||
| 228 | return regmap_raw_write(control_data, be16_to_cpu(sa->addr), | ||
| 229 | sa->payload, len - 2); | ||
| 230 | } | ||
| 231 | |||
| 232 | int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap, | ||
| 233 | const char *name) | ||
| 234 | { | ||
| 235 | struct sigma_firmware ssfw; | ||
| 236 | |||
| 237 | ssfw.control_data = regmap; | ||
| 238 | ssfw.write = sigma_action_write_regmap; | ||
| 239 | |||
| 240 | return _process_sigma_firmware(dev, &ssfw, name); | ||
| 241 | } | ||
| 242 | EXPORT_SYMBOL(process_sigma_firmware_regmap); | ||
| 243 | |||
| 244 | #endif | ||
| 245 | 184 | ||
| 246 | MODULE_LICENSE("GPL"); | 185 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/sigmadsp.h b/sound/soc/codecs/sigmadsp.h index e439cbd7af7d..c47cd23e9827 100644 --- a/sound/soc/codecs/sigmadsp.h +++ b/sound/soc/codecs/sigmadsp.h | |||
| @@ -12,6 +12,26 @@ | |||
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <linux/regmap.h> | 13 | #include <linux/regmap.h> |
| 14 | 14 | ||
| 15 | struct sigma_action { | ||
| 16 | u8 instr; | ||
| 17 | u8 len_hi; | ||
| 18 | __le16 len; | ||
| 19 | __be16 addr; | ||
| 20 | unsigned char payload[]; | ||
| 21 | } __packed; | ||
| 22 | |||
| 23 | struct sigma_firmware { | ||
| 24 | const struct firmware *fw; | ||
| 25 | size_t pos; | ||
| 26 | |||
| 27 | void *control_data; | ||
| 28 | int (*write)(void *control_data, const struct sigma_action *sa, | ||
| 29 | size_t len); | ||
| 30 | }; | ||
| 31 | |||
| 32 | int _process_sigma_firmware(struct device *dev, | ||
| 33 | struct sigma_firmware *ssfw, const char *name); | ||
| 34 | |||
| 15 | struct i2c_client; | 35 | struct i2c_client; |
| 16 | 36 | ||
| 17 | extern int process_sigma_firmware(struct i2c_client *client, const char *name); | 37 | extern int process_sigma_firmware(struct i2c_client *client, const char *name); |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 6bb0ea59284f..a609aafc994d 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
| @@ -923,8 +923,8 @@ static int fsl_soc_dma_probe(struct platform_device *pdev) | |||
| 923 | dma->dai.pcm_free = fsl_dma_free_dma_buffers; | 923 | dma->dai.pcm_free = fsl_dma_free_dma_buffers; |
| 924 | 924 | ||
| 925 | /* Store the SSI-specific information that we need */ | 925 | /* Store the SSI-specific information that we need */ |
| 926 | dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0); | 926 | dma->ssi_stx_phys = res.start + CCSR_SSI_STX0; |
| 927 | dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0); | 927 | dma->ssi_srx_phys = res.start + CCSR_SSI_SRX0; |
| 928 | 928 | ||
| 929 | iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); | 929 | iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); |
| 930 | if (iprop) | 930 | if (iprop) |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index b912d45a2a4c..d7a60614dd21 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
| @@ -762,7 +762,7 @@ static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol, | |||
| 762 | struct regmap *regmap = spdif_priv->regmap; | 762 | struct regmap *regmap = spdif_priv->regmap; |
| 763 | u32 val; | 763 | u32 val; |
| 764 | 764 | ||
| 765 | val = regmap_read(regmap, REG_SPDIF_SIS, &val); | 765 | regmap_read(regmap, REG_SPDIF_SIS, &val); |
| 766 | ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0; | 766 | ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0; |
| 767 | regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD); | 767 | regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD); |
| 768 | 768 | ||
| @@ -1076,7 +1076,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | |||
| 1076 | goto out; | 1076 | goto out; |
| 1077 | } else if (arate / rate[index] == 1) { | 1077 | } else if (arate / rate[index] == 1) { |
| 1078 | /* A little bigger than expect */ | 1078 | /* A little bigger than expect */ |
| 1079 | sub = (arate - rate[index]) * 100000; | 1079 | sub = (u64)(arate - rate[index]) * 100000; |
| 1080 | do_div(sub, rate[index]); | 1080 | do_div(sub, rate[index]); |
| 1081 | if (sub >= savesub) | 1081 | if (sub >= savesub) |
| 1082 | continue; | 1082 | continue; |
| @@ -1086,7 +1086,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | |||
| 1086 | spdif_priv->txrate[index] = arate; | 1086 | spdif_priv->txrate[index] = arate; |
| 1087 | } else if (rate[index] / arate == 1) { | 1087 | } else if (rate[index] / arate == 1) { |
| 1088 | /* A little smaller than expect */ | 1088 | /* A little smaller than expect */ |
| 1089 | sub = (rate[index] - arate) * 100000; | 1089 | sub = (u64)(rate[index] - arate) * 100000; |
| 1090 | do_div(sub, rate[index]); | 1090 | do_div(sub, rate[index]); |
| 1091 | if (sub >= savesub) | 1091 | if (sub >= savesub) |
| 1092 | continue; | 1092 | continue; |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 6acb225ec6fd..2434b6d61675 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
| @@ -11,6 +11,7 @@ config SND_PXA2XX_SOC | |||
| 11 | config SND_MMP_SOC | 11 | config SND_MMP_SOC |
| 12 | bool "Soc Audio for Marvell MMP chips" | 12 | bool "Soc Audio for Marvell MMP chips" |
| 13 | depends on ARCH_MMP | 13 | depends on ARCH_MMP |
| 14 | select MMP_SRAM | ||
| 14 | select SND_SOC_GENERIC_DMAENGINE_PCM | 15 | select SND_SOC_GENERIC_DMAENGINE_PCM |
| 15 | select SND_ARM | 16 | select SND_ARM |
| 16 | help | 17 | help |
| @@ -40,7 +41,7 @@ config SND_MMP_SOC_SSPA | |||
| 40 | 41 | ||
| 41 | config SND_PXA2XX_SOC_CORGI | 42 | config SND_PXA2XX_SOC_CORGI |
| 42 | tristate "SoC Audio support for Sharp Zaurus SL-C7x0" | 43 | tristate "SoC Audio support for Sharp Zaurus SL-C7x0" |
| 43 | depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx | 44 | depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx && I2C |
| 44 | select SND_PXA2XX_SOC_I2S | 45 | select SND_PXA2XX_SOC_I2S |
| 45 | select SND_SOC_WM8731 | 46 | select SND_SOC_WM8731 |
| 46 | help | 47 | help |
| @@ -49,7 +50,7 @@ config SND_PXA2XX_SOC_CORGI | |||
| 49 | 50 | ||
| 50 | config SND_PXA2XX_SOC_SPITZ | 51 | config SND_PXA2XX_SOC_SPITZ |
| 51 | tristate "SoC Audio support for Sharp Zaurus SL-Cxx00" | 52 | tristate "SoC Audio support for Sharp Zaurus SL-Cxx00" |
| 52 | depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 | 53 | depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 && I2C |
| 53 | select SND_PXA2XX_SOC_I2S | 54 | select SND_PXA2XX_SOC_I2S |
| 54 | select SND_SOC_WM8750 | 55 | select SND_SOC_WM8750 |
| 55 | help | 56 | help |
| @@ -58,7 +59,7 @@ config SND_PXA2XX_SOC_SPITZ | |||
| 58 | 59 | ||
| 59 | config SND_PXA2XX_SOC_Z2 | 60 | config SND_PXA2XX_SOC_Z2 |
| 60 | tristate "SoC Audio support for Zipit Z2" | 61 | tristate "SoC Audio support for Zipit Z2" |
| 61 | depends on SND_PXA2XX_SOC && MACH_ZIPIT2 | 62 | depends on SND_PXA2XX_SOC && MACH_ZIPIT2 && I2C |
| 62 | select SND_PXA2XX_SOC_I2S | 63 | select SND_PXA2XX_SOC_I2S |
| 63 | select SND_SOC_WM8750 | 64 | select SND_SOC_WM8750 |
| 64 | help | 65 | help |
| @@ -66,7 +67,7 @@ config SND_PXA2XX_SOC_Z2 | |||
| 66 | 67 | ||
| 67 | config SND_PXA2XX_SOC_POODLE | 68 | config SND_PXA2XX_SOC_POODLE |
| 68 | tristate "SoC Audio support for Poodle" | 69 | tristate "SoC Audio support for Poodle" |
| 69 | depends on SND_PXA2XX_SOC && MACH_POODLE | 70 | depends on SND_PXA2XX_SOC && MACH_POODLE && I2C |
| 70 | select SND_PXA2XX_SOC_I2S | 71 | select SND_PXA2XX_SOC_I2S |
| 71 | select SND_SOC_WM8731 | 72 | select SND_SOC_WM8731 |
| 72 | help | 73 | help |
| @@ -181,7 +182,7 @@ config SND_PXA2XX_SOC_HX4700 | |||
| 181 | 182 | ||
| 182 | config SND_PXA2XX_SOC_MAGICIAN | 183 | config SND_PXA2XX_SOC_MAGICIAN |
| 183 | tristate "SoC Audio support for HTC Magician" | 184 | tristate "SoC Audio support for HTC Magician" |
| 184 | depends on SND_PXA2XX_SOC && MACH_MAGICIAN | 185 | depends on SND_PXA2XX_SOC && MACH_MAGICIAN && I2C |
| 185 | select SND_PXA2XX_SOC_I2S | 186 | select SND_PXA2XX_SOC_I2S |
| 186 | select SND_PXA_SOC_SSP | 187 | select SND_PXA_SOC_SSP |
| 187 | select SND_SOC_UDA1380 | 188 | select SND_SOC_UDA1380 |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 91880156e1ae..4e86265f625c 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
| @@ -315,7 +315,7 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma, | |||
| 315 | dst_mod = mod[index]; | 315 | dst_mod = mod[index]; |
| 316 | } else { | 316 | } else { |
| 317 | src_mod = mod[index]; | 317 | src_mod = mod[index]; |
| 318 | dst_mod = mod[index + 1]; | 318 | dst_mod = mod[index - 1]; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | index = 0; | 321 | index = 0; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a74b9bf23d9f..cdc837ed144d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -2755,7 +2755,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 2755 | unsigned int mask = (1 << fls(max)) - 1; | 2755 | unsigned int mask = (1 << fls(max)) - 1; |
| 2756 | unsigned int invert = mc->invert; | 2756 | unsigned int invert = mc->invert; |
| 2757 | unsigned int val; | 2757 | unsigned int val; |
| 2758 | int connect, change; | 2758 | int connect, change, reg_change = 0; |
| 2759 | struct snd_soc_dapm_update update; | 2759 | struct snd_soc_dapm_update update; |
| 2760 | int ret = 0; | 2760 | int ret = 0; |
| 2761 | 2761 | ||
| @@ -2773,20 +2773,23 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 2773 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2773 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
| 2774 | 2774 | ||
| 2775 | change = dapm_kcontrol_set_value(kcontrol, val); | 2775 | change = dapm_kcontrol_set_value(kcontrol, val); |
| 2776 | if (change) { | ||
| 2777 | if (reg != SND_SOC_NOPM) { | ||
| 2778 | mask = mask << shift; | ||
| 2779 | val = val << shift; | ||
| 2780 | |||
| 2781 | if (snd_soc_test_bits(codec, reg, mask, val)) { | ||
| 2782 | update.kcontrol = kcontrol; | ||
| 2783 | update.reg = reg; | ||
| 2784 | update.mask = mask; | ||
| 2785 | update.val = val; | ||
| 2786 | card->update = &update; | ||
| 2787 | } | ||
| 2788 | 2776 | ||
| 2777 | if (reg != SND_SOC_NOPM) { | ||
| 2778 | mask = mask << shift; | ||
| 2779 | val = val << shift; | ||
| 2780 | |||
| 2781 | reg_change = snd_soc_test_bits(codec, reg, mask, val); | ||
| 2782 | } | ||
| 2783 | |||
| 2784 | if (change || reg_change) { | ||
| 2785 | if (reg_change) { | ||
| 2786 | update.kcontrol = kcontrol; | ||
| 2787 | update.reg = reg; | ||
| 2788 | update.mask = mask; | ||
| 2789 | update.val = val; | ||
| 2790 | card->update = &update; | ||
| 2789 | } | 2791 | } |
| 2792 | change |= reg_change; | ||
| 2790 | 2793 | ||
| 2791 | ret = soc_dapm_mixer_update_power(card, kcontrol, connect); | 2794 | ret = soc_dapm_mixer_update_power(card, kcontrol, connect); |
| 2792 | 2795 | ||
