summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/onyx.c76
-rw-r--r--sound/aoa/codecs/tas.c66
-rw-r--r--sound/arm/aaci.c2
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c4
-rw-r--r--sound/core/pcm_lib.c17
-rw-r--r--sound/core/pcm_native.c6
-rw-r--r--sound/drivers/pcsp/pcsp_mixer.c4
-rw-r--r--sound/drivers/serial-u16550.c11
-rw-r--r--sound/isa/msnd/msnd.c6
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_patch.c7
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/bt87x.c6
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c2
-rw-r--r--sound/pci/cmipci.c2
-rw-r--r--sound/pci/echoaudio/indigodjx.c1
-rw-r--r--sound/pci/echoaudio/indigoiox.c1
-rw-r--r--sound/pci/emu10k1/io.c2
-rw-r--r--sound/pci/hda/hda_codec.c8
-rw-r--r--sound/pci/hda/hda_intel.c3
-rw-r--r--sound/pci/hda/patch_analog.c53
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_realtek.c113
-rw-r--r--sound/pci/hda/patch_sigmatel.c27
-rw-r--r--sound/pci/intel8x0.c18
-rw-r--r--sound/pci/korg1212/korg1212.c6
-rw-r--r--sound/pci/riptide/riptide.c10
-rw-r--r--sound/pci/via82xx.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c3
-rw-r--r--sound/ppc/keywest.c82
-rw-r--r--sound/soc/au1x/dbdma2.c2
-rw-r--r--sound/soc/codecs/Makefile1
-rw-r--r--sound/soc/codecs/twl4030.c8
-rw-r--r--sound/soc/codecs/wm8350.c2
-rw-r--r--sound/soc/codecs/wm8580.c16
-rw-r--r--sound/soc/codecs/wm8990.c40
-rw-r--r--sound/soc/codecs/wm9705.c2
-rw-r--r--sound/soc/davinci/Kconfig7
-rw-r--r--sound/soc/davinci/davinci-evm.c63
-rw-r--r--sound/soc/davinci/davinci-i2s.c26
-rw-r--r--sound/soc/davinci/davinci-pcm.c71
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c3
-rw-r--r--sound/soc/omap/n810.c4
-rw-r--r--sound/soc/omap/omap-mcbsp.c12
-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/omap/osk5912.c4
-rw-r--r--sound/soc/pxa/palm27x.c27
-rw-r--r--sound/soc/pxa/pxa-ssp.c37
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c12
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c21
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c2
-rw-r--r--sound/soc/sh/dma-sh7760.c3
-rw-r--r--sound/soc/soc-core.c3
-rw-r--r--sound/sparc/dbri.c3
-rw-r--r--sound/usb/caiaq/audio.c12
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/usbaudio.c2
-rw-r--r--sound/usb/usbaudio.h2
-rw-r--r--sound/usb/usbmidi.c12
-rw-r--r--sound/usb/usbquirks.h2
-rw-r--r--sound/usb/usx2y/us122l.c12
-rw-r--r--sound/usb/usx2y/usb_stream.c67
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c3
65 files changed, 724 insertions, 317 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 15500b9d2da0..84bb07d39a7f 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 008e0f85097d..f0ebc971c686 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/arm/aaci.c b/sound/arm/aaci.c
index 7fbd68fab944..5c48e36038f2 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -1074,7 +1074,7 @@ static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
return i;
}
-static int __devinit aaci_probe(struct amba_device *dev, void *id)
+static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
{
struct aaci *aaci;
int ret, i;
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 0afd1a8226fb..6fdca97186e7 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -65,7 +65,7 @@ static void set_resetgpio_mode(int resetgpio_action)
switch (resetgpio_action) {
case RESETGPIO_NORMAL_ALTFUNC:
if (reset_gpio == 113)
- mode = 113 | GPIO_OUT | GPIO_DFLT_LOW;
+ mode = 113 | GPIO_ALT_FN_2_OUT;
if (reset_gpio == 95)
mode = 95 | GPIO_ALT_FN_1_OUT;
break;
@@ -364,7 +364,7 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
{
int ret;
- struct pxa2xx_ac97_platform_data *pdata = dev->dev.platform_data;
+ pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
if (pdata) {
switch (pdata->reset_gpio) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 63d088f2265f..d659995ac3ac 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -249,6 +249,17 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
new_hw_ptr = hw_base + pos;
}
}
+
+ /* Do jiffies check only in xrun_debug mode */
+ if (!xrun_debug(substream))
+ goto no_jiffies_check;
+
+ /* Skip the jiffies check for hardwares with BATCH flag.
+ * Such hardware usually just increases the position at each IRQ,
+ * thus it can't give any strange position.
+ */
+ if (runtime->hw.info & SNDRV_PCM_INFO_BATCH)
+ goto no_jiffies_check;
hdelta = new_hw_ptr - old_hw_ptr;
jdelta = jiffies - runtime->hw_ptr_jiffies;
if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) {
@@ -272,6 +283,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
hw_base -= hw_base % runtime->buffer_size;
delta = 0;
}
+ no_jiffies_check:
if (delta > runtime->period_size + runtime->period_size / 2) {
hw_ptr_error(substream,
"Lost interrupts? "
@@ -329,7 +341,9 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
hw_base = 0;
new_hw_ptr = hw_base + pos;
}
- if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
+ /* Do jiffies check only in xrun_debug mode */
+ if (xrun_debug(substream) &&
+ ((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
hw_ptr_error(substream,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
@@ -1471,7 +1485,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
runtime->status->hw_ptr %= runtime->buffer_size;
else
runtime->status->hw_ptr = 0;
- runtime->hw_ptr_jiffies = jiffies;
snd_pcm_stream_unlock_irqrestore(substream, flags);
return 0;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index fc6f98e257df..b5da656d1ece 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -848,6 +848,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_trigger_tstamp(substream);
+ runtime->hw_ptr_jiffies = jiffies;
runtime->status->state = state;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
runtime->silence_size > 0)
@@ -961,6 +962,11 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
{
if (substream->runtime->trigger_master != substream)
return 0;
+ /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
+ * a delta betwen the current jiffies, this gives a large enough
+ * delta, effectively to skip the check once.
+ */
+ substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
return substream->ops->trigger(substream,
push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c
index caeb0f57fcca..199b03377142 100644
--- a/sound/drivers/pcsp/pcsp_mixer.c
+++ b/sound/drivers/pcsp/pcsp_mixer.c
@@ -50,8 +50,8 @@ static int pcsp_treble_info(struct snd_kcontrol *kcontrol,
uinfo->value.enumerated.items = chip->max_treble + 1;
if (uinfo->value.enumerated.item > chip->max_treble)
uinfo->value.enumerated.item = chip->max_treble;
- sprintf(uinfo->value.enumerated.name, "%d",
- PCSP_CALC_RATE(uinfo->value.enumerated.item));
+ sprintf(uinfo->value.enumerated.name, "%lu",
+ (unsigned long)PCSP_CALC_RATE(uinfo->value.enumerated.item));
return 0;
}
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index b2b6d50c9425..a25fb7b1f441 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -963,16 +963,11 @@ static int __devinit snd_serial_probe(struct platform_device *devptr)
if (err < 0)
goto _err;
- sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d",
+ sprintf(card->longname, "%s [%s] at %#lx, irq %d",
card->shortname,
- uart->base,
- uart->irq,
- uart->speed,
- (int)uart->divisor,
- outs[dev],
- ins[dev],
adaptor_names[uart->adaptor],
- uart->drop_on_full);
+ uart->base,
+ uart->irq);
snd_card_set_dev(card, &devptr->dev);
diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c
index 906454413ed2..3a1526ae1729 100644
--- a/sound/isa/msnd/msnd.c
+++ b/sound/isa/msnd/msnd.c
@@ -438,7 +438,8 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
static struct snd_pcm_hardware snd_msnd_playback = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_8000_48000,
.rate_min = 8000,
@@ -456,7 +457,8 @@ static struct snd_pcm_hardware snd_msnd_playback = {
static struct snd_pcm_hardware snd_msnd_capture = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID,
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_8000_48000,
.rate_min = 8000,
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 97ee127ac33d..78288dbfc17a 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/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 81bc93e5f1e3..7337abdbe4e3 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -958,10 +958,13 @@ static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
}
static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker =
-AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
+AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch",
+ AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
+/* "Sigmatel " removed due to excessive name length: */
static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert =
-AC97_SINGLE("Sigmatel Surround Phase Inversion Playback Switch", AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
+AC97_SINGLE("Surround Phase Inversion Playback Switch",
+ AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = {
AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 9ce8548c03e4..71515ddb4593 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/bt87x.c b/sound/pci/bt87x.c
index a299340519df..ce3f2e90f4d7 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -349,7 +349,8 @@ static struct snd_pcm_hardware snd_bt87x_digital_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID,
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = 0, /* set at runtime */
.channels_min = 2,
@@ -365,7 +366,8 @@ static struct snd_pcm_hardware snd_bt87x_analog_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID,
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
.rates = SNDRV_PCM_RATE_KNOT,
.rate_min = ANALOG_CLOCK / CLOCK_DIV_MAX,
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index ad2888705d2a..c111efe61c3c 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -800,7 +800,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
"Capture Volume",
"External Amplifier",
"Sigmatel 4-Speaker Stereo Playback Switch",
- "Sigmatel Surround Phase Inversion Playback ",
+ "Surround Phase Inversion Playback Switch",
NULL
};
static char *ca0106_rename_ctls[] = {
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index c7899c32aba1..449fe02f666e 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3014,7 +3014,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
.dev_free = snd_cmipci_dev_free,
};
unsigned int val;
- long iomidi;
+ long iomidi = 0;
int integrated_midi = 0;
char modelstr[16];
int pcm_index, pcm_spdif_index;
diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c
index 3482ef69f491..2e44316530a2 100644
--- a/sound/pci/echoaudio/indigodjx.c
+++ b/sound/pci/echoaudio/indigodjx.c
@@ -88,6 +88,7 @@ static struct snd_pcm_hardware pcm_hardware_skel = {
.rates = SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_64000 |
SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000,
.rate_min = 32000,
diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c
index aebee27a40ff..eb3819f9654a 100644
--- a/sound/pci/echoaudio/indigoiox.c
+++ b/sound/pci/echoaudio/indigoiox.c
@@ -89,6 +89,7 @@ static struct snd_pcm_hardware pcm_hardware_skel = {
.rates = SNDRV_PCM_RATE_32000 |
SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_64000 |
SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000,
.rate_min = 32000,
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 4bfc31d1b281..c1a5aa15af8f 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -490,7 +490,7 @@ void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
if (newtime != curtime)
break;
}
- if (count >= 16384)
+ if (count > 16384)
break;
curtime = newtime;
}
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index fd6e6f337d10..8820faf6c9d8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -642,19 +642,21 @@ static int get_codec_name(struct hda_codec *codec)
*/
static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
{
- int i, total_nodes;
+ int i, total_nodes, function_id;
hda_nid_t nid;
total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
for (i = 0; i < total_nodes; i++, nid++) {
- codec->function_id = snd_hda_param_read(codec, nid,
+ function_id = snd_hda_param_read(codec, nid,
AC_PAR_FUNCTION_TYPE) & 0xff;
- switch (codec->function_id) {
+ switch (function_id) {
case AC_GRP_AUDIO_FUNCTION:
codec->afg = nid;
+ codec->function_id = function_id;
break;
case AC_GRP_MODEM_FUNCTION:
codec->mfg = nid;
+ codec->function_id = function_id;
break;
default:
break;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bc882f8f163c..3128e1a6bc65 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -312,7 +312,6 @@ struct azx_dev {
unsigned int period_bytes; /* size of the period in bytes */
unsigned int frags; /* number for period in the play buffer */
unsigned int fifo_size; /* FIFO size */
- unsigned int start_flag: 1; /* stream full start flag */
unsigned long start_jiffies; /* start + minimum jiffies */
unsigned long min_jiffies; /* minimum jiffies before position is valid */
@@ -333,6 +332,7 @@ struct azx_dev {
unsigned int opened :1;
unsigned int running :1;
unsigned int irq_pending :1;
+ unsigned int start_flag: 1; /* stream full start flag */
/*
* For VIA:
* A flag to ensure DMA position is 0
@@ -2141,6 +2141,7 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
/* including bogus ALC268 in slot#2 that conflicts with ALC888 */
SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
/* forced codec slots */
+ SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
{}
};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 38ad3f7b040f..84cc49ca9148 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3817,6 +3817,49 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
{ } /* end */
};
+static struct hda_verb ad1884a_mobile_verbs[] = {
+ /* DACs; unmute as default */
+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
+ /* Port-A (HP) mixer - route only from analog mixer */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* Port-A pin */
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ /* Port-A (HP) pin - always unmuted */
+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ /* Port-B (mic jack) pin */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
+ /* Port-C (int mic) pin */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
+ /* Port-F (int speaker) mixer - route only from analog mixer */
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ /* Port-F pin */
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Analog mixer; mute as default */
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ /* Analog Mix output amp */
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* capture sources */
+ /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* unsolicited event for pin-sense */
+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
+ { } /* end */
+};
+
/*
* Thinkpad X300
* 0x11 - HP
@@ -3977,10 +4020,18 @@ static int patch_ad1884a(struct hda_codec *codec)
spec->input_mux = &ad1884a_laptop_capture_source;
codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
codec->patch_ops.init = ad1884a_hp_init;
+ /* set the upper-limit for mixer amp to 0dB for avoiding the
+ * possible damage by overloading
+ */
+ snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
break;
case AD1884A_MOBILE:
spec->mixers[0] = ad1884a_mobile_mixers;
- spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
+ spec->init_verbs[0] = ad1884a_mobile_verbs;
spec->multiout.dig_out_nid = 0;
codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
codec->patch_ops.init = ad1884a_hp_init;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 56ce19e68cb5..4fcbe21829ab 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1848,6 +1848,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
+ SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
CXT5051_LAPTOP),
SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6ed787eedd06..0fd258eba3a5 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,
};
@@ -774,6 +776,12 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
if (pincap & AC_PINCAP_VREF_80)
val = PIN_VREF80;
+ else if (pincap & AC_PINCAP_VREF_50)
+ val = PIN_VREF50;
+ else if (pincap & AC_PINCAP_VREF_100)
+ val = PIN_VREF100;
+ else if (pincap & AC_PINCAP_VREF_GRD)
+ val = PIN_VREFGRD;
}
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
}
@@ -12056,6 +12064,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
+ SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
@@ -12976,10 +12985,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 +15226,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 +15668,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 +15863,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 +16416,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 +16430,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 +16471,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 +16709,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/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index ce30b459aee6..d2fd8ef6aef8 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -150,6 +150,7 @@ enum {
STAC_D965_REF,
STAC_D965_3ST,
STAC_D965_5ST,
+ STAC_D965_5ST_NO_FP,
STAC_DELL_3ST,
STAC_DELL_BIOS,
STAC_927X_MODELS
@@ -2154,6 +2155,13 @@ static unsigned int d965_5st_pin_configs[14] = {
0x40000100, 0x40000100
};
+static unsigned int d965_5st_no_fp_pin_configs[14] = {
+ 0x40000100, 0x40000100, 0x0181304e, 0x01014010,
+ 0x01a19040, 0x01011012, 0x01016011, 0x40000100,
+ 0x40000100, 0x40000100, 0x40000100, 0x01442070,
+ 0x40000100, 0x40000100
+};
+
static unsigned int dell_3st_pin_configs[14] = {
0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
0x01111212, 0x01116211, 0x01813050, 0x01112214,
@@ -2166,6 +2174,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
[STAC_D965_REF] = ref927x_pin_configs,
[STAC_D965_3ST] = d965_3st_pin_configs,
[STAC_D965_5ST] = d965_5st_pin_configs,
+ [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
[STAC_DELL_3ST] = dell_3st_pin_configs,
[STAC_DELL_BIOS] = NULL,
};
@@ -2176,6 +2185,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
[STAC_D965_REF] = "ref",
[STAC_D965_3ST] = "3stack",
[STAC_D965_5ST] = "5stack",
+ [STAC_D965_5ST_NO_FP] = "5stack-no-fp",
[STAC_DELL_3ST] = "dell-3stack",
[STAC_DELL_BIOS] = "dell-bios",
};
@@ -3076,6 +3086,11 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
unsigned int wid_caps;
for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) {
+ if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
+ wid_caps = get_wcaps(codec, pins[i]);
+ if (wid_caps & AC_WCAP_UNSOL_CAP)
+ spec->hp_detect = 1;
+ }
nid = dac_nids[i];
if (!nid)
continue;
@@ -3119,11 +3134,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
err = create_controls_idx(codec, name, idx, nid, 3);
if (err < 0)
return err;
- if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) {
- wid_caps = get_wcaps(codec, pins[i]);
- if (wid_caps & AC_WCAP_UNSOL_CAP)
- spec->hp_detect = 1;
- }
}
}
return 0;
@@ -4079,7 +4089,12 @@ static int stac92xx_init(struct hda_codec *codec)
pinctl = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
/* if PINCTL already set then skip */
- if (!(pinctl & AC_PINCTL_IN_EN)) {
+ /* Also, if both INPUT and OUTPUT are set,
+ * it must be a BIOS bug; need to override, too
+ */
+ if (!(pinctl & AC_PINCTL_IN_EN) ||
+ (pinctl & AC_PINCTL_OUT_EN)) {
+ pinctl &= ~AC_PINCTL_OUT_EN;
pinctl |= AC_PINCTL_IN_EN;
stac92xx_auto_set_pinctl(codec, nid,
pinctl);
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 5dced5b79387..173bebf9f51d 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1854,6 +1854,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x1028,
+ .subdevice = 0x016a,
+ .name = "Dell Inspiron 8600", /* STAC9750/51 */
+ .type = AC97_TUNE_HP_ONLY
+ },
+ {
+ .subvendor = 0x1028,
.subdevice = 0x0186,
.name = "Dell Latitude D810", /* cf. Malone #41015 */
.type = AC97_TUNE_HP_MUTE_LED
@@ -1896,12 +1902,6 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
},
{
.subvendor = 0x103c,
- .subdevice = 0x0934,
- .name = "HP nx8220",
- .type = AC97_TUNE_MUTE_LED
- },
- {
- .subvendor = 0x103c,
.subdevice = 0x129d,
.name = "HP xw8000",
.type = AC97_TUNE_HP_ONLY
@@ -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/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 8b79969034be..7cc38a11e997 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1238,7 +1238,8 @@ static struct snd_pcm_hardware snd_korg1212_playback_info =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED),
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = (SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000),
@@ -1258,7 +1259,8 @@ static struct snd_pcm_hardware snd_korg1212_capture_info =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED),
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = (SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000),
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 6f1034417a02..e51a5ef1954d 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -889,7 +889,7 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
spin_lock_irqsave(&cif->lock, irqflags);
while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport))
udelay(10);
- if (i >= CMDIF_TIMEOUT) {
+ if (i > CMDIF_TIMEOUT) {
err = -EBUSY;
goto errout;
}
@@ -907,8 +907,10 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */
if ((flags & RESP) && ret) {
while (!IS_DATF(cmdport) &&
- time++ < CMDIF_TIMEOUT)
+ time < CMDIF_TIMEOUT) {
udelay(10);
+ time++;
+ }
if (time < CMDIF_TIMEOUT) { /* read response */
ret->retlongs[0] =
READ_PORT_ULONG(cmdport->data1);
@@ -1454,7 +1456,7 @@ static int snd_riptide_trigger(struct snd_pcm_substream *substream, int cmd)
SEND_GPOS(cif, 0, data->id, &rptr);
udelay(1);
} while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY);
- if (j >= MAX_WRITE_RETRY)
+ if (j > MAX_WRITE_RETRY)
snd_printk(KERN_ERR "Riptide: Could not stop stream!");
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
@@ -1783,7 +1785,7 @@ snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
SEND_SACR(cif, val, reg);
SEND_RACR(cif, reg, &rptr);
} while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY);
- if (i == MAX_WRITE_RETRY)
+ if (i > MAX_WRITE_RETRY)
snd_printdd("Write AC97 reg failed\n");
}
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 809b233dd4a3..1ef58c51c213 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1687,7 +1687,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1);
+static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
.name = "PCM Playback Volume",
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 01066c95580e..d057e6489643 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -240,7 +240,8 @@ static int pdacf_pcm_prepare(struct snd_pcm_substream *subs)
static struct snd_pcm_hardware pdacf_pcm_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 6ff99ed77516..a5afb2682e7f 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/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 30490a259148..594c6c5b7838 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -82,7 +82,7 @@ static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2];
/* PCM hardware DMA capabilities - platform specific */
static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED,
+ SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH,
.formats = AU1XPSC_PCM_FMTS,
.period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES,
.period_bytes_max = 4096 * 1024 - 1,
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 030d2454725f..f2653803ede8 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -56,7 +56,6 @@ obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
-obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 921b205de28a..df7c8c281d2f 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -836,6 +836,12 @@ static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
/*
+ * Gain control for earpiece amplifier
+ * 0 dB to 12 dB in 6 dB steps (mute instead of -6)
+ */
+static DECLARE_TLV_DB_SCALE(output_ear_tvl, -600, 600, 1);
+
+/*
* Capture gain after the ADCs
* from 0 dB to 31 dB in 1 dB steps
*/
@@ -900,7 +906,7 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
4, 3, 0, output_tvl),
SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
- TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
+ TWL4030_REG_EAR_CTL, 4, 3, 0, output_ear_tvl),
/* Common capture gain controls */
SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 3b1d0993bed9..0275321ff8ab 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -968,7 +968,7 @@ static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
* required for LRC in master mode. The DACs or ADCs need a
* valid audio path i.e. pin -> ADC or DAC -> pin before
* the LRC will be enabled in master mode. */
- if (!master && cmd != SNDRV_PCM_TRIGGER_START)
+ if (!master || cmd != SNDRV_PCM_TRIGGER_START)
return 0;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 442ea6f160fc..9f6be3d31ac0 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -268,9 +268,11 @@ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int reg = kcontrol->private_value & 0xff;
- int reg2 = (kcontrol->private_value >> 24) & 0xff;
+ unsigned int reg = mc->reg;
+ unsigned int reg2 = mc->rreg;
int ret;
u16 val;
@@ -292,15 +294,17 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
return 0;
}
-#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \
+#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
+ xinvert, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
SNDRV_CTL_ELEM_ACCESS_READWRITE, \
.tlv.p = (tlv_array), \
.info = snd_soc_info_volsw_2r, \
.get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
- .private_value = (reg_left) | ((shift) << 8) | \
- ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
+ .private_value = (unsigned long)&(struct soc_mixer_control) \
+ {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
+ .max = xmax, .invert = xinvert} }
static const struct snd_kcontrol_new wm8580_snd_controls[] = {
SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume",
@@ -522,7 +526,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
reg = wm8580_read(codec, WM8580_PLLA4 + offset);
reg &= ~0x3f;
reg |= pll_div.prescale | pll_div.postscale << 1 |
- pll_div.freqmode << 4;
+ pll_div.freqmode << 3;
wm8580_write(codec, WM8580_PLLA4 + offset, reg);
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index c518c3e5aa3f..40cd274eb1ef 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -729,7 +729,7 @@ SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0,
inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* AINLMUX */
-SND_SOC_DAPM_MUX_E("AILNMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
+SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
&wm8990_dapm_ainlmux_controls, inmixer_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -740,7 +740,7 @@ SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0,
inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* AINRMUX */
-SND_SOC_DAPM_MUX_E("AIRNMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
+SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
&wm8990_dapm_ainrmux_controls, inmixer_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
@@ -848,40 +848,40 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"LIN12 PGA", "LIN2 Switch", "LIN2"},
/* LIN34 PGA */
{"LIN34 PGA", "LIN3 Switch", "LIN3"},
- {"LIN34 PGA", "LIN4 Switch", "LIN4"},
+ {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
/* INMIXL */
{"INMIXL", "Record Left Volume", "LOMIX"},
{"INMIXL", "LIN2 Volume", "LIN2"},
{"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
{"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
- /* AILNMUX */
- {"AILNMUX", "INMIXL Mix", "INMIXL"},
- {"AILNMUX", "DIFFINL Mix", "LIN12PGA"},
- {"AILNMUX", "DIFFINL Mix", "LIN34PGA"},
- {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
- {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
+ /* AINLMUX */
+ {"AINLMUX", "INMIXL Mix", "INMIXL"},
+ {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
+ {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
+ {"AINLMUX", "RXVOICE Mix", "LIN4/RXN"},
+ {"AINLMUX", "RXVOICE Mix", "RIN4/RXP"},
/* ADC */
- {"Left ADC", NULL, "AILNMUX"},
+ {"Left ADC", NULL, "AINLMUX"},
/* RIN12 PGA */
{"RIN12 PGA", "RIN1 Switch", "RIN1"},
{"RIN12 PGA", "RIN2 Switch", "RIN2"},
/* RIN34 PGA */
{"RIN34 PGA", "RIN3 Switch", "RIN3"},
- {"RIN34 PGA", "RIN4 Switch", "RIN4"},
+ {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
/* INMIXL */
{"INMIXR", "Record Right Volume", "ROMIX"},
{"INMIXR", "RIN2 Volume", "RIN2"},
{"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
{"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
- /* AIRNMUX */
- {"AIRNMUX", "INMIXR Mix", "INMIXR"},
- {"AIRNMUX", "DIFFINR Mix", "RIN12PGA"},
- {"AIRNMUX", "DIFFINR Mix", "RIN34PGA"},
- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXN"},
- {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
+ /* AINRMUX */
+ {"AINRMUX", "INMIXR Mix", "INMIXR"},
+ {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
+ {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
+ {"AINRMUX", "RXVOICE Mix", "LIN4/RXN"},
+ {"AINRMUX", "RXVOICE Mix", "RIN4/RXP"},
/* ADC */
- {"Right ADC", NULL, "AIRNMUX"},
+ {"Right ADC", NULL, "AINRMUX"},
/* LOMIX */
{"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
@@ -922,7 +922,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
/* OUT3MIX */
- {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXP"},
+ {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
{"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
/* OUT4MIX */
@@ -949,7 +949,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
/* Output Pins */
{"LON", NULL, "LONMIX"},
{"LOP", NULL, "LOPMIX"},
- {"OUT", NULL, "OUT3MIX"},
+ {"OUT3", NULL, "OUT3MIX"},
{"LOUT", NULL, "LOUT PGA"},
{"SPKN", NULL, "SPKMIX"},
{"ROUT", NULL, "ROUT PGA"},
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 6e23a81dba78..c2d1a7a18fa3 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/davinci/Kconfig b/sound/soc/davinci/Kconfig
index bd7392c9657e..411a710be660 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -10,13 +10,14 @@ config SND_DAVINCI_SOC_I2S
tristate
config SND_DAVINCI_SOC_EVM
- tristate "SoC Audio support for DaVinci EVM"
- depends on SND_DAVINCI_SOC && MACH_DAVINCI_EVM
+ tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM"
+ depends on SND_DAVINCI_SOC
+ depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM
select SND_DAVINCI_SOC_I2S
select SND_SOC_TLV320AIC3X
help
Say Y if you want to add support for SoC audio on TI
- DaVinci EVM platform.
+ DaVinci DM6446 or DM355 EVM platforms.
config SND_DAVINCI_SOC_SFFSDR
tristate "SoC Audio support for SFFSDR"
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 9b90b347007c..58fd1cbedd88 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -20,7 +20,11 @@
#include <sound/soc-dapm.h>
#include <asm/dma.h>
-#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#include <mach/asp.h>
+#include <mach/edma.h>
+#include <mach/mux.h>
#include "../codecs/tlv320aic3x.h"
#include "davinci-pcm.h"
@@ -150,7 +154,7 @@ static struct snd_soc_card snd_soc_card_evm = {
/* evm audio private data */
static struct aic3x_setup_data evm_aic3x_setup = {
- .i2c_bus = 0,
+ .i2c_bus = 1,
.i2c_address = 0x1b,
};
@@ -161,36 +165,73 @@ static struct snd_soc_device evm_snd_devdata = {
.codec_data = &evm_aic3x_setup,
};
+/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
static struct resource evm_snd_resources[] = {
{
- .start = DAVINCI_MCBSP_BASE,
- .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
+ .start = DAVINCI_ASP0_BASE,
+ .end = DAVINCI_ASP0_BASE + SZ_8K - 1,
.flags = IORESOURCE_MEM,
},
};
static struct evm_snd_platform_data evm_snd_data = {
- .tx_dma_ch = DM644X_DMACH_MCBSP_TX,
- .rx_dma_ch = DM644X_DMACH_MCBSP_RX,
+ .tx_dma_ch = DAVINCI_DMA_ASP0_TX,
+ .rx_dma_ch = DAVINCI_DMA_ASP0_RX,
+};
+
+/* DM335 EVM uses ASP1; line-out is a stereo mini-jack */
+static struct resource dm335evm_snd_resources[] = {
+ {
+ .start = DAVINCI_ASP1_BASE,
+ .end = DAVINCI_ASP1_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct evm_snd_platform_data dm335evm_snd_data = {
+ .tx_dma_ch = DAVINCI_DMA_ASP1_TX,
+ .rx_dma_ch = DAVINCI_DMA_ASP1_RX,
};
static struct platform_device *evm_snd_device;
static int __init evm_init(void)
{
+ struct resource *resources;
+ unsigned num_resources;
+ struct evm_snd_platform_data *data;
+ int index;
int ret;
- evm_snd_device = platform_device_alloc("soc-audio", 0);
+ if (machine_is_davinci_evm()) {
+ davinci_cfg_reg(DM644X_MCBSP);
+
+ resources = evm_snd_resources;
+ num_resources = ARRAY_SIZE(evm_snd_resources);
+ data = &evm_snd_data;
+ index = 0;
+ } else if (machine_is_davinci_dm355_evm()) {
+ /* we don't use ASP1 IRQs, or we'd need to mux them ... */
+ davinci_cfg_reg(DM355_EVT8_ASP1_TX);
+ davinci_cfg_reg(DM355_EVT9_ASP1_RX);
+
+ resources = dm335evm_snd_resources;
+ num_resources = ARRAY_SIZE(dm335evm_snd_resources);
+ data = &dm335evm_snd_data;
+ index = 1;
+ } else
+ return -EINVAL;
+
+ evm_snd_device = platform_device_alloc("soc-audio", index);
if (!evm_snd_device)
return -ENOMEM;
platform_set_drvdata(evm_snd_device, &evm_snd_devdata);
evm_snd_devdata.dev = &evm_snd_device->dev;
- platform_device_add_data(evm_snd_device, &evm_snd_data,
- sizeof(evm_snd_data));
+ platform_device_add_data(evm_snd_device, data, sizeof(*data));
- ret = platform_device_add_resources(evm_snd_device, evm_snd_resources,
- ARRAY_SIZE(evm_snd_resources));
+ ret = platform_device_add_resources(evm_snd_device, resources,
+ num_resources);
if (ret) {
platform_device_put(evm_snd_device);
return ret;
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index ffdb9439d3d8..b1ea52fc83c7 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -24,6 +24,26 @@
#include "davinci-pcm.h"
+
+/*
+ * NOTE: terminology here is confusing.
+ *
+ * - This driver supports the "Audio Serial Port" (ASP),
+ * found on dm6446, dm355, and other DaVinci chips.
+ *
+ * - But it labels it a "Multi-channel Buffered Serial Port"
+ * (McBSP) as on older chips like the dm642 ... which was
+ * backward-compatible, possibly explaining that confusion.
+ *
+ * - OMAP chips have a controller called McBSP, which is
+ * incompatible with the DaVinci flavor of McBSP.
+ *
+ * - Newer DaVinci chips have a controller called McASP,
+ * incompatible with ASP and with either McBSP.
+ *
+ * In short: this uses ASP to implement I2S, not McBSP.
+ * And it won't be the only DaVinci implemention of I2S.
+ */
#define DAVINCI_MCBSP_DRR_REG 0x00
#define DAVINCI_MCBSP_DXR_REG 0x04
#define DAVINCI_MCBSP_SPCR_REG 0x08
@@ -421,7 +441,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_card *card = socdev->card;
- struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
+ struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
struct davinci_mcbsp_dev *dev;
struct resource *mem, *ioarea;
struct evm_snd_platform_data *pdata;
@@ -448,7 +468,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
cpu_dai->private_data = dev;
- dev->clk = clk_get(&pdev->dev, "McBSPCLK");
+ dev->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(dev->clk)) {
ret = -ENODEV;
goto err_free_mem;
@@ -483,7 +503,7 @@ static void davinci_i2s_remove(struct platform_device *pdev,
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_card *card = socdev->card;
- struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
+ struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
struct resource *mem;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 7af3b5b3a53d..a05996588489 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -22,6 +22,7 @@
#include <sound/soc.h>
#include <asm/dma.h>
+#include <mach/edma.h>
#include "davinci-pcm.h"
@@ -51,7 +52,7 @@ struct davinci_runtime_data {
spinlock_t lock;
int period; /* current DMA period */
int master_lch; /* Master DMA channel */
- int slave_lch; /* Slave DMA channel */
+ int slave_lch; /* linked parameter RAM reload slot */
struct davinci_pcm_dma_params *params; /* DMA params */
};
@@ -90,18 +91,18 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
dst_bidx = data_type;
}
- davinci_set_dma_src_params(lch, src, INCR, W8BIT);
- davinci_set_dma_dest_params(lch, dst, INCR, W8BIT);
- davinci_set_dma_src_index(lch, src_bidx, 0);
- davinci_set_dma_dest_index(lch, dst_bidx, 0);
- davinci_set_dma_transfer_params(lch, data_type, count, 1, 0, ASYNC);
+ edma_set_src(lch, src, INCR, W8BIT);
+ edma_set_dest(lch, dst, INCR, W8BIT);
+ edma_set_src_index(lch, src_bidx, 0);
+ edma_set_dest_index(lch, dst_bidx, 0);
+ edma_set_transfer_params(lch, data_type, count, 1, 0, ASYNC);
prtd->period++;
if (unlikely(prtd->period >= runtime->periods))
prtd->period = 0;
}
-static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data)
+static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
{
struct snd_pcm_substream *substream = data;
struct davinci_runtime_data *prtd = substream->runtime->private_data;
@@ -125,7 +126,7 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
struct davinci_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
- int tcc = TCC_ANY;
+ struct edmacc_param p_ram;
int ret;
if (!dma_data)
@@ -134,22 +135,34 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
prtd->params = dma_data;
/* Request master DMA channel */
- ret = davinci_request_dma(prtd->params->channel, prtd->params->name,
+ ret = edma_alloc_channel(prtd->params->channel,
davinci_pcm_dma_irq, substream,
- &prtd->master_lch, &tcc, EVENTQ_0);
- if (ret)
+ EVENTQ_0);
+ if (ret < 0)
return ret;
+ prtd->master_lch = ret;
- /* Request slave DMA channel */
- ret = davinci_request_dma(PARAM_ANY, "Link",
- NULL, NULL, &prtd->slave_lch, &tcc, EVENTQ_0);
- if (ret) {
- davinci_free_dma(prtd->master_lch);
+ /* Request parameter RAM reload slot */
+ ret = edma_alloc_slot(EDMA_SLOT_ANY);
+ if (ret < 0) {
+ edma_free_channel(prtd->master_lch);
return ret;
}
-
- /* Link slave DMA channel in loopback */
- davinci_dma_link_lch(prtd->slave_lch, prtd->slave_lch);
+ prtd->slave_lch = ret;
+
+ /* Issue transfer completion IRQ when the channel completes a
+ * transfer, then always reload from the same slot (by a kind
+ * of loopback link). The completion IRQ handler will update
+ * the reload slot with a new buffer.
+ *
+ * REVISIT save p_ram here after setting up everything except
+ * the buffer and its length (ccnt) ... use it as a template
+ * so davinci_pcm_enqueue_dma() takes less time in IRQ.
+ */
+ edma_read_slot(prtd->slave_lch, &p_ram);
+ p_ram.opt |= TCINTEN | EDMA_TCC(prtd->master_lch);
+ p_ram.link_bcntrld = prtd->slave_lch << 5;
+ edma_write_slot(prtd->slave_lch, &p_ram);
return 0;
}
@@ -165,12 +178,12 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- davinci_start_dma(prtd->master_lch);
+ edma_start(prtd->master_lch);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- davinci_stop_dma(prtd->master_lch);
+ edma_stop(prtd->master_lch);
break;
default:
ret = -EINVAL;
@@ -185,14 +198,14 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
{
struct davinci_runtime_data *prtd = substream->runtime->private_data;
- struct paramentry_descriptor temp;
+ struct edmacc_param temp;
prtd->period = 0;
davinci_pcm_enqueue_dma(substream);
- /* Get slave channel dma params for master channel startup */
- davinci_get_dma_params(prtd->slave_lch, &temp);
- davinci_set_dma_params(prtd->master_lch, &temp);
+ /* Copy self-linked parameter RAM entry into master channel */
+ edma_read_slot(prtd->slave_lch, &temp);
+ edma_write_slot(prtd->master_lch, &temp);
return 0;
}
@@ -208,7 +221,7 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
spin_lock(&prtd->lock);
- davinci_dma_getposition(prtd->master_lch, &src, &dst);
+ edma_get_position(prtd->master_lch, &src, &dst);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
count = src - runtime->dma_addr;
else
@@ -253,10 +266,10 @@ static int davinci_pcm_close(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct davinci_runtime_data *prtd = runtime->private_data;
- davinci_dma_unlink_lch(prtd->slave_lch, prtd->slave_lch);
+ edma_unlink(prtd->slave_lch);
- davinci_free_dma(prtd->slave_lch);
- davinci_free_dma(prtd->master_lch);
+ edma_free_slot(prtd->slave_lch);
+ edma_free_channel(prtd->master_lch);
kfree(prtd);
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 3aa729df27b5..1111c710118a 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -504,7 +504,8 @@ static struct snd_soc_dai psc_i2s_dai_template = {
static const struct snd_pcm_hardware psc_i2s_pcm_hardware = {
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
.rate_min = 8000,
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index a6d1178ce128..91ef17992de5 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 9c09b94f0cf8..912614283848 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
@@ -283,7 +284,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
break;
case SND_SOC_DAIFMT_DSP_B:
regs->srgr2 |= FPER(wlen * channels - 1);
- regs->srgr1 |= FWID(wlen * channels - 2);
+ regs->srgr1 |= FWID(0);
break;
}
@@ -302,6 +303,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
{
struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
+ unsigned int temp_fmt = fmt;
if (mcbsp_data->configured)
return 0;
@@ -328,6 +330,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
/* 0-bit data delay */
regs->rcr2 |= RDATDLY(0);
regs->xcr2 |= XDATDLY(0);
+ /* Invert FS polarity configuration */
+ temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
break;
default:
/* Unsupported data format */
@@ -351,7 +355,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
}
/* Set bit clock (CLKX/CLKR) and FS polarities */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
/*
* Normal BCLK + FS.
@@ -529,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 df7ad13ba73d..c8147aace813 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 1bdbb0427183..07cf7f46b584 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 e4369bdfd77d..8d9d26916b05 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/omap/osk5912.c b/sound/soc/omap/osk5912.c
index a952a4eb3361..a4e149b7f0eb 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -62,7 +62,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
/* Set codec DAI configuration */
err = snd_soc_dai_set_fmt(codec_dai,
SND_SOC_DAIFMT_DSP_B |
- SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM);
if (err < 0) {
printk(KERN_ERR "can't set codec DAI configuration\n");
@@ -72,7 +72,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
/* Set cpu DAI configuration */
err = snd_soc_dai_set_fmt(cpu_dai,
SND_SOC_DAIFMT_DSP_B |
- SND_SOC_DAIFMT_NB_IF |
+ SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM);
if (err < 0) {
printk(KERN_ERR "can't set cpu DAI configuration\n");
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 48a73f64500b..44fcc4e01e08 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -200,7 +200,7 @@ static struct snd_soc_device palm27x_snd_devdata = {
static struct platform_device *palm27x_snd_device;
-static int __init palm27x_asoc_init(void)
+static int palm27x_asoc_probe(struct platform_device *pdev)
{
int ret;
@@ -208,6 +208,10 @@ static int __init palm27x_asoc_init(void)
machine_is_palmld()))
return -ENODEV;
+ if (pdev->dev.platform_data)
+ palm27x_ep_gpio = ((struct palm27x_asoc_info *)
+ (pdev->dev.platform_data))->jack_gpio;
+
ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
if (ret)
return ret;
@@ -245,16 +249,31 @@ err_alloc:
return ret;
}
-static void __exit palm27x_asoc_exit(void)
+static int __devexit palm27x_asoc_remove(struct platform_device *pdev)
{
free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
gpio_free(palm27x_ep_gpio);
platform_device_unregister(palm27x_snd_device);
+ return 0;
}
-void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data)
+static struct platform_driver palm27x_wm9712_driver = {
+ .probe = palm27x_asoc_probe,
+ .remove = __devexit_p(palm27x_asoc_remove),
+ .driver = {
+ .name = "palm27x-asoc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init palm27x_asoc_init(void)
+{
+ return platform_driver_register(&palm27x_wm9712_driver);
+}
+
+static void __exit palm27x_asoc_exit(void)
{
- palm27x_ep_gpio = data->jack_gpio;
+ platform_driver_unregister(&palm27x_wm9712_driver);
}
module_init(palm27x_asoc_init);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 308a657928d2..286be31545df 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.
@@ -806,6 +826,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
goto err_priv;
}
+ priv->dai_fmt = (unsigned int) -1;
dai->private_data = priv;
return 0;
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 32063790d95b..93e6c87b7399 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -69,8 +69,8 @@ static int jive_hw_params(struct snd_pcm_substream *substream,
break;
}
- s3c_i2sv2_calc_rate(&div, NULL, params_rate(params),
- s3c2412_get_iisclk());
+ s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
+ s3c2412_get_iisclk());
/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
@@ -145,8 +145,9 @@ static struct snd_soc_dai_link jive_dai = {
};
/* jive audio machine driver */
-static struct snd_soc_machine snd_soc_machine_jive = {
+static struct snd_soc_card snd_soc_machine_jive = {
.name = "Jive",
+ .platform = &s3c24xx_soc_platform,
.dai_link = &jive_dai,
.num_links = 1,
};
@@ -157,9 +158,8 @@ static struct wm8750_setup_data jive_wm8750_setup = {
/* jive audio subsystem */
static struct snd_soc_device jive_snd_devdata = {
- .machine = &snd_soc_machine_jive,
- .platform = &s3c24xx_soc_platform,
- .codec_dev = &soc_codec_dev_wm8750_spi,
+ .card = &snd_soc_machine_jive,
+ .codec_dev = &soc_codec_dev_wm8750,
.codec_data = &jive_wm8750_setup,
};
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 295a4c910262..ab680aac3fcb 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -473,9 +473,9 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
/* default table of all avaialable root fs divisors */
static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
-int s3c2412_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
- unsigned int *fstab,
- unsigned int rate, struct clk *clk)
+int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
+ unsigned int *fstab,
+ unsigned int rate, struct clk *clk)
{
unsigned long clkrate = clk_get_rate(clk);
unsigned int div;
@@ -531,7 +531,7 @@ int s3c2412_iis_calc_rate(struct s3c_i2sv2_rate_calc *info,
return 0;
}
-EXPORT_SYMBOL_GPL(s3c2412_iis_calc_rate);
+EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate);
int s3c_i2sv2_probe(struct platform_device *pdev,
struct snd_soc_dai *dai,
@@ -624,15 +624,18 @@ static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
int s3c_i2sv2_register_dai(struct snd_soc_dai *dai)
{
- dai->ops.trigger = s3c2412_i2s_trigger;
- dai->ops.hw_params = s3c2412_i2s_hw_params;
- dai->ops.set_fmt = s3c2412_i2s_set_fmt;
- dai->ops.set_clkdiv = s3c2412_i2s_set_clkdiv;
+ struct snd_soc_dai_ops *ops = dai->ops;
+
+ ops->trigger = s3c2412_i2s_trigger;
+ ops->hw_params = s3c2412_i2s_hw_params;
+ ops->set_fmt = s3c2412_i2s_set_fmt;
+ ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
dai->suspend = s3c2412_i2s_suspend;
dai->resume = s3c2412_i2s_resume;
return snd_soc_register_dai(dai);
}
-
EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index 1ca3cdaa8213..b7e0b3f0bfc8 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -33,8 +33,8 @@
#include <plat/regs-s3c2412-iis.h>
-#include <plat/regs-gpio.h>
#include <plat/audio.h>
+#include <mach/regs-gpio.h>
#include <mach/dma.h>
#include "s3c24xx-pcm.h"
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 0dad3a0bb920..baddb1242c71 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -103,7 +103,8 @@ static struct snd_pcm_hardware camelot_pcm_hardware = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH),
.formats = DMABRG_FMTS,
.rates = DMABRG_RATES,
.rate_min = 8000,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 99712f652d0d..1cd149b9ce69 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -954,6 +954,9 @@ static int soc_remove(struct platform_device *pdev)
struct snd_soc_platform *platform = card->platform;
struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
+ if (!card->instantiated)
+ return 0;
+
run_delayed_work(&card->delayed_work);
if (platform->remove)
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index af95ff1e126c..1d2e51b3f918 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -1975,7 +1975,8 @@ static struct snd_pcm_hardware snd_dbri_pcm_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID,
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH,
.formats = SNDRV_PCM_FMTBIT_MU_LAW |
SNDRV_PCM_FMTBIT_A_LAW |
SNDRV_PCM_FMTBIT_U8 |
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 3f45c0fe61ab..b13ce767ac72 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -195,11 +195,14 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
debug("%s(%p)\n", __func__, substream);
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ dev->period_out_count[index] = BYTES_PER_SAMPLE + 1;
dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1;
- else
+ } else {
+ dev->period_in_count[index] = BYTES_PER_SAMPLE;
dev->audio_in_buf_pos[index] = BYTES_PER_SAMPLE;
-
+ }
+
if (dev->streaming)
return 0;
@@ -300,8 +303,7 @@ static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
if (!sub)
continue;
- pb = frames_to_bytes(sub->runtime,
- sub->runtime->period_size);
+ pb = snd_pcm_lib_period_bytes(sub);
cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
&dev->period_out_count[stream] :
&dev->period_in_count[stream];
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 6d517705da0e..515de1cd2a3e 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -35,7 +35,7 @@
#include "input.h"
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio, version 1.3.13");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.3.14");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, RigKontrol3},"
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 823296d7d578..a6b88482637b 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3347,7 +3347,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
[QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface,
[QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface,
[QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface,
- [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
+ [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface,
[QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
[QUIRK_MIDI_CME] = snd_usb_create_midi_interface,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 36e4f7a29adc..8e7f78941ba6 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -153,7 +153,7 @@ enum quirk_type {
QUIRK_MIDI_YAMAHA,
QUIRK_MIDI_MIDIMAN,
QUIRK_MIDI_NOVATION,
- QUIRK_MIDI_RAW,
+ QUIRK_MIDI_FASTLANE,
QUIRK_MIDI_EMAGIC,
QUIRK_MIDI_CME,
QUIRK_MIDI_US122L,
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 26bad373fe65..2fb35cc22a30 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -1778,8 +1778,18 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
- case QUIRK_MIDI_RAW:
+ case QUIRK_MIDI_FASTLANE:
umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
+ /*
+ * Interface 1 contains isochronous endpoints, but with the same
+ * numbers as in interface 0. Since it is interface 1 that the
+ * USB core has most recently seen, these descriptors are now
+ * associated with the endpoint numbers. This will foul up our
+ * attempts to submit bulk/interrupt URBs to the endpoints in
+ * interface 0, so we have to make sure that the USB core looks
+ * again at interface 0 by calling usb_set_interface() on it.
+ */
+ usb_set_interface(umidi->chip->dev, 0, 0);
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
case QUIRK_MIDI_EMAGIC:
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 647ef5029651..5d955aaad85f 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1868,7 +1868,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.data = & (const struct snd_usb_audio_quirk[]) {
{
.ifnum = 0,
- .type = QUIRK_MIDI_RAW
+ .type = QUIRK_MIDI_FASTLANE
},
{
.ifnum = 1,
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 012ff1f6f8af..a5aae9d67f31 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 24393dafcb6e..12ae0340adc0 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)
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 9a608fa85155..dd1ab6177840 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -870,7 +870,8 @@ static struct snd_pcm_hardware snd_usX2Y_2c =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
.rate_min = 44100,