diff --git a/include/sound/version.h b/include/sound/version.h index 8d4a8dd892373e63d1ce518c2bdb61ecf0192514..a2be8ad8894b2d7386104ac6fa3193e1ddf61abe 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by alsa/ksync script. */ #define CONFIG_SND_VERSION "1.0.15" -#define CONFIG_SND_DATE " (Tue Oct 16 14:57:44 2007 UTC)" +#define CONFIG_SND_DATE " (Tue Oct 23 06:09:18 2007 UTC)" diff --git a/sound/core/control.c b/sound/core/control.c index 4c3aa8e10378bd306763dba42f16b6b9a564ebd5..df0774c76f6fc4eba16eb5abc0863ac01bbcedbc 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -93,15 +93,16 @@ static int snd_ctl_open(struct inode *inode, struct file *file) static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl) { + unsigned long flags; struct snd_kctl_event *cread; - spin_lock(&ctl->read_lock); + spin_lock_irqsave(&ctl->read_lock, flags); while (!list_empty(&ctl->events)) { cread = snd_kctl_event(ctl->events.next); list_del(&cread->list); kfree(cread); } - spin_unlock(&ctl->read_lock); + spin_unlock_irqrestore(&ctl->read_lock, flags); } static int snd_ctl_release(struct inode *inode, struct file *file) diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 91f9e6a112ffd6749421fa8ba9d4ec93cc50b7d9..2dba752faf4e6281a2a31bddf4a0998197f4d535 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -165,7 +165,7 @@ struct snd_bt87x_board { unsigned no_digital:1; /* No digital input */ }; -static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = { +static __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = { [SND_BT87X_BOARD_UNKNOWN] = { .dig_rate = 32000, /* just a guess */ }, @@ -848,7 +848,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) int i; const struct pci_device_id *supported; - supported = pci_match_device(&driver, pci); + supported = pci_match_id(snd_bt87x_ids, pci); if (supported && supported->driver_data > 0) return supported->driver_data; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 187533e477c6e178d2b57cc8575548778448ffb2..ad4cb38109fcc2de06f0891ea737adc91769f2eb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -626,24 +626,19 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); -#ifdef CONFIG_SND_HDA_GENERIC if (is_generic_config(codec)) { err = snd_hda_parse_generic_codec(codec); goto patched; } -#endif if (codec->preset && codec->preset->patch) { err = codec->preset->patch(codec); goto patched; } /* call the default parser */ -#ifdef CONFIG_SND_HDA_GENERIC err = snd_hda_parse_generic_codec(codec); -#else - printk(KERN_ERR "hda-codec: No codec parser is available\n"); - err = -ENODEV; -#endif + if (err < 0) + printk(KERN_ERR "hda-codec: No codec parser is available\n"); patched: if (err < 0) { diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index a79d0ed5469c297215d37d741f2a569e905148c5..20c5e6250374b5d1a61d96e01d0789035b140bf5 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -245,7 +245,14 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, /* * generic codec parser */ +#ifdef CONFIG_SND_HDA_GENERIC int snd_hda_parse_generic_codec(struct hda_codec *codec); +#else +static inline int snd_hda_parse_generic_codec(struct hda_codec *codec) +{ + return -ENODEV; +} +#endif /* * generic proc interface @@ -303,16 +310,17 @@ enum { extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; +#define AUTO_CFG_MAX_OUTS 5 + struct auto_pin_cfg { int line_outs; - hda_nid_t line_out_pins[5]; /* sorted in the order of - * Front/Surr/CLFE/Side - */ + /* sorted in the order of Front/Surr/CLFE/Side */ + hda_nid_t line_out_pins[AUTO_CFG_MAX_OUTS]; int speaker_outs; - hda_nid_t speaker_pins[5]; + hda_nid_t speaker_pins[AUTO_CFG_MAX_OUTS]; int hp_outs; int line_out_type; /* AUTO_PIN_XXX_OUT */ - hda_nid_t hp_pins[5]; + hda_nid_t hp_pins[AUTO_CFG_MAX_OUTS]; hda_nid_t input_pins[AUTO_PIN_LAST]; hda_nid_t dig_out_pin; hda_nid_t dig_in_pin; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 54cfd4526d209e9e58190a5f287378fd57793dd1..0ee8ae4d4410b89c7405ac3c5c25ba111fc8703d 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -72,7 +72,7 @@ struct ad198x_spec { unsigned int num_kctl_alloc, num_kctl_used; struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[4]; + hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; unsigned int jack_present :1; @@ -612,7 +612,8 @@ static void ad1986a_hp_automute(struct hda_codec *codec) unsigned int present; present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; + /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ + spec->jack_present = !(present & 0x80000000); ad1986a_update_hp(codec); } diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 2468f31712221842ef4e813ffbef9547a8b327e3..6c54793bf424cf4e52d4a922ad4532fa1726a613 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -50,7 +50,7 @@ struct cmi_spec { /* playback */ struct hda_multi_out multiout; - hda_nid_t dac_nids[4]; /* NID for each DAC */ + hda_nid_t dac_nids[AUTO_CFG_MAX_OUTS]; /* NID for each DAC */ int num_dacs; /* capture */ @@ -73,7 +73,6 @@ struct cmi_spec { unsigned int pin_def_confs; /* multichannel pins */ - hda_nid_t multich_pin[4]; /* max 8-channel */ struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */ }; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 080e3001d9c548d0e775425b7ce94b743de88782..6aa073986747bd20a26c0c7a4e1e154a173e5c39 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -85,7 +85,7 @@ struct conexant_spec { unsigned int num_kctl_alloc, num_kctl_used; struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[4]; + hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; }; @@ -554,10 +554,16 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put }, - HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -576,16 +582,15 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* HP, Amp */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, - {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x01}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x02}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, + {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x11, AC_VERB_SET_CONNECT_SEL, 0x1}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Record selector: Int mic */ {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 53b0428abfc2059d6f2918b584290b29f2399f4f..d9f78c809ee977e8a79ff926be121d5d93d7cc0c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -238,7 +238,7 @@ struct alc_spec { unsigned int num_kctl_alloc, num_kctl_used; struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[5]; + hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; /* hooks */ void (*init_hook)(struct hda_codec *codec); diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index bf950195107c0a3ec4648197b7fb4f15a605dcf0..f9b2c435a1303ec767193b6d7dcb7197dd60497d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -111,6 +111,7 @@ struct sigmatel_spec { unsigned int alt_switch: 1; unsigned int hp_detect: 1; unsigned int gpio_mute: 1; + unsigned int no_vol_knob :1; unsigned int gpio_mask, gpio_data; @@ -1930,7 +1931,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, } if (spec->multiout.hp_nid) { const char *pfx; - if (old_num_dacs == spec->multiout.num_dacs) + if (old_num_dacs == spec->multiout.num_dacs && + spec->no_vol_knob) pfx = "Master"; else pfx = "Headphone"; @@ -2487,6 +2489,7 @@ static int patch_stac9200(struct hda_codec *codec) codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); spec->pin_nids = stac9200_pin_nids; + spec->no_vol_knob = 1; spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, stac9200_models, stac9200_cfg_tbl); @@ -2541,6 +2544,7 @@ static int patch_stac925x(struct hda_codec *codec) codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); spec->pin_nids = stac925x_pin_nids; + spec->no_vol_knob = 1; spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, stac925x_models, stac925x_cfg_tbl); diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 33b5e1ffa8175d27e6c739a4bcdcb9a3562007c9..4cdf3e6df4baf20fa4ce2570c7cda55ef72a3d21 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -114,7 +114,7 @@ struct via_spec { unsigned int num_kctl_alloc, num_kctl_used; struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; - hda_nid_t private_dac_nids[4]; + hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 131ec4812288e6043a1cfb2fa8bad7001ae6585e..88dc840152ce9369f57956c2d43cde2ac0e936ab 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -106,11 +106,14 @@ static void spu_write_wait(void) static void spu_memset(u32 toi, u32 what, int length) { int i; + unsigned long flags; snd_assert(length % 4 == 0, return); for (i = 0; i < length; i++) { if (!(i % 8)) spu_write_wait(); + local_irq_save(flags); writel(what, toi + SPU_MEMORY_BASE); + local_irq_restore(flags); toi++; } } @@ -118,6 +121,7 @@ static void spu_memset(u32 toi, u32 what, int length) /* spu_memload - write to SPU address space */ static void spu_memload(u32 toi, void *from, int length) { + unsigned long flags; u32 *froml = from; u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi); int i; @@ -128,7 +132,9 @@ static void spu_memload(u32 toi, void *from, int length) if (!(i % 8)) spu_write_wait(); val = *froml; + local_irq_save(flags); writel(val, to); + local_irq_restore(flags); froml++; to++; } @@ -138,28 +144,36 @@ static void spu_memload(u32 toi, void *from, int length) static void spu_disable(void) { int i; + unsigned long flags; u32 regval; spu_write_wait(); regval = readl(ARM_RESET_REGISTER); regval |= 1; spu_write_wait(); + local_irq_save(flags); writel(regval, ARM_RESET_REGISTER); + local_irq_restore(flags); for (i = 0; i < 64; i++) { spu_write_wait(); regval = readl(SPU_REGISTER_BASE + (i * 0x80)); regval = (regval & ~0x4000) | 0x8000; spu_write_wait(); + local_irq_save(flags); writel(regval, SPU_REGISTER_BASE + (i * 0x80)); + local_irq_restore(flags); } } /* spu_enable - set spu registers to enable sound output */ static void spu_enable(void) { + unsigned long flags; u32 regval = readl(ARM_RESET_REGISTER); regval &= ~1; spu_write_wait(); + local_irq_save(flags); writel(regval, ARM_RESET_REGISTER); + local_irq_restore(flags); } /* @@ -168,25 +182,34 @@ static void spu_enable(void) */ static void spu_reset(void) { + unsigned long flags; spu_disable(); spu_memset(0, 0, 0x200000 / 4); /* Put ARM7 in endless loop */ + local_irq_save(flags); ctrl_outl(0xea000002, SPU_MEMORY_BASE); + local_irq_restore(flags); spu_enable(); } /* aica_chn_start - write to spu to start playback */ static void aica_chn_start(void) { + unsigned long flags; spu_write_wait(); + local_irq_save(flags); writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT); + local_irq_restore(flags); } /* aica_chn_halt - write to spu to halt playback */ static void aica_chn_halt(void) { + unsigned long flags; spu_write_wait(); + local_irq_save(flags); writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT); + local_irq_restore(flags); } /* ALSA code below */ @@ -213,12 +236,13 @@ static int aica_dma_transfer(int channels, int buffer_size, int q, err, period_offset; struct snd_card_aica *dreamcastcard; struct snd_pcm_runtime *runtime; - err = 0; + unsigned long flags; dreamcastcard = substream->pcm->private_data; period_offset = dreamcastcard->clicks; period_offset %= (AICA_PERIOD_NUMBER / channels); runtime = substream->runtime; for (q = 0; q < channels; q++) { + local_irq_save(flags); err = dma_xfer(AICA_DMA_CHANNEL, (unsigned long) (runtime->dma_area + (AICA_BUFFER_SIZE * q) / @@ -228,9 +252,12 @@ static int aica_dma_transfer(int channels, int buffer_size, AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET + AICA_PERIOD_SIZE * period_offset, buffer_size / channels, AICA_DMA_MODE); - if (unlikely(err < 0)) + if (unlikely(err < 0)) { + local_irq_restore(flags); break; + } dma_wait_for_completion(AICA_DMA_CHANNEL); + local_irq_restore(flags); } return err; } diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 9785382a5f39fc6b6f125adc00600eb0432cc101..f8c7a120ccbb3ce2c98821523c55223fcbbb3458 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -400,65 +400,44 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip) static void snd_cs4231_mce_down(struct snd_cs4231 *chip) { - unsigned long flags; - unsigned long end_time; - int timeout; + unsigned long flags, timeout; + int reg; - spin_lock_irqsave(&chip->lock, flags); snd_cs4231_busy_wait(chip); + spin_lock_irqsave(&chip->lock, flags); #ifdef CONFIG_SND_DEBUG if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231U(chip, REGSEL)); #endif chip->mce_bit &= ~CS4231_MCE; - timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL)); - __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), + reg = __cs4231_readb(chip, CS4231U(chip, REGSEL)); + __cs4231_writeb(chip, chip->mce_bit | (reg & 0x1f), CS4231U(chip, REGSEL)); - if (timeout == 0x80) - snd_printdd("mce_down [%p]: serious init problem - " - "codec still busy\n", - chip->port); - if ((timeout & CS4231_MCE) == 0) { + if (reg == 0x80) + snd_printdd("mce_down [%p]: serious init problem " + "- codec still busy\n", chip->port); + if ((reg & CS4231_MCE) == 0) { spin_unlock_irqrestore(&chip->lock, flags); return; } /* - * Wait for (possible -- during init auto-calibration may not be set) - * calibration process to start. Needs upto 5 sample periods on AD1848 - * which at the slowest possible rate of 5.5125 kHz means 907 us. + * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low. */ - msleep(1); - - /* check condition up to 250ms */ - end_time = jiffies + msecs_to_jiffies(250); - while (snd_cs4231_in(chip, CS4231_TEST_INIT) & - CS4231_CALIB_IN_PROGRESS) { - + timeout = jiffies + msecs_to_jiffies(250); + do { spin_unlock_irqrestore(&chip->lock, flags); - if (time_after(jiffies, end_time)) { - snd_printk("mce_down - " - "auto calibration time out (2)\n"); - return; - } - msleep(1); - spin_lock_irqsave(&chip->lock, flags); - } - - /* check condition up to 100ms */ - end_time = jiffies + msecs_to_jiffies(100); - while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) { - spin_unlock_irqrestore(&chip->lock, flags); - if (time_after(jiffies, end_time)) { - snd_printk("mce_down - " - "auto calibration time out (3)\n"); - return; - } msleep(1); spin_lock_irqsave(&chip->lock, flags); - } + reg = snd_cs4231_in(chip, CS4231_TEST_INIT); + reg &= CS4231_CALIB_IN_PROGRESS; + } while (reg && time_before(jiffies, timeout)); spin_unlock_irqrestore(&chip->lock, flags); + + if (reg) + snd_printk(KERN_ERR + "mce_down - auto calibration time out (2)\n"); } static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 743568f8990711424d3285ce9fa9839b6f20fdff..59410f437705a745c5fb5736761ad725517d190b 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -79,6 +79,15 @@ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x046d, + .idProduct = 0x08f5, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL +}, { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_CLASS |