aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/aoa/codecs/onyx.c76
-rw-r--r--sound/aoa/codecs/tas.c66
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/hda/patch_realtek.c106
-rw-r--r--sound/pci/intel8x0.c6
-rw-r--r--sound/ppc/keywest.c82
-rw-r--r--sound/soc/codecs/wm9705.c2
-rw-r--r--sound/soc/omap/n810.c4
-rw-r--r--sound/soc/omap/omap-mcbsp.c5
-rw-r--r--sound/soc/omap/omap-mcbsp.h3
-rw-r--r--sound/soc/omap/omap-pcm.c5
-rw-r--r--sound/soc/omap/omap-pcm.h3
-rw-r--r--sound/soc/pxa/pxa-ssp.c36
-rw-r--r--sound/usb/usx2y/us122l.c12
-rw-r--r--sound/usb/usx2y/usb_stream.c67
16 files changed, 327 insertions, 154 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 15500b9d2da..84bb07d39a7 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -47,7 +47,7 @@ MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
struct onyx {
/* cache registers 65 to 80, they are write-only! */
u8 cache[16];
- struct i2c_client i2c;
+ struct i2c_client *i2c;
struct aoa_codec codec;
u32 initialised:1,
spdif_locked:1,
@@ -72,7 +72,7 @@ static int onyx_read_register(struct onyx *onyx, u8 reg, u8 *value)
*value = onyx->cache[reg-FIRSTREGISTER];
return 0;
}
- v = i2c_smbus_read_byte_data(&onyx->i2c, reg);
+ v = i2c_smbus_read_byte_data(onyx->i2c, reg);
if (v < 0)
return -1;
*value = (u8)v;
@@ -84,7 +84,7 @@ static int onyx_write_register(struct onyx *onyx, u8 reg, u8 value)
{
int result;
- result = i2c_smbus_write_byte_data(&onyx->i2c, reg, value);
+ result = i2c_smbus_write_byte_data(onyx->i2c, reg, value);
if (!result)
onyx->cache[reg-FIRSTREGISTER] = value;
return result;
@@ -996,12 +996,45 @@ static void onyx_exit_codec(struct aoa_codec *codec)
onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
}
-static struct i2c_driver onyx_driver;
-
static int onyx_create(struct i2c_adapter *adapter,
struct device_node *node,
int addr)
{
+ struct i2c_board_info info;
+ struct i2c_client *client;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
+ info.addr = addr;
+ info.platform_data = node;
+ client = i2c_new_device(adapter, &info);
+ if (!client)
+ return -ENODEV;
+
+ /*
+ * We know the driver is already loaded, so the device should be
+ * already bound. If not it means binding failed, which suggests
+ * the device doesn't really exist and should be deleted.
+ * Ideally this would be replaced by better checks _before_
+ * instantiating the device.
+ */
+ if (!client->driver) {
+ i2c_unregister_device(client);
+ return -ENODEV;
+ }
+
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&client->detected, &client->driver->clients);
+ return 0;
+}
+
+static int onyx_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device_node *node = client->dev.platform_data;
struct onyx *onyx;
u8 dummy;
@@ -1011,20 +1044,12 @@ static int onyx_create(struct i2c_adapter *adapter,
return -ENOMEM;
mutex_init(&onyx->mutex);
- onyx->i2c.driver = &onyx_driver;
- onyx->i2c.adapter = adapter;
- onyx->i2c.addr = addr & 0x7f;
- strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE);
-
- if (i2c_attach_client(&onyx->i2c)) {
- printk(KERN_ERR PFX "failed to attach to i2c\n");
- goto fail;
- }
+ onyx->i2c = client;
+ i2c_set_clientdata(client, onyx);
/* we try to read from register ONYX_REG_CONTROL
* to check if the codec is present */
if (onyx_read_register(onyx, ONYX_REG_CONTROL, &dummy) != 0) {
- i2c_detach_client(&onyx->i2c);
printk(KERN_ERR PFX "failed to read control register\n");
goto fail;
}
@@ -1036,14 +1061,14 @@ static int onyx_create(struct i2c_adapter *adapter,
onyx->codec.node = of_node_get(node);
if (aoa_codec_register(&onyx->codec)) {
- i2c_detach_client(&onyx->i2c);
goto fail;
}
printk(KERN_DEBUG PFX "created and attached onyx instance\n");
return 0;
fail:
+ i2c_set_clientdata(client, NULL);
kfree(onyx);
- return -EINVAL;
+ return -ENODEV;
}
static int onyx_i2c_attach(struct i2c_adapter *adapter)
@@ -1080,28 +1105,33 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter)
return onyx_create(adapter, NULL, 0x47);
}
-static int onyx_i2c_detach(struct i2c_client *client)
+static int onyx_i2c_remove(struct i2c_client *client)
{
- struct onyx *onyx = container_of(client, struct onyx, i2c);
- int err;
+ struct onyx *onyx = i2c_get_clientdata(client);
- if ((err = i2c_detach_client(client)))
- return err;
aoa_codec_unregister(&onyx->codec);
of_node_put(onyx->codec.node);
if (onyx->codec_info)
kfree(onyx->codec_info);
+ i2c_set_clientdata(client, onyx);
kfree(onyx);
return 0;
}
+static const struct i2c_device_id onyx_i2c_id[] = {
+ { "aoa_codec_onyx", 0 },
+ { }
+};
+
static struct i2c_driver onyx_driver = {
.driver = {
.name = "aoa_codec_onyx",
.owner = THIS_MODULE,
},
.attach_adapter = onyx_i2c_attach,
- .detach_client = onyx_i2c_detach,
+ .probe = onyx_i2c_probe,
+ .remove = onyx_i2c_remove,
+ .id_table = onyx_i2c_id,
};
static int __init onyx_init(void)
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 008e0f85097..f0ebc971c68 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -82,7 +82,7 @@ MODULE_DESCRIPTION("tas codec driver for snd-aoa");
struct tas {
struct aoa_codec codec;
- struct i2c_client i2c;
+ struct i2c_client *i2c;
u32 mute_l:1, mute_r:1 ,
controls_created:1 ,
drc_enabled:1,
@@ -108,9 +108,9 @@ static struct tas *codec_to_tas(struct aoa_codec *codec)
static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data)
{
if (len == 1)
- return i2c_smbus_write_byte_data(&tas->i2c, reg, *data);
+ return i2c_smbus_write_byte_data(tas->i2c, reg, *data);
else
- return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data);
+ return i2c_smbus_write_i2c_block_data(tas->i2c, reg, len, data);
}
static void tas3004_set_drc(struct tas *tas)
@@ -882,12 +882,34 @@ static void tas_exit_codec(struct aoa_codec *codec)
}
-static struct i2c_driver tas_driver;
-
static int tas_create(struct i2c_adapter *adapter,
struct device_node *node,
int addr)
{
+ struct i2c_board_info info;
+ struct i2c_client *client;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
+ info.addr = addr;
+ info.platform_data = node;
+
+ client = i2c_new_device(adapter, &info);
+ if (!client)
+ return -ENODEV;
+
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&client->detected, &client->driver->clients);
+ return 0;
+}
+
+static int tas_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device_node *node = client->dev.platform_data;
struct tas *tas;
tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
@@ -896,17 +918,11 @@ static int tas_create(struct i2c_adapter *adapter,
return -ENOMEM;
mutex_init(&tas->mtx);
- tas->i2c.driver = &tas_driver;
- tas->i2c.adapter = adapter;
- tas->i2c.addr = addr;
+ tas->i2c = client;
+ i2c_set_clientdata(client, tas);
+
/* seems that half is a saner default */
tas->drc_range = TAS3004_DRC_MAX / 2;
- strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE);
-
- if (i2c_attach_client(&tas->i2c)) {
- printk(KERN_ERR PFX "failed to attach to i2c\n");
- goto fail;
- }
strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
tas->codec.owner = THIS_MODULE;
@@ -915,14 +931,12 @@ static int tas_create(struct i2c_adapter *adapter,
tas->codec.node = of_node_get(node);
if (aoa_codec_register(&tas->codec)) {
- goto detach;
+ goto fail;
}
printk(KERN_DEBUG
"snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
- addr, node->full_name);
+ (unsigned int)client->addr, node->full_name);
return 0;
- detach:
- i2c_detach_client(&tas->i2c);
fail:
mutex_destroy(&tas->mtx);
kfree(tas);
@@ -970,14 +984,11 @@ static int tas_i2c_attach(struct i2c_adapter *adapter)
return -ENODEV;
}
-static int tas_i2c_detach(struct i2c_client *client)
+static int tas_i2c_remove(struct i2c_client *client)
{
- struct tas *tas = container_of(client, struct tas, i2c);
- int err;
+ struct tas *tas = i2c_get_clientdata(client);
u8 tmp = TAS_ACR_ANALOG_PDOWN;
- if ((err = i2c_detach_client(client)))
- return err;
aoa_codec_unregister(&tas->codec);
of_node_put(tas->codec.node);
@@ -989,13 +1000,20 @@ static int tas_i2c_detach(struct i2c_client *client)
return 0;
}
+static const struct i2c_device_id tas_i2c_id[] = {
+ { "aoa_codec_tas", 0 },
+ { }
+};
+
static struct i2c_driver tas_driver = {
.driver = {
.name = "aoa_codec_tas",
.owner = THIS_MODULE,
},
.attach_adapter = tas_i2c_attach,
- .detach_client = tas_i2c_detach,
+ .probe = tas_i2c_probe,
+ .remove = tas_i2c_remove,
+ .id_table = tas_i2c_id,
};
static int __init tas_init(void)
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 97ee127ac33..78288dbfc17 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -2122,7 +2122,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
}
/* nothing should be in powerdown mode */
snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
- end_time = jiffies + msecs_to_jiffies(100);
+ end_time = jiffies + msecs_to_jiffies(120);
do {
if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
goto __ready_ok;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 9ce8548c03e..71515ddb459 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1393,6 +1393,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "HP nx6125",
.type = AC97_TUNE_MUTE_LED
},
+ {
+ .subvendor = 0x103c,
+ .subdevice = 0x3091,
+ .name = "unknown HP",
+ .type = AC97_TUNE_MUTE_LED
+ },
{ } /* terminator */
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6ed787eedd0..b8a0d3e7927 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -188,6 +188,8 @@ enum {
ALC663_ASUS_MODE4,
ALC663_ASUS_MODE5,
ALC663_ASUS_MODE6,
+ ALC272_DELL,
+ ALC272_DELL_ZM1,
ALC662_AUTO,
ALC662_MODEL_LAST,
};
@@ -12976,10 +12978,17 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
+ SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
ALC269_ASUS_EEEPC_P901),
SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
ALC269_ASUS_EEEPC_P901),
+ SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
{}
@@ -15210,12 +15219,23 @@ static hda_nid_t alc662_dac_nids[4] = {
0x02, 0x03, 0x04
};
+static hda_nid_t alc272_dac_nids[2] = {
+ 0x02, 0x03
+};
+
static hda_nid_t alc662_adc_nids[1] = {
/* ADC1-2 */
0x09,
};
+static hda_nid_t alc272_adc_nids[1] = {
+ /* ADC1-2 */
+ 0x08,
+};
+
static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
+static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
+
/* input MUX */
/* FIXME: should be a matrix-type input source selection */
@@ -15641,14 +15661,7 @@ static struct hda_verb alc662_init_verbs[] = {
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
/* Input mixer */
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
-
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
/* always trun on EAPD */
{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
@@ -15843,12 +15856,48 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
{}
};
+static struct hda_verb alc272_dell_zm1_init_verbs[] = {
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+static struct hda_verb alc272_dell_init_verbs[] = {
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
{ } /* end */
};
+static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
{
unsigned int present;
@@ -16360,6 +16409,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
+ SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
+ SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
@@ -16372,26 +16423,36 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
+ SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
/*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
+ SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
/*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
+ SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
@@ -16403,6 +16464,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
ALC662_3ST_6ch_DIG),
@@ -16640,6 +16702,36 @@ static struct alc_config_preset alc662_presets[] = {
.unsol_event = alc663_mode6_unsol_event,
.init_hook = alc663_mode6_inithook,
},
+ [ALC272_DELL] = {
+ .mixers = { alc663_m51va_mixer },
+ .cap_mixer = alc272_auto_capture_mixer,
+ .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc272_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .adc_nids = alc272_adc_nids,
+ .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
+ .capsrc_nids = alc272_capsrc_nids,
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc663_m51va_capture_source,
+ .unsol_event = alc663_m51va_unsol_event,
+ .init_hook = alc663_m51va_inithook,
+ },
+ [ALC272_DELL_ZM1] = {
+ .mixers = { alc663_m51va_mixer },
+ .cap_mixer = alc662_auto_capture_mixer,
+ .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc272_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .adc_nids = alc662_adc_nids,
+ .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+ .capsrc_nids = alc662_capsrc_nids,
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc663_m51va_capture_source,
+ .unsol_event = alc663_m51va_unsol_event,
+ .init_hook = alc663_m51va_inithook,
+ },
};
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 8042d539889..173bebf9f51 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2751,11 +2751,12 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
if (pos == 0) {
snd_printk(KERN_ERR "intel8x0: measure - unreliable DMA position..\n");
__retry:
- if (attempt < 2) {
+ if (attempt < 3) {
+ msleep(300);
attempt++;
goto __again;
}
- return;
+ goto __end;
}
pos /= 4;
@@ -2782,6 +2783,7 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
else if (pos < 47500 || pos > 48500)
/* not 48000Hz, tuning the clock.. */
chip->ac97_bus->clock = (chip->ac97_bus->clock * 48000) / pos;
+ __end:
printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock);
snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0);
}
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 6ff99ed7751..a5afb2682e7 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -33,26 +33,25 @@
static struct pmac_keywest *keywest_ctx;
-static int keywest_attach_adapter(struct i2c_adapter *adapter);
-static int keywest_detach_client(struct i2c_client *client);
-
-struct i2c_driver keywest_driver = {
- .driver = {
- .name = "PMac Keywest Audio",
- },
- .attach_adapter = &keywest_attach_adapter,
- .detach_client = &keywest_detach_client,
-};
-
-
#ifndef i2c_device_name
#define i2c_device_name(x) ((x)->name)
#endif
+static int keywest_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ i2c_set_clientdata(client, keywest_ctx);
+ return 0;
+}
+
+/*
+ * This is kind of a hack, best would be to turn powermac to fixed i2c
+ * bus numbers and declare the sound device as part of platform
+ * initialization
+ */
static int keywest_attach_adapter(struct i2c_adapter *adapter)
{
- int err;
- struct i2c_client *new_client;
+ struct i2c_board_info info;
if (! keywest_ctx)
return -EINVAL;
@@ -60,46 +59,47 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
if (strncmp(i2c_device_name(adapter), "mac-io", 6))
return 0; /* ignored */
- new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (! new_client)
- return -ENOMEM;
-
- new_client->addr = keywest_ctx->addr;
- i2c_set_clientdata(new_client, keywest_ctx);
- new_client->adapter = adapter;
- new_client->driver = &keywest_driver;
- new_client->flags = 0;
-
- strcpy(i2c_device_name(new_client), keywest_ctx->name);
- keywest_ctx->client = new_client;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "keywest", I2C_NAME_SIZE);
+ info.addr = keywest_ctx->addr;
+ keywest_ctx->client = i2c_new_device(adapter, &info);
- /* Tell the i2c layer a new client has arrived */
- if (i2c_attach_client(new_client)) {
- snd_printk(KERN_ERR "tumbler: cannot attach i2c client\n");
- err = -ENODEV;
- goto __err;
- }
-
+ /*
+ * Let i2c-core delete that device on driver removal.
+ * This is safe because i2c-core holds the core_lock mutex for us.
+ */
+ list_add_tail(&keywest_ctx->client->detected,
+ &keywest_ctx->client->driver->clients);
return 0;
-
- __err:
- kfree(new_client);
- keywest_ctx->client = NULL;
- return err;
}
-static int keywest_detach_client(struct i2c_client *client)
+static int keywest_remove(struct i2c_client *client)
{
+ i2c_set_clientdata(client, NULL);
if (! keywest_ctx)
return 0;
if (client == keywest_ctx->client)
keywest_ctx->client = NULL;
- i2c_detach_client(client);
- kfree(client);
return 0;
}
+
+static const struct i2c_device_id keywest_i2c_id[] = {
+ { "keywest", 0 },
+ { }
+};
+
+struct i2c_driver keywest_driver = {
+ .driver = {
+ .name = "PMac Keywest Audio",
+ },
+ .attach_adapter = keywest_attach_adapter,
+ .probe = keywest_probe,
+ .remove = keywest_remove,
+ .id_table = keywest_i2c_id,
+};
+
/* exported */
void snd_pmac_keywest_cleanup(struct pmac_keywest *i2c)
{
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 6e23a81dba7..c2d1a7a18fa 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -318,7 +318,7 @@ static int wm9705_reset(struct snd_soc_codec *codec)
}
#ifdef CONFIG_PM
-static int wm9705_soc_suspend(struct platform_device *pdev)
+static int wm9705_soc_suspend(struct platform_device *pdev, pm_message_t msg)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index a6d1178ce12..91ef17992de 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Contact: Jarkko Nikula <jhnikula@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -417,6 +417,6 @@ static void __exit n810_soc_exit(void)
module_init(n810_soc_init);
module_exit(n810_soc_exit);
-MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
+MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
MODULE_DESCRIPTION("ALSA SoC Nokia N810");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 90f4df7fd90..91261428384 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -3,7 +3,8 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Peter Ujfalusi <peter.ujfalusi@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -532,6 +533,6 @@ static void __exit snd_omap_mcbsp_exit(void)
}
module_exit(snd_omap_mcbsp_exit);
-MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
+MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
MODULE_DESCRIPTION("OMAP I2S SoC Interface");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index df7ad13ba73..c8147aace81 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -3,7 +3,8 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Peter Ujfalusi <peter.ujfalusi@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 1bdbb042718..07cf7f46b58 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -3,7 +3,8 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Peter Ujfalusi <peter.ujfalusi@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -367,6 +368,6 @@ static void __exit omap_soc_platform_exit(void)
}
module_exit(omap_soc_platform_exit);
-MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
+MODULE_AUTHOR("Jarkko Nikula <jhnikula@gmail.com>");
MODULE_DESCRIPTION("OMAP PCM DMA module");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index e4369bdfd77..8d9d26916b0 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -3,7 +3,8 @@
*
* Copyright (C) 2008 Nokia Corporation
*
- * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Contact: Jarkko Nikula <jhnikula@gmail.com>
+ * Peter Ujfalusi <peter.ujfalusi@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index de2254475d5..286be31545d 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -280,12 +280,33 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
* ssp_set_clkdiv - set SSP clock divider
* @div: serial clock rate divider
*/
-static void ssp_set_scr(struct ssp_dev *dev, u32 div)
+static void ssp_set_scr(struct ssp_device *ssp, u32 div)
{
- struct ssp_device *ssp = dev->ssp;
- u32 sscr0 = ssp_read_reg(dev->ssp, SSCR0) & ~SSCR0_SCR;
+ u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+
+ if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
+ sscr0 &= ~0x0000ff00;
+ sscr0 |= ((div - 2)/2) << 8; /* 2..512 */
+ } else {
+ sscr0 &= ~0x000fff00;
+ sscr0 |= (div - 1) << 8; /* 1..4096 */
+ }
+ ssp_write_reg(ssp, SSCR0, sscr0);
+}
+
+/**
+ * ssp_get_clkdiv - get SSP clock divider
+ */
+static u32 ssp_get_scr(struct ssp_device *ssp)
+{
+ u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+ u32 div;
- ssp_write_reg(ssp, SSCR0, (sscr0 | SSCR0_SerClkDiv(div)));
+ if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
+ div = ((sscr0 >> 8) & 0xff) * 2 + 2;
+ else
+ div = ((sscr0 >> 8) & 0xfff) + 1;
+ return div;
}
/*
@@ -326,7 +347,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
break;
case PXA_SSP_CLK_AUDIO:
priv->sysclk = 0;
- ssp_set_scr(&priv->dev, 1);
+ ssp_set_scr(ssp, 1);
sscr0 |= SSCR0_ACS;
break;
default:
@@ -387,7 +408,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
ssp_write_reg(ssp, SSACD, val);
break;
case PXA_SSP_DIV_SCR:
- ssp_set_scr(&priv->dev, div);
+ ssp_set_scr(ssp, div);
break;
default:
return -ENODEV;
@@ -674,8 +695,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
case SND_SOC_DAIFMT_I2S:
sspsp = ssp_read_reg(ssp, SSPSP);
- if (((sscr0 & SSCR0_SCR) == SSCR0_SerClkDiv(4)) &&
- (width == 16)) {
+ if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
/* This is a special case where the bitclk is 64fs
* and we're not dealing with 2*32 bits of audio
* samples.
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 012ff1f6f8a..a5aae9d67f3 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -474,6 +474,14 @@ static bool us122l_create_card(struct snd_card *card)
return true;
}
+static void snd_us122l_free(struct snd_card *card)
+{
+ struct us122l *us122l = US122L(card);
+ int index = us122l->chip.index;
+ if (index >= 0 && index < SNDRV_CARDS)
+ snd_us122l_card_used[index] = 0;
+}
+
static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
{
int dev;
@@ -490,7 +498,7 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
if (err < 0)
return err;
snd_us122l_card_used[US122L(card)->chip.index = dev] = 1;
-
+ card->private_free = snd_us122l_free;
US122L(card)->chip.dev = device;
US122L(card)->chip.card = card;
mutex_init(&US122L(card)->mutex);
@@ -584,7 +592,7 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
}
usb_put_intf(intf);
- usb_put_dev(US122L(card)->chip.dev);
+ usb_put_dev(us122l->chip.dev);
while (atomic_read(&us122l->mmap_count))
msleep(500);
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index 24393dafcb6..12ae0340adc 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -33,32 +33,26 @@ static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
{
struct usb_stream *s = sk->s;
- unsigned l = 0;
- int pack;
-
- urb->iso_frame_desc[0].offset = 0;
- urb->iso_frame_desc[0].length = usb_stream_next_packet_size(sk);
- sk->out_phase = sk->out_phase_peeked;
- urb->transfer_buffer_length = urb->iso_frame_desc[0].length;
-
- for (pack = 1; pack < sk->n_o_ps; pack++) {
- l = usb_stream_next_packet_size(sk);
- if (s->idle_outsize + urb->transfer_buffer_length + l >
- s->period_size)
+ int pack, lb = 0;
+
+ for (pack = 0; pack < sk->n_o_ps; pack++) {
+ int l = usb_stream_next_packet_size(sk);
+ if (s->idle_outsize + lb + l > s->period_size)
goto check;
sk->out_phase = sk->out_phase_peeked;
- urb->iso_frame_desc[pack].offset = urb->transfer_buffer_length;
+ urb->iso_frame_desc[pack].offset = lb;
urb->iso_frame_desc[pack].length = l;
- urb->transfer_buffer_length += l;
+ lb += l;
}
- snd_printdd(KERN_DEBUG "%i\n", urb->transfer_buffer_length);
+ snd_printdd(KERN_DEBUG "%i\n", lb);
check:
urb->number_of_packets = pack;
- s->idle_outsize += urb->transfer_buffer_length - s->period_size;
+ urb->transfer_buffer_length = lb;
+ s->idle_outsize += lb - s->period_size;
snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize,
- urb->transfer_buffer_length, s->period_size);
+ lb, s->period_size);
}
static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
@@ -282,21 +276,20 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
struct usb_stream *s = sk->s;
struct urb *io;
struct usb_iso_packet_descriptor *id, *od;
- int p, l = 0;
+ int p = 0, lb = 0, l = 0;
io = sk->idle_outurb;
od = io->iso_frame_desc;
- io->transfer_buffer_length = 0;
- for (p = 0; s->sync_packet < 0; ++p, ++s->sync_packet) {
+ for (; s->sync_packet < 0; ++p, ++s->sync_packet) {
struct urb *ii = sk->completed_inurb;
id = ii->iso_frame_desc +
ii->number_of_packets + s->sync_packet;
l = id->actual_length;
od[p].length = l;
- od[p].offset = io->transfer_buffer_length;
- io->transfer_buffer_length += l;
+ od[p].offset = lb;
+ lb += l;
}
for (;
@@ -304,38 +297,38 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
++p, ++s->sync_packet) {
l = inurb->iso_frame_desc[s->sync_packet].actual_length;
- if (s->idle_outsize + io->transfer_buffer_length + l >
- s->period_size)
+ if (s->idle_outsize + lb + l > s->period_size)
goto check_ok;
od[p].length = l;
- od[p].offset = io->transfer_buffer_length;
- io->transfer_buffer_length += l;
+ od[p].offset = lb;
+ lb += l;
}
check_ok:
s->sync_packet -= inurb->number_of_packets;
- if (s->sync_packet < -2 || s->sync_packet > 0) {
+ if (unlikely(s->sync_packet < -2 || s->sync_packet > 0)) {
snd_printk(KERN_WARNING "invalid sync_packet = %i;"
" p=%i nop=%i %i %x %x %x > %x\n",
s->sync_packet, p, inurb->number_of_packets,
- s->idle_outsize + io->transfer_buffer_length + l,
- s->idle_outsize, io->transfer_buffer_length, l,
+ s->idle_outsize + lb + l,
+ s->idle_outsize, lb, l,
s->period_size);
return -1;
}
- if (io->transfer_buffer_length % s->cfg.frame_size) {
+ if (unlikely(lb % s->cfg.frame_size)) {
snd_printk(KERN_WARNING"invalid outsize = %i\n",
- io->transfer_buffer_length);
+ lb);
return -1;
}
- s->idle_outsize += io->transfer_buffer_length - s->period_size;
+ s->idle_outsize += lb - s->period_size;
io->number_of_packets = p;
- if (s->idle_outsize > 0) {
- snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize);
- return -1;
- }
- return 0;
+ io->transfer_buffer_length = lb;
+ if (s->idle_outsize <= 0)
+ return 0;
+
+ snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize);
+ return -1;
}
static void prepare_inurb(int number_of_packets, struct urb *iu)