aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig4
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_native.c13
-rw-r--r--sound/core/rawmidi.c4
-rw-r--r--sound/mips/au1x00.c1
-rw-r--r--sound/pci/Kconfig2
-rw-r--r--sound/pci/ca0106/ca0106_main.c5
-rw-r--r--sound/pci/hda/hda_intel.c9
-rw-r--r--sound/pci/hda/patch_realtek.c75
-rw-r--r--sound/pci/hda/patch_sigmatel.c7
-rw-r--r--sound/pci/oxygen/hifier.c4
-rw-r--r--sound/pci/oxygen/oxygen.c4
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c5
-rw-r--r--sound/pci/oxygen/virtuoso.c73
-rw-r--r--sound/ppc/awacs.c50
-rw-r--r--sound/soc/at32/at32-pcm.c5
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c1
-rw-r--r--sound/soc/codecs/ak4535.c11
-rw-r--r--sound/soc/codecs/cs4270.c103
-rw-r--r--sound/soc/codecs/tlv320aic3x.c11
-rw-r--r--sound/soc/codecs/uda1380.c9
-rw-r--r--sound/soc/codecs/wm8510.c9
-rw-r--r--sound/soc/codecs/wm8731.c11
-rw-r--r--sound/soc/codecs/wm8750.c10
-rw-r--r--sound/soc/codecs/wm8753.c16
-rw-r--r--sound/soc/codecs/wm8990.c21
-rw-r--r--sound/soc/codecs/wm8990.h14
-rw-r--r--sound/soc/codecs/wm9712.c1
-rw-r--r--sound/soc/omap/n810.c18
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c40
30 files changed, 364 insertions, 176 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index a37bee094eb..8ebf512ced6 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -91,6 +91,9 @@ endif # SOUND_PRIME
endif # !M68K
+endif # SOUND
+
+# AC97_BUS is used from both sound and ucb1400
config AC97_BUS
tristate
help
@@ -99,4 +102,3 @@ config AC97_BUS
sound although they're sharing the AC97 bus. Concerned drivers
should "select" this.
-endif # SOUND
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 9dd9bc73fe1..ece25c718e9 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -781,7 +781,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
return -ENODEV;
card = pcm->card;
- down_read(&card->controls_rwsem);
+ read_lock(&card->ctl_files_rwlock);
list_for_each_entry(kctl, &card->ctl_files, list) {
if (kctl->pid == current->pid) {
prefer_subdevice = kctl->prefer_pcm_subdevice;
@@ -789,7 +789,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
break;
}
}
- up_read(&card->controls_rwsem);
+ read_unlock(&card->ctl_files_rwlock);
switch (stream) {
case SNDRV_PCM_STREAM_PLAYBACK:
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c49b9d9e303..c487025d345 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1546,16 +1546,10 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
card = substream->pcm->card;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
- runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+ runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
+ runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
return -EBADFD;
- snd_power_lock(card);
- if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
- result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result < 0)
- goto _unlock;
- }
-
snd_pcm_stream_lock_irq(substream);
/* resume pause */
if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
@@ -1564,8 +1558,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
/* runtime->control->appl_ptr = runtime->status->hw_ptr; */
snd_pcm_stream_unlock_irq(substream);
- _unlock:
- snd_power_unlock(card);
+
return result;
}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index f7ea7287c59..b917a9f981c 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -418,7 +418,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
mutex_lock(&rmidi->open_mutex);
while (1) {
subdevice = -1;
- down_read(&card->controls_rwsem);
+ read_lock(&card->ctl_files_rwlock);
list_for_each_entry(kctl, &card->ctl_files, list) {
if (kctl->pid == current->pid) {
subdevice = kctl->prefer_rawmidi_subdevice;
@@ -426,7 +426,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
break;
}
}
- up_read(&card->controls_rwsem);
+ read_unlock(&card->ctl_files_rwlock);
err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
subdevice, fflags, rawmidi_file);
if (err >= 0)
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index ee0741f9eb5..fbef38a9604 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -38,7 +38,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/slab.h>
-#include <linux/version.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index f7d95b224a9..31f52d3fc21 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -845,7 +845,7 @@ config SND_VIRTUOSO
select SND_OXYGEN_LIB
help
Say Y here to include support for sound cards based on the
- Asus AV100/AV200 chips, i.e., Xonar D2, DX and D2X.
+ Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X.
To compile this driver as a module, choose M here: the module
will be called snd-virtuoso.
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 2f8b28add27..6abe8a3bd36 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -249,11 +249,12 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
.name = "MSI K8N Diamond MB [SB0438]",
.gpio_type = 2,
.i2c_adc = 1 } ,
- /* Another MSI K8N Diamond MB, which has apprently a different SSID */
+ /* MSI K8N Diamond PLUS MB */
{ .serial = 0x10091102,
.name = "MSI K8N Diamond MB",
.gpio_type = 2,
- .i2c_adc = 1 } ,
+ .i2c_adc = 1,
+ .spi_dac = 2 },
/* Shuttle XPC SD31P which has an onboard Creative Labs
* Sound Blaster Live! 24-bit EAX
* high-definition 7.1 audio processor".
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index a73d6ca0a90..1c53e337ecb 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -278,6 +278,9 @@ enum {
/* Defines for Nvidia HDA support */
#define NVIDIA_HDA_TRANSREG_ADDR 0x4e
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
+#define NVIDIA_HDA_ISTRM_COH 0x4d
+#define NVIDIA_HDA_OSTRM_COH 0x4c
+#define NVIDIA_HDA_ENABLE_COHBIT 0x01
/* Defines for Intel SCH HDA snoop control */
#define INTEL_SCH_HDA_DEVC 0x78
@@ -900,6 +903,12 @@ static void azx_init_pci(struct azx *chip)
update_pci_byte(chip->pci,
NVIDIA_HDA_TRANSREG_ADDR,
0x0f, NVIDIA_HDA_ENABLE_COHBITS);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_ISTRM_COH,
+ 0x01, NVIDIA_HDA_ENABLE_COHBIT);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_OSTRM_COH,
+ 0x01, NVIDIA_HDA_ENABLE_COHBIT);
break;
case AZX_DRIVER_SCH:
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index add4e87e0b2..66025161bd6 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -952,7 +952,7 @@ do_sku:
tmp | 0x2010);
break;
case 0x10ec0888:
- alc888_coef_init(codec);
+ /*alc888_coef_init(codec);*/ /* called in alc_init() */
break;
case 0x10ec0267:
case 0x10ec0268:
@@ -2439,6 +2439,8 @@ static int alc_init(struct hda_codec *codec)
unsigned int i;
alc_fix_pll(codec);
+ if (codec->vendor_id == 0x10ec0888)
+ alc888_coef_init(codec);
for (i = 0; i < spec->num_init_verbs; i++)
snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -6195,7 +6197,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
- SND_PCI_QUIRK(0x106b, 0x00a0, "Apple iMac 24''", ALC885_IMAC24),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
@@ -6437,6 +6438,39 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
}
}
+static void alc882_auto_init_input_src(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ const struct hda_input_mux *imux = spec->input_mux;
+ int c;
+
+ for (c = 0; c < spec->num_adc_nids; c++) {
+ hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
+ hda_nid_t nid = spec->capsrc_nids[c];
+ int conns, mute, idx, item;
+
+ conns = snd_hda_get_connections(codec, nid, conn_list,
+ ARRAY_SIZE(conn_list));
+ if (conns < 0)
+ continue;
+ for (idx = 0; idx < conns; idx++) {
+ /* if the current connection is the selected one,
+ * unmute it as default - otherwise mute it
+ */
+ mute = AMP_IN_MUTE(idx);
+ for (item = 0; item < imux->num_items; item++) {
+ if (imux->items[item].index == idx) {
+ if (spec->cur_mux[c] == item)
+ mute = AMP_IN_UNMUTE(idx);
+ break;
+ }
+ }
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, mute);
+ }
+ }
+}
+
/* add mic boosts if needed */
static int alc_auto_add_mic_boost(struct hda_codec *codec)
{
@@ -6491,6 +6525,7 @@ static void alc882_auto_init(struct hda_codec *codec)
alc882_auto_init_multi_out(codec);
alc882_auto_init_hp_out(codec);
alc882_auto_init_analog_input(codec);
+ alc882_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -8285,6 +8320,8 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc883_auto_init_input_src alc882_auto_init_input_src
+
/* almost identical with ALC880 parser... */
static int alc883_parse_auto_config(struct hda_codec *codec)
{
@@ -8315,6 +8352,7 @@ static void alc883_auto_init(struct hda_codec *codec)
alc883_auto_init_multi_out(codec);
alc883_auto_init_hp_out(codec);
alc883_auto_init_analog_input(codec);
+ alc883_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -8389,8 +8427,6 @@ static int patch_alc883(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC883_AUTO)
spec->init_hook = alc883_auto_init;
- else if (codec->vendor_id == 0x10ec0888)
- spec->init_hook = alc888_coef_init;
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
@@ -9663,6 +9699,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
#define alc262_auto_init_multi_out alc882_auto_init_multi_out
#define alc262_auto_init_hp_out alc882_auto_init_hp_out
#define alc262_auto_init_analog_input alc882_auto_init_analog_input
+#define alc262_auto_init_input_src alc882_auto_init_input_src
/* init callback for auto-configuration model -- overriding the default init */
@@ -9672,6 +9709,7 @@ static void alc262_auto_init(struct hda_codec *codec)
alc262_auto_init_multi_out(codec);
alc262_auto_init_hp_out(codec);
alc262_auto_init_analog_input(codec);
+ alc262_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -13330,6 +13368,8 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc861vd_auto_init_input_src alc882_auto_init_input_src
+
#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
@@ -13512,6 +13552,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
alc861vd_auto_init_multi_out(codec);
alc861vd_auto_init_hp_out(codec);
alc861vd_auto_init_analog_input(codec);
+ alc861vd_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
@@ -14025,6 +14066,13 @@ static struct hda_verb alc662_auto_init_verbs[] = {
{ }
};
+/* additional verbs for ALC663 */
+static struct hda_verb alc663_auto_init_verbs[] = {
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ { }
+};
+
static struct hda_verb alc663_m51va_init_verbs[] = {
{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -14553,6 +14601,14 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
if (!pin)
return 0;
+ if (pin == 0x17) {
+ /* ALC663 has a mono output pin on 0x17 */
+ sprintf(name, "%s Playback Switch", pfx);
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
+ return err;
+ }
+
if (alc880_is_fixed_pin(pin)) {
nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
/* printk("DAC nid=%x\n",nid); */
@@ -14677,6 +14733,8 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
}
}
+#define alc662_auto_init_input_src alc882_auto_init_input_src
+
static int alc662_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
@@ -14721,6 +14779,14 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
spec->input_mux = &spec->private_imux;
spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
+ if (codec->vendor_id == 0x10ec0663)
+ spec->init_verbs[spec->num_init_verbs++] =
+ alc663_auto_init_verbs;
+
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
spec->mixers[spec->num_mixers] = alc662_capture_mixer;
spec->num_mixers++;
return 1;
@@ -14733,6 +14799,7 @@ static void alc662_auto_init(struct hda_codec *codec)
alc662_auto_init_multi_out(codec);
alc662_auto_init_hp_out(codec);
alc662_auto_init_analog_input(codec);
+ alc662_auto_init_input_src(codec);
if (spec->unsol_event)
alc_sku_automute(codec);
}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7fdafcb0015..f3da621f25c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -560,8 +560,9 @@ static struct hda_verb dell_eq_core_init[] = {
};
static struct hda_verb dell_m6_core_init[] = {
- /* set master volume and direct control */
- { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+ /* set master volume to max value without distortion
+ * and direct control */
+ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
/* setup audio connections */
{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
{ 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -1682,8 +1683,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
/* Dell 3 stack systems with verb table in BIOS */
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS),
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 7442460583d..dad393ae040 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/delay.h>
#include <linux/pci.h>
#include <sound/control.h>
#include <sound/core.h>
@@ -107,6 +108,9 @@ static void set_ak4396_params(struct oxygen *chip,
else
value |= AK4396_DFS_QUAD;
data->ak4396_ctl2 = value;
+
+ msleep(1); /* wait for the new MCLK to become stable */
+
ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB);
ak4396_write(chip, AK4396_CONTROL_2, value);
ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 7c8ae31eb46..c5829d30ef8 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -28,6 +28,7 @@
* GPIO 1 -> DFS1 of AK5385
*/
+#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <sound/ac97_codec.h>
@@ -213,6 +214,9 @@ static void set_ak4396_params(struct oxygen *chip,
else
value |= AK4396_DFS_QUAD;
data->ak4396_ctl2 = value;
+
+ msleep(1); /* wait for the new MCLK to become stable */
+
for (i = 0; i < 4; ++i) {
ak4396_write(chip, i,
AK4396_CONTROL_1, AK4396_DIF_24_MSB);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 6facac5aed9..05eb8994c14 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -512,9 +512,12 @@ static int ac97_switch_get(struct snd_kcontrol *ctl,
static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
{
- unsigned int priv_idx = chip->controls[control]->private_value & 0xff;
+ unsigned int priv_idx;
u16 value;
+ if (!chip->controls[control])
+ return;
+ priv_idx = chip->controls[control]->private_value & 0xff;
value = oxygen_read_ac97(chip, 0, priv_idx);
if (!(value & 0x8000)) {
oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 9a2c16bf94e..01d7b75f918 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -36,15 +36,15 @@
*/
/*
- * Xonar DX
- * --------
+ * Xonar D1/DX
+ * -----------
*
* CMI8788:
*
* I²C <-> CS4398 (front)
* <-> CS4362A (surround, center/LFE, back)
*
- * GPI 0 <- external power present
+ * GPI 0 <- external power present (DX only)
*
* GPIO 0 -> enable output to speakers
* GPIO 1 -> enable front panel I/O
@@ -96,6 +96,7 @@ MODULE_PARM_DESC(enable, "enable card");
enum {
MODEL_D2,
MODEL_D2X,
+ MODEL_D1,
MODEL_DX,
};
@@ -103,6 +104,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = {
{ OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 },
{ OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX },
{ OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X },
+ { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 },
{ }
};
MODULE_DEVICE_TABLE(pci, xonar_ids);
@@ -313,15 +315,12 @@ static void cs43xx_init(struct oxygen *chip)
cs4362a_write(chip, 0x01, CS4362A_CPEN);
}
-static void xonar_dx_init(struct oxygen *chip)
+static void xonar_d1_init(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
data->anti_pop_delay = 800;
data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
- data->ext_power_reg = OXYGEN_GPI_DATA;
- data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
- data->ext_power_bit = GPI_DX_EXT_POWER;
data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
data->cs4362a_fm = CS4362A_FM_SINGLE |
CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
@@ -345,6 +344,16 @@ static void xonar_dx_init(struct oxygen *chip)
snd_component_add(chip->card, "CS5361");
}
+static void xonar_dx_init(struct oxygen *chip)
+{
+ struct xonar_data *data = chip->model_data;
+
+ data->ext_power_reg = OXYGEN_GPI_DATA;
+ data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
+ data->ext_power_bit = GPI_DX_EXT_POWER;
+ xonar_d1_init(chip);
+}
+
static void xonar_cleanup(struct oxygen *chip)
{
struct xonar_data *data = chip->model_data;
@@ -352,7 +361,7 @@ static void xonar_cleanup(struct oxygen *chip)
oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit);
}
-static void xonar_dx_cleanup(struct oxygen *chip)
+static void xonar_d1_cleanup(struct oxygen *chip)
{
xonar_cleanup(chip);
cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
@@ -365,7 +374,7 @@ static void xonar_d2_resume(struct oxygen *chip)
xonar_enable_output(chip);
}
-static void xonar_dx_resume(struct oxygen *chip)
+static void xonar_d1_resume(struct oxygen *chip)
{
cs43xx_init(chip);
xonar_enable_output(chip);
@@ -513,7 +522,7 @@ static const struct snd_kcontrol_new front_panel_switch = {
.put = front_panel_put,
};
-static void xonar_dx_ac97_switch(struct oxygen *chip,
+static void xonar_d1_ac97_switch(struct oxygen *chip,
unsigned int reg, unsigned int mute)
{
if (reg == AC97_LINE) {
@@ -536,7 +545,7 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
return 0;
}
-static int xonar_dx_control_filter(struct snd_kcontrol_new *template)
+static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
{
if (!strncmp(template->name, "CD Capture ", 11))
return 1; /* no CD input */
@@ -548,7 +557,7 @@ static int xonar_mixer_init(struct oxygen *chip)
return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
}
-static int xonar_dx_mixer_init(struct oxygen *chip)
+static int xonar_d1_mixer_init(struct oxygen *chip)
{
return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
}
@@ -615,23 +624,51 @@ static const struct oxygen_model xonar_models[] = {
.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
},
+ [MODEL_D1] = {
+ .shortname = "Xonar D1",
+ .longname = "Asus Virtuoso 100",
+ .chip = "AV200",
+ .owner = THIS_MODULE,
+ .init = xonar_d1_init,
+ .control_filter = xonar_d1_control_filter,
+ .mixer_init = xonar_d1_mixer_init,
+ .cleanup = xonar_d1_cleanup,
+ .suspend = xonar_d1_cleanup,
+ .resume = xonar_d1_resume,
+ .set_dac_params = set_cs43xx_params,
+ .set_adc_params = set_cs53x1_params,
+ .update_dac_volume = update_cs43xx_volume,
+ .update_dac_mute = update_cs43xx_mute,
+ .ac97_switch = xonar_d1_ac97_switch,
+ .dac_tlv = cs4362a_db_scale,
+ .model_data_size = sizeof(struct xonar_data),
+ .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
+ PLAYBACK_1_TO_SPDIF |
+ CAPTURE_0_FROM_I2S_2,
+ .dac_channels = 8,
+ .dac_volume_min = 0,
+ .dac_volume_max = 127,
+ .function_flags = OXYGEN_FUNCTION_2WIRE,
+ .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
+ },
[MODEL_DX] = {
.shortname = "Xonar DX",
.longname = "Asus Virtuoso 100",
.chip = "AV200",
.owner = THIS_MODULE,
.init = xonar_dx_init,
- .control_filter = xonar_dx_control_filter,
- .mixer_init = xonar_dx_mixer_init,
- .cleanup = xonar_dx_cleanup,
- .suspend = xonar_dx_cleanup,
- .resume = xonar_dx_resume,
+ .control_filter = xonar_d1_control_filter,
+ .mixer_init = xonar_d1_mixer_init,
+ .cleanup = xonar_d1_cleanup,
+ .suspend = xonar_d1_cleanup,
+ .resume = xonar_d1_resume,
.set_dac_params = set_cs43xx_params,
.set_adc_params = set_cs53x1_params,
.update_dac_volume = update_cs43xx_volume,
.update_dac_mute = update_cs43xx_mute,
.gpio_changed = xonar_gpio_changed,
- .ac97_switch = xonar_dx_ac97_switch,
+ .ac97_switch = xonar_d1_ac97_switch,
.dac_tlv = cs4362a_db_scale,
.model_data_size = sizeof(struct xonar_data),
.pcm_dev_cfg = PLAYBACK_0_TO_I2S |
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index 566a6d0daf4..106c48225bb 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -621,6 +621,13 @@ static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __initdata = {
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
};
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __initdata = {
+ AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
+ AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
+ AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
+ AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
+};
+
static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __initdata = {
AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
@@ -688,7 +695,10 @@ static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = {
static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata =
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac __initdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __initdata =
+AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
+
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __initdata =
AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
@@ -765,11 +775,12 @@ static void snd_pmac_awacs_resume(struct snd_pmac *chip)
#define IS_PM7500 (machine_is_compatible("AAPL,7500"))
#define IS_BEIGE (machine_is_compatible("AAPL,Gossamer"))
-#define IS_IMAC (machine_is_compatible("PowerMac2,1") \
- || machine_is_compatible("PowerMac2,2") \
+#define IS_IMAC1 (machine_is_compatible("PowerMac2,1"))
+#define IS_IMAC2 (machine_is_compatible("PowerMac2,2") \
|| machine_is_compatible("PowerMac4,1"))
+#define IS_G4AGP (machine_is_compatible("PowerMac3,1"))
-static int imac;
+static int imac1, imac2;
#ifdef PMAC_SUPPORT_AUTOMUTE
/*
@@ -815,13 +826,18 @@ static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
{
int reg = chip->awacs_reg[1]
| (MASK_HDMUTE | MASK_SPKMUTE);
- if (imac) {
+ if (imac1) {
+ reg &= ~MASK_SPKMUTE;
+ reg |= MASK_PAROUT1;
+ } else if (imac2) {
reg &= ~MASK_SPKMUTE;
reg &= ~MASK_PAROUT1;
}
if (snd_pmac_awacs_detect_headphone(chip))
reg &= ~MASK_HDMUTE;
- else if (imac)
+ else if (imac1)
+ reg &= ~MASK_PAROUT1;
+ else if (imac2)
reg |= MASK_PAROUT1;
else
reg &= ~MASK_SPKMUTE;
@@ -850,9 +866,13 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
{
int pm7500 = IS_PM7500;
int beige = IS_BEIGE;
+ int g4agp = IS_G4AGP;
+ int imac;
int err, vol;
- imac = IS_IMAC;
+ imac1 = IS_IMAC1;
+ imac2 = IS_IMAC2;
+ imac = imac1 || imac2;
/* looks like MASK_GAINLINE triggers something, so we set here
* as start-up
*/
@@ -939,7 +959,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
snd_pmac_awacs_mixers);
if (err < 0)
return err;
- if (beige)
+ if (beige || g4agp)
;
else if (chip->model == PMAC_SCREAMER)
err = build_mixers(chip, ARRAY_SIZE(snd_pmac_screamer_mixers2),
@@ -961,13 +981,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
err = build_mixers(chip,
ARRAY_SIZE(snd_pmac_screamer_mixers_imac),
snd_pmac_screamer_mixers_imac);
+ else if (g4agp)
+ err = build_mixers(chip,
+ ARRAY_SIZE(snd_pmac_screamer_mixers_g4agp),
+ snd_pmac_screamer_mixers_g4agp);
else
err = build_mixers(chip,
ARRAY_SIZE(snd_pmac_awacs_mixers_pmac),
snd_pmac_awacs_mixers_pmac);
if (err < 0)
return err;
- chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac)
+ chip->master_sw_ctl = snd_ctl_new1((pm7500 || imac || g4agp)
? &snd_pmac_awacs_master_sw_imac
: &snd_pmac_awacs_master_sw, chip);
err = snd_ctl_add(chip->card, chip->master_sw_ctl);
@@ -1004,15 +1028,17 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
snd_pmac_awacs_speaker_vol);
if (err < 0)
return err;
- chip->speaker_sw_ctl = snd_ctl_new1(imac
- ? &snd_pmac_awacs_speaker_sw_imac
+ chip->speaker_sw_ctl = snd_ctl_new1(imac1
+ ? &snd_pmac_awacs_speaker_sw_imac1
+ : imac2
+ ? &snd_pmac_awacs_speaker_sw_imac2
: &snd_pmac_awacs_speaker_sw, chip);
err = snd_ctl_add(chip->card, chip->speaker_sw_ctl);
if (err < 0)
return err;
}
- if (beige)
+ if (beige || g4agp)
err = build_mixers(chip,
ARRAY_SIZE(snd_pmac_screamer_mic_boost_beige),
snd_pmac_screamer_mic_boost_beige);
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
index 435f1daf177..c83584f989a 100644
--- a/sound/soc/at32/at32-pcm.c
+++ b/sound/soc/at32/at32-pcm.c
@@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev,
params = prtd->params;
/* Disable the PDC and save the PDC registers */
- ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+ params->mask->pdc_disable);
prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
@@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev,
ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
- ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+ ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
return 0;
}
#else /* CONFIG_PM */
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
index b081e83766b..b81d6b2cfa1 100644
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ b/sound/soc/at91/eti_b1_wm8731.c
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/timer.h>
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index b26003c4f3e..7da9f467b7b 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -562,10 +562,9 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -583,7 +582,6 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -660,6 +658,11 @@ static int ak4535_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 9deb8c74fdf..0bbd94501d7 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
#endif
-static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind);
-
-/*
- * Notify the driver that a new I2C bus has been found.
- *
- * This function is called for each I2C bus in the system. The function
- * then asks the I2C subsystem to probe that bus at the addresses on which
- * our device (the CS4270) could exist. If a device is found at one of
- * those addresses, then our probe function (cs4270_i2c_probe) is called.
- */
-static int cs4270_i2c_attach(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
-}
-
-static int cs4270_i2c_detach(struct i2c_client *client)
-{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
-
- i2c_detach_client(client);
- codec->control_data = NULL;
-
- kfree(codec->reg_cache);
- codec->reg_cache = NULL;
-
- kfree(client);
- return 0;
-}
+static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
/* A list of non-DAPM controls that the CS4270 supports */
static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
};
+static const struct i2c_device_id cs4270_id[] = {
+ {"cs4270", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, cs4270_id);
+
static struct i2c_driver cs4270_i2c_driver = {
.driver = {
.name = "CS4270 I2C",
.owner = THIS_MODULE,
},
- .id = I2C_DRIVERID_CS4270,
- .attach_adapter = cs4270_i2c_attach,
- .detach_client = cs4270_i2c_detach,
+ .id_table = cs4270_id,
+ .probe = cs4270_i2c_probe,
};
/*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
* Note: snd_soc_new_pcms() must be called before this function can be called,
* because of snd_ctl_add().
*/
-static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int cs4270_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
{
struct snd_soc_device *socdev = cs4270_socdev;
struct snd_soc_codec *codec = socdev->codec;
- struct i2c_client *i2c_client = NULL;
int i;
int ret = 0;
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
/* Note: codec_dai->codec is NULL here */
- i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!i2c_client) {
- printk(KERN_ERR "cs4270: could not allocate I2C client\n");
- return -ENOMEM;
- }
-
codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
if (!codec->reg_cache) {
printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
goto error;
}
- i2c_set_clientdata(i2c_client, codec);
- strcpy(i2c_client->name, "CS4270");
-
- i2c_client->driver = &cs4270_i2c_driver;
- i2c_client->adapter = adapter;
- i2c_client->addr = addr;
-
/* Verify that we have a CS4270 */
ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
goto error;
}
- printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr);
+ printk(KERN_INFO "cs4270: found device at I2C address %X\n",
+ i2c_client->addr);
printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
- /* Tell the I2C layer a new client has arrived */
-
- ret = i2c_attach_client(i2c_client);
- if (ret) {
- printk(KERN_ERR "cs4270: could not attach codec, "
- "I2C address %x, error code %i\n", addr, ret);
- goto error;
- }
-
codec->control_data = i2c_client;
codec->read = cs4270_read_reg_cache;
codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
goto error;
}
+ i2c_set_clientdata(i2c_client, codec);
+
return 0;
error:
- if (codec->control_data) {
- i2c_detach_client(i2c_client);
- codec->control_data = NULL;
- }
+ codec->control_data = NULL;
kfree(codec->reg_cache);
codec->reg_cache = NULL;
codec->reg_cache_size = 0;
- kfree(i2c_client);
-
return ret;
}
@@ -727,7 +681,7 @@ static int cs4270_probe(struct platform_device *pdev)
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
printk(KERN_ERR "cs4270: failed to create PCMs\n");
- return ret;
+ goto error_free_codec;
}
#ifdef USE_I2C
@@ -736,8 +690,7 @@ static int cs4270_probe(struct platform_device *pdev)
ret = i2c_add_driver(&cs4270_i2c_driver);
if (ret) {
printk(KERN_ERR "cs4270: failed to attach driver");
- snd_soc_free_pcms(socdev);
- return ret;
+ goto error_free_pcms;
}
/* Did we find a CS4270 on the I2C bus? */
@@ -759,10 +712,23 @@ static int cs4270_probe(struct platform_device *pdev)
ret = snd_soc_register_card(socdev);
if (ret < 0) {
printk(KERN_ERR "cs4270: failed to register card\n");
- snd_soc_free_pcms(socdev);
- return ret;
+ goto error_del_driver;
}
+ return 0;
+
+error_del_driver:
+#ifdef USE_I2C
+ i2c_del_driver(&cs4270_i2c_driver);
+
+error_free_pcms:
+#endif
+ snd_soc_free_pcms(socdev);
+
+error_free_codec:
+ kfree(socdev->codec);
+ socdev->codec = NULL;
+
return ret;
}
@@ -773,8 +739,7 @@ static int cs4270_remove(struct platform_device *pdev)
snd_soc_free_pcms(socdev);
#ifdef USE_I2C
- if (socdev->codec->control_data)
- i2c_del_driver(&cs4270_i2c_driver);
+ i2c_del_driver(&cs4270_i2c_driver);
#endif
kfree(socdev->codec);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index b1dce5f459d..5f9abb19943 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1199,10 +1199,9 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -1221,7 +1220,6 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -1302,6 +1300,11 @@ static int aic3x_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index a52d6d9e007..807318fbdc8 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -729,10 +729,9 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -750,7 +749,6 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -817,6 +815,9 @@ static int uda1380_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0)
+ kfree(codec);
return ret;
}
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 67325fd9544..3d998e6a997 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -693,10 +693,9 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -714,7 +713,6 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -782,6 +780,9 @@ static int wm8510_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0)
+ kfree(codec);
return ret;
}
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 369d39c3f74..9402fcaf04f 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -596,10 +596,9 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -617,7 +616,6 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -693,6 +691,11 @@ static int wm8731_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index c6a8edf302a..dd1f55404b2 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -869,10 +869,9 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -890,7 +889,6 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -966,6 +964,10 @@ static int wm8750_probe(struct platform_device *pdev)
/* Add other interfaces here */
#endif
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8604809f0c3..e873414840c 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -34,7 +34,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -584,7 +583,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* out 4 */
{"Out4 Mux", "VREF", "VREF"},
- {"Out4 Mux", "Capture ST", "Capture ST Mixer"},
+ {"Out4 Mux", "Capture ST", "Playback Mixer"},
{"Out4 Mux", "LOUT2", "LOUT2"},
{"Out 4", NULL, "Out4 Mux"},
{"OUT4", NULL, "Out 4"},
@@ -608,7 +607,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Capture Right Mux */
{"Capture Right Mux", "PGA", "Right Capture Volume"},
{"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
- {"Capture Right Mux", "Sidetone", "Capture ST Mixer"},
+ {"Capture Right Mux", "Sidetone", "Playback Mixer"},
/* Mono Capture mixer-mux */
{"Capture Right Mixer", "Stereo", "Capture Right Mux"},
@@ -1661,10 +1660,9 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (!i2c) {
- kfree(codec);
+ if (!i2c)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -1683,7 +1681,6 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -1760,6 +1757,11 @@ static int wm8753_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 3ecce5168e9..dd995ef448b 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -82,7 +82,7 @@ static const u16 wm8990_reg[] = {
0x0003, /* R35 - ClassD1 */
0x0000, /* R36 */
0x0100, /* R37 - ClassD3 */
- 0x0000, /* R38 */
+ 0x0079, /* R38 - ClassD4 */
0x0000, /* R39 - Input Mixer1 */
0x0000, /* R40 - Input Mixer2 */
0x0000, /* R41 - Input Mixer3 */
@@ -311,11 +311,15 @@ SOC_SINGLE("Speaker Mode Switch", WM8990_CLASSD1,
WM8990_CDMODE_BIT, 1, 0),
SOC_SINGLE("Speaker Output Attenuation Volume", WM8990_SPEAKER_VOLUME,
- WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0),
+ WM8990_SPKATTN_SHIFT, WM8990_SPKATTN_MASK, 0),
SOC_SINGLE("Speaker DC Boost Volume", WM8990_CLASSD3,
WM8990_DCGAIN_SHIFT, WM8990_DCGAIN_MASK, 0),
SOC_SINGLE("Speaker AC Boost Volume", WM8990_CLASSD3,
WM8990_ACGAIN_SHIFT, WM8990_ACGAIN_MASK, 0),
+SOC_SINGLE_TLV("Speaker Volume", WM8990_CLASSD4,
+ WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0, out_pga_tlv),
+SOC_SINGLE("Speaker ZC Switch", WM8990_CLASSD4,
+ WM8990_SPKZC_SHIFT, WM8990_SPKZC_MASK, 0),
SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
WM8990_LEFT_DAC_DIGITAL_VOLUME,
@@ -920,7 +924,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
{"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
{"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
- {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
+ {"SPKMIX", "SPKMIX Left DAC Switch", "Left DAC"},
/* LONMIX */
{"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
@@ -1496,10 +1500,9 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
client_template.addr = addr;
i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
- if (i2c == NULL) {
- kfree(codec);
+ if (i2c == NULL)
return -ENOMEM;
- }
+
i2c_set_clientdata(i2c, codec);
codec->control_data = i2c;
@@ -1517,7 +1520,6 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
return ret;
err:
- kfree(codec);
kfree(i2c);
return ret;
}
@@ -1591,6 +1593,11 @@ static int wm8990_probe(struct platform_device *pdev)
#else
/* Add other interfaces here */
#endif
+
+ if (ret != 0) {
+ kfree(codec->private_data);
+ kfree(codec);
+ }
return ret;
}
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 6bea5748528..0a08325d544 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -54,6 +54,7 @@
#define WM8990_SPEAKER_VOLUME 0x22
#define WM8990_CLASSD1 0x23
#define WM8990_CLASSD3 0x25
+#define WM8990_CLASSD4 0x26
#define WM8990_INPUT_MIXER1 0x27
#define WM8990_INPUT_MIXER2 0x28
#define WM8990_INPUT_MIXER3 0x29
@@ -528,8 +529,8 @@
/*
* R34 (0x22) - Speaker Volume
*/
-#define WM8990_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */
-#define WM8990_SPKVOL_SHIFT 0
+#define WM8990_SPKATTN_MASK 0x0003 /* SPKATTN - [1:0] */
+#define WM8990_SPKATTN_SHIFT 0
/*
* R35 (0x23) - ClassD1
@@ -544,6 +545,15 @@
#define WM8990_DCGAIN_SHIFT 3
#define WM8990_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
#define WM8990_ACGAIN_SHIFT 0
+
+/*
+ * R38 (0x26) - ClassD4
+ */
+#define WM8990_SPKZC_MASK 0x0001 /* SPKZC */
+#define WM8990_SPKZC_SHIFT 7 /* SPKZC */
+#define WM8990_SPKVOL_MASK 0x007F /* SPKVOL - [6:0] */
+#define WM8990_SPKVOL_SHIFT 0 /* SPKVOL - [6:0] */
+
/*
* R39 (0x27) - Input Mixer1
*/
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1fb7f9a7aec..2f1c91b1d55 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <sound/core.h>
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 7694621ec40..87d0ed01f65 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -329,12 +329,14 @@ static int __init n810_soc_init(void)
sys_clkout2_src = clk_get(dev, "sys_clkout2_src");
if (IS_ERR(sys_clkout2_src)) {
dev_err(dev, "Could not get sys_clkout2_src clock\n");
- return -ENODEV;
+ err = PTR_ERR(sys_clkout2_src);
+ goto err2;
}
sys_clkout2 = clk_get(dev, "sys_clkout2");
if (IS_ERR(sys_clkout2)) {
dev_err(dev, "Could not get sys_clkout2\n");
- goto err1;
+ err = PTR_ERR(sys_clkout2);
+ goto err3;
}
/*
* Configure 12 MHz output on SYS_CLKOUT2. Therefore we must use
@@ -343,7 +345,8 @@ static int __init n810_soc_init(void)
func96m_clk = clk_get(dev, "func_96m_ck");
if (IS_ERR(func96m_clk)) {
dev_err(dev, "Could not get func 96M clock\n");
- goto err2;
+ err = PTR_ERR(func96m_clk);
+ goto err4;
}
clk_set_parent(sys_clkout2_src, func96m_clk);
clk_set_rate(sys_clkout2, 12000000);
@@ -356,20 +359,25 @@ static int __init n810_soc_init(void)
gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0);
return 0;
-err2:
+err4:
clk_put(sys_clkout2);
+err3:
+ clk_put(sys_clkout2_src);
+err2:
platform_device_del(n810_snd_device);
err1:
platform_device_put(n810_snd_device);
return err;
-
}
static void __exit n810_soc_exit(void)
{
gpio_free(N810_SPEAKER_AMP_GPIO);
gpio_free(N810_HEADSET_AMP_GPIO);
+ clk_put(sys_clkout2_src);
+ clk_put(sys_clkout2);
+ clk_put(func96m_clk);
platform_device_unregister(n810_snd_device);
}
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 8548818eea0..c796b188277 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/clk.h>
+#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
@@ -81,7 +82,6 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- clk_i2s = clk_get(NULL, "I2SCLK");
if (IS_ERR(clk_i2s))
return PTR_ERR(clk_i2s);
@@ -152,6 +152,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx);
pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm);
pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk);
+ BUG_ON(IS_ERR(clk_i2s));
clk_enable(clk_i2s);
pxa_i2s_wait();
@@ -317,6 +318,43 @@ struct snd_soc_dai pxa_i2s_dai = {
EXPORT_SYMBOL_GPL(pxa_i2s_dai);
+static int pxa2xx_i2s_probe(struct platform_device *dev)
+{
+ clk_i2s = clk_get(&dev->dev, "I2SCLK");
+ return IS_ERR(clk_i2s) ? PTR_ERR(clk_i2s) : 0;
+}
+
+static int __devexit pxa2xx_i2s_remove(struct platform_device *dev)
+{
+ clk_put(clk_i2s);
+ clk_i2s = ERR_PTR(-ENOENT);
+ return 0;
+}
+
+static struct platform_driver pxa2xx_i2s_driver = {
+ .probe = pxa2xx_i2s_probe,
+ .remove = __devexit_p(pxa2xx_i2s_remove),
+
+ .driver = {
+ .name = "pxa2xx-i2s",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pxa2xx_i2s_init(void)
+{
+ clk_i2s = ERR_PTR(-ENOENT);
+ return platform_driver_register(&pxa2xx_i2s_driver);
+}
+
+static void __exit pxa2xx_i2s_exit(void)
+{
+ platform_driver_unregister(&pxa2xx_i2s_driver);
+}
+
+module_init(pxa2xx_i2s_init);
+module_exit(pxa2xx_i2s_exit);
+
/* Module information */
MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");