提交 20107f84 编写于 作者: L Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: hda - Don't check invalid HP pin
  ALSA: dummy - Fix descriptions of pcm_substreams parameter
  ALSA: pcmcia: use dynamic debug infrastructure, deprecate CS_CHECK (sound)
  ALSA: hda: Use quirk mask for Dell Inspiron Mini9/Vostro A90 using ALC268
  sound: via82xx: deactivate DXS controls of inactive streams
  ALSA: snd-usb-caiaq: Bump version number to 1.3.20
  ALSA: snd-usb-caiaq: Lock on stream start/unpause
  ALSA: snd-usb-caiaq: Missing lock around use of buffer positions
  ALSA: sound/parisc: Move dereference after NULL test
  ALSA: sound: Move dereference after NULL test and drop unnecessary NULL tests
  ALSA: hda_intel: Add the Linux device ID for NVIDIA HDA controller
  ALSA: pcsp - Fix nforce workaround
  ALSA: SND_CS5535AUDIO: Remove the X86 platform dependency
  ASoC: Amstrad Delta: add info about the line discipline requirement to Kconfig help text
  ASoC: Fix possible codec_dai->ops NULL pointer problems
  ALSA: hda - Fix capture source checks for ALC662/663 codecs
  ASoC: Serialize access to dapm_power_widgets()
......@@ -522,7 +522,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
pcm_devs - Number of PCM devices assigned to each card
(default = 1, up to 4)
pcm_substreams - Number of PCM substreams assigned to each PCM
(default = 8, up to 16)
(default = 8, up to 128)
hrtimer - Use hrtimer (=1, default) or system timer (=0)
fake_buffer - Fake buffer allocations (default = 1)
......
......@@ -953,11 +953,12 @@ static int snd_pcm_dev_register(struct snd_device *device)
struct snd_pcm_substream *substream;
struct snd_pcm_notify *notify;
char str[16];
struct snd_pcm *pcm = device->device_data;
struct snd_pcm *pcm;
struct device *dev;
if (snd_BUG_ON(!pcm || !device))
if (snd_BUG_ON(!device || !device->device_data))
return -ENXIO;
pcm = device->device_data;
mutex_lock(&register_mutex);
err = snd_pcm_add(pcm);
if (err) {
......
......@@ -165,7 +165,7 @@ MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
module_param_array(pcm_devs, int, NULL, 0444);
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
module_param_array(pcm_substreams, int, NULL, 0444);
MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver.");
MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
//module_param_array(midi_devs, int, NULL, 0444);
//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
module_param(fake_buffer, bool, 0444);
......@@ -808,8 +808,6 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
unsigned int idx;
int err;
if (snd_BUG_ON(!dummy))
return -EINVAL;
spin_lock_init(&dummy->mixer_lock);
strcpy(card->mixername, "Dummy Mixer");
......
......@@ -39,25 +39,20 @@ static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
/* write the port and returns the next expire time in ns;
* called at the trigger-start and in hrtimer callback
*/
static unsigned long pcsp_timer_update(struct hrtimer *handle)
static u64 pcsp_timer_update(struct snd_pcsp *chip)
{
unsigned char timer_cnt, val;
u64 ns;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
unsigned long flags;
if (chip->thalf) {
outb(chip->val61, 0x61);
chip->thalf = 0;
if (!atomic_read(&chip->timer_active))
return 0;
return chip->ns_rem;
}
if (!atomic_read(&chip->timer_active))
return 0;
substream = chip->playback_substream;
if (!substream)
return 0;
......@@ -88,24 +83,17 @@ static unsigned long pcsp_timer_update(struct hrtimer *handle)
return ns;
}
enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
static void pcsp_pointer_update(struct snd_pcsp *chip)
{
struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
struct snd_pcm_substream *substream;
int periods_elapsed, pointer_update;
size_t period_bytes, buffer_bytes;
unsigned long ns;
int periods_elapsed;
unsigned long flags;
pointer_update = !chip->thalf;
ns = pcsp_timer_update(handle);
if (!ns)
return HRTIMER_NORESTART;
/* update the playback position */
substream = chip->playback_substream;
if (!substream)
return HRTIMER_NORESTART;
return;
period_bytes = snd_pcm_lib_period_bytes(substream);
buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
......@@ -134,6 +122,26 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
if (periods_elapsed)
tasklet_schedule(&pcsp_pcm_tasklet);
}
enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
{
struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
int pointer_update;
u64 ns;
if (!atomic_read(&chip->timer_active) || !chip->playback_substream)
return HRTIMER_NORESTART;
pointer_update = !chip->thalf;
ns = pcsp_timer_update(chip);
if (!ns) {
printk(KERN_WARNING "PCSP: unexpected stop\n");
return HRTIMER_NORESTART;
}
if (pointer_update)
pcsp_pointer_update(chip);
hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
......@@ -142,8 +150,6 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
static int pcsp_start_playing(struct snd_pcsp *chip)
{
unsigned long ns;
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: start_playing called\n");
#endif
......@@ -159,11 +165,7 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
atomic_set(&chip->timer_active, 1);
chip->thalf = 0;
ns = pcsp_timer_update(&pcsp_chip.timer);
if (!ns)
return -EIO;
hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL);
return 0;
}
......@@ -232,21 +234,22 @@ static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
pcsp_sync_stop(chip);
chip->playback_ptr = 0;
chip->period_ptr = 0;
chip->fmt_size =
snd_pcm_format_physical_width(substream->runtime->format) >> 3;
chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: prepare called, "
"size=%zi psize=%zi f=%zi f1=%i\n",
"size=%zi psize=%zi f=%zi f1=%i fsize=%i\n",
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream),
snd_pcm_lib_buffer_bytes(substream) /
snd_pcm_lib_period_bytes(substream),
substream->runtime->periods);
substream->runtime->periods,
chip->fmt_size);
#endif
pcsp_sync_stop(chip);
chip->playback_ptr = 0;
chip->period_ptr = 0;
chip->fmt_size =
snd_pcm_format_physical_width(substream->runtime->format) >> 3;
chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
return 0;
}
......
......@@ -72,7 +72,7 @@ static int pcsp_treble_put(struct snd_kcontrol *kcontrol,
if (treble != chip->treble) {
chip->treble = treble;
#if PCSP_DEBUG
printk(KERN_INFO "PCSP: rate set to %i\n", PCSP_RATE());
printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE());
#endif
changed = 1;
}
......
......@@ -624,6 +624,9 @@ snd_harmony_pcm_init(struct snd_harmony *h)
struct snd_pcm *pcm;
int err;
if (snd_BUG_ON(!h))
return -EINVAL;
harmony_disable_interrupts(h);
err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
......@@ -865,11 +868,12 @@ snd_harmony_mixer_reset(struct snd_harmony *h)
static int __devinit
snd_harmony_mixer_init(struct snd_harmony *h)
{
struct snd_card *card = h->card;
struct snd_card *card;
int idx, err;
if (snd_BUG_ON(!h))
return -EINVAL;
card = h->card;
strcpy(card->mixername, "Harmony Gain control interface");
for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
......
......@@ -259,7 +259,6 @@ config SND_CS5530
config SND_CS5535AUDIO
tristate "CS5535/CS5536 Audio"
depends on X86 && !X86_64
select SND_PCM
select SND_AC97_CODEC
help
......
......@@ -973,7 +973,7 @@ static void snd_ali_free_voice(struct snd_ali * codec,
void *private_data;
snd_ali_printk("free_voice: channel=%d\n",pvoice->number);
if (pvoice == NULL || !pvoice->use)
if (!pvoice->use)
return;
snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
spin_lock_irq(&codec->voice_alloc);
......
......@@ -2674,6 +2674,7 @@ static struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
{ PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
......
......@@ -965,6 +965,8 @@ static void alc_automute_pin(struct hda_codec *codec)
unsigned int nid = spec->autocfg.hp_pins[0];
int i;
if (!nid)
return;
pincap = snd_hda_query_pin_caps(codec, nid);
if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
......@@ -12602,7 +12604,8 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
ALC268_ACER_ASPIRE_ONE),
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
"Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
/* almost compatible with toshiba but with optional digital outs;
* auto-probing seems working fine
*/
......@@ -17374,7 +17377,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
/* create playback/capture controls for input pins */
#define alc662_auto_create_input_ctls \
alc880_auto_create_input_ctls
alc882_auto_create_input_ctls
static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
hda_nid_t nid, int pin_type,
......
......@@ -386,6 +386,7 @@ struct via82xx {
struct snd_pcm *pcms[2];
struct snd_rawmidi *rmidi;
struct snd_kcontrol *dxs_controls[4];
struct snd_ac97_bus *ac97_bus;
struct snd_ac97 *ac97;
......@@ -1216,9 +1217,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
/*
* open callback for playback on via686 and via823x DSX
* open callback for playback on via686
*/
static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
static int snd_via686_playback_open(struct snd_pcm_substream *substream)
{
struct via82xx *chip = snd_pcm_substream_chip(substream);
struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
......@@ -1229,6 +1230,32 @@ static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
return 0;
}
/*
* open callback for playback on via823x DXS
*/
static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
{
struct via82xx *chip = snd_pcm_substream_chip(substream);
struct viadev *viadev;
unsigned int stream;
int err;
viadev = &chip->devs[chip->playback_devno + substream->number];
if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
return err;
stream = viadev->reg_offset / 0x10;
if (chip->dxs_controls[stream]) {
chip->playback_volume[stream][0] = 0;
chip->playback_volume[stream][1] = 0;
chip->dxs_controls[stream]->vd[0].access &=
~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
SNDRV_CTL_EVENT_MASK_INFO,
&chip->dxs_controls[stream]->id);
}
return 0;
}
/*
* open callback for playback on via823x multi-channel
*/
......@@ -1302,10 +1329,26 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
return 0;
}
static int snd_via8233_playback_close(struct snd_pcm_substream *substream)
{
struct via82xx *chip = snd_pcm_substream_chip(substream);
struct viadev *viadev = substream->runtime->private_data;
unsigned int stream;
stream = viadev->reg_offset / 0x10;
if (chip->dxs_controls[stream]) {
chip->dxs_controls[stream]->vd[0].access |=
SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO,
&chip->dxs_controls[stream]->id);
}
return snd_via82xx_pcm_close(substream);
}
/* via686 playback callbacks */
static struct snd_pcm_ops snd_via686_playback_ops = {
.open = snd_via82xx_playback_open,
.open = snd_via686_playback_open,
.close = snd_via82xx_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
......@@ -1331,8 +1374,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = {
/* via823x DSX playback callbacks */
static struct snd_pcm_ops snd_via8233_playback_ops = {
.open = snd_via82xx_playback_open,
.close = snd_via82xx_pcm_close,
.open = snd_via8233_playback_open,
.close = snd_via8233_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_via82xx_hw_params,
.hw_free = snd_via82xx_hw_free,
......@@ -1709,8 +1752,9 @@ static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
.device = 0,
/* .subdevice set later */
.name = "PCM Playback Volume",
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ |
SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
......@@ -1948,6 +1992,7 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
err = snd_ctl_add(chip->card, kctl);
if (err < 0)
return err;
chip->dxs_controls[i] = kctl;
}
}
}
......
......@@ -217,20 +217,25 @@ static void snd_pdacf_detach(struct pcmcia_device *link)
* configuration callback
*/
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int pdacf_config(struct pcmcia_device *link)
{
struct snd_pdacf *pdacf = link->priv;
int last_fn, last_ret;
int ret;
snd_printdd(KERN_DEBUG "pdacf_config called\n");
link->conf.ConfigIndex = 0x5;
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
ret = pcmcia_request_io(link, &link->io);
if (ret)
goto failed;
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
ret = pcmcia_request_configuration(link, &link->conf);
if (ret)
goto failed;
if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
goto failed;
......@@ -238,8 +243,6 @@ static int pdacf_config(struct pcmcia_device *link)
link->dev_node = &pdacf->node;
return 0;
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
pcmcia_disable_device(link);
return -ENODEV;
......
......@@ -213,14 +213,11 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
* configuration callback
*/
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
static int vxpocket_config(struct pcmcia_device *link)
{
struct vx_core *chip = link->priv;
struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
int last_fn, last_ret;
int ret;
snd_printdd(KERN_DEBUG "vxpocket_config called\n");
......@@ -235,9 +232,17 @@ static int vxpocket_config(struct pcmcia_device *link)
strcpy(chip->card->driver, vxp440_hw.name);
}
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
ret = pcmcia_request_io(link, &link->io);
if (ret)
goto failed;
ret = pcmcia_request_irq(link, &link->irq);
if (ret)
goto failed;
ret = pcmcia_request_configuration(link, &link->conf);
if (ret)
goto failed;
chip->dev = &handle_to_dev(link);
snd_card_set_dev(chip->card, chip->dev);
......@@ -248,8 +253,6 @@ static int vxpocket_config(struct pcmcia_device *link)
link->dev_node = &vxp->node;
return 0;
cs_failed:
cs_error(link, last_fn, last_ret);
failed:
pcmcia_disable_device(link);
return -ENODEV;
......
......@@ -21,7 +21,18 @@ config SND_OMAP_SOC_AMS_DELTA
select SND_OMAP_SOC_MCBSP
select SND_SOC_CX20442
help
Say Y if you want to add support for SoC audio on Amstrad Delta.
Say Y if you want to add support for SoC audio device connected to
a handset and a speakerphone found on Amstrad E3 (Delta) videophone.
Note that in order to get those devices fully supported, you have to
build the kernel with standard serial port driver included and
configured for at least 4 ports. Then, from userspace, you must load
a line discipline #19 on the modem (ttyS3) serial line. The simplest
way to achieve this is to install util-linux-ng and use the included
ldattach utility. This can be started automatically from udev,
a simple rule like this one should do the trick (it does for me):
ACTION=="add", KERNEL=="controlC0", \
RUN+="/usr/sbin/ldattach 19 /dev/ttyS3"
config SND_OMAP_SOC_OSK5912
tristate "SoC Audio support for omap osk5912"
......
......@@ -834,6 +834,9 @@ EXPORT_SYMBOL_GPL(snd_soc_resume_device);
#define soc_resume NULL
#endif
static struct snd_soc_dai_ops null_dai_ops = {
};
static void snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct platform_device *pdev = container_of(card->dev,
......@@ -877,6 +880,11 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
ac97 = 1;
}
for (i = 0; i < card->num_links; i++) {
if (!card->dai_link[i].codec_dai->ops)
card->dai_link[i].codec_dai->ops = &null_dai_ops;
}
/* If we have AC97 in the system then don't wait for the
* codec. This will need revisiting if we have to handle
* systems with mixed AC97 and non-AC97 parts. Only check for
......@@ -2329,9 +2337,6 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
return 0;
}
static struct snd_soc_dai_ops null_dai_ops = {
};
/**
* snd_soc_register_dai - Register a DAI with the ASoC core
*
......
......@@ -2072,9 +2072,9 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
}
}
}
mutex_unlock(&codec->mutex);
dapm_power_widgets(codec, event);
mutex_unlock(&codec->mutex);
dump_dapm(codec, __func__);
return 0;
}
......
......@@ -62,10 +62,14 @@ static void
activate_substream(struct snd_usb_caiaqdev *dev,
struct snd_pcm_substream *sub)
{
spin_lock(&dev->spinlock);
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
dev->sub_playback[sub->number] = sub;
else
dev->sub_capture[sub->number] = sub;
spin_unlock(&dev->spinlock);
}
static void
......@@ -269,16 +273,22 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
{
int index = sub->number;
struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
snd_pcm_uframes_t ptr;
spin_lock(&dev->spinlock);
if (dev->input_panic || dev->output_panic)
return SNDRV_PCM_POS_XRUN;
ptr = SNDRV_PCM_POS_XRUN;
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
return bytes_to_frames(sub->runtime,
ptr = bytes_to_frames(sub->runtime,
dev->audio_out_buf_pos[index]);
else
return bytes_to_frames(sub->runtime,
ptr = bytes_to_frames(sub->runtime,
dev->audio_in_buf_pos[index]);
spin_unlock(&dev->spinlock);
return ptr;
}
/* operators for both playback and capture */
......
......@@ -35,7 +35,7 @@
#include "input.h"
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_DESCRIPTION("caiaq USB audio, version 1.3.19");
MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, RigKontrol3},"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册