diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-03-18 18:22:33 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-03-18 18:22:33 +0100 |
commit | 44c76a960a62fcc46cbcaa0a22a34e666a729329 (patch) | |
tree | d3887c858f6adffb6714da3cdc0059f93588344c | |
parent | dbf117cbb9c89991727d42e3161e68b868a1b6ae (diff) | |
parent | c6b76d1f02e2ab1109d8549877a3a24c6a2b4587 (diff) |
Merge branch 'topic/misc' into for-linus
33 files changed, 612 insertions, 193 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 0cf91b2f08c..4ae9e22c482 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -264,7 +264,7 @@ struct snd_pcm_hw_constraint_ratdens { struct snd_pcm_hw_constraint_list { unsigned int count; - unsigned int *list; + const unsigned int *list; unsigned int mask; }; @@ -781,7 +781,8 @@ void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interva unsigned int k, struct snd_interval *c); void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k, const struct snd_interval *b, struct snd_interval *c); -int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask); +int snd_interval_list(struct snd_interval *i, unsigned int count, + const unsigned int *list, unsigned int mask); int snd_interval_ratnum(struct snd_interval *i, unsigned int rats_count, struct snd_ratnum *rats, unsigned int *nump, unsigned int *denp); diff --git a/include/sound/version.h b/include/sound/version.h index 8fc5321e1ec..cc75024c108 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.24" +#define CONFIG_SND_VERSION "1.0.25" #define CONFIG_SND_DATE "" diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h index 444cd6ba0ba..41199664666 100644 --- a/include/sound/ymfpci.h +++ b/include/sound/ymfpci.h @@ -366,6 +366,8 @@ struct snd_ymfpci { #ifdef CONFIG_PM u32 *saved_regs; u32 saved_ydsxgr_mode; + u16 saved_dsxg_legacy; + u16 saved_dsxg_elegacy; #endif }; diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 762af68c899..270790d384e 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -1132,15 +1132,4 @@ static struct i2c_driver onyx_driver = { .id_table = onyx_i2c_id, }; -static int __init onyx_init(void) -{ - return i2c_add_driver(&onyx_driver); -} - -static void __exit onyx_exit(void) -{ - i2c_del_driver(&onyx_driver); -} - -module_init(onyx_init); -module_exit(onyx_exit); +module_i2c_driver(onyx_driver); diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index fd2188c3df2..8e63d1f35ce 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -1026,15 +1026,4 @@ static struct i2c_driver tas_driver = { .id_table = tas_i2c_id, }; -static int __init tas_init(void) -{ - return i2c_add_driver(&tas_driver); -} - -static void __exit tas_exit(void) -{ - i2c_del_driver(&tas_driver); -} - -module_init(tas_init); -module_exit(tas_exit); +module_i2c_driver(tas_driver); diff --git a/sound/core/control.c b/sound/core/control.c index 819a5c579a3..2487a6bb1c5 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1313,7 +1313,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, err = -EPERM; goto __kctl_end; } - err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); + err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); if (err > 0) { up_read(&card->controls_rwsem); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); diff --git a/sound/core/init.c b/sound/core/init.c index 3ac49b1b7cb..068cf08d3ff 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -480,74 +480,104 @@ int snd_card_free(struct snd_card *card) EXPORT_SYMBOL(snd_card_free); -static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) +/* retrieve the last word of shortname or longname */ +static const char *retrieve_id_from_card_name(const char *name) { - int i, len, idx_flag = 0, loops = SNDRV_CARDS; - const char *spos, *src; - char *id; - - if (nid == NULL) { - id = card->shortname; - spos = src = id; - while (*id != '\0') { - if (*id == ' ') - spos = id + 1; - id++; - } - } else { - spos = src = nid; + const char *spos = name; + + while (*name) { + if (isspace(*name) && isalnum(name[1])) + spos = name + 1; + name++; } - id = card->id; - while (*spos != '\0' && !isalnum(*spos)) - spos++; - if (isdigit(*spos)) - *id++ = isalpha(src[0]) ? src[0] : 'D'; - while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { - if (isalnum(*spos)) - *id++ = *spos; - spos++; + return spos; +} + +/* return true if the given id string doesn't conflict any other card ids */ +static bool card_id_ok(struct snd_card *card, const char *id) +{ + int i; + if (!snd_info_check_reserved_words(id)) + return false; + for (i = 0; i < snd_ecards_limit; i++) { + if (snd_cards[i] && snd_cards[i] != card && + !strcmp(snd_cards[i]->id, id)) + return false; } - *id = '\0'; + return true; +} - id = card->id; +/* copy to card->id only with valid letters from nid */ +static void copy_valid_id_string(struct snd_card *card, const char *src, + const char *nid) +{ + char *id = card->id; + + while (*nid && !isalnum(*nid)) + nid++; + if (isdigit(*nid)) + *id++ = isalpha(*src) ? *src : 'D'; + while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) { + if (isalnum(*nid)) + *id++ = *nid; + nid++; + } + *id = 0; +} + +/* Set card->id from the given string + * If the string conflicts with other ids, add a suffix to make it unique. + */ +static void snd_card_set_id_no_lock(struct snd_card *card, const char *src, + const char *nid) +{ + int len, loops; + bool with_suffix; + bool is_default = false; + char *id; - if (*id == '\0') + copy_valid_id_string(card, src, nid); + id = card->id; + + again: + /* use "Default" for obviously invalid strings + * ("card" conflicts with proc directories) + */ + if (!*id || !strncmp(id, "card", 4)) { strcpy(id, "Default"); + is_default = true; + } - while (1) { - if (loops-- == 0) { - snd_printk(KERN_ERR "unable to set card id (%s)\n", id); - strcpy(card->id, card->proc_root->name); - return; - } - if (!snd_info_check_reserved_words(id)) - goto __change; - for (i = 0; i < snd_ecards_limit; i++) { - if (snd_cards[i] && !strcmp(snd_cards[i]->id, id)) - goto __change; - } - break; + with_suffix = false; + for (loops = 0; loops < SNDRV_CARDS; loops++) { + if (card_id_ok(card, id)) + return; /* OK */ - __change: len = strlen(id); - if (idx_flag) { - if (id[len-1] != '9') - id[len-1]++; - else - id[len-1] = 'A'; - } else if ((size_t)len <= sizeof(card->id) - 3) { - strcat(id, "_1"); - idx_flag++; + if (!with_suffix) { + /* add the "_X" suffix */ + char *spos = id + len; + if (len > sizeof(card->id) - 3) + spos = id + sizeof(card->id) - 3; + strcpy(spos, "_1"); + with_suffix = true; } else { - spos = id + len - 2; - if ((size_t)len <= sizeof(card->id) - 2) - spos++; - *(char *)spos++ = '_'; - *(char *)spos++ = '1'; - *(char *)spos++ = '\0'; - idx_flag++; + /* modify the existing suffix */ + if (id[len - 1] != '9') + id[len - 1]++; + else + id[len - 1] = 'A'; } } + /* fallback to the default id */ + if (!is_default) { + *id = 0; + goto again; + } + /* last resort... */ + snd_printk(KERN_ERR "unable to set card id (%s)\n", id); + if (card->proc_root->name) + strcpy(card->id, card->proc_root->name); } /** @@ -564,7 +594,7 @@ void snd_card_set_id(struct snd_card *card, const char *nid) if (card->id[0] != '\0') return; mutex_lock(&snd_card_mutex); - snd_card_set_id_no_lock(card, nid); + snd_card_set_id_no_lock(card, nid, nid); mutex_unlock(&snd_card_mutex); } EXPORT_SYMBOL(snd_card_set_id); @@ -596,22 +626,12 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr, memcpy(buf1, buf, copy); buf1[copy] = '\0'; mutex_lock(&snd_card_mutex); - if (!snd_info_check_reserved_words(buf1)) { - __exist: + if (!card_id_ok(NULL, buf1)) { mutex_unlock(&snd_card_mutex); return -EEXIST; } - for (idx = 0; idx < snd_ecards_limit; idx++) { - if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) { - if (card == snd_cards[idx]) - goto __ok; - else - goto __exist; - } - } strcpy(card->id, buf1); snd_info_card_id_change(card); -__ok: mutex_unlock(&snd_card_mutex); return count; @@ -665,7 +685,18 @@ int snd_card_register(struct snd_card *card) mutex_unlock(&snd_card_mutex); return 0; } - snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id); + if (*card->id) { + /* make a unique id name from the given string */ + char tmpid[sizeof(card->id)]; + memcpy(tmpid, card->id, sizeof(card->id)); + snd_card_set_id_no_lock(card, tmpid, tmpid); + } else { + /* create an id from either shortname or longname */ + const char *src; + src = *card->shortname ? card->shortname : card->longname; + snd_card_set_id_no_lock(card, src, + retrieve_id_from_card_name(src)); + } snd_cards[card->number] = card; mutex_unlock(&snd_card_mutex); init_info_for_card(card); diff --git a/sound/core/misc.c b/sound/core/misc.c index 465f0ce772c..76816792540 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c @@ -72,7 +72,7 @@ void __snd_printk(unsigned int level, const char *path, int line, char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; #endif -#ifdef CONFIG_SND_DEBUG +#ifdef CONFIG_SND_DEBUG if (debug < level) return; #endif diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 3420bd3da5d..4d18941178e 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1029,7 +1029,8 @@ static int snd_interval_ratden(struct snd_interval *i, * * Returns non-zero if the value is changed, zero if not changed. */ -int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) +int snd_interval_list(struct snd_interval *i, unsigned int count, + const unsigned int *list, unsigned int mask) { unsigned int k; struct snd_interval list_range; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 25ed9fe41b8..3fe99e644eb 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1586,12 +1586,18 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) struct file *file; struct snd_pcm_file *pcm_file; struct snd_pcm_substream *substream1; + struct snd_pcm_group *group; file = snd_pcm_file_fd(fd); if (!file) return -EBADFD; pcm_file = file->private_data; substream1 = pcm_file->substream; + group = kmalloc(sizeof(*group), GFP_KERNEL); + if (!group) { + res = -ENOMEM; + goto _nolock; + } down_write(&snd_pcm_link_rwsem); write_lock_irq(&snd_pcm_link_rwlock); if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || @@ -1604,11 +1610,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) goto _end; } if (!snd_pcm_stream_linked(substream)) { - substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC); - if (substream->group == NULL) { - res = -ENOMEM; - goto _end; - } + substream->group = group; spin_lock_init(&substream->group->lock); INIT_LIST_HEAD(&substream->group->substreams); list_add_tail(&substream->link_list, &substream->group->substreams); @@ -1620,7 +1622,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) _end: write_unlock_irq(&snd_pcm_link_rwlock); up_write(&snd_pcm_link_rwsem); + _nolock: fput(file); + if (res < 0) + kfree(group); return res; } diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index bb938153a96..466a5c8e835 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -26,7 +26,7 @@ #include <sound/mpu401.h> #include <sound/hwdep.h> #include <sound/ac97_codec.h> - +#include <sound/tlv.h> #endif #ifndef CHIP_AU8820 @@ -107,6 +107,14 @@ #define NR_WTPB 0x20 /* WT channels per each bank. */ #define NR_PCM 0x10 +struct pcm_vol { + struct snd_kcontrol *kctl; + int active; + int dma; + int mixin[4]; + int vol[4]; +}; + /* Structs */ typedef struct { //int this_08; /* Still unknown */ @@ -168,6 +176,7 @@ struct snd_vortex { /* Xtalk canceler */ int xt_mode; /* 1: speakers, 0:headphones. */ #endif + struct pcm_vol pcm_vol[NR_PCM]; int isquad; /* cache of extended ID codec flag. */ @@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt); /* Connection stuff. */ static void vortex_connect_default(vortex_t * vortex, int en); static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, - int dir, int type); + int dir, int type, int subdev); static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype); #ifndef CHIP_AU8810 diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 6933a27a5d7..525f881f040 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) } /* Default Connections */ -static int -vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type); static void vortex_connect_default(vortex_t * vortex, int en) { @@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en) Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. */ static int -vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) +vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir, + int type, int subdev) { stream_t *stream; int i, en; + struct pcm_vol *p; - if ((nr_ch == 3) - || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2))) - return -EBUSY; - if (dma >= 0) { en = 0; vortex_adb_checkinout(vortex, @@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) MIX_DEFIGAIN); #endif } + if (stream->type == VORTEX_PCM_ADB && en) { + p = &vortex->pcm_vol[subdev]; + p->dma = dma; + for (i = 0; i < nr_ch; i++) + p->mixin[i] = mix[i]; + for (i = 0; i < ch_top; i++) + p->vol[i] = 0; + } } #ifndef CHIP_AU8820 else { @@ -2473,7 +2477,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) hwread(vortex->mmio, VORTEX_IRQ_STAT); handled = 1; } - if (source & IRQ_MIDI) { + if ((source & IRQ_MIDI) && vortex->rmidi) { snd_mpu401_uart_interrupt(vortex->irq, vortex->rmidi->private_data); handled = 1; diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 0ef2f971220..e59f120742a 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = { .mask = 0, }; #endif + +static void vortex_notify_pcm_vol_change(struct snd_card *card, + struct snd_kcontrol *kctl, int activate) +{ + if (activate) + kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + else + kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id)); +} + /* open callback */ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) { @@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, if (stream != NULL) vortex_adb_allocroute(chip, stream->dma, stream->nr_ch, stream->dir, - stream->type); + stream->type, + substream->number); /* Alloc routes. */ dma = vortex_adb_allocroute(chip, -1, params_channels(hw_params), - substream->stream, type); + substream->stream, type, + substream->number); if (dma < 0) { spin_unlock_irq(&chip->lock); return dma; @@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, vortex_adbdma_setbuffers(chip, dma, params_period_bytes(hw_params), params_periods(hw_params)); + if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) { + chip->pcm_vol[substream->number].active = 1; + vortex_notify_pcm_vol_change(chip->card, + chip->pcm_vol[substream->number].kctl, 1); + } } #ifndef CHIP_AU8810 else { @@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream) spin_lock_irq(&chip->lock); // Delete audio routes. if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { - if (stream != NULL) + if (stream != NULL) { + if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) { + chip->pcm_vol[substream->number].active = 0; + vortex_notify_pcm_vol_change(chip->card, + chip->pcm_vol[substream->number].kctl, + 0); + } vortex_adb_allocroute(chip, stream->dma, stream->nr_ch, stream->dir, - stream->type); + stream->type, + substream->number); + } } #ifndef CHIP_AU8810 else { @@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = { }, }; +/* subdevice PCM Volume control */ + +static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + vortex_t *vortex = snd_kcontrol_chip(kcontrol); + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2); + uinfo->value.integer.min = -128; + uinfo->value.integer.max = 32; + return 0; +} + +static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + vortex_t *vortex = snd_kcontrol_chip(kcontrol); + int subdev = kcontrol->id.subdevice; + struct pcm_vol *p = &vortex->pcm_vol[subdev]; + int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2); + for (i = 0; i < max_chn; i++) + ucontrol->value.integer.value[i] = p->vol[i]; + return 0; +} + +static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int i; + int changed = 0; + int mixin; + unsigned char vol; + vortex_t *vortex = snd_kcontrol_chip(kcontrol); + int subdev = kcontrol->id.subdevice; + struct pcm_vol *p = &vortex->pcm_vol[subdev]; + int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2); + for (i = 0; i < max_chn; i++) { + if (p->vol[i] != ucontrol->value.integer.value[i]) { + p->vol[i] = ucontrol->value.integer.value[i]; + if (p->active) { + switch (vortex->dma_adb[p->dma].nr_ch) { + case 1: + mixin = p->mixin[0]; + break; + case 2: + default: + mixin = p->mixin[(i < 2) ? i : (i - 2)]; + break; + case 4: + mixin = p->mixin[i]; + break; + }; + vol = p->vol[i]; + vortex_mix_setinputvolumebyte(vortex, + vortex->mixplayb[i], mixin, vol); + } + changed = 1; + } + } + return changed; +} + +static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400); + +static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "PCM Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_INACTIVE, + .info = snd_vortex_pcm_vol_info, + .get = snd_vortex_pcm_vol_get, + .put = snd_vortex_pcm_vol_put, + .tlv = { .p = vortex_pcm_vol_db_scale }, +}; + /* create a pcm device */ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) { @@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) return err; } } + if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) { + for (i = 0; i < NR_PCM; i++) { + chip->pcm_vol[i].active = 0; + chip->pcm_vol[i].dma = -1; + kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip); + if (!kctl) + return -ENOMEM; + chip->pcm_vol[i].kctl = kctl; + kctl->id.device = 0; + kctl->id.subdevice = i; + err = snd_ctl_add(chip->card, kctl); + if (err < 0) + return err; + } + } return 0; } diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index b78f3fc3c33..6109490b83e 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c @@ -36,7 +36,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size) size = CT_PAGE_ALIGN(size); if (size > vm->size) { - printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " + printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual " "memory space available!\n"); return NULL; } diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 92362973764..812d10e43ae 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice, ice->hw_rates); } +/* if the card has the internal rate locked (is_pro_locked), limit runtime + hw rates to the current internal rate only. +*/ +static void constrain_rate_if_locked(struct snd_pcm_substream *substream) +{ + struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned int rate; + if (is_pro_rate_locked(ice)) { + rate = ice->get_rate(ice); + if (rate >= runtime->hw.rate_min + && rate <= runtime->hw.rate_max) { + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } + } +} + + /* multi-channel playback needs alignment 8x32bit regardless of the channels * actually used */ @@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) VT1724_BUFFER_ALIGN); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, VT1724_BUFFER_ALIGN); + constrain_rate_if_locked(substream); if (ice->pro_open) ice->pro_open(ice, substream); return 0; @@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream) VT1724_BUFFER_ALIGN); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, VT1724_BUFFER_ALIGN); + constrain_rate_if_locked(substream); if (ice->pro_open) ice->pro_open(ice, substream); return 0; @@ -1215,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream) VT1724_BUFFER_ALIGN); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, VT1724_BUFFER_ALIGN); + constrain_rate_if_locked(substream); if (ice->spdif.ops.open) ice->spdif.ops.open(ice, substream); return 0; @@ -1251,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream) VT1724_BUFFER_ALIGN); snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, VT1724_BUFFER_ALIGN); + constrain_rate_if_locked(substream); if (ice->spdif.ops.open) ice->spdif.ops.open(ice, substream); return 0; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 12a9a2b0338..a8159b81e9c 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2317,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); + pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, + &chip->saved_dsxg_legacy); + pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, + &chip->saved_dsxg_elegacy); snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); snd_ymfpci_disable_dsp(chip); @@ -2351,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci) snd_ac97_resume(chip->ac97); + pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, + chip->saved_dsxg_legacy); + pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, + chip->saved_dsxg_elegacy); + /* start hw again */ if (chip->start_count > 0) { spin_lock_irq(&chip->reg_lock); diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index 4dd051bdf4f..c6500d00053 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c @@ -1112,17 +1112,7 @@ static struct spi_driver at73c213_driver = { .remove = __devexit_p(snd_at73c213_remove), }; -static int __init at73c213_init(void) -{ - return spi_register_driver(&at73c213_driver); -} -module_init(at73c213_init); - -static void __exit at73c213_exit(void) -{ - spi_unregister_driver(&at73c213_driver); -} -module_exit(at73c213_exit); +module_spi_driver(at73c213_driver); MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC"); diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index 8af92e3e9c1..fc8cc823e43 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c @@ -5,7 +5,6 @@ * * Author: Torsten Schenk <torsten.schenk@zoho.com> * Created: Jan 01, 2011 - * Versi |