summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/control.c78
-rw-r--r--sound/core/init.c1
-rw-r--r--sound/pci/hda/hda_auto_parser.c1
-rw-r--r--sound/pci/hda/hda_i915.c12
-rw-r--r--sound/pci/hda/hda_i915.h4
-rw-r--r--sound/pci/hda/hda_intel.c72
-rw-r--r--sound/pci/hda/hda_local.h21
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c489
-rw-r--r--sound/pci/hda/patch_sigmatel.c58
-rw-r--r--sound/soc/codecs/Kconfig12
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/sigmadsp-i2c.c35
-rw-r--r--sound/soc/codecs/sigmadsp-regmap.c36
-rw-r--r--sound/soc/codecs/sigmadsp.c65
-rw-r--r--sound/soc/codecs/sigmadsp.h20
-rw-r--r--sound/soc/fsl/fsl_dma.c4
-rw-r--r--sound/soc/fsl/fsl_spdif.c6
-rw-r--r--sound/soc/pxa/Kconfig11
-rw-r--r--sound/soc/sh/rcar/core.c2
-rw-r--r--sound/soc/soc-dapm.c29
-rw-r--r--sound/usb/card.c13
-rw-r--r--sound/usb/endpoint.c17
-rw-r--r--sound/usb/endpoint.h1
24 files changed, 547 insertions, 446 deletions
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,
{
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) {
@@ -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)
@@ -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);
@@ -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;
@@ -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;
@@ -423,8 +433,9 @@ add:
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;
@@ -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;
}
}
@@ -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 */
@@ -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;
}
@@ -1043,10 +1057,12 @@ 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;
}
@@ -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;
}
@@ -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 :
@@ -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;
+
+ if (replace) {
+ err = snd_ctl_remove_user_ctl(file, &info->id);
+ if (err)
+ return err;
}
- up_write(&card->controls_rwsem);
- if (err < 0)
- 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;
@@ -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);
@@ -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 {
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,
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);
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index b684c6e4f301..dabe41975a9d 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -898,6 +898,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
if (!strcmp(codec->modelname, models->name)) {
codec->fixup_id = models->id;
codec->fixup_name = models->name;
+ codec->fixup_list = fixlist;
codec->fixup_forced = 1;
return;
}
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 @@
#include <drm/i915_powerwell.h>
#include "hda_i915.h"
-static void (*get_power)(void);
-static void (*put_power)(void);
+static int (*get_power)(void);
+static int (*put_power)(void);
-void hda_display_power(bool enable)
+int hda_display_power(bool enable)
{
if (!get_power || !put_power)
- return;
+ return -ENODEV;
pr_debug("HDA display power %s \n",
enable ? "Enable" : "Disable");
if (enable)
- get_power();
+ return get_power();
else
- put_power();
+ return put_power();
}
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 @@
#define __SOUND_HDA_I915_H
#ifdef CONFIG_SND_HDA_I915
-void hda_display_power(bool enable);
+int hda_display_power(bool enable);
int hda_i915_init(void);
int hda_i915_exit(void);
#else
-static inline void hda_display_power(bool enable) {}
+static inline int hda_display_power(bool enable) { return 0; }
static inline int hda_i915_init(void)
{
return -ENODEV;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bb65a124e006..25753db97071 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -288,6 +288,24 @@ static char *driver_short_names[] = {
[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
};
+
+/* Intel HSW/BDW display HDA controller Extended Mode registers.
+ * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display
+ * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
+ * The values will be lost when the display power well is disabled.
+ */
+#define ICH6_REG_EM4 0x100c
+#define ICH6_REG_EM5 0x1010
+
+struct hda_intel {
+ struct azx chip;
+
+ /* HSW/BDW display HDA controller to restore BCLK from CDCLK */
+ unsigned int bclk_m;
+ unsigned int bclk_n;
+};
+
+
#ifdef CONFIG_X86
static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
{
@@ -580,6 +598,22 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
#define azx_del_card_list(chip) /* NOP */
#endif /* CONFIG_PM */
+static void haswell_save_bclk(struct azx *chip)
+{
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
+ hda->bclk_m = azx_readw(chip, EM4);
+ hda->bclk_n = azx_readw(chip, EM5);
+}
+
+static void haswell_restore_bclk(struct azx *chip)
+{
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
+ azx_writew(chip, EM4, hda->bclk_m);
+ azx_writew(chip, EM5, hda->bclk_n);
+}
+
#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
/*
* power management
@@ -606,6 +640,13 @@ static int azx_suspend(struct device *dev)
free_irq(chip->irq, chip);
chip->irq = -1;
}
+
+ /* Save BCLK M/N values before they become invalid in D3.
+ * Will test if display power well can be released now.
+ */
+ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+ haswell_save_bclk(chip);
+
if (chip->msi)
pci_disable_msi(chip->pci);
pci_disable_device(pci);
@@ -625,8 +666,10 @@ static int azx_resume(struct device *dev)
if (chip->disabled)
return 0;
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
hda_display_power(true);
+ haswell_restore_bclk(chip);
+ }
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
if (pci_enable_device(pci) < 0) {
@@ -670,8 +713,10 @@ static int azx_runtime_suspend(struct device *dev)
azx_stop_chip(chip);
azx_enter_link_reset(chip);
azx_clear_irq_pending(chip);
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+ haswell_save_bclk(chip);
hda_display_power(false);
+ }
return 0;
}
@@ -689,8 +734,10 @@ static int azx_runtime_resume(struct device *dev)
if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
return 0;
- if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
hda_display_power(true);
+ haswell_restore_bclk(chip);
+ }
/* Read STATESTS before controller reset */
status = azx_readw(chip, STATESTS);
@@ -883,6 +930,8 @@ static int register_vga_switcheroo(struct azx *chip)
static int azx_free(struct azx *chip)
{
struct pci_dev *pci = chip->pci;
+ struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
+
int i;
if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
@@ -930,7 +979,7 @@ static int azx_free(struct azx *chip)
hda_display_power(false);
hda_i915_exit();
}
- kfree(chip);
+ kfree(hda);
return 0;
}
@@ -1174,6 +1223,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
static struct snd_device_ops ops = {
.dev_free = azx_dev_free,
};
+ struct hda_intel *hda;
struct azx *chip;
int err;
@@ -1183,13 +1233,14 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
if (err < 0)
return err;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (!chip) {
- dev_err(card->dev, "Cannot allocate chip\n");
+ hda = kzalloc(sizeof(*hda), GFP_KERNEL);
+ if (!hda) {
+ dev_err(card->dev, "Cannot allocate hda\n");
pci_disable_device(pci);
return -ENOMEM;
}
+ chip = &hda->chip;
spin_lock_init(&chip->reg_lock);
mutex_init(&chip->open_mutex);
chip->card = card;
@@ -1656,8 +1707,13 @@ static int azx_probe_continue(struct azx *chip)
"Error request power-well from i915\n");
goto out_free;
}
+ err = hda_display_power(true);
+ if (err < 0) {
+ dev_err(chip->card->dev,
+ "Cannot turn on display power on i915\n");
+ goto out_free;
+ }
#endif
- hda_display_power(true);
}
err = azx_first_init(chip);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index ebd1fa6f015c..4e2d4863daa1 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -417,6 +417,27 @@ struct snd_hda_pin_quirk {
int value; /* quirk value */
};
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+
+#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
+ { .codec = _codec,\
+ .subvendor = _subvendor,\
+ .name = _name,\
+ .value = _value,\
+ .pins = (const struct hda_pintbl[]) { _pins } \
+ }
+#else
+
+#define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
+ { .codec = _codec,\
+ .subvendor = _subvendor,\
+ .value = _value,\
+ .pins = (const struct hda_pintbl[]) { _pins } \
+ }
+
+#endif
+
+
/* fixup types */
enum {
HDA_FIXUP_INVALID,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 3e4417b0ddbe..4fe876b65fda 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2204,7 +2204,7 @@ static int generic_hdmi_resume(struct hda_codec *codec)
struct hdmi_spec *spec = codec->spec;
int pin_idx;
- generic_hdmi_init(codec);
+ codec->patch_ops.init(codec);
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index af76995fa966..1c654effcd1a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4962,228 +4962,129 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
};
static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60140},
- {0x14, 0x90170110},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211020},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60160},
- {0x14, 0x90170120},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211030},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60160},
- {0x14, 0x90170120},
- {0x17, 0x90170140},
- {0x18, 0x40000000},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x41163b05},
- {0x1e, 0x411111f0},
- {0x21, 0x0321102f},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60160},
- {0x14, 0x90170130},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211040},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60160},
- {0x14, 0x90170140},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211050},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60170},
- {0x14, 0x90170120},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211030},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0255,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60170},
- {0x14, 0x90170130},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211040},
- },
- .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0283,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60130},
- {0x14, 0x90170110},
- {0x17, 0x40020008},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40e00001},
- {0x1e, 0x411111f0},
- {0x21, 0x0321101f},
- },
- .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0283,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60160},
- {0x14, 0x90170120},
- {0x17, 0x40000000},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- {0x21, 0x02211030},
- },
- .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0292,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x90a60140},
- {0x13, 0x411111f0},
- {0x14, 0x90170110},
- {0x15, 0x0221401f},
- {0x16, 0x411111f0},
- {0x18, 0x411111f0},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- },
- .value = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
- },
- {
- .codec = 0x10ec0293,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x40000000},
- {0x13, 0x90a60140},
- {0x14, 0x90170110},
- {0x15, 0x0221401f},
- {0x16, 0x21014020},
- {0x18, 0x411111f0},
- {0x19, 0x21a19030},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x40700001},
- {0x1e, 0x411111f0},
- },
- .value = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
- },
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60140},
+ {0x14, 0x90170110},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211020}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60160},
+ {0x14, 0x90170120},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60160},
+ {0x14, 0x90170120},
+ {0x17, 0x90170140},
+ {0x18, 0x40000000},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x41163b05},
+ {0x1e, 0x411111f0},
+ {0x21, 0x0321102f}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60160},
+ {0x14, 0x90170130},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211040}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60160},
+ {0x14, 0x90170140},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211050}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60170},
+ {0x14, 0x90170120},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60170},
+ {0x14, 0x90170130},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211040}),
+ SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60130},
+ {0x14, 0x90170110},
+ {0x17, 0x40020008},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40e00001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x0321101f}),
+ SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60160},
+ {0x14, 0x90170120},
+ {0x17, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0},
+ {0x21, 0x02211030}),
+ SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
+ {0x12, 0x90a60140},
+ {0x13, 0x411111f0},
+ {0x14, 0x90170110},
+ {0x15, 0x0221401f},
+ {0x16, 0x411111f0},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0}),
+ SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x40000000},
+ {0x13, 0x90a60140},
+ {0x14, 0x90170110},
+ {0x15, 0x0221401f},
+ {0x16, 0x21014020},
+ {0x18, 0x411111f0},
+ {0x19, 0x21a19030},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40700001},
+ {0x1e, 0x411111f0}),
{}
};
@@ -6039,90 +5940,66 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
};
static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
- {
- .codec = 0x10ec0668,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x99a30130},
- {0x14, 0x90170110},
- {0x15, 0x0321101f},
- {0x16, 0x03011020},
- {0x18, 0x40000008},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x41000001},
- {0x1e, 0x411111f0},
- {0x1f, 0x411111f0},
- },
- .value = ALC668_FIXUP_AUTO_MUTE,
- },
- {
- .codec = 0x10ec0668,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x99a30140},
- {0x14, 0x90170110},
- {0x15, 0x0321101f},
- {0x16, 0x03011020},
- {0x18, 0x40000008},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x41000001},
- {0x1e, 0x411111f0},
- {0x1f, 0x411111f0},
- },
- .value = ALC668_FIXUP_AUTO_MUTE,
- },
- {
- .codec = 0x10ec0668,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x99a30150},
- {0x14, 0x90170110},
- {0x15, 0x0321101f},
- {0x16, 0x03011020},
- {0x18, 0x40000008},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x41000001},
- {0x1e, 0x411111f0},
- {0x1f, 0x411111f0},
- },
- .value = ALC668_FIXUP_AUTO_MUTE,
- },
- {
- .codec = 0x10ec0668,
- .subvendor = 0x1028,
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- .name = "Dell",
-#endif
- .pins = (const struct hda_pintbl[]) {
- {0x12, 0x411111f0},
- {0x14, 0x90170110},
- {0x15, 0x0321101f},
- {0x16, 0x03011020},
- {0x18, 0x40000008},
- {0x19, 0x411111f0},
- {0x1a, 0x411111f0},
- {0x1b, 0x411111f0},
- {0x1d, 0x41000001},
- {0x1e, 0x411111f0},
- {0x1f, 0x411111f0},
- },
- .value = ALC668_FIXUP_AUTO_MUTE,
- },
+ SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+ {0x12, 0x99a30130},
+ {0x14, 0x90170110},
+ {0x15, 0x0321101f},
+ {0x16, 0x03011020},
+ {0x18, 0x40000008},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x41000001},
+ {0x1e, 0x411111f0},
+ {0x1f, 0x411111f0}),
+ SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+ {0x12, 0x99a30140},
+ {0x14, 0x90170110},
+ {0x15, 0x0321101f},
+ {0x16, 0x03011020},
+ {0x18, 0x40000008},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x41000001},
+ {0x1e, 0x411111f0},
+ {0x1f, 0x411111f0}),
+ SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+ {0x12, 0x99a30150},
+ {0x14, 0x90170110},
+ {0x15, 0x0321101f},
+ {0x16, 0x03011020},
+ {0x18, 0x40000008},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x41000001},
+ {0x1e, 0x411111f0},
+ {0x1f, 0x411111f0}),
+ SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
+ {0x12, 0x411111f0},
+ {0x14, 0x90170110},
+ {0x15, 0x0321101f},
+ {0x16, 0x03011020},
+ {0x18, 0x40000008},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x41000001},
+ {0x1e, 0x411111f0},
+ {0x1f, 0x411111f0}),
+ SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
+ {0x12, 0x90a60130},
+ {0x14, 0x90170110},
+ {0x15, 0x0321101f},
+ {0x16, 0x40000000},
+ {0x18, 0x411111f0},
+ {0x19, 0x411111f0},
+ {0x1a, 0x411111f0},
+ {0x1b, 0x411111f0},
+ {0x1d, 0x40d6832d},
+ {0x1e, 0x411111f0},
+ {0x1f, 0x411111f0}),
{}
};
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7f40a150899c..3744ea4e843d 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -122,6 +122,12 @@ enum {
};
enum {
+ STAC_92HD95_HP_LED,
+ STAC_92HD95_HP_BASS,
+ STAC_92HD95_MODELS
+};
+
+enum {
STAC_925x_REF,
STAC_M1,
STAC_M1_2,
@@ -4128,6 +4134,48 @@ static const struct snd_pci_quirk stac9205_fixup_tbl[] = {
{} /* terminator */
};
+static void stac92hd95_fixup_hp_led(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ struct sigmatel_spec *spec = codec->spec;
+
+ if (action != HDA_FIXUP_ACT_PRE_PROBE)
+ return;
+
+ if (find_mute_led_cfg(codec, spec->default_polarity))
+ codec_dbg(codec, "mute LED gpio %d polarity %d\n",
+ spec->gpio_led,
+ spec->gpio_led_polarity);
+}
+
+static const struct hda_fixup stac92hd95_fixups[] = {
+ [STAC_92HD95_HP_LED] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = stac92hd95_fixup_hp_led,
+ },
+ [STAC_92HD95_HP_BASS] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ {0x1a, 0x795, 0x00}, /* HPF to 100Hz */
+ {}
+ },
+ .chained = true,
+ .chain_id = STAC_92HD95_HP_LED,
+ },
+};
+
+static const struct snd_pci_quirk stac92hd95_fixup_tbl[] = {
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1911, "HP Spectre 13", STAC_92HD95_HP_BASS),
+ {} /* terminator */
+};
+
+static const struct hda_model_fixup stac92hd95_models[] = {
+ { .id = STAC_92HD95_HP_LED, .name = "hp-led" },
+ { .id = STAC_92HD95_HP_BASS, .name = "hp-bass" },
+ {}
+};
+
+
static int stac_parse_auto_config(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
@@ -4580,10 +4628,16 @@ static int patch_stac92hd95(struct hda_codec *codec)
spec->gen.beep_nid = 0x19; /* digital beep */
spec->pwr_nids = stac92hd95_pwr_nids;
spec->num_pwrs = ARRAY_SIZE(stac92hd95_pwr_nids);
- spec->default_polarity = -1; /* no default cfg */
+ spec->default_polarity = 0;
codec->patch_ops = stac_patch_ops;
+ snd_hda_pick_fixup(codec, stac92hd95_models, stac92hd95_fixup_tbl,
+ stac92hd95_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
+ stac_setup_gpio(codec);
+
err = stac_parse_auto_config(codec);
if (err < 0) {
stac_free(codec);
@@ -4592,6 +4646,8 @@ static int patch_stac92hd95(struct hda_codec *codec)
codec->proc_widget_hook = stac92hd_proc_hook;
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+
return 0;
}
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
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
@@ -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
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
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
@@ -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
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 @@
+/*
+ * Load Analog Devices SigmaStudio firmware files
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/i2c.h>
+#include <linux/export.h>
+#include <linux/module.h>
+
+#include "sigmadsp.h"
+
+static int sigma_action_write_i2c(void *control_data,
+ const struct sigma_action *sa, size_t len)
+{
+ return i2c_master_send(control_data, (const unsigned char *)&sa->addr,
+ len);
+}
+
+int process_sigma_firmware(struct i2c_client *client, const char *name)
+{
+ struct sigma_firmware ssfw;
+
+ ssfw.control_data = client;
+ ssfw.write = sigma_action_write_i2c;
+
+ return _process_sigma_firmware(&client->dev, &ssfw, name);
+}
+EXPORT_SYMBOL(process_sigma_firmware);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("SigmaDSP I2C firmware loader");
+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 @@
+/*
+ * Load Analog Devices SigmaStudio firmware files
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/regmap.h>
+#include <linux/export.h>
+#include <linux/module.h>
+
+#include "sigmadsp.h"
+
+static int sigma_action_write_regmap(void *control_data,
+ const struct sigma_action *sa, size_t len)
+{
+ return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
+ sa->payload, len - 2);
+}
+
+int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap,
+ const char *name)
+{
+ struct sigma_firmware ssfw;
+
+ ssfw.control_data = regmap;
+ ssfw.write = sigma_action_write_regmap;
+
+ return _process_sigma_firmware(dev, &ssfw, name);
+}
+EXPORT_SYMBOL(process_sigma_firmware_regmap);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("SigmaDSP regmap firmware loader");
+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 {
SIGMA_ACTION_END,
};
-struct sigma_action {
- u8 instr;
- u8 len_hi;
- __le16 len;
- __be16 addr;
- unsigned char payload[];
-} __packed;
-
-struct sigma_firmware {
- const struct firmware *fw;
- size_t pos;
-
- void *control_data;
- int (*write)(void *control_data, const struct sigma_action *sa,
- size_t len);
-};
-
static inline u32 sigma_action_len(struct sigma_action *sa)
{
return (sa->len_hi << 16) | le16_to_cpu(sa->len);
@@ -138,7 +121,7 @@ process_sigma_actions(struct sigma_firmware *ssfw)
return 0;
}
-static int _process_sigma_firmware(struct device *dev,
+int _process_sigma_firmware(struct device *dev,
struct sigma_firmware *ssfw, const char *name)
{
int ret;
@@ -197,50 +180,6 @@ static int _process_sigma_firmware(struct device *dev,
return ret;
}
-
-#if IS_ENABLED(CONFIG_I2C)
-
-static int sigma_action_write_i2c(void *control_data,
- const struct sigma_action *sa, size_t len)
-{
- return i2c_master_send(control_data, (const unsigned char *)&sa->addr,
- len);
-}
-
-int process_sigma_firmware(struct i2c_client *client, const char *name)
-{
- struct sigma_firmware ssfw;
-
- ssfw.control_data = client;
- ssfw.write = sigma_action_write_i2c;
-
- return _process_sigma_firmware(&client->dev, &ssfw, name);
-}
-EXPORT_SYMBOL(process_sigma_firmware);
-
-#endif
-
-#if IS_ENABLED(CONFIG_REGMAP)
-
-static int sigma_action_write_regmap(void *control_data,
- const struct sigma_action *sa, size_t len)
-{
- return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
- sa->payload, len - 2);
-}
-
-int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap,
- const char *name)
-{
- struct sigma_firmware ssfw;
-
- ssfw.control_data = regmap;
- ssfw.write = sigma_action_write_regmap;
-
- return _process_sigma_firmware(dev, &ssfw, name);
-}
-EXPORT_SYMBOL(process_sigma_firmware_regmap);
-
-#endif
+EXPORT_SYMBOL_GPL(_process_sigma_firmware);
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 @@
#include <linux/device.h>
#include <linux/regmap.h>
+struct sigma_action {
+ u8 instr;
+ u8 len_hi;
+ __le16 len;
+ __be16 addr;
+ unsigned char payload[];
+} __packed;
+
+struct sigma_firmware {
+ const struct firmware *fw;
+ size_t pos;
+
+ void *control_data;
+ int (*write)(void *control_data, const struct sigma_action *sa,
+ size_t len);
+};
+
+int _process_sigma_firmware(struct device *dev,
+ struct sigma_firmware *ssfw, const char *name);
+
struct i2c_client;
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)
dma->dai.pcm_free = fsl_dma_free_dma_buffers;
/* Store the SSI-specific information that we need */
- dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0);
- dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0);
+ dma->ssi_stx_phys = res.start + CCSR_SSI_STX0;
+ dma->ssi_srx_phys = res.start + CCSR_SSI_SRX0;
iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
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,
struct regmap *regmap = spdif_priv->regmap;
u32 val;
- val = regmap_read(regmap, REG_SPDIF_SIS, &val);
+ regmap_read(regmap, REG_SPDIF_SIS, &val);
ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0;
regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD);
@@ -1076,7 +1076,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
goto out;
} else if (arate / rate[index] == 1) {
/* A little bigger than expect */
- sub = (arate - rate[index]) * 100000;
+ sub = (u64)(arate - rate[index]) * 100000;
do_div(sub, rate[index]);
if (sub >= savesub)
continue;
@@ -1086,7 +1086,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
spdif_priv->txrate[index] = arate;
} else if (rate[index] / arate == 1) {
/* A little smaller than expect */
- sub = (rate[index] - arate) * 100000;
+ sub = (u64)(rate[index] - arate) * 100000;
do_div(sub, rate[index]);
if (sub >= savesub)
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
config SND_MMP_SOC
bool "Soc Audio for Marvell MMP chips"
depends on ARCH_MMP
+ select MMP_SRAM
select SND_SOC_GENERIC_DMAENGINE_PCM
select SND_ARM
help
@@ -40,7 +41,7 @@ config SND_MMP_SOC_SSPA
config SND_PXA2XX_SOC_CORGI
tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
- depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
+ depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8731
help
@@ -49,7 +50,7 @@ config SND_PXA2XX_SOC_CORGI
config SND_PXA2XX_SOC_SPITZ
tristate "SoC Audio support for Sharp Zaurus SL-Cxx00"
- depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00
+ depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8750
help
@@ -58,7 +59,7 @@ config SND_PXA2XX_SOC_SPITZ
config SND_PXA2XX_SOC_Z2
tristate "SoC Audio support for Zipit Z2"
- depends on SND_PXA2XX_SOC && MACH_ZIPIT2
+ depends on SND_PXA2XX_SOC && MACH_ZIPIT2 && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8750
help
@@ -66,7 +67,7 @@ config SND_PXA2XX_SOC_Z2
config SND_PXA2XX_SOC_POODLE
tristate "SoC Audio support for Poodle"
- depends on SND_PXA2XX_SOC && MACH_POODLE
+ depends on SND_PXA2XX_SOC && MACH_POODLE && I2C
select SND_PXA2XX_SOC_I2S
select SND_SOC_WM8731
help
@@ -181,7 +182,7 @@ config SND_PXA2XX_SOC_HX4700
config SND_PXA2XX_SOC_MAGICIAN
tristate "SoC Audio support for HTC Magician"
- depends on SND_PXA2XX_SOC && MACH_MAGICIAN
+ depends on SND_PXA2XX_SOC && MACH_MAGICIAN && I2C
select SND_PXA2XX_SOC_I2S
select SND_PXA_SOC_SSP
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,
dst_mod = mod[index];
} else {
src_mod = mod[index];
- dst_mod = mod[index + 1];
+ dst_mod = mod[index - 1];
}
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,
unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert;
unsigned int val;
- int connect, change;
+ int connect, change, reg_change = 0;
struct snd_soc_dapm_update update;
int ret = 0;
@@ -2773,20 +2773,23 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
change = dapm_kcontrol_set_value(kcontrol, val);
- if (change) {
- if (reg != SND_SOC_NOPM) {
- mask = mask << shift;
- val = val << shift;
-
- if (snd_soc_test_bits(codec, reg, mask, val)) {
- update.kcontrol = kcontrol;
- update.reg = reg;
- update.mask = mask;
- update.val = val;
- card->update = &update;
- }
+ if (reg != SND_SOC_NOPM) {
+ mask = mask << shift;
+ val = val << shift;
+
+ reg_change = snd_soc_test_bits(codec, reg, mask, val);
+ }
+
+ if (change || reg_change) {
+ if (reg_change) {
+ update.kcontrol = kcontrol;
+ update.reg = reg;
+ update.mask = mask;
+ update.val = val;
+ card->update = &update;
}
+ change |= reg_change;
ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index c3b5b7dca1c3..a09e5f3519e3 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -307,6 +307,11 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
static int snd_usb_audio_free(struct snd_usb_audio *chip)
{
+ struct list_head *p, *n;
+
+ list_for_each_safe(p, n, &chip->ep_list)
+ snd_usb_endpoint_free(p);
+
mutex_destroy(&chip->mutex);
kfree(chip);
return 0;
@@ -585,7 +590,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
struct snd_usb_audio *chip)
{
struct snd_card *card;
- struct list_head *p, *n;
+ struct list_head *p;
if (chip == (void *)-1L)
return;
@@ -598,14 +603,16 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
mutex_lock(&register_mutex);
chip->num_interfaces--;
if (chip->num_interfaces <= 0) {
+ struct snd_usb_endpoint *ep;
+
snd_card_disconnect(card);
/* release the pcm resources */
list_for_each(p, &chip->pcm_list) {
snd_usb_stream_disconnect(p);
}
/* release the endpoint resources */
- list_for_each_safe(p, n, &chip->ep_list) {
- snd_usb_endpoint_free(p);
+ list_for_each_entry(ep, &chip->ep_list, list) {
+ snd_usb_endpoint_release(ep);
}
/* release the midi resources */
list_for_each(p, &chip->midi_list) {
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 289f582c9130..114e3e7ff511 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -987,19 +987,30 @@ void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep)
}
/**
+ * snd_usb_endpoint_release: Tear down an snd_usb_endpoint
+ *
+ * @ep: the endpoint to release
+ *
+ * This function does not care for the endpoint's use count but will tear
+ * down all the streaming URBs immediately.
+ */
+void snd_usb_endpoint_release(struct snd_usb_endpoint *ep)
+{
+ release_urbs(ep, 1);
+}
+
+/**
* snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint
*
* @ep: the list header of the endpoint to free
*
- * This function does not care for the endpoint's use count but will tear
- * down all the streaming URBs immediately and free all resources.
+ * This free all resources of the given ep.
*/
void snd_usb_endpoint_free(struct list_head *head)
{
struct snd_usb_endpoint *ep;
ep = list_entry(head, struct snd_usb_endpoint, list);
- release_urbs(ep, 1);
kfree(ep);
}
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 1c7e8ee48abc..e61ee5c356a3 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -23,6 +23,7 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
+void snd_usb_endpoint_release(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_free(struct list_head *head);
int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep);
OpenPOWER on IntegriCloud