Commit 7b724a22 authored by Linus Torvalds's avatar 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: Fix yet another race in disconnection
  ALSA: asihpi - Update verbose debug print macros
  ALSA: asihpi - Improve non-busmaster adapter operation
  ALSA: asihpi - Support single-rate no-SRC cards
  ALSA: HDA: New AD1984A model for Dell Precision R5500
  ALSA: vmalloc buffers should use normal mmap
  ALSA: hda - Fix SPDIF out regression on ALC889
  ALSA: usb-audio - Support for Boss JS-8 Jam Station
  ALSA: usb-audio: add Cakewalk UM-1G support
  sound/oss/opl3: validate voice and channel indexes
  sound/oss: remove offset from load_patch callbacks
parents 551b0bda a45e3d6b
...@@ -1031,9 +1031,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s ...@@ -1031,9 +1031,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
#define snd_pcm_lib_mmap_iomem NULL #define snd_pcm_lib_mmap_iomem NULL
#endif #endif
int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, #define snd_pcm_lib_mmap_vmalloc NULL
struct vm_area_struct *area);
#define snd_pcm_lib_mmap_vmalloc snd_pcm_lib_mmap_noncached
static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
{ {
......
...@@ -848,6 +848,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) ...@@ -848,6 +848,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
return -ENOMEM; return -ENOMEM;
mfile->file = file; mfile->file = file;
mfile->disconnected_f_op = NULL; mfile->disconnected_f_op = NULL;
INIT_LIST_HEAD(&mfile->shutdown_list);
spin_lock(&card->files_lock); spin_lock(&card->files_lock);
if (card->shutdown) { if (card->shutdown) {
spin_unlock(&card->files_lock); spin_unlock(&card->files_lock);
...@@ -883,6 +884,9 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) ...@@ -883,6 +884,9 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
list_for_each_entry(mfile, &card->files_list, list) { list_for_each_entry(mfile, &card->files_list, list) {
if (mfile->file == file) { if (mfile->file == file) {
list_del(&mfile->list); list_del(&mfile->list);
spin_lock(&shutdown_lock);
list_del(&mfile->shutdown_list);
spin_unlock(&shutdown_lock);
if (mfile->disconnected_f_op) if (mfile->disconnected_f_op)
fops_put(mfile->disconnected_f_op); fops_put(mfile->disconnected_f_op);
found = mfile; found = mfile;
......
...@@ -3201,15 +3201,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, ...@@ -3201,15 +3201,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
#endif /* SNDRV_PCM_INFO_MMAP */ #endif /* SNDRV_PCM_INFO_MMAP */
/* mmap callback with pgprot_noncached */
int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
return snd_pcm_default_mmap(substream, area);
}
EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached);
/* /*
* mmap DMA buffer * mmap DMA buffer
*/ */
......
...@@ -271,7 +271,7 @@ struct synth_operations ...@@ -271,7 +271,7 @@ struct synth_operations
void (*reset) (int dev); void (*reset) (int dev);
void (*hw_control) (int dev, unsigned char *event); void (*hw_control) (int dev, unsigned char *event);
int (*load_patch) (int dev, int format, const char __user *addr, int (*load_patch) (int dev, int format, const char __user *addr,
int offs, int count, int pmgr_flag); int count, int pmgr_flag);
void (*aftertouch) (int dev, int voice, int pressure); void (*aftertouch) (int dev, int voice, int pressure);
void (*controller) (int dev, int voice, int ctrl_num, int value); void (*controller) (int dev, int voice, int ctrl_num, int value);
void (*panning) (int dev, int voice, int value); void (*panning) (int dev, int voice, int value);
......
...@@ -476,7 +476,7 @@ EXPORT_SYMBOL(midi_synth_hw_control); ...@@ -476,7 +476,7 @@ EXPORT_SYMBOL(midi_synth_hw_control);
int int
midi_synth_load_patch(int dev, int format, const char __user *addr, midi_synth_load_patch(int dev, int format, const char __user *addr,
int offs, int count, int pmgr_flag) int count, int pmgr_flag)
{ {
int orig_dev = synth_devs[dev]->midi_dev; int orig_dev = synth_devs[dev]->midi_dev;
...@@ -491,31 +491,27 @@ midi_synth_load_patch(int dev, int format, const char __user *addr, ...@@ -491,31 +491,27 @@ midi_synth_load_patch(int dev, int format, const char __user *addr,
if (!prefix_cmd(orig_dev, 0xf0)) if (!prefix_cmd(orig_dev, 0xf0))
return 0; return 0;
/* Invalid patch format */
if (format != SYSEX_PATCH) if (format != SYSEX_PATCH)
{
/* printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/
return -EINVAL; return -EINVAL;
}
/* Patch header too short */
if (count < hdr_size) if (count < hdr_size)
{
/* printk("MIDI Error: Patch header too short\n");*/
return -EINVAL; return -EINVAL;
}
count -= hdr_size; count -= hdr_size;
/* /*
* Copy the header from user space but ignore the first bytes which have * Copy the header from user space
* been transferred already.
*/ */
if(copy_from_user(&((char *) &sysex)[offs], &(addr)[offs], hdr_size - offs)) if (copy_from_user(&sysex, addr, hdr_size))
return -EFAULT; return -EFAULT;
if (count < sysex.len) /* Sysex record too short */
{ if ((unsigned)count < (unsigned)sysex.len)
/* printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/
sysex.len = count; sysex.len = count;
}
left = sysex.len; left = sysex.len;
src_offs = 0; src_offs = 0;
......
...@@ -8,7 +8,7 @@ int midi_synth_open (int dev, int mode); ...@@ -8,7 +8,7 @@ int midi_synth_open (int dev, int mode);
void midi_synth_close (int dev); void midi_synth_close (int dev);
void midi_synth_hw_control (int dev, unsigned char *event); void midi_synth_hw_control (int dev, unsigned char *event);
int midi_synth_load_patch (int dev, int format, const char __user * addr, int midi_synth_load_patch (int dev, int format, const char __user * addr,
int offs, int count, int pmgr_flag); int count, int pmgr_flag);
void midi_synth_panning (int dev, int channel, int pressure); void midi_synth_panning (int dev, int channel, int pressure);
void midi_synth_aftertouch (int dev, int channel, int pressure); void midi_synth_aftertouch (int dev, int channel, int pressure);
void midi_synth_controller (int dev, int channel, int ctrl_num, int value); void midi_synth_controller (int dev, int channel, int ctrl_num, int value);
......
...@@ -820,7 +820,7 @@ static void opl3_hw_control(int dev, unsigned char *event) ...@@ -820,7 +820,7 @@ static void opl3_hw_control(int dev, unsigned char *event)
} }
static int opl3_load_patch(int dev, int format, const char __user *addr, static int opl3_load_patch(int dev, int format, const char __user *addr,
int offs, int count, int pmgr_flag) int count, int pmgr_flag)
{ {
struct sbi_instrument ins; struct sbi_instrument ins;
...@@ -830,11 +830,7 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, ...@@ -830,11 +830,7 @@ static int opl3_load_patch(int dev, int format, const char __user *addr,
return -EINVAL; return -EINVAL;
} }
/* if (copy_from_user(&ins, addr, sizeof(ins)))
* What the fuck is going on here? We leave junk in the beginning
* of ins and then check the field pretty close to that beginning?
*/
if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs))
return -EFAULT; return -EFAULT;
if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
...@@ -849,6 +845,10 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, ...@@ -849,6 +845,10 @@ static int opl3_load_patch(int dev, int format, const char __user *addr,
static void opl3_panning(int dev, int voice, int value) static void opl3_panning(int dev, int voice, int value)
{ {
if (voice < 0 || voice >= devc->nr_voice)
return;
devc->voc[voice].panning = value; devc->voc[voice].panning = value;
} }
...@@ -1066,8 +1066,15 @@ static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info ...@@ -1066,8 +1066,15 @@ static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info
static void opl3_setup_voice(int dev, int voice, int chn) static void opl3_setup_voice(int dev, int voice, int chn)
{ {
struct channel_info *info = struct channel_info *info;
&synth_devs[dev]->chn_info[chn];
if (voice < 0 || voice >= devc->nr_voice)
return;
if (chn < 0 || chn > 15)
return;
info = &synth_devs[dev]->chn_info[chn];
opl3_set_instr(dev, voice, info->pgm_num); opl3_set_instr(dev, voice, info->pgm_num);
......
...@@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file *file, const char __user *buf, int coun ...@@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file *file, const char __user *buf, int coun
return -ENXIO; return -ENXIO;
fmt = (*(short *) &event_rec[0]) & 0xffff; fmt = (*(short *) &event_rec[0]) & 0xffff;
err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0); err = synth_devs[dev]->load_patch(dev, fmt, buf + p, c, 0);
if (err < 0) if (err < 0)
return err; return err;
......
This diff is collapsed.
...@@ -4255,6 +4255,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) ...@@ -4255,6 +4255,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
return 0; return 0;
} }
/*
* Precision R5500
* 0x12 - HP/line-out
* 0x13 - speaker (mono)
* 0x15 - mic-in
*/
static struct hda_verb ad1984a_precision_verbs[] = {
/* Unmute main output path */
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
/* 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)},
/* Select mic as input */
{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
/* Configure as mic */
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
/* HP unmute */
{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* turn on EAPD */
{0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
/* unsolicited event for pin-sense */
{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
{ } /* end */
};
static struct snd_kcontrol_new ad1984a_precision_mixers[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
{ } /* end */
};
/* mute internal speaker if HP is plugged */
static void ad1984a_precision_automute(struct hda_codec *codec)
{
unsigned int present;
present = snd_hda_jack_detect(codec, 0x12);
snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
/* unsolicited event for HP jack sensing */
static void ad1984a_precision_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) != AD1884A_HP_EVENT)
return;
ad1984a_precision_automute(codec);
}
/* initialize jack-sensing, too */
static int ad1984a_precision_init(struct hda_codec *codec)
{
ad198x_init(codec);
ad1984a_precision_automute(codec);
return 0;
}
/* /*
* HP Touchsmart * HP Touchsmart
* port-A (0x11) - front hp-out * port-A (0x11) - front hp-out
...@@ -4384,6 +4462,7 @@ enum { ...@@ -4384,6 +4462,7 @@ enum {
AD1884A_MOBILE, AD1884A_MOBILE,
AD1884A_THINKPAD, AD1884A_THINKPAD,
AD1984A_TOUCHSMART, AD1984A_TOUCHSMART,
AD1984A_PRECISION,
AD1884A_MODELS AD1884A_MODELS
}; };
...@@ -4393,9 +4472,11 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { ...@@ -4393,9 +4472,11 @@ static const char * const ad1884a_models[AD1884A_MODELS] = {
[AD1884A_MOBILE] = "mobile", [AD1884A_MOBILE] = "mobile",
[AD1884A_THINKPAD] = "thinkpad", [AD1884A_THINKPAD] = "thinkpad",
[AD1984A_TOUCHSMART] = "touchsmart", [AD1984A_TOUCHSMART] = "touchsmart",
[AD1984A_PRECISION] = "precision",
}; };
static struct snd_pci_quirk ad1884a_cfg_tbl[] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
...@@ -4489,6 +4570,14 @@ static int patch_ad1884a(struct hda_codec *codec) ...@@ -4489,6 +4570,14 @@ static int patch_ad1884a(struct hda_codec *codec)
codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
codec->patch_ops.init = ad1984a_thinkpad_init; codec->patch_ops.init = ad1984a_thinkpad_init;
break; break;
case AD1984A_PRECISION:
spec->mixers[0] = ad1984a_precision_mixers;
spec->init_verbs[spec->num_init_verbs++] =
ad1984a_precision_verbs;
spec->multiout.dig_out_nid = 0;
codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
codec->patch_ops.init = ad1984a_precision_init;
break;
case AD1984A_TOUCHSMART: case AD1984A_TOUCHSMART:
spec->mixers[0] = ad1984a_touchsmart_mixers; spec->mixers[0] = ad1984a_touchsmart_mixers;
spec->init_verbs[0] = ad1984a_touchsmart_verbs; spec->init_verbs[0] = ad1984a_touchsmart_verbs;
......
...@@ -1290,7 +1290,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) ...@@ -1290,7 +1290,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
case 0x10ec0883: case 0x10ec0883:
case 0x10ec0885: case 0x10ec0885:
case 0x10ec0887: case 0x10ec0887:
case 0x10ec0889: /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
alc889_coef_init(codec); alc889_coef_init(codec);
break; break;
case 0x10ec0888: case 0x10ec0888:
......
...@@ -1567,6 +1567,46 @@ YAMAHA_DEVICE(0x7010, "UB99"), ...@@ -1567,6 +1567,46 @@ YAMAHA_DEVICE(0x7010, "UB99"),
} }
} }
}, },
{
USB_DEVICE_VENDOR_SPEC(0x0582, 0x0104),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
/* .vendor_name = "Roland", */
/* .product_name = "UM-1G", */
.ifnum = 0,
.type = QUIRK_MIDI_FIXED_ENDPOINT,
.data = & (const struct snd_usb_midi_endpoint_info) {
.out_cables = 0x0001,
.in_cables = 0x0001
}
}
},
{
/* Boss JS-8 Jam Station */
USB_DEVICE(0x0582, 0x0109),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
/* .vendor_name = "BOSS", */
/* .product_name = "JS-8", */
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_COMPOSITE,
.data = (const struct snd_usb_audio_quirk[]) {
{
.ifnum = 0,
.type = QUIRK_AUDIO_STANDARD_INTERFACE
},
{
.ifnum = 1,
.type = QUIRK_AUDIO_STANDARD_INTERFACE
},
{
.ifnum = 2,
.type = QUIRK_MIDI_STANDARD_INTERFACE
},
{
.ifnum = -1
}
}
}
},
{ {
/* has ID 0x0110 when not in Advanced Driver mode */ /* has ID 0x0110 when not in Advanced Driver mode */
USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f), USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment