diff options
84 files changed, 2033 insertions, 700 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index a18ecb92b356..5c49ba07e709 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
| @@ -132,6 +132,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 132 | mpu_irq - IRQ # for MPU-401 UART (PnP setup) | 132 | mpu_irq - IRQ # for MPU-401 UART (PnP setup) |
| 133 | dma1 - first DMA # for AD1816A chip (PnP setup) | 133 | dma1 - first DMA # for AD1816A chip (PnP setup) |
| 134 | dma2 - second DMA # for AD1816A chip (PnP setup) | 134 | dma2 - second DMA # for AD1816A chip (PnP setup) |
| 135 | clockfreq - Clock frequency for AD1816A chip (default = 0, 33000Hz) | ||
| 135 | 136 | ||
| 136 | Module supports up to 8 cards, autoprobe and PnP. | 137 | Module supports up to 8 cards, autoprobe and PnP. |
| 137 | 138 | ||
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index db0b7d2dc477..0475478c2484 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl | |||
| @@ -3422,10 +3422,17 @@ struct _snd_pcm_runtime { | |||
| 3422 | 3422 | ||
| 3423 | <para> | 3423 | <para> |
| 3424 | The <structfield>iface</structfield> field specifies the type of | 3424 | The <structfield>iface</structfield> field specifies the type of |
| 3425 | the control, | 3425 | the control, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which |
| 3426 | <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>. There are | 3426 | is usually <constant>MIXER</constant>. |
| 3427 | <constant>MIXER</constant>, <constant>PCM</constant>, | 3427 | Use <constant>CARD</constant> for global controls that are not |
| 3428 | <constant>CARD</constant>, etc. | 3428 | logically part of the mixer. |
| 3429 | If the control is closely associated with some specific device on | ||
| 3430 | the sound card, use <constant>HWDEP</constant>, | ||
| 3431 | <constant>PCM</constant>, <constant>RAWMIDI</constant>, | ||
| 3432 | <constant>TIMER</constant>, or <constant>SEQUENCER</constant>, and | ||
| 3433 | specify the device number with the | ||
| 3434 | <structfield>device</structfield> and | ||
| 3435 | <structfield>subdevice</structfield> fields. | ||
| 3429 | </para> | 3436 | </para> |
| 3430 | 3437 | ||
| 3431 | <para> | 3438 | <para> |
diff --git a/include/linux/sound.h b/include/linux/sound.h index 428f59794f48..72b9af4c3fd4 100644 --- a/include/linux/sound.h +++ b/include/linux/sound.h | |||
| @@ -29,7 +29,9 @@ | |||
| 29 | * Sound core interface functions | 29 | * Sound core interface functions |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | struct device; | ||
| 32 | extern int register_sound_special(struct file_operations *fops, int unit); | 33 | extern int register_sound_special(struct file_operations *fops, int unit); |
| 34 | extern int register_sound_special_device(struct file_operations *fops, int unit, struct device *dev); | ||
| 33 | extern int register_sound_mixer(struct file_operations *fops, int dev); | 35 | extern int register_sound_mixer(struct file_operations *fops, int dev); |
| 34 | extern int register_sound_midi(struct file_operations *fops, int dev); | 36 | extern int register_sound_midi(struct file_operations *fops, int dev); |
| 35 | extern int register_sound_dsp(struct file_operations *fops, int dev); | 37 | extern int register_sound_dsp(struct file_operations *fops, int dev); |
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index 1309c12b8f71..2857cf0472df 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
| 29 | #include <linux/device.h> | ||
| 29 | #include "pcm.h" | 30 | #include "pcm.h" |
| 30 | #include "control.h" | 31 | #include "control.h" |
| 31 | #include "info.h" | 32 | #include "info.h" |
| @@ -374,6 +375,9 @@ | |||
| 374 | #define AC97_HAS_NO_PC_BEEP (1<<12) /* no PC Beep volume */ | 375 | #define AC97_HAS_NO_PC_BEEP (1<<12) /* no PC Beep volume */ |
| 375 | #define AC97_HAS_NO_VIDEO (1<<13) /* no Video volume */ | 376 | #define AC97_HAS_NO_VIDEO (1<<13) /* no Video volume */ |
| 376 | #define AC97_HAS_NO_CD (1<<14) /* no CD volume */ | 377 | #define AC97_HAS_NO_CD (1<<14) /* no CD volume */ |
| 378 | #define AC97_HAS_NO_MIC (1<<15) /* no MIC volume */ | ||
| 379 | #define AC97_HAS_NO_TONE (1<<16) /* no Tone volume */ | ||
| 380 | #define AC97_HAS_NO_STD_PCM (1<<17) /* no standard AC97 PCM volume and mute */ | ||
| 377 | 381 | ||
| 378 | /* rates indexes */ | 382 | /* rates indexes */ |
| 379 | #define AC97_RATES_FRONT_DAC 0 | 383 | #define AC97_RATES_FRONT_DAC 0 |
| @@ -520,6 +524,7 @@ struct _snd_ac97 { | |||
| 520 | /* jack-sharing info */ | 524 | /* jack-sharing info */ |
| 521 | unsigned char indep_surround; | 525 | unsigned char indep_surround; |
| 522 | unsigned char channel_mode; | 526 | unsigned char channel_mode; |
| 527 | struct device dev; | ||
| 523 | }; | 528 | }; |
| 524 | 529 | ||
| 525 | /* conditions */ | 530 | /* conditions */ |
| @@ -599,4 +604,8 @@ struct ac97_enum { | |||
| 599 | unsigned short mask; | 604 | unsigned short mask; |
| 600 | const char **texts; | 605 | const char **texts; |
| 601 | }; | 606 | }; |
| 607 | |||
| 608 | /* ad hoc AC97 device driver access */ | ||
| 609 | extern struct bus_type ac97_bus_type; | ||
| 610 | |||
| 602 | #endif /* __SOUND_AC97_CODEC_H */ | 611 | #endif /* __SOUND_AC97_CODEC_H */ |
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h index 395978e375cf..ca2e0e4fa937 100644 --- a/include/sound/ad1816a.h +++ b/include/sound/ad1816a.h | |||
| @@ -138,6 +138,7 @@ struct _snd_ad1816a { | |||
| 138 | spinlock_t lock; | 138 | spinlock_t lock; |
| 139 | 139 | ||
| 140 | unsigned short mode; | 140 | unsigned short mode; |
| 141 | unsigned int clock_freq; | ||
| 141 | 142 | ||
| 142 | snd_card_t *card; | 143 | snd_card_t *card; |
| 143 | snd_pcm_t *pcm; | 144 | snd_pcm_t *pcm; |
diff --git a/include/sound/asound.h b/include/sound/asound.h index 9974f83cca44..8e552d627fa5 100644 --- a/include/sound/asound.h +++ b/include/sound/asound.h | |||
| @@ -560,7 +560,7 @@ enum { | |||
| 560 | * Timer section - /dev/snd/timer | 560 | * Timer section - /dev/snd/timer |
| 561 | */ | 561 | */ |
| 562 | 562 | ||
| 563 | #define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 4) | 563 | #define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5) |
| 564 | 564 | ||
| 565 | enum sndrv_timer_class { | 565 | enum sndrv_timer_class { |
| 566 | SNDRV_TIMER_CLASS_NONE = -1, | 566 | SNDRV_TIMER_CLASS_NONE = -1, |
| @@ -693,11 +693,15 @@ enum sndrv_timer_event { | |||
| 693 | SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ | 693 | SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ |
| 694 | SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */ | 694 | SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */ |
| 695 | SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */ | 695 | SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */ |
| 696 | SNDRV_TIMER_EVENT_SUSPEND, /* val = 0 */ | ||
| 697 | SNDRV_TIMER_EVENT_RESUME, /* val = resolution in ns */ | ||
| 696 | /* master timer events for slave timer instances */ | 698 | /* master timer events for slave timer instances */ |
| 697 | SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, | 699 | SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, |
| 698 | SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, | 700 | SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, |
| 699 | SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, | 701 | SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, |
| 700 | SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, | 702 | SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, |
| 703 | SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10, | ||
| 704 | SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10, | ||
| 701 | }; | 705 | }; |
| 702 | 706 | ||
| 703 | struct sndrv_timer_tread { | 707 | struct sndrv_timer_tread { |
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h index 182dd276ee74..9b94510eda60 100644 --- a/include/sound/cs46xx.h +++ b/include/sound/cs46xx.h | |||
| @@ -1748,7 +1748,7 @@ int snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t **rpcm); | |||
| 1748 | int snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t **rpcm); | 1748 | int snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t **rpcm); |
| 1749 | int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm); | 1749 | int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm); |
| 1750 | int snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t **rpcm); | 1750 | int snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t **rpcm); |
| 1751 | int snd_cs46xx_mixer(cs46xx_t *chip); | 1751 | int snd_cs46xx_mixer(cs46xx_t *chip, int spdif_device); |
| 1752 | int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi); | 1752 | int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi); |
| 1753 | int snd_cs46xx_start_dsp(cs46xx_t *chip); | 1753 | int snd_cs46xx_start_dsp(cs46xx_t *chip); |
| 1754 | int snd_cs46xx_gameport(cs46xx_t *chip); | 1754 | int snd_cs46xx_gameport(cs46xx_t *chip); |
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index c2ef3f023687..4e3993dfcefe 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
| @@ -1178,7 +1178,7 @@ int snd_p16v_free(emu10k1_t * emu); | |||
| 1178 | int snd_p16v_mixer(emu10k1_t * emu); | 1178 | int snd_p16v_mixer(emu10k1_t * emu); |
| 1179 | int snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); | 1179 | int snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); |
| 1180 | int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); | 1180 | int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); |
| 1181 | int snd_emu10k1_mixer(emu10k1_t * emu); | 1181 | int snd_emu10k1_mixer(emu10k1_t * emu, int pcm_device, int multi_device); |
| 1182 | int snd_emu10k1_timer(emu10k1_t * emu, int device); | 1182 | int snd_emu10k1_timer(emu10k1_t * emu, int device); |
| 1183 | int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep); | 1183 | int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep); |
| 1184 | 1184 | ||
diff --git a/include/sound/gus.h b/include/sound/gus.h index b4b461ca173d..7000d9d9199d 100644 --- a/include/sound/gus.h +++ b/include/sound/gus.h | |||
| @@ -512,13 +512,13 @@ extern void snd_gf1_ctrl_stop(snd_gus_card_t * gus, unsigned char reg); | |||
| 512 | 512 | ||
| 513 | extern void snd_gf1_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data); | 513 | extern void snd_gf1_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data); |
| 514 | extern unsigned char snd_gf1_look8(snd_gus_card_t * gus, unsigned char reg); | 514 | extern unsigned char snd_gf1_look8(snd_gus_card_t * gus, unsigned char reg); |
| 515 | extern inline unsigned char snd_gf1_read8(snd_gus_card_t * gus, unsigned char reg) | 515 | static inline unsigned char snd_gf1_read8(snd_gus_card_t * gus, unsigned char reg) |
| 516 | { | 516 | { |
| 517 | return snd_gf1_look8(gus, reg | 0x80); | 517 | return snd_gf1_look8(gus, reg | 0x80); |
| 518 | } | 518 | } |
| 519 | extern void snd_gf1_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data); | 519 | extern void snd_gf1_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data); |
| 520 | extern unsigned short snd_gf1_look16(snd_gus_card_t * gus, unsigned char reg); | 520 | extern unsigned short snd_gf1_look16(snd_gus_card_t * gus, unsigned char reg); |
| 521 | extern inline unsigned short snd_gf1_read16(snd_gus_card_t * gus, unsigned char reg) | 521 | static inline unsigned short snd_gf1_read16(snd_gus_card_t * gus, unsigned char reg) |
| 522 | { | 522 | { |
| 523 | return snd_gf1_look16(gus, reg | 0x80); | 523 | return snd_gf1_look16(gus, reg | 0x80); |
| 524 | } | 524 | } |
| @@ -532,12 +532,12 @@ extern void snd_gf1_i_ctrl_stop(snd_gus_card_t * gus, unsigned char reg); | |||
| 532 | extern void snd_gf1_i_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data); | 532 | extern void snd_gf1_i_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data); |
| 533 | extern unsigned char snd_gf1_i_look8(snd_gus_card_t * gus, unsigned char reg); | 533 | extern unsigned char snd_gf1_i_look8(snd_gus_card_t * gus, unsigned char reg); |
| 534 | extern void snd_gf1_i_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data); | 534 | extern void snd_gf1_i_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data); |
| 535 | extern inline unsigned char snd_gf1_i_read8(snd_gus_card_t * gus, unsigned char reg) | 535 | static inline unsigned char snd_gf1_i_read8(snd_gus_card_t * gus, unsigned char reg) |
| 536 | { | 536 | { |
| 537 | return snd_gf1_i_look8(gus, reg | 0x80); | 537 | return snd_gf1_i_look8(gus, reg | 0x80); |
| 538 | } | 538 | } |
| 539 | extern unsigned short snd_gf1_i_look16(snd_gus_card_t * gus, unsigned char reg); | 539 | extern unsigned short snd_gf1_i_look16(snd_gus_card_t * gus, unsigned char reg); |
| 540 | extern inline unsigned short snd_gf1_i_read16(snd_gus_card_t * gus, unsigned char reg) | 540 | static inline unsigned short snd_gf1_i_read16(snd_gus_card_t * gus, unsigned char reg) |
| 541 | { | 541 | { |
| 542 | return snd_gf1_i_look16(gus, reg | 0x80); | 542 | return snd_gf1_i_look16(gus, reg | 0x80); |
| 543 | } | 543 | } |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index d935417575b5..fa23ebfb857a 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
| @@ -379,7 +379,6 @@ struct _snd_pcm_substream { | |||
| 379 | unsigned int dma_buf_id; | 379 | unsigned int dma_buf_id; |
| 380 | size_t dma_max; | 380 | size_t dma_max; |
| 381 | /* -- hardware operations -- */ | 381 | /* -- hardware operations -- */ |
| 382 | unsigned int open_flag: 1; /* lowlevel device has been opened */ | ||
| 383 | snd_pcm_ops_t *ops; | 382 | snd_pcm_ops_t *ops; |
| 384 | /* -- runtime information -- */ | 383 | /* -- runtime information -- */ |
| 385 | snd_pcm_runtime_t *runtime; | 384 | snd_pcm_runtime_t *runtime; |
diff --git a/include/sound/version.h b/include/sound/version.h index c085136f391f..8d19bfabb7e0 100644 --- a/include/sound/version.h +++ b/include/sound/version.h | |||
| @@ -1,3 +1,3 @@ | |||
| 1 | /* include/version.h. Generated by configure. */ | 1 | /* include/version.h. Generated by configure. */ |
| 2 | #define CONFIG_SND_VERSION "1.0.9b" | 2 | #define CONFIG_SND_VERSION "1.0.10rc1" |
| 3 | #define CONFIG_SND_DATE " (Thu Jul 28 12:20:13 2005 UTC)" | 3 | #define CONFIG_SND_DATE " (Tue Aug 30 05:31:08 2005 UTC)" |
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h index 4b570684a6aa..9a3c1e6c820a 100644 --- a/include/sound/ymfpci.h +++ b/include/sound/ymfpci.h | |||
| @@ -295,6 +295,7 @@ struct _snd_ymfpci_pcm { | |||
| 295 | unsigned int running: 1; | 295 | unsigned int running: 1; |
| 296 | unsigned int output_front: 1; | 296 | unsigned int output_front: 1; |
| 297 | unsigned int output_rear: 1; | 297 | unsigned int output_rear: 1; |
| 298 | unsigned int update_pcm_vol; | ||
| 298 | u32 period_size; /* cached from runtime->period_size */ | 299 | u32 period_size; /* cached from runtime->period_size */ |
| 299 | u32 buffer_size; /* cached from runtime->buffer_size */ | 300 | u32 buffer_size; /* cached from runtime->buffer_size */ |
| 300 | u32 period_pos; | 301 | u32 period_pos; |
| @@ -367,6 +368,11 @@ struct _snd_ymfpci { | |||
| 367 | int mode_dup4ch; | 368 | int mode_dup4ch; |
| 368 | int rear_opened; | 369 | int rear_opened; |
| 369 | int spdif_opened; | 370 | int spdif_opened; |
| 371 | struct { | ||
| 372 | u16 left; | ||
| 373 | u16 right; | ||
| 374 | snd_kcontrol_t *ctl; | ||
| 375 | } pcm_mixer[32]; | ||
| 370 | 376 | ||
| 371 | spinlock_t reg_lock; | 377 | spinlock_t reg_lock; |
| 372 | spinlock_t voice_lock; | 378 | spinlock_t voice_lock; |
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 46052304e230..29450befb5da 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c | |||
| @@ -132,9 +132,9 @@ static void pxa2xx_ac97_reset(ac97_t *ac97) | |||
| 132 | udelay(10); | 132 | udelay(10); |
| 133 | GCR |= GCR_WARM_RST; | 133 | GCR |= GCR_WARM_RST; |
| 134 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | 134 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); |
| 135 | udelay(50); | 135 | udelay(500); |
| 136 | #else | 136 | #else |
| 137 | GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN;; | 137 | GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN; |
| 138 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | 138 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); |
| 139 | #endif | 139 | #endif |
| 140 | 140 | ||
| @@ -261,7 +261,7 @@ static int pxa2xx_ac97_do_suspend(snd_card_t *card, unsigned int state) | |||
| 261 | return 0; | 261 | return 0; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | static int pxa2xx_ac97_do_resume(snd_card_t *card, unsigned int state) | 264 | static int pxa2xx_ac97_do_resume(snd_card_t *card) |
| 265 | { | 265 | { |
| 266 | if (card->power_state != SNDRV_CTL_POWER_D0) { | 266 | if (card->power_state != SNDRV_CTL_POWER_D0) { |
| 267 | pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; | 267 | pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; |
| @@ -275,13 +275,13 @@ static int pxa2xx_ac97_do_resume(snd_card_t *card, unsigned int state) | |||
| 275 | return 0; | 275 | return 0; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | static int pxa2xx_ac97_suspend(struct device *_dev, u32 state, u32 level) | 278 | static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state, u32 level) |
| 279 | { | 279 | { |
| 280 | snd_card_t *card = dev_get_drvdata(_dev); | 280 | snd_card_t *card = dev_get_drvdata(_dev); |
| 281 | int ret = 0; | 281 | int ret = 0; |
| 282 | 282 | ||
| 283 | if (card && level == SUSPEND_DISABLE) | 283 | if (card && level == SUSPEND_DISABLE) |
| 284 | ret = pxa2xx_ac97_do_suspend(card, SNDRV_CTL_POWER_D3cold); | 284 | ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND); |
| 285 | 285 | ||
| 286 | return ret; | 286 | return ret; |
| 287 | } | 287 | } |
| @@ -292,7 +292,7 @@ static int pxa2xx_ac97_resume(struct device *_dev, u32 level) | |||
| 292 | int ret = 0; | 292 | int ret = 0; |
| 293 | 293 | ||
| 294 | if (card && level == RESUME_ENABLE) | 294 | if (card && level == RESUME_ENABLE) |
| 295 | ret = pxa2xx_ac97_do_resume(card, SNDRV_CTL_POWER_D0); | 295 | ret = pxa2xx_ac97_do_resume(card); |
| 296 | 296 | ||
| 297 | return ret; | 297 | return ret; |
| 298 | } | 298 | } |
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 02132561c3f8..39a54a415528 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c | |||
| @@ -512,7 +512,7 @@ static void free_all_reserved_pages(void) | |||
| 512 | * proc file interface | 512 | * proc file interface |
| 513 | */ | 513 | */ |
| 514 | #define SND_MEM_PROC_FILE "driver/snd-page-alloc" | 514 | #define SND_MEM_PROC_FILE "driver/snd-page-alloc" |
| 515 | struct proc_dir_entry *snd_mem_proc; | 515 | static struct proc_dir_entry *snd_mem_proc; |
| 516 | 516 | ||
| 517 | static int snd_mem_proc_read(char *page, char **start, off_t off, | 517 | static int snd_mem_proc_read(char *page, char **start, off_t off, |
| 518 | int count, int *eof, void *data) | 518 | int count, int *eof, void *data) |
| @@ -655,8 +655,7 @@ static int __init snd_mem_init(void) | |||
| 655 | 655 | ||
| 656 | static void __exit snd_mem_exit(void) | 656 | static void __exit snd_mem_exit(void) |
| 657 | { | 657 | { |
| 658 | if (snd_mem_proc) | 658 | remove_proc_entry(SND_MEM_PROC_FILE, NULL); |
| 659 | remove_proc_entry(SND_MEM_PROC_FILE, NULL); | ||
| 660 | free_all_reserved_pages(); | 659 | free_all_reserved_pages(); |
| 661 | if (snd_allocated_pages > 0) | 660 | if (snd_allocated_pages > 0) |
| 662 | printk(KERN_ERR "snd-malloc: Memory leak? pages not freed = %li\n", snd_allocated_pages); | 661 | printk(KERN_ERR "snd-malloc: Memory leak? pages not freed = %li\n", snd_allocated_pages); |
diff --git a/sound/core/memory.c b/sound/core/memory.c index f6895577bf86..1622893d00a2 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c | |||
| @@ -56,7 +56,7 @@ static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock); | |||
| 56 | #define VMALLOC_MAGIC 0x87654320 | 56 | #define VMALLOC_MAGIC 0x87654320 |
| 57 | static snd_info_entry_t *snd_memory_info_entry; | 57 | static snd_info_entry_t *snd_memory_info_entry; |
| 58 | 58 | ||
| 59 | void snd_memory_init(void) | 59 | void __init snd_memory_init(void) |
| 60 | { | 60 | { |
| 61 | snd_alloc_kmalloc = 0; | 61 | snd_alloc_kmalloc = 0; |
| 62 | snd_alloc_vmalloc = 0; | 62 | snd_alloc_vmalloc = 0; |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index de7444c586f9..a13bd7bb4c9f 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
| @@ -1705,13 +1705,12 @@ static int snd_pcm_oss_release_file(snd_pcm_oss_file_t *pcm_oss_file) | |||
| 1705 | if (snd_pcm_running(substream)) | 1705 | if (snd_pcm_running(substream)) |
| 1706 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); | 1706 | snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); |
| 1707 | snd_pcm_stream_unlock_irq(substream); | 1707 | snd_pcm_stream_unlock_irq(substream); |
| 1708 | if (substream->open_flag) { | 1708 | if (substream->ffile != NULL) { |
| 1709 | if (substream->ops->hw_free != NULL) | 1709 | if (substream->ops->hw_free != NULL) |
| 1710 | substream->ops->hw_free(substream); | 1710 | substream->ops->hw_free(substream); |
| 1711 | substream->ops->close(substream); | 1711 | substream->ops->close(substream); |
| 1712 | substream->open_flag = 0; | 1712 | substream->ffile = NULL; |
| 1713 | } | 1713 | } |
| 1714 | substream->ffile = NULL; | ||
| 1715 | snd_pcm_oss_release_substream(substream); | 1714 | snd_pcm_oss_release_substream(substream); |
| 1716 | snd_pcm_release_substream(substream); | 1715 | snd_pcm_release_substream(substream); |
| 1717 | } | 1716 | } |
| @@ -1778,14 +1777,13 @@ static int snd_pcm_oss_open_file(struct file *file, | |||
| 1778 | snd_pcm_oss_release_file(pcm_oss_file); | 1777 | snd_pcm_oss_release_file(pcm_oss_file); |
| 1779 | return err; | 1778 | return err; |
| 1780 | } | 1779 | } |
| 1781 | psubstream->open_flag = 1; | 1780 | psubstream->ffile = file; |
| 1782 | err = snd_pcm_hw_constraints_complete(psubstream); | 1781 | err = snd_pcm_hw_constraints_complete(psubstream); |
| 1783 | if (err < 0) { | 1782 | if (err < 0) { |
| 1784 | snd_printd("snd_pcm_hw_constraint_complete failed\n"); | 1783 | snd_printd("snd_pcm_hw_constraint_complete failed\n"); |
| 1785 | snd_pcm_oss_release_file(pcm_oss_file); | 1784 | snd_pcm_oss_release_file(pcm_oss_file); |
| 1786 | return err; | 1785 | return err; |
| 1787 | } | 1786 | } |
| 1788 | psubstream->ffile = file; | ||
| 1789 | snd_pcm_oss_init_substream(psubstream, psetup, minor); | 1787 | snd_pcm_oss_init_substream(psubstream, psetup, minor); |
| 1790 | } | 1788 | } |
| 1791 | if (csubstream != NULL) { | 1789 | if (csubstream != NULL) { |
| @@ -1800,14 +1798,13 @@ static int snd_pcm_oss_open_file(struct file *file, | |||
| 1800 | snd_pcm_oss_release_file(pcm_oss_file); | 1798 | snd_pcm_oss_release_file(pcm_oss_file); |
| 1801 | return err; | 1799 | return err; |
| 1802 | } | 1800 | } |
| 1803 | csubstream->open_flag = 1; | 1801 | csubstream->ffile = file; |
| 1804 | err = snd_pcm_hw_constraints_complete(csubstream); | 1802 | err = snd_pcm_hw_constraints_complete(csubstream); |
| 1805 | if (err < 0) { | 1803 | if (err < 0) { |
| 1806 | snd_printd("snd_pcm_hw_constraint_complete failed\n"); | 1804 | snd_printd("snd_pcm_hw_constraint_complete failed\n"); |
| 1807 | snd_pcm_oss_release_file(pcm_oss_file); | 1805 | snd_pcm_oss_release_file(pcm_oss_file); |
| 1808 | return err; | 1806 | return err; |
| 1809 | } | 1807 | } |
| 1810 | csubstream->ffile = file; | ||
| 1811 | snd_pcm_oss_init_substream(csubstream, csetup, minor); | 1808 | snd_pcm_oss_init_substream(csubstream, csetup, minor); |
| 1812 | } | 1809 | } |
| 1813 | 1810 | ||
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 3920bf0eebbf..4b6307df846d 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c | |||
| @@ -103,10 +103,24 @@ struct sndrv_pcm_sw_params32 { | |||
| 103 | unsigned char reserved[64]; | 103 | unsigned char reserved[64]; |
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | /* recalcuate the boundary within 32bit */ | ||
| 107 | static snd_pcm_uframes_t recalculate_boundary(snd_pcm_runtime_t *runtime) | ||
| 108 | { | ||
| 109 | snd_pcm_uframes_t boundary; | ||
| 110 | |||
| 111 | if (! runtime->buffer_size) | ||
| 112 | return 0; | ||
| 113 | boundary = runtime->buffer_size; | ||
| 114 | while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size) | ||
| 115 | boundary *= 2; | ||
| 116 | return boundary; | ||
| 117 | } | ||
| 118 | |||
| 106 | static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream, | 119 | static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream, |
| 107 | struct sndrv_pcm_sw_params32 __user *src) | 120 | struct sndrv_pcm_sw_params32 __user *src) |
| 108 | { | 121 | { |
| 109 | snd_pcm_sw_params_t params; | 122 | snd_pcm_sw_params_t params; |
| 123 | snd_pcm_uframes_t boundary; | ||
| 110 | int err; | 124 | int err; |
| 111 | 125 | ||
| 112 | memset(¶ms, 0, sizeof(params)); | 126 | memset(¶ms, 0, sizeof(params)); |
| @@ -120,10 +134,17 @@ static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream, | |||
| 120 | get_user(params.silence_threshold, &src->silence_threshold) || | 134 | get_user(params.silence_threshold, &src->silence_threshold) || |
| 121 | get_user(params.silence_size, &src->silence_size)) | 135 | get_user(params.silence_size, &src->silence_size)) |
| 122 | return -EFAULT; | 136 | return -EFAULT; |
| 137 | /* | ||
| 138 | * Check silent_size parameter. Since we have 64bit boundary, | ||
| 139 | * silence_size must be compared with the 32bit boundary. | ||
| 140 | */ | ||
| 141 | boundary = recalculate_boundary(substream->runtime); | ||
| 142 | if (boundary && params.silence_size >= boundary) | ||
| 143 | params.silence_size = substream->runtime->boundary; | ||
| 123 | err = snd_pcm_sw_params(substream, ¶ms); | 144 | err = snd_pcm_sw_params(substream, ¶ms); |
| 124 | if (err < 0) | 145 | if (err < 0) |
| 125 | return err; | 146 | return err; |
| 126 | if (put_user(params.boundary, &src->boundary)) | 147 | if (boundary && put_user(boundary, &src->boundary)) |
| 127 | return -EFAULT; | 148 | return -EFAULT; |
| 128 | return err; | 149 | return err; |
| 129 | } | 150 | } |
| @@ -199,16 +220,6 @@ static int snd_pcm_status_user_compat(snd_pcm_substream_t *substream, | |||
| 199 | return err; | 220 | return err; |
| 200 | } | 221 | } |
| 201 | 222 | ||
| 202 | /* recalcuate the boundary within 32bit */ | ||
| 203 | static void recalculate_boundary(snd_pcm_runtime_t *runtime) | ||
| 204 | { | ||
| 205 | if (! runtime->buffer_size) | ||
| 206 | return; | ||
| 207 | runtime->boundary = runtime->buffer_size; | ||
| 208 | while (runtime->boundary * 2 <= 0x7fffffffUL - runtime->buffer_size) | ||
| 209 | runtime->boundary *= 2; | ||
| 210 | } | ||
| 211 | |||
| 212 | /* both for HW_PARAMS and HW_REFINE */ | 223 | /* both for HW_PARAMS and HW_REFINE */ |
| 213 | static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream, | 224 | static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream, |
| 214 | int refine, | 225 | int refine, |
| @@ -241,8 +252,11 @@ static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream, | |||
| 241 | goto error; | 252 | goto error; |
| 242 | } | 253 | } |
| 243 | 254 | ||
| 244 | if (! refine) | 255 | if (! refine) { |
| 245 | recalculate_boundary(runtime); | 256 | unsigned int new_boundary = recalculate_boundary(runtime); |
| 257 | if (new_boundary) | ||
| 258 | runtime->boundary = new_boundary; | ||
| 259 | } | ||
| 246 | error: | 260 | error: |
| 247 | kfree(data); | 261 | kfree(data); |
| 248 | return err; | 262 | return err; |
| @@ -380,6 +394,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(snd_pcm_substream_t *substream, | |||
| 380 | u32 sflags; | 394 | u32 sflags; |
| 381 | struct sndrv_pcm_mmap_control scontrol; | 395 | struct sndrv_pcm_mmap_control scontrol; |
| 382 | struct sndrv_pcm_mmap_status sstatus; | 396 | struct sndrv_pcm_mmap_status sstatus; |
| 397 | snd_pcm_uframes_t boundary; | ||
| 383 | int err; | 398 | int err; |
| 384 | 399 | ||
| 385 | snd_assert(runtime, return -EINVAL); | 400 | snd_assert(runtime, return -EINVAL); |
| @@ -395,17 +410,21 @@ static int snd_pcm_ioctl_sync_ptr_compat(snd_pcm_substream_t *substream, | |||
| 395 | } | 410 | } |
| 396 | status = runtime->status; | 411 | status = runtime->status; |
| 397 | control = runtime->control; | 412 | control = runtime->control; |
| 413 | boundary = recalculate_boundary(runtime); | ||
| 414 | if (! boundary) | ||
| 415 | boundary = 0x7fffffff; | ||
| 398 | snd_pcm_stream_lock_irq(substream); | 416 | snd_pcm_stream_lock_irq(substream); |
| 417 | /* FIXME: we should consider the boundary for the sync from app */ | ||
| 399 | if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) | 418 | if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) |
| 400 | control->appl_ptr = scontrol.appl_ptr; | 419 | control->appl_ptr = scontrol.appl_ptr; |
| 401 | else | 420 | else |
| 402 | scontrol.appl_ptr = control->appl_ptr; | 421 | scontrol.appl_ptr = control->appl_ptr % boundary; |
| 403 | if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) | 422 | if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) |
| 404 | control->avail_min = scontrol.avail_min; | 423 | control->avail_min = scontrol.avail_min; |
| 405 | else | 424 | else |
| 406 | scontrol.avail_min = control->avail_min; | 425 | scontrol.avail_min = control->avail_min; |
| 407 | sstatus.state = status->state; | 426 | sstatus.state = status->state; |
| 408 | sstatus.hw_ptr = status->hw_ptr; | 427 | sstatus.hw_ptr = status->hw_ptr % boundary; |
| 409 | sstatus.tstamp = status->tstamp; | 428 | sstatus.tstamp = status->tstamp; |
| 410 | sstatus.suspended_state = status->suspended_state; | 429 | sstatus.suspended_state = status->suspended_state; |
| 411 | snd_pcm_stream_unlock_irq(substream); | 430 | snd_pcm_stream_unlock_irq(substream); |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index c5bfd0918cff..0082914a7e33 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
| @@ -1584,8 +1584,8 @@ int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, | |||
| 1584 | return snd_pcm_hw_param_value(params, var, NULL); | 1584 | return snd_pcm_hw_param_value(params, var, NULL); |
| 1585 | } | 1585 | } |
| 1586 | 1586 | ||
| 1587 | int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, | 1587 | static int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, |
| 1588 | snd_pcm_hw_param_t var, const snd_mask_t *val) | 1588 | snd_pcm_hw_param_t var, const snd_mask_t *val) |
| 1589 | { | 1589 | { |
| 1590 | int changed; | 1590 | int changed; |
| 1591 | assert(hw_is_mask(var)); | 1591 | assert(hw_is_mask(var)); |
| @@ -2063,7 +2063,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, | |||
| 2063 | if (((avail < runtime->control->avail_min && size > avail) || | 2063 | if (((avail < runtime->control->avail_min && size > avail) || |
| 2064 | (size >= runtime->xfer_align && avail < runtime->xfer_align))) { | 2064 | (size >= runtime->xfer_align && avail < runtime->xfer_align))) { |
| 2065 | wait_queue_t wait; | 2065 | wait_queue_t wait; |
| 2066 | enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state; | 2066 | enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state; |
| 2067 | long tout; | 2067 | long tout; |
| 2068 | 2068 | ||
| 2069 | if (nonblock) { | 2069 | if (nonblock) { |
| @@ -2097,6 +2097,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, | |||
| 2097 | case SNDRV_PCM_STATE_SUSPENDED: | 2097 | case SNDRV_PCM_STATE_SUSPENDED: |
| 2098 | state = SUSPENDED; | 2098 | state = SUSPENDED; |
| 2099 | goto _end_loop; | 2099 | goto _end_loop; |
| 2100 | case SNDRV_PCM_STATE_SETUP: | ||
| 2101 | state = DROPPED; | ||
| 2102 | goto _end_loop; | ||
| 2100 | default: | 2103 | default: |
| 2101 | break; | 2104 | break; |
| 2102 | } | 2105 | } |
| @@ -2123,6 +2126,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, | |||
| 2123 | snd_printd("playback write error (DMA or IRQ trouble?)\n"); | 2126 | snd_printd("playback write error (DMA or IRQ trouble?)\n"); |
| 2124 | err = -EIO; | 2127 | err = -EIO; |
| 2125 | goto _end_unlock; | 2128 | goto _end_unlock; |
| 2129 | case DROPPED: | ||
| 2130 | err = -EBADFD; | ||
| 2131 | goto _end_unlock; | ||
| 2126 | default: | 2132 | default: |
| 2127 | break; | 2133 | break; |
| 2128 | } | 2134 | } |
| @@ -2359,7 +2365,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, | |||
| 2359 | } else if ((avail < runtime->control->avail_min && size > avail) || | 2365 | } else if ((avail < runtime->control->avail_min && size > avail) || |
| 2360 | (size >= runtime->xfer_align && avail < runtime->xfer_align)) { | 2366 | (size >= runtime->xfer_align && avail < runtime->xfer_align)) { |
| 2361 | wait_queue_t wait; | 2367 | wait_queue_t wait; |
| 2362 | enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state; | 2368 | enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state; |
| 2363 | long tout; | 2369 | long tout; |
| 2364 | 2370 | ||
| 2365 | if (nonblock) { | 2371 | if (nonblock) { |
| @@ -2394,6 +2400,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, | |||
| 2394 | goto _end_loop; | 2400 | goto _end_loop; |
| 2395 | case SNDRV_PCM_STATE_DRAINING: | 2401 | case SNDRV_PCM_STATE_DRAINING: |
| 2396 | goto __draining; | 2402 | goto __draining; |
| 2403 | case SNDRV_PCM_STATE_SETUP: | ||
| 2404 | state = DROPPED; | ||
| 2405 | goto _end_loop; | ||
| 2397 | default: | 2406 | default: |
| 2398 | break; | 2407 | break; |
| 2399 | } | 2408 | } |
| @@ -2420,6 +2429,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, | |||
| 2420 | snd_printd("capture read error (DMA or IRQ trouble?)\n"); | 2429 | snd_printd("capture read error (DMA or IRQ trouble?)\n"); |
| 2421 | err = -EIO; | 2430 | err = -EIO; |
| 2422 | goto _end_unlock; | 2431 | goto _end_unlock; |
| 2432 | case DROPPED: | ||
| 2433 | err = -EBADFD; | ||
| 2434 | goto _end_unlock; | ||
| 2423 | default: | 2435 | default: |
| 2424 | break; | 2436 | break; |
| 2425 | } | 2437 | } |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 10c2c9832649..03c17159dd8e 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -1025,7 +1025,7 @@ static void snd_pcm_post_suspend(snd_pcm_substream_t *substream, int state) | |||
| 1025 | snd_pcm_runtime_t *runtime = substream->runtime; | 1025 | snd_pcm_runtime_t *runtime = substream->runtime; |
| 1026 | snd_pcm_trigger_tstamp(substream); | 1026 | snd_pcm_trigger_tstamp(substream); |
| 1027 | if (substream->timer) | 1027 | if (substream->timer) |
| 1028 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, &runtime->trigger_tstamp); | 1028 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND, &runtime->trigger_tstamp); |
| 1029 | runtime->status->suspended_state = runtime->status->state; | 1029 | runtime->status->suspended_state = runtime->status->state; |
| 1030 | runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; | 1030 | runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; |
| 1031 | snd_pcm_tick_set(substream, 0); | 1031 | snd_pcm_tick_set(substream, 0); |
| @@ -1115,7 +1115,7 @@ static void snd_pcm_post_resume(snd_pcm_substream_t *substream, int state) | |||
| 1115 | snd_pcm_runtime_t *runtime = substream->runtime; | 1115 | snd_pcm_runtime_t *runtime = substream->runtime; |
| 1116 | snd_pcm_trigger_tstamp(substream); | 1116 | snd_pcm_trigger_tstamp(substream); |
| 1117 | if (substream->timer) | 1117 | if (substream->timer) |
| 1118 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MCONTINUE, &runtime->trigger_tstamp); | 1118 | snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME, &runtime->trigger_tstamp); |
| 1119 | runtime->status->state = runtime->status->suspended_state; | 1119 | runtime->status->state = runtime->status->suspended_state; |
| 1120 | if (runtime->sleep_min) | 1120 | if (runtime->sleep_min) |
| 1121 | snd_pcm_tick_prepare(substream); | 1121 | snd_pcm_tick_prepare(substream); |
| @@ -1967,13 +1967,12 @@ static int snd_pcm_release_file(snd_pcm_file_t * pcm_file) | |||
| 1967 | runtime = substream->runtime; | 1967 | runtime = substream->runtime; |
| 1968 | str = substream->pstr; | 1968 | str = substream->pstr; |
| 1969 | snd_pcm_unlink(substream); | 1969 | snd_pcm_unlink(substream); |
| 1970 | if (substream->open_flag) { | 1970 | if (substream->ffile != NULL) { |
| 1971 | if (substream->ops->hw_free != NULL) | 1971 | if (substream->ops->hw_free != NULL) |
| 1972 | substream->ops->hw_free(substream); | 1972 | substream->ops->hw_free(substream); |
| 1973 | substream->ops->close(substream); | 1973 | substream->ops->close(substream); |
| 1974 | substream->open_flag = 0; | 1974 | substream->ffile = NULL; |
| 1975 | } | 1975 | } |
| 1976 | substream->ffile = NULL; | ||
| 1977 | snd_pcm_remove_file(str, pcm_file); | 1976 | snd_pcm_remove_file(str, pcm_file); |
| 1978 | snd_pcm_release_substream(substream); | 1977 | snd_pcm_release_substream(substream); |
| 1979 | kfree(pcm_file); | 1978 | kfree(pcm_file); |
| @@ -2022,18 +2021,15 @@ static int snd_pcm_open_file(struct file *file, | |||
| 2022 | snd_pcm_release_file(pcm_file); | 2021 | snd_pcm_release_file(pcm_file); |
| 2023 | return err; | 2022 | return err; |
| 2024 | } | 2023 | } |
| 2025 | substream->open_flag = 1; | 2024 | substream->ffile = file; |
| 2026 | 2025 | ||
| 2027 | err = snd_pcm_hw_constraints_complete(substream); | 2026 | err = snd_pcm_hw_constraints_complete(substream); |
| 2028 | if (err < 0) { | 2027 | if (err < 0) { |
| 2029 | snd_printd("snd_pcm_hw_constraints_complete failed\n"); | 2028 | snd_printd("snd_pcm_hw_constraints_complete failed\n"); |
| 2030 | substream->ops->close(substream); | ||
| 2031 | snd_pcm_release_file(pcm_file); | 2029 | snd_pcm_release_file(pcm_file); |
| 2032 | return err; | 2030 | return err; |
| 2033 | } | 2031 | } |
| 2034 | 2032 | ||
| 2035 | substream->ffile = file; | ||
| 2036 | |||
| 2037 | file->private_data = pcm_file; | 2033 | file->private_data = pcm_file; |
| 2038 | *rpcm_file = pcm_file; | 2034 | *rpcm_file = pcm_file; |
| 2039 | return 0; | 2035 | return 0; |
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index de39d212bc15..e401c6703297 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c | |||
| @@ -98,6 +98,7 @@ int snd_register_oss_device(int type, snd_card_t * card, int dev, snd_minor_t * | |||
| 98 | int cidx = SNDRV_MINOR_OSS_CARD(minor); | 98 | int cidx = SNDRV_MINOR_OSS_CARD(minor); |
| 99 | int track2 = -1; | 99 | int track2 = -1; |
| 100 | int register1 = -1, register2 = -1; | 100 | int register1 = -1, register2 = -1; |
| 101 | struct device *carddev = NULL; | ||
| 101 | 102 | ||
| 102 | if (minor < 0) | 103 | if (minor < 0) |
| 103 | return minor; | 104 | return minor; |
| @@ -121,11 +122,13 @@ int snd_register_oss_device(int type, snd_card_t * card, int dev, snd_minor_t * | |||
| 121 | track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); | 122 | track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); |
| 122 | break; | 123 | break; |
| 123 | } | 124 | } |
| 124 | register1 = register_sound_special(reg->f_ops, minor); | 125 | if (card) |
| 126 | carddev = card->dev; | ||
| 127 | register1 = register_sound_special_device(reg->f_ops, minor, carddev); | ||
| 125 | if (register1 != minor) | 128 | if (register1 != minor) |
| 126 | goto __end; | 129 | goto __end; |
| 127 | if (track2 >= 0) { | 130 | if (track2 >= 0) { |
| 128 | register2 = register_sound_special(reg->f_ops, track2); | 131 | register2 = register_sound_special_device(reg->f_ops, track2, carddev); |
| 129 | if (register2 != track2) | 132 | if (register2 != track2) |
| 130 | goto __end; | 133 | goto __end; |
| 131 | } | 134 | } |
diff --git a/sound/core/timer.c b/sound/core/timer.c index cfaccd415b3b..4104f6e292e9 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
| @@ -799,13 +799,13 @@ static int snd_timer_free(snd_timer_t *timer) | |||
| 799 | return 0; | 799 | return 0; |
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | int snd_timer_dev_free(snd_device_t *device) | 802 | static int snd_timer_dev_free(snd_device_t *device) |
| 803 | { | 803 | { |
| 804 | snd_timer_t *timer = device->device_data; | 804 | snd_timer_t *timer = device->device_data; |
| 805 | return snd_timer_free(timer); | 805 | return snd_timer_free(timer); |
| 806 | } | 806 | } |
| 807 | 807 | ||
| 808 | int snd_timer_dev_register(snd_device_t *dev) | 808 | static int snd_timer_dev_register(snd_device_t *dev) |
| 809 | { | 809 | { |
| 810 | snd_timer_t *timer = dev->device_data; | 810 | snd_timer_t *timer = dev->device_data; |
| 811 | snd_timer_t *timer1; | 811 | snd_timer_t *timer1; |
| @@ -880,9 +880,11 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t | |||
| 880 | struct list_head *p, *n; | 880 | struct list_head *p, *n; |
| 881 | 881 | ||
| 882 | snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return); | 882 | snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return); |
| 883 | snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MPAUSE, return); | 883 | snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); |
| 884 | spin_lock_irqsave(&timer->lock, flags); | 884 | spin_lock_irqsave(&timer->lock, flags); |
| 885 | if (event == SNDRV_TIMER_EVENT_MSTART || event == SNDRV_TIMER_EVENT_MCONTINUE) { | 885 | if (event == SNDRV_TIMER_EVENT_MSTART || |
| 886 | event == SNDRV_TIMER_EVENT_MCONTINUE || | ||
| 887 | event == SNDRV_TIMER_EVENT_MRESUME) { | ||
| 886 | if (timer->hw.c_resolution) | 888 | if (timer->hw.c_resolution) |
| 887 | resolution = timer->hw.c_resolution(timer); | 889 | resolution = timer->hw.c_resolution(timer); |
| 888 | else | 890 | else |
| @@ -1555,10 +1557,14 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
| 1555 | (1<<SNDRV_TIMER_EVENT_STOP)| | 1557 | (1<<SNDRV_TIMER_EVENT_STOP)| |
| 1556 | (1<<SNDRV_TIMER_EVENT_CONTINUE)| | 1558 | (1<<SNDRV_TIMER_EVENT_CONTINUE)| |
| 1557 | (1<<SNDRV_TIMER_EVENT_PAUSE)| | 1559 | (1<<SNDRV_TIMER_EVENT_PAUSE)| |
| 1560 | (1<<SNDRV_TIMER_EVENT_SUSPEND)| | ||
| 1561 | (1<<SNDRV_TIMER_EVENT_RESUME)| | ||
| 1558 | (1<<SNDRV_TIMER_EVENT_MSTART)| | 1562 | (1<<SNDRV_TIMER_EVENT_MSTART)| |
| 1559 | (1<<SNDRV_TIMER_EVENT_MSTOP)| | 1563 | (1<<SNDRV_TIMER_EVENT_MSTOP)| |
| 1560 | (1<<SNDRV_TIMER_EVENT_MCONTINUE)| | 1564 | (1<<SNDRV_TIMER_EVENT_MCONTINUE)| |
| 1561 | (1<<SNDRV_TIMER_EVENT_MPAUSE))) { | 1565 | (1<<SNDRV_TIMER_EVENT_MPAUSE)| |
| 1566 | (1<<SNDRV_TIMER_EVENT_MSUSPEND)| | ||
| 1567 | (1<<SNDRV_TIMER_EVENT_MRESUME))) { | ||
| 1562 | err = -EINVAL; | 1568 | err = -EINVAL; |
| 1563 | goto _end; | 1569 | goto _end; |
| 1564 | } | 1570 | } |
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index f00c88886460..19fc68c23378 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c | |||
| @@ -796,14 +796,14 @@ static int vx_iec958_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontro | |||
| 796 | 796 | ||
| 797 | static snd_kcontrol_new_t vx_control_iec958_mask = { | 797 | static snd_kcontrol_new_t vx_control_iec958_mask = { |
| 798 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 798 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 799 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 799 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 800 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | 800 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
| 801 | .info = vx_iec958_info, /* shared */ | 801 | .info = vx_iec958_info, /* shared */ |
| 802 | .get = vx_iec958_mask_get, | 802 | .get = vx_iec958_mask_get, |
| 803 | }; | 803 | }; |
| 804 | 804 | ||
| 805 | static snd_kcontrol_new_t vx_control_iec958 = { | 805 | static snd_kcontrol_new_t vx_control_iec958 = { |
| 806 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 806 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 807 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 807 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
| 808 | .info = vx_iec958_info, | 808 | .info = vx_iec958_info, |
| 809 | .get = vx_iec958_get, | 809 | .get = vx_iec958_get, |
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index af381b15fe5c..d4becf44e247 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c | |||
| @@ -549,8 +549,8 @@ static int vx_stop_stream(vx_core_t *chip, vx_pipe_t *pipe) | |||
| 549 | 549 | ||
| 550 | static snd_pcm_hardware_t vx_pcm_playback_hw = { | 550 | static snd_pcm_hardware_t vx_pcm_playback_hw = { |
| 551 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 551 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 552 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID | | 552 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/ |
| 553 | SNDRV_PCM_INFO_RESUME), | 553 | /*SNDRV_PCM_INFO_RESUME*/), |
| 554 | .formats = /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, | 554 | .formats = /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, |
| 555 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 555 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
| 556 | .rate_min = 5000, | 556 | .rate_min = 5000, |
| @@ -949,8 +949,8 @@ static snd_pcm_ops_t vx_pcm_playback_ops = { | |||
| 949 | 949 | ||
| 950 | static snd_pcm_hardware_t vx_pcm_capture_hw = { | 950 | static snd_pcm_hardware_t vx_pcm_capture_hw = { |
| 951 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 951 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 952 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID | | 952 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/ |
| 953 | SNDRV_PCM_INFO_RESUME), | 953 | /*SNDRV_PCM_INFO_RESUME*/), |
| 954 | .formats = /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, | 954 | .formats = /*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, |
| 955 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 955 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
| 956 | .rate_min = 5000, | 956 | .rate_min = 5000, |
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 563296d02894..0eb442ca23d6 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
| @@ -53,6 +53,7 @@ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ | |||
| 53 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ | 53 | static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ |
| 54 | static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ | 54 | static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ |
| 55 | static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ | 55 | static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ |
| 56 | static int clockfreq[SNDRV_CARDS]; | ||
| 56 | 57 | ||
| 57 | module_param_array(index, int, NULL, 0444); | 58 | module_param_array(index, int, NULL, 0444); |
| 58 | MODULE_PARM_DESC(index, "Index value for ad1816a based soundcard."); | 59 | MODULE_PARM_DESC(index, "Index value for ad1816a based soundcard."); |
| @@ -74,6 +75,8 @@ module_param_array(dma1, int, NULL, 0444); | |||
| 74 | MODULE_PARM_DESC(dma1, "1st DMA # for ad1816a driver."); | 75 | MODULE_PARM_DESC(dma1, "1st DMA # for ad1816a driver."); |
| 75 | module_param_array(dma2, int, NULL, 0444); | 76 | module_param_array(dma2, int, NULL, 0444); |
| 76 | MODULE_PARM_DESC(dma2, "2nd DMA # for ad1816a driver."); | 77 | MODULE_PARM_DESC(dma2, "2nd DMA # for ad1816a driver."); |
| 78 | module_param_array(clockfreq, int, NULL, 0444); | ||
| 79 | MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0)."); | ||
| 77 | 80 | ||
| 78 | struct snd_card_ad1816a { | 81 | struct snd_card_ad1816a { |
| 79 | struct pnp_dev *dev; | 82 | struct pnp_dev *dev; |
| @@ -209,6 +212,8 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard | |||
| 209 | snd_card_free(card); | 212 | snd_card_free(card); |
| 210 | return error; | 213 | return error; |
| 211 | } | 214 | } |
| 215 | if (clockfreq[dev] >= 5000 && clockfreq[dev] <= 100000) | ||
| 216 | chip->clock_freq = clockfreq[dev]; | ||
| 212 | 217 | ||
| 213 | strcpy(card->driver, "AD1816A"); | 218 | strcpy(card->driver, "AD1816A"); |
| 214 | strcpy(card->shortname, "ADI SoundPort AD1816A"); | 219 | strcpy(card->shortname, "ADI SoundPort AD1816A"); |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 625b2eff14a1..ae860360ecf9 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
| @@ -234,7 +234,7 @@ static int snd_ad1816a_playback_prepare(snd_pcm_substream_t *substream) | |||
| 234 | ad1816a_t *chip = snd_pcm_substream_chip(substream); | 234 | ad1816a_t *chip = snd_pcm_substream_chip(substream); |
| 235 | unsigned long flags; | 235 | unsigned long flags; |
| 236 | snd_pcm_runtime_t *runtime = substream->runtime; | 236 | snd_pcm_runtime_t *runtime = substream->runtime; |
| 237 | unsigned int size; | 237 | unsigned int size, rate; |
| 238 | 238 | ||
| 239 | spin_lock_irqsave(&chip->lock, flags); | 239 | spin_lock_irqsave(&chip->lock, flags); |
| 240 | 240 | ||
| @@ -245,7 +245,10 @@ static int snd_ad1816a_playback_prepare(snd_pcm_substream_t *substream) | |||
| 245 | snd_dma_program(chip->dma1, runtime->dma_addr, size, | 245 | snd_dma_program(chip->dma1, runtime->dma_addr, size, |
| 246 | DMA_MODE_WRITE | DMA_AUTOINIT); | 246 | DMA_MODE_WRITE | DMA_AUTOINIT); |
| 247 | 247 | ||
| 248 | snd_ad1816a_write(chip, AD1816A_PLAYBACK_SAMPLE_RATE, runtime->rate); | 248 | rate = runtime->rate; |
| 249 | if (chip->clock_freq) | ||
| 250 | rate = (rate * 33000) / chip->clock_freq; | ||
| 251 | snd_ad1816a_write(chip, AD1816A_PLAYBACK_SAMPLE_RATE, rate); | ||
| 249 | snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG, | 252 | snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG, |
| 250 | AD1816A_FMT_ALL | AD1816A_FMT_STEREO, | 253 | AD1816A_FMT_ALL | AD1816A_FMT_STEREO, |
| 251 | snd_ad1816a_get_format(chip, runtime->format, | 254 | snd_ad1816a_get_format(chip, runtime->format, |
| @@ -263,7 +266,7 @@ static int snd_ad1816a_capture_prepare(snd_pcm_substream_t *substream) | |||
| 263 | ad1816a_t *chip = snd_pcm_substream_chip(substream); | 266 | ad1816a_t *chip = snd_pcm_substream_chip(substream); |
| 264 | unsigned long flags; | 267 | unsigned long flags; |
| 265 | snd_pcm_runtime_t *runtime = substream->runtime; | 268 | snd_pcm_runtime_t *runtime = substream->runtime; |
| 266 | unsigned int size; | 269 | unsigned int size, rate; |
| 267 | 270 | ||
| 268 | spin_lock_irqsave(&chip->lock, flags); | 271 | spin_lock_irqsave(&chip->lock, flags); |
| 269 | 272 | ||
| @@ -274,7 +277,10 @@ static int snd_ad1816a_capture_prepare(snd_pcm_substream_t *substream) | |||
| 274 | snd_dma_program(chip->dma2, runtime->dma_addr, size, | 277 | snd_dma_program(chip->dma2, runtime->dma_addr, size, |
| 275 | DMA_MODE_READ | DMA_AUTOINIT); | 278 | DMA_MODE_READ | DMA_AUTOINIT); |
| 276 | 279 | ||
| 277 | snd_ad1816a_write(chip, AD1816A_CAPTURE_SAMPLE_RATE, runtime->rate); | 280 | rate = runtime->rate; |
| 281 | if (chip->clock_freq) | ||
| 282 | rate = (rate * 33000) / chip->clock_freq; | ||
| 283 | snd_ad1816a_write(chip, AD1816A_CAPTURE_SAMPLE_RATE, rate); | ||
| 278 | snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG, | 284 | snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG, |
| 279 | AD1816A_FMT_ALL | AD1816A_FMT_STEREO, | 285 | AD1816A_FMT_ALL | AD1816A_FMT_STEREO, |
| 280 | snd_ad1816a_get_format(chip, runtime->format, | 286 | snd_ad1816a_get_format(chip, runtime->format, |
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index 8fb3db103e48..bc642dc94547 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c | |||
| @@ -1196,6 +1196,7 @@ int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, un | |||
| 1196 | .put = snd_ad1848_put_double, | 1196 | .put = snd_ad1848_put_double, |
| 1197 | }, | 1197 | }, |
| 1198 | [AD1848_MIX_CAPTURE] = { | 1198 | [AD1848_MIX_CAPTURE] = { |
| 1199 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 1199 | .info = snd_ad1848_info_mux, | 1200 | .info = snd_ad1848_info_mux, |
| 1200 | .get = snd_ad1848_get_mux, | 1201 | .get = snd_ad1848_get_mux, |
| 1201 | .put = snd_ad1848_put_mux, | 1202 | .put = snd_ad1848_put_mux, |
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index 46776cc0c157..1fce8b9f37cf 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c | |||
| @@ -194,8 +194,8 @@ AD1848_DOUBLE("Wavetable Capture Volume", 0, CMI8330_WAVGAIN, CMI8330_WAVGAIN, 4 | |||
| 194 | AD1848_SINGLE("3D Control - Switch", 0, CMI8330_RMUX3D, 5, 1, 1), | 194 | AD1848_SINGLE("3D Control - Switch", 0, CMI8330_RMUX3D, 5, 1, 1), |
| 195 | AD1848_SINGLE("PC Speaker Playback Volume", 0, CMI8330_OUTPUTVOL, 3, 3, 0), | 195 | AD1848_SINGLE("PC Speaker Playback Volume", 0, CMI8330_OUTPUTVOL, 3, 3, 0), |
| 196 | AD1848_SINGLE("FM Playback Switch", 0, CMI8330_RECMUX, 3, 1, 1), | 196 | AD1848_SINGLE("FM Playback Switch", 0, CMI8330_RECMUX, 3, 1, 1), |
| 197 | AD1848_SINGLE("IEC958 Input Capture Switch", 0, CMI8330_RMUX3D, 7, 1, 1), | 197 | AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",CAPTURE,SWITCH), 0, CMI8330_RMUX3D, 7, 1, 1), |
| 198 | AD1848_SINGLE("IEC958 Input Playback Switch", 0, CMI8330_MUTEMUX, 7, 1, 1), | 198 | AD1848_SINGLE(SNDRV_CTL_NAME_IEC958("Input ",PLAYBACK,SWITCH), 0, CMI8330_MUTEMUX, 7, 1, 1), |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| 201 | #ifdef ENABLE_SB_MIXER | 201 | #ifdef ENABLE_SB_MIXER |
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index 3e7a2a33a5ca..3199941edd9b 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c | |||
| @@ -1346,6 +1346,8 @@ static void snd_cs4231_suspend(cs4231_t *chip) | |||
| 1346 | int reg; | 1346 | int reg; |
| 1347 | unsigned long flags; | 1347 | unsigned long flags; |
| 1348 | 1348 | ||
| 1349 | if (chip->pcm) | ||
| 1350 | snd_pcm_suspend_all(chip->pcm); | ||
| 1349 | spin_lock_irqsave(&chip->reg_lock, flags); | 1351 | spin_lock_irqsave(&chip->reg_lock, flags); |
| 1350 | for (reg = 0; reg < 32; reg++) | 1352 | for (reg = 0; reg < 32; reg++) |
| 1351 | chip->image[reg] = snd_cs4231_in(chip, reg); | 1353 | chip->image[reg] = snd_cs4231_in(chip, reg); |
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c index 337b0e2a8a36..23e1b5f19e1a 100644 --- a/sound/isa/gus/gus_io.c +++ b/sound/isa/gus/gus_io.c | |||
| @@ -269,8 +269,9 @@ void snd_gf1_i_write_addr(snd_gus_card_t * gus, unsigned char reg, | |||
| 269 | 269 | ||
| 270 | #endif /* 0 */ | 270 | #endif /* 0 */ |
| 271 | 271 | ||
| 272 | unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, | 272 | #ifdef CONFIG_SND_DEBUG |
| 273 | unsigned char reg, short w_16bit) | 273 | static unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, |
| 274 | unsigned char reg, short w_16bit) | ||
| 274 | { | 275 | { |
| 275 | unsigned int res; | 276 | unsigned int res; |
| 276 | unsigned long flags; | 277 | unsigned long flags; |
| @@ -280,6 +281,7 @@ unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, | |||
| 280 | spin_unlock_irqrestore(&gus->reg_lock, flags); | 281 | spin_unlock_irqrestore(&gus->reg_lock, flags); |
| 281 | return res; | 282 | return res; |
| 282 | } | 283 | } |
| 284 | #endif | ||
| 283 | 285 | ||
| 284 | /* | 286 | /* |
| 285 | 287 | ||
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 95c7b3e53407..75bd6eca63e7 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
| @@ -145,6 +145,14 @@ static snd_card_t *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | |||
| 145 | 145 | ||
| 146 | #ifdef CONFIG_PNP | 146 | #ifdef CONFIG_PNP |
| 147 | 147 | ||
| 148 | static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { | ||
| 149 | { .id = "YMH0021" }, | ||
| 150 | { .id = "NMX2210" }, /* Gateway Solo 2500 */ | ||
| 151 | { .id = "" } /* end */ | ||
| 152 | }; | ||
| 153 | |||
| 154 | MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosids); | ||
| 155 | |||
| 148 | static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { | 156 | static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { |
| 149 | /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ | 157 | /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ |
| 150 | { .id = "YMH0020", .devs = { { "YMH0021" } } }, | 158 | { .id = "YMH0020", .devs = { { "YMH0021" } } }, |
| @@ -568,20 +576,18 @@ static int snd_opl3sa2_resume(snd_card_t *card) | |||
| 568 | 576 | ||
| 569 | #ifdef CONFIG_PNP | 577 | #ifdef CONFIG_PNP |
| 570 | static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, | 578 | static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, |
| 571 | struct pnp_card_link *card, | 579 | struct pnp_dev *pdev, |
| 572 | const struct pnp_card_device_id *id) | 580 | int isapnp) |
| 573 | { | 581 | { |
| 574 | struct pnp_dev *pdev; | 582 | struct pnp_resource_table * cfg; |
| 575 | struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); | ||
| 576 | int err; | 583 | int err; |
| 577 | 584 | ||
| 585 | if (!isapnp && pnp_device_is_isapnp(pdev)) | ||
| 586 | return -ENOENT; /* we have another procedure - card */ | ||
| 587 | |||
| 588 | cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); | ||
| 578 | if (!cfg) | 589 | if (!cfg) |
| 579 | return -ENOMEM; | 590 | return -ENOMEM; |
| 580 | pdev = chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL); | ||
| 581 | if (chip->dev == NULL) { | ||
| 582 | kfree(cfg); | ||
| 583 | return -EBUSY; | ||
| 584 | } | ||
| 585 | /* PnP initialization */ | 591 | /* PnP initialization */ |
| 586 | pnp_init_resource_table(cfg); | 592 | pnp_init_resource_table(cfg); |
| 587 | if (sb_port[dev] != SNDRV_AUTO_PORT) | 593 | if (sb_port[dev] != SNDRV_AUTO_PORT) |
| @@ -601,7 +607,7 @@ static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, | |||
| 601 | if (irq[dev] != SNDRV_AUTO_IRQ) | 607 | if (irq[dev] != SNDRV_AUTO_IRQ) |
| 602 | pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); | 608 | pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); |
| 603 | err = pnp_manual_config_dev(pdev, cfg, 0); | 609 | err = pnp_manual_config_dev(pdev, cfg, 0); |
| 604 | if (err < 0) | 610 | if (err < 0 && isapnp) |
| 605 | snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n"); | 611 | snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n"); |
| 606 | err = pnp_activate_dev(pdev); | 612 | err = pnp_activate_dev(pdev); |
| 607 | if (err < 0) { | 613 | if (err < 0) { |
| @@ -617,13 +623,31 @@ static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, | |||
| 617 | dma1[dev] = pnp_dma(pdev, 0); | 623 | dma1[dev] = pnp_dma(pdev, 0); |
| 618 | dma2[dev] = pnp_dma(pdev, 1); | 624 | dma2[dev] = pnp_dma(pdev, 1); |
| 619 | irq[dev] = pnp_irq(pdev, 0); | 625 | irq[dev] = pnp_irq(pdev, 0); |
| 620 | snd_printdd("PnP OPL3-SA: sb port=0x%lx, wss port=0x%lx, fm port=0x%lx, midi port=0x%lx\n", | 626 | snd_printdd("%sPnP OPL3-SA: sb port=0x%lx, wss port=0x%lx, fm port=0x%lx, midi port=0x%lx\n", |
| 621 | sb_port[dev], wss_port[dev], fm_port[dev], midi_port[dev]); | 627 | pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", sb_port[dev], wss_port[dev], fm_port[dev], midi_port[dev]); |
| 622 | snd_printdd("PnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n", | 628 | snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n", |
| 623 | port[dev], dma1[dev], dma2[dev], irq[dev]); | 629 | pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]); |
| 624 | kfree(cfg); | 630 | kfree(cfg); |
| 631 | chip->dev = pdev; | ||
| 625 | return 0; | 632 | return 0; |
| 626 | } | 633 | } |
| 634 | |||
| 635 | static int __init snd_opl3sa2_cpnp(int dev, opl3sa2_t *chip, | ||
| 636 | struct pnp_card_link *card, | ||
| 637 | const struct pnp_card_device_id *id) | ||
| 638 | { | ||
| 639 | struct pnp_dev *pdev; | ||
| 640 | struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); | ||
| 641 | |||
| 642 | if (!cfg) | ||
| 643 | return -ENOMEM; | ||
| 644 | pdev = pnp_request_card_device(card, id->devs[0].id, NULL); | ||
| 645 | if (pdev == NULL) { | ||
| 646 | kfree(cfg); | ||
| 647 | return -EBUSY; | ||
| 648 | } | ||
| 649 | return snd_opl3sa2_pnp(dev, chip, pdev, 1); | ||
| 650 | } | ||
| 627 | #endif /* CONFIG_PNP */ | 651 | #endif /* CONFIG_PNP */ |
| 628 | 652 | ||
| 629 | static int snd_opl3sa2_free(opl3sa2_t *chip) | 653 | static int snd_opl3sa2_free(opl3sa2_t *chip) |
| @@ -645,6 +669,7 @@ static int snd_opl3sa2_dev_free(snd_device_t *device) | |||
| 645 | } | 669 | } |
| 646 | 670 | ||
| 647 | static int __devinit snd_opl3sa2_probe(int dev, | 671 | static int __devinit snd_opl3sa2_probe(int dev, |
| 672 | struct pnp_dev *pdev, | ||
| 648 | struct pnp_card_link *pcard, | 673 | struct pnp_card_link *pcard, |
| 649 | const struct pnp_card_device_id *pid) | 674 | const struct pnp_card_device_id *pid) |
| 650 | { | 675 | { |
| @@ -695,8 +720,13 @@ static int __devinit snd_opl3sa2_probe(int dev, | |||
| 695 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) | 720 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) |
| 696 | goto __error; | 721 | goto __error; |
| 697 | #ifdef CONFIG_PNP | 722 | #ifdef CONFIG_PNP |
| 698 | if (isapnp[dev]) { | 723 | if (pdev) { |
| 699 | if ((err = snd_opl3sa2_pnp(dev, chip, pcard, pid)) < 0) | 724 | if ((err = snd_opl3sa2_pnp(dev, chip, pdev, 0)) < 0) |
| 725 | goto __error; | ||
| 726 | snd_card_set_dev(card, &pdev->dev); | ||
| 727 | } | ||
| 728 | if (pcard) { | ||
| 729 | if ((err = snd_opl3sa2_cpnp(dev, chip, pcard, pid)) < 0) | ||
| 700 | goto __error; | 730 | goto __error; |
| 701 | snd_card_set_dev(card, &pcard->card->dev); | 731 | snd_card_set_dev(card, &pcard->card->dev); |
| 702 | } | 732 | } |
| @@ -768,7 +798,9 @@ static int __devinit snd_opl3sa2_probe(int dev, | |||
| 768 | if ((err = snd_card_register(card)) < 0) | 798 | if ((err = snd_card_register(card)) < 0) |
| 769 | goto __error; | 799 | goto __error; |
| 770 | 800 | ||
| 771 | if (pcard) | 801 | if (pdev) |
| 802 | pnp_set_drvdata(pdev, card); | ||
| 803 | else if (pcard) | ||
| 772 | pnp_set_card_drvdata(pcard, card); | 804 | pnp_set_card_drvdata(pcard, card); |
| 773 | else | 805 | else |
| 774 | snd_opl3sa2_legacy[dev] = card; | 806 | snd_opl3sa2_legacy[dev] = card; |
| @@ -780,8 +812,8 @@ static int __devinit snd_opl3sa2_probe(int dev, | |||
| 780 | } | 812 | } |
| 781 | 813 | ||
| 782 | #ifdef CONFIG_PNP | 814 | #ifdef CONFIG_PNP |
| 783 | static int __devinit snd_opl3sa2_pnp_detect(struct pnp_card_link *card, | 815 | static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, |
| 784 | const struct pnp_card_device_id *id) | 816 | const struct pnp_device_id *id) |
| 785 | { | 817 | { |
| 786 | static int dev; | 818 | static int dev; |
| 787 | int res; | 819 | int res; |
| @@ -789,7 +821,7 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_card_link *card, | |||
| 789 | for ( ; dev < SNDRV_CARDS; dev++) { | 821 | for ( ; dev < SNDRV_CARDS; dev++) { |
| 790 | if (!enable[dev] || !isapnp[dev]) | 822 | if (!enable[dev] || !isapnp[dev]) |
| 791 | continue; | 823 | continue; |
| 792 | res = snd_opl3sa2_probe(dev, card, id); | 824 | res = snd_opl3sa2_probe(dev, pdev, NULL, NULL); |
| 793 | if (res < 0) | 825 | if (res < 0) |
| 794 | return res; | 826 | return res; |
| 795 | dev++; | 827 | dev++; |
| @@ -798,7 +830,40 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_card_link *card, | |||
| 798 | return -ENODEV; | 830 | return -ENODEV; |
| 799 | } | 831 | } |
| 800 | 832 | ||
| 801 | static void __devexit snd_opl3sa2_pnp_remove(struct pnp_card_link * pcard) | 833 | static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev) |
| 834 | { | ||
| 835 | snd_card_t *card = (snd_card_t *) pnp_get_drvdata(pdev); | ||
| 836 | |||
| 837 | snd_card_disconnect(card); | ||
| 838 | snd_card_free_in_thread(card); | ||
| 839 | } | ||
| 840 | |||
| 841 | static struct pnp_driver opl3sa2_pnp_driver = { | ||
| 842 | .name = "opl3sa2-pnpbios", | ||
| 843 | .id_table = snd_opl3sa2_pnpbiosids, | ||
| 844 | .probe = snd_opl3sa2_pnp_detect, | ||
| 845 | .remove = __devexit_p(snd_opl3sa2_pnp_remove), | ||
| 846 | }; | ||
| 847 | |||
| 848 | static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *card, | ||
| 849 | const struct pnp_card_device_id *id) | ||
| 850 | { | ||
| 851 | static int dev; | ||
| 852 | int res; | ||
| 853 | |||
| 854 | for ( ; dev < SNDRV_CARDS; dev++) { | ||
| 855 | if (!enable[dev] || !isapnp[dev]) | ||
| 856 | continue; | ||
| 857 | res = snd_opl3sa2_probe(dev, NULL, card, id); | ||
| 858 | if (res < 0) | ||
| 859 | return res; | ||
| 860 | dev++; | ||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | return -ENODEV; | ||
| 864 | } | ||
| 865 | |||
| 866 | static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard) | ||
| 802 | { | 867 | { |
| 803 | snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); | 868 | snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); |
| 804 | 869 | ||
| @@ -810,8 +875,8 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = { | |||
| 810 | .flags = PNP_DRIVER_RES_DISABLE, | 875 | .flags = PNP_DRIVER_RES_DISABLE, |
| 811 | .name = "opl3sa2", | 876 | .name = "opl3sa2", |
| 812 | .id_table = snd_opl3sa2_pnpids, | 877 | .id_table = snd_opl3sa2_pnpids, |
| 813 | .probe = snd_opl3sa2_pnp_detect, | 878 | .probe = snd_opl3sa2_pnp_cdetect, |
| 814 | .remove = __devexit_p(snd_opl3sa2_pnp_remove), | 879 | .remove = __devexit_p(snd_opl3sa2_pnp_cremove), |
| 815 | }; | 880 | }; |
| 816 | #endif /* CONFIG_PNP */ | 881 | #endif /* CONFIG_PNP */ |
| 817 | 882 | ||
| @@ -826,10 +891,11 @@ static int __init alsa_card_opl3sa2_init(void) | |||
| 826 | if (isapnp[dev]) | 891 | if (isapnp[dev]) |
| 827 | continue; | 892 | continue; |
| 828 | #endif | 893 | #endif |
| 829 | if (snd_opl3sa2_probe(dev, NULL, NULL) >= 0) | 894 | if (snd_opl3sa2_probe(dev, NULL, NULL, NULL) >= 0) |
| 830 | cards++; | 895 | cards++; |
| 831 | } | 896 | } |
| 832 | #ifdef CONFIG_PNP | 897 | #ifdef CONFIG_PNP |
| 898 | cards += pnp_register_driver(&opl3sa2_pnp_driver); | ||
| 833 | cards += pnp_register_card_driver(&opl3sa2_pnpc_driver); | 899 | cards += pnp_register_card_driver(&opl3sa2_pnpc_driver); |
| 834 | #endif | 900 | #endif |
| 835 | if (!cards) { | 901 | if (!cards) { |
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index a6a0fa516268..a99e642a68b5 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c | |||
| @@ -729,7 +729,7 @@ static int snd_sb16_dma_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu | |||
| 729 | } | 729 | } |
| 730 | 730 | ||
| 731 | static snd_kcontrol_new_t snd_sb16_dma_control = { | 731 | static snd_kcontrol_new_t snd_sb16_dma_control = { |
| 732 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 732 | .iface = SNDRV_CTL_ELEM_IFACE_CARD, |
| 733 | .name = "16-bit DMA Allocation", | 733 | .name = "16-bit DMA Allocation", |
| 734 | .info = snd_sb16_dma_control_info, | 734 | .info = snd_sb16_dma_control_info, |
| 735 | .get = snd_sb16_dma_control_get, | 735 | .get = snd_sb16_dma_control_get, |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 26b42bb20a0a..1e458919cce6 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | # ALSA PCI drivers | 1 | # ALSA PCI drivers |
| 2 | 2 | ||
| 3 | menu "PCI devices" | ||
| 4 | depends on SND!=n && PCI | ||
| 5 | |||
| 6 | config SND_AC97_CODEC | 3 | config SND_AC97_CODEC |
| 7 | tristate | 4 | tristate |
| 8 | select SND_PCM | 5 | select SND_PCM |
| 6 | select SND_AC97_BUS | ||
| 7 | |||
| 8 | config SND_AC97_BUS | ||
| 9 | tristate | ||
| 10 | |||
| 11 | menu "PCI devices" | ||
| 12 | depends on SND!=n && PCI | ||
| 9 | 13 | ||
| 10 | config SND_ALI5451 | 14 | config SND_ALI5451 |
| 11 | tristate "ALi M5451 PCI Audio Controller" | 15 | tristate "ALi M5451 PCI Audio Controller" |
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 3c3222122d8b..77b3482cb133 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile | |||
| @@ -10,9 +10,11 @@ snd-ac97-codec-objs += ac97_proc.o | |||
| 10 | endif | 10 | endif |
| 11 | 11 | ||
| 12 | snd-ak4531-codec-objs := ak4531_codec.o | 12 | snd-ak4531-codec-objs := ak4531_codec.o |
| 13 | snd-ac97-bus-objs := ac97_bus.o | ||
| 13 | 14 | ||
| 14 | # Toplevel Module Dependency | 15 | # Toplevel Module Dependency |
| 15 | obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o | 16 | obj-$(CONFIG_SND_AC97_CODEC) += snd-ac97-codec.o |
| 16 | obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o | 17 | obj-$(CONFIG_SND_ENS1370) += snd-ak4531-codec.o |
| 18 | obj-$(CONFIG_SND_AC97_BUS) += snd-ac97-bus.o | ||
| 17 | 19 | ||
| 18 | obj-m := $(sort $(obj-m)) | 20 | obj-m := $(sort $(obj-m)) |
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c new file mode 100644 index 000000000000..227f8b9f67ce --- /dev/null +++ b/sound/pci/ac97/ac97_bus.c | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /* | ||
| 2 | * Linux driver model AC97 bus interface | ||
| 3 | * | ||
| 4 | * Author: Nicolas Pitre | ||
| 5 | * Created: Jan 14, 2005 | ||
| 6 | * Copyright: (C) MontaVista Software Inc. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/string.h> | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Codec families have names seperated by commas, so we search for an | ||
| 21 | * individual codec name within the family string. | ||
| 22 | */ | ||
| 23 | static int ac97_bus_match(struct device *dev, struct device_driver *drv) | ||
| 24 | { | ||
| 25 | return (strstr(dev->bus_id, drv->name) != NULL); | ||
| 26 | } | ||
| 27 | |||
| 28 | static int ac97_bus_suspend(struct device *dev, pm_message_t state) | ||
| 29 | { | ||
| 30 | int ret = 0; | ||
| 31 | |||
| 32 | if (dev->driver && dev->driver->suspend) { | ||
| 33 | ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE); | ||
| 34 | if (ret == 0) | ||
| 35 | ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE); | ||
| 36 | if (ret == 0) | ||
| 37 | ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN); | ||
| 38 | } | ||
| 39 | return ret; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int ac97_bus_resume(struct device *dev) | ||
| 43 | { | ||
| 44 | int ret = 0; | ||
| 45 | |||
| 46 | if (dev->driver && dev->driver->resume) { | ||
| 47 | ret = dev->driver->resume(dev, RESUME_POWER_ON); | ||
| 48 | if (ret == 0) | ||
| 49 | ret = dev->driver->resume(dev, RESUME_RESTORE_STATE); | ||
| 50 | if (ret == 0) | ||
| 51 | ret = dev->driver->resume(dev, RESUME_ENABLE); | ||
| 52 | } | ||
| 53 | return ret; | ||
| 54 | } | ||
| 55 | |||
| 56 | struct bus_type ac97_bus_type = { | ||
| 57 | .name = "ac97", | ||
| 58 | .match = ac97_bus_match, | ||
| 59 | .suspend = ac97_bus_suspend, | ||
| 60 | .resume = ac97_bus_resume, | ||
| 61 | }; | ||
| 62 | |||
| 63 | static int __init ac97_bus_init(void) | ||
| 64 | { | ||
| 65 | return bus_register(&ac97_bus_type); | ||
| 66 | } | ||
| 67 | |||
| 68 | subsys_initcall(ac97_bus_init); | ||
| 69 | |||
| 70 | static void __exit ac97_bus_exit(void) | ||
| 71 | { | ||
| 72 | bus_unregister(&ac97_bus_type); | ||
| 73 | } | ||
| 74 | |||
| 75 | module_exit(ac97_bus_exit); | ||
| 76 | |||
| 77 | EXPORT_SYMBOL(ac97_bus_type); | ||
| 78 | |||
| 79 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6983eea226da..5501f4440c92 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
| @@ -157,6 +157,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { | |||
| 157 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] | 157 | { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] |
| 158 | { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, | 158 | { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, |
| 159 | { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF | 159 | { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF |
| 160 | { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF | ||
| 160 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, | 161 | { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, |
| 161 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, | 162 | { 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL }, |
| 162 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, | 163 | { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, |
| @@ -1307,16 +1308,18 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
| 1307 | } | 1308 | } |
| 1308 | 1309 | ||
| 1309 | /* build master tone controls */ | 1310 | /* build master tone controls */ |
| 1310 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { | 1311 | if (!(ac97->flags & AC97_HAS_NO_TONE)) { |
| 1311 | for (idx = 0; idx < 2; idx++) { | 1312 | if (snd_ac97_try_volume_mix(ac97, AC97_MASTER_TONE)) { |
| 1312 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) | 1313 | for (idx = 0; idx < 2; idx++) { |
| 1313 | return err; | 1314 | if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0) |
| 1314 | if (ac97->id == AC97_ID_YMF753) { | 1315 | return err; |
| 1315 | kctl->private_value &= ~(0xff << 16); | 1316 | if (ac97->id == AC97_ID_YMF753) { |
| 1316 | kctl->private_value |= 7 << 16; | 1317 | kctl->private_value &= ~(0xff << 16); |
| 1318 | kctl->private_value |= 7 << 16; | ||
| 1319 | } | ||
| 1317 | } | 1320 | } |
| 1321 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
| 1318 | } | 1322 | } |
| 1319 | snd_ac97_write_cache(ac97, AC97_MASTER_TONE, 0x0f0f); | ||
| 1320 | } | 1323 | } |
| 1321 | 1324 | ||
| 1322 | /* build PC Speaker controls */ | 1325 | /* build PC Speaker controls */ |
| @@ -1339,11 +1342,13 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
| 1339 | } | 1342 | } |
| 1340 | 1343 | ||
| 1341 | /* build MIC controls */ | 1344 | /* build MIC controls */ |
| 1342 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { | 1345 | if (!(ac97->flags & AC97_HAS_NO_MIC)) { |
| 1343 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) | 1346 | if (snd_ac97_try_volume_mix(ac97, AC97_MIC)) { |
| 1344 | return err; | 1347 | if ((err = snd_ac97_cmix_new(card, "Mic Playback", AC97_MIC, ac97)) < 0) |
| 1345 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) | 1348 | return err; |
| 1346 | return err; | 1349 | if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_mic_boost, ac97))) < 0) |
| 1350 | return err; | ||
| 1351 | } | ||
| 1347 | } | 1352 | } |
| 1348 | 1353 | ||
| 1349 | /* build Line controls */ | 1354 | /* build Line controls */ |
| @@ -1402,12 +1407,14 @@ static int snd_ac97_mixer_build(ac97_t * ac97) | |||
| 1402 | } | 1407 | } |
| 1403 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); | 1408 | snd_ac97_write_cache(ac97, AC97_PCM, init_val); |
| 1404 | } else { | 1409 | } else { |
| 1405 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) | 1410 | if (!(ac97->flags & AC97_HAS_NO_STD_PCM)) { |
| 1406 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); | 1411 | if (ac97->flags & AC97_HAS_NO_PCM_VOL) |
| 1407 | else | 1412 | err = snd_ac97_cmute_new(card, "PCM Playback Switch", AC97_PCM, ac97); |
| 1408 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); | 1413 | else |
| 1409 | if (err < 0) | 1414 | err = snd_ac97_cmix_new(card, "PCM Playback", AC97_PCM, ac97); |
| 1410 | return err; | 1415 | if (err < 0) |
| 1416 | return err; | ||
| 1417 | } | ||
| 1411 | } | 1418 | } |
| 1412 | 1419 | ||
| 1413 | /* build Capture controls */ | 1420 | /* build Capture controls */ |
| @@ -1807,6 +1814,39 @@ int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, | |||
| 1807 | return 0; | 1814 | return 0; |
| 1808 | } | 1815 | } |
| 1809 | 1816 | ||
| 1817 | /* stop no dev release warning */ | ||
| 1818 | static void ac97_device_release(struct device * dev) | ||
| 1819 | { | ||
| 1820 | } | ||
| 1821 | |||
| 1822 | /* register ac97 codec to bus */ | ||
| 1823 | static int snd_ac97_dev_register(snd_device_t *device) | ||
| 1824 | { | ||
| 1825 | ac97_t *ac97 = device->device_data; | ||
| 1826 | int err; | ||
| 1827 | |||
| 1828 | ac97->dev.bus = &ac97_bus_type; | ||
| 1829 | ac97->dev.parent = ac97->bus->card->dev; | ||
| 1830 | ac97->dev.platform_data = ac97; | ||
| 1831 | ac97->dev.release = ac97_device_release; | ||
| 1832 | snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "card%d-%d", ac97->bus->card->number, ac97->num); | ||
| 1833 | if ((err = device_register(&ac97->dev)) < 0) { | ||
| 1834 | snd_printk(KERN_ERR "Can't register ac97 bus\n"); | ||
| 1835 | ac97->dev.bus = NULL; | ||
| 1836 | return err; | ||
| 1837 | } | ||
| 1838 | return 0; | ||
| 1839 | } | ||
| 1840 | |||
| 1841 | /* unregister ac97 codec */ | ||
| 1842 | static int snd_ac97_dev_unregister(snd_device_t *device) | ||
| 1843 | { | ||
| 1844 | ac97_t *ac97 = device->device_data; | ||
| 1845 | if (ac97->dev.bus) | ||
| 1846 | device_unregister(&ac97->dev); | ||
| 1847 | return snd_ac97_free(ac97); | ||
| 1848 | } | ||
| 1849 | |||
| 1810 | /* build_ops to do nothing */ | 1850 | /* build_ops to do nothing */ |
| 1811 | static struct snd_ac97_build_ops null_build_ops; | 1851 | static struct snd_ac97_build_ops null_build_ops; |
| 1812 | 1852 | ||
| @@ -1840,6 +1880,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
| 1840 | const ac97_codec_id_t *pid; | 1880 | const ac97_codec_id_t *pid; |
| 1841 | static snd_device_ops_t ops = { | 1881 | static snd_device_ops_t ops = { |
| 1842 | .dev_free = snd_ac97_dev_free, | 1882 | .dev_free = snd_ac97_dev_free, |
| 1883 | .dev_register = snd_ac97_dev_register, | ||
| 1884 | .dev_unregister = snd_ac97_dev_unregister, | ||
| 1843 | }; | 1885 | }; |
| 1844 | 1886 | ||
| 1845 | snd_assert(rac97 != NULL, return -EINVAL); | 1887 | snd_assert(rac97 != NULL, return -EINVAL); |
| @@ -2539,8 +2581,6 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o | |||
| 2539 | { | 2581 | { |
| 2540 | int result; | 2582 | int result; |
| 2541 | 2583 | ||
| 2542 | snd_assert(quirk, return -EINVAL); | ||
| 2543 | |||
| 2544 | /* quirk overriden? */ | 2584 | /* quirk overriden? */ |
| 2545 | if (override && strcmp(override, "-1") && strcmp(override, "default")) { | 2585 | if (override && strcmp(override, "-1") && strcmp(override, "default")) { |
| 2546 | result = apply_quirk_str(ac97, override); | 2586 | result = apply_quirk_str(ac97, override); |
| @@ -2549,6 +2589,9 @@ int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *o | |||
| 2549 | return result; | 2589 | return result; |
| 2550 | } | 2590 | } |
| 2551 | 2591 | ||
| 2592 | if (! quirk) | ||
| 2593 | return -EINVAL; | ||
| 2594 | |||
| 2552 | for (; quirk->subvendor; quirk++) { | 2595 | for (; quirk->subvendor; quirk++) { |
| 2553 | if (quirk->subvendor != ac97->subsystem_vendor) | 2596 | if (quirk->subvendor != ac97->subsystem_vendor) |
| 2554 | continue; | 2597 | continue; |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 66edc857d3e6..b584172c1104 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
| @@ -370,141 +370,387 @@ int patch_yamaha_ymf753(ac97_t * ac97) | |||
| 370 | * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. | 370 | * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. |
| 371 | */ | 371 | */ |
| 372 | 372 | ||
| 373 | int patch_wolfson03(ac97_t * ac97) | 373 | static const snd_kcontrol_new_t wm97xx_snd_ac97_controls[] = { |
| 374 | AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), | ||
| 375 | AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), | ||
| 376 | }; | ||
| 377 | |||
| 378 | static int patch_wolfson_wm9703_specific(ac97_t * ac97) | ||
| 374 | { | 379 | { |
| 375 | /* This is known to work for the ViewSonic ViewPad 1000 | 380 | /* This is known to work for the ViewSonic ViewPad 1000 |
| 376 | Randolph Bentson <bentson@holmsjoen.com> */ | 381 | * Randolph Bentson <bentson@holmsjoen.com> |
| 382 | * WM9703/9707/9708/9717 | ||
| 383 | */ | ||
| 384 | int err, i; | ||
| 385 | |||
| 386 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
| 387 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
| 388 | return err; | ||
| 389 | } | ||
| 390 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | ||
| 391 | return 0; | ||
| 392 | } | ||
| 393 | |||
| 394 | static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { | ||
| 395 | .build_specific = patch_wolfson_wm9703_specific, | ||
| 396 | }; | ||
| 377 | 397 | ||
| 378 | // WM9703/9707/9708/9717 | 398 | int patch_wolfson03(ac97_t * ac97) |
| 379 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 399 | { |
| 380 | snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000); | 400 | ac97->build_ops = &patch_wolfson_wm9703_ops; |
| 381 | return 0; | 401 | return 0; |
| 382 | } | 402 | } |
| 383 | 403 | ||
| 384 | int patch_wolfson04(ac97_t * ac97) | 404 | static const snd_kcontrol_new_t wm9704_snd_ac97_controls[] = { |
| 405 | AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1), | ||
| 406 | AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1), | ||
| 407 | AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1), | ||
| 408 | AC97_SINGLE("Rear Playback Switch", AC97_WM9704_RMIXER_VOL, 15, 1, 1), | ||
| 409 | AC97_DOUBLE("Rear DAC Volume", AC97_WM9704_RPCM_VOL, 8, 0, 31, 1), | ||
| 410 | AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), | ||
| 411 | }; | ||
| 412 | |||
| 413 | static int patch_wolfson_wm9704_specific(ac97_t * ac97) | ||
| 385 | { | 414 | { |
| 386 | // WM9704M/9704Q | 415 | int err, i; |
| 387 | // set front and rear mixer volume | 416 | for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) { |
| 388 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 417 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9704_snd_ac97_controls[i], ac97))) < 0) |
| 389 | snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808); | 418 | return err; |
| 390 | 419 | } | |
| 391 | // patch for DVD noise | 420 | /* patch for DVD noise */ |
| 392 | snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); | 421 | snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200); |
| 393 | |||
| 394 | // init vol | ||
| 395 | snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808); | ||
| 396 | |||
| 397 | // set rear surround volume | ||
| 398 | snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000); | ||
| 399 | return 0; | 422 | return 0; |
| 400 | } | 423 | } |
| 401 | 424 | ||
| 425 | static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { | ||
| 426 | .build_specific = patch_wolfson_wm9704_specific, | ||
| 427 | }; | ||
| 428 | |||
| 429 | int patch_wolfson04(ac97_t * ac97) | ||
| 430 | { | ||
| 431 | /* WM9704M/9704Q */ | ||
| 432 | ac97->build_ops = &patch_wolfson_wm9704_ops; | ||
| 433 | return 0; | ||
| 434 | } | ||
| 435 | |||
| 436 | static int patch_wolfson_wm9705_specific(ac97_t * ac97) | ||
| 437 | { | ||
| 438 | int err, i; | ||
| 439 | for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) { | ||
| 440 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm97xx_snd_ac97_controls[i], ac97))) < 0) | ||
| 441 | return err; | ||
| 442 | } | ||
| 443 | snd_ac97_write_cache(ac97, 0x72, 0x0808); | ||
| 444 | return 0; | ||
| 445 | } | ||
| 446 | |||
| 447 | static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { | ||
| 448 | .build_specific = patch_wolfson_wm9705_specific, | ||
| 449 | }; | ||
| 450 | |||
| 402 | int patch_wolfson05(ac97_t * ac97) | 451 | int patch_wolfson05(ac97_t * ac97) |
| 403 | { | 452 | { |
| 404 | // WM9705, WM9710 | 453 | /* WM9705, WM9710 */ |
| 405 | // set front mixer volume | 454 | ac97->build_ops = &patch_wolfson_wm9705_ops; |
| 406 | snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808); | 455 | return 0; |
| 456 | } | ||
| 457 | |||
| 458 | static const char* wm9711_alc_select[] = {"None", "Left", "Right", "Stereo"}; | ||
| 459 | static const char* wm9711_alc_mix[] = {"Stereo", "Right", "Left", "None"}; | ||
| 460 | static const char* wm9711_out3_src[] = {"Left", "VREF", "Left + Right", "Mono"}; | ||
| 461 | static const char* wm9711_out3_lrsrc[] = {"Master Mix", "Headphone Mix"}; | ||
| 462 | static const char* wm9711_rec_adc[] = {"Stereo", "Left", "Right", "Mute"}; | ||
| 463 | static const char* wm9711_base[] = {"Linear Control", "Adaptive Boost"}; | ||
| 464 | static const char* wm9711_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; | ||
| 465 | static const char* wm9711_mic[] = {"Mic 1", "Differential", "Mic 2", "Stereo"}; | ||
| 466 | static const char* wm9711_rec_sel[] = | ||
| 467 | {"Mic 1", "NC", "NC", "Master Mix", "Line", "Headphone Mix", "Phone Mix", "Phone"}; | ||
| 468 | static const char* wm9711_ng_type[] = {"Constant Gain", "Mute"}; | ||
| 469 | |||
| 470 | static const struct ac97_enum wm9711_enum[] = { | ||
| 471 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9711_alc_select), | ||
| 472 | AC97_ENUM_SINGLE(AC97_VIDEO, 10, 4, wm9711_alc_mix), | ||
| 473 | AC97_ENUM_SINGLE(AC97_AUX, 9, 4, wm9711_out3_src), | ||
| 474 | AC97_ENUM_SINGLE(AC97_AUX, 8, 2, wm9711_out3_lrsrc), | ||
| 475 | AC97_ENUM_SINGLE(AC97_REC_SEL, 12, 4, wm9711_rec_adc), | ||
| 476 | AC97_ENUM_SINGLE(AC97_MASTER_TONE, 15, 2, wm9711_base), | ||
| 477 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 14, 6, 2, wm9711_rec_gain), | ||
| 478 | AC97_ENUM_SINGLE(AC97_MIC, 5, 4, wm9711_mic), | ||
| 479 | AC97_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, wm9711_rec_sel), | ||
| 480 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type), | ||
| 481 | }; | ||
| 482 | |||
| 483 | static const snd_kcontrol_new_t wm9711_snd_ac97_controls[] = { | ||
| 484 | AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), | ||
| 485 | AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), | ||
| 486 | AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), | ||
| 487 | AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), | ||
| 488 | AC97_ENUM("ALC Function", wm9711_enum[0]), | ||
| 489 | AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 1), | ||
| 490 | AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 1), | ||
| 491 | AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), | ||
| 492 | AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), | ||
| 493 | AC97_ENUM("ALC NG Type", wm9711_enum[9]), | ||
| 494 | AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 1), | ||
| 495 | |||
| 496 | AC97_SINGLE("Side Tone Switch", AC97_VIDEO, 15, 1, 1), | ||
| 497 | AC97_SINGLE("Side Tone Volume", AC97_VIDEO, 12, 7, 1), | ||
| 498 | AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]), | ||
| 499 | AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1), | ||
| 500 | |||
| 501 | AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1), | ||
| 502 | AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1), | ||
| 503 | AC97_ENUM("Out3 Mux", wm9711_enum[2]), | ||
| 504 | AC97_ENUM("Out3 LR Mux", wm9711_enum[3]), | ||
| 505 | AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1), | ||
| 506 | |||
| 507 | AC97_SINGLE("Beep to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), | ||
| 508 | AC97_SINGLE("Beep to Headphone Volume", AC97_PC_BEEP, 12, 7, 1), | ||
| 509 | AC97_SINGLE("Beep to Side Tone Switch", AC97_PC_BEEP, 11, 1, 1), | ||
| 510 | AC97_SINGLE("Beep to Side Tone Volume", AC97_PC_BEEP, 8, 7, 1), | ||
| 511 | AC97_SINGLE("Beep to Phone Switch", AC97_PC_BEEP, 7, 1, 1), | ||
| 512 | AC97_SINGLE("Beep to Phone Volume", AC97_PC_BEEP, 4, 7, 1), | ||
| 513 | |||
| 514 | AC97_SINGLE("Aux to Headphone Switch", AC97_CD, 15, 1, 1), | ||
| 515 | AC97_SINGLE("Aux to Headphone Volume", AC97_CD, 12, 7, 1), | ||
| 516 | AC97_SINGLE("Aux to Side Tone Switch", AC97_CD, 11, 1, 1), | ||
| 517 | AC97_SINGLE("Aux to Side Tone Volume", AC97_CD, 8, 7, 1), | ||
| 518 | AC97_SINGLE("Aux to Phone Switch", AC97_CD, 7, 1, 1), | ||
| 519 | AC97_SINGLE("Aux to Phone Volume", AC97_CD, 4, 7, 1), | ||
| 520 | |||
| 521 | AC97_SINGLE("Phone to Headphone Switch", AC97_PHONE, 15, 1, 1), | ||
| 522 | AC97_SINGLE("Phone to Master Switch", AC97_PHONE, 14, 1, 1), | ||
| 523 | |||
| 524 | AC97_SINGLE("Line to Headphone Switch", AC97_LINE, 15, 1, 1), | ||
| 525 | AC97_SINGLE("Line to Master Switch", AC97_LINE, 14, 1, 1), | ||
| 526 | AC97_SINGLE("Line to Phone Switch", AC97_LINE, 13, 1, 1), | ||
| 527 | |||
| 528 | AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PCM, 15, 1, 1), | ||
| 529 | AC97_SINGLE("PCM Playback to Master Switch", AC97_PCM, 14, 1, 1), | ||
| 530 | AC97_SINGLE("PCM Playback to Phone Switch", AC97_PCM, 13, 1, 1), | ||
| 531 | |||
| 532 | AC97_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0), | ||
| 533 | AC97_ENUM("Capture to Phone Mux", wm9711_enum[4]), | ||
| 534 | AC97_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1), | ||
| 535 | AC97_ENUM("Capture Select", wm9711_enum[8]), | ||
| 536 | |||
| 537 | AC97_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1), | ||
| 538 | AC97_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1), | ||
| 539 | |||
| 540 | AC97_ENUM("Bass Control", wm9711_enum[5]), | ||
| 541 | AC97_SINGLE("Bass Cut-off Switch", AC97_MASTER_TONE, 12, 1, 1), | ||
| 542 | AC97_SINGLE("Tone Cut-off Switch", AC97_MASTER_TONE, 4, 1, 1), | ||
| 543 | AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0), | ||
| 544 | |||
| 545 | AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1), | ||
| 546 | AC97_ENUM("Capture Volume Steps", wm9711_enum[6]), | ||
| 547 | AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1), | ||
| 548 | AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | ||
| 549 | |||
| 550 | AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1), | ||
| 551 | AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1), | ||
| 552 | AC97_ENUM("Mic Select Source", wm9711_enum[7]), | ||
| 553 | AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1), | ||
| 554 | AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), | ||
| 555 | |||
| 556 | AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0), | ||
| 557 | AC97_SINGLE("Headphone ZC Switch", AC97_HEADPHONE, 7, 1, 0), | ||
| 558 | AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0), | ||
| 559 | }; | ||
| 560 | |||
| 561 | static int patch_wolfson_wm9711_specific(ac97_t * ac97) | ||
| 562 | { | ||
| 563 | int err, i; | ||
| 564 | |||
| 565 | for (i = 0; i < ARRAY_SIZE(wm9711_snd_ac97_controls); i++) { | ||
| 566 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm9711_snd_ac97_controls[i], ac97))) < 0) | ||
| 567 | return err; | ||
| 568 | } | ||
| 569 | snd_ac97_write_cache(ac97, AC97_CODEC_CLASS_REV, 0x0808); | ||
| 570 | snd_ac97_write_cache(ac97, AC97_PCI_SVID, 0x0808); | ||
| 571 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0x0808); | ||
| 572 | snd_ac97_write_cache(ac97, AC97_AUX, 0x0808); | ||
| 573 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); | ||
| 574 | snd_ac97_write_cache(ac97, AC97_CD, 0x0000); | ||
| 407 | return 0; | 575 | return 0; |
| 408 | } | 576 | } |
| 409 | 577 | ||
| 578 | static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { | ||
| 579 | .build_specific = patch_wolfson_wm9711_specific, | ||
| 580 | }; | ||
| 581 | |||
| 410 | int patch_wolfson11(ac97_t * ac97) | 582 | int patch_wolfson11(ac97_t * ac97) |
| 411 | { | 583 | { |
| 412 | // WM9711, WM9712 | 584 | /* WM9711, WM9712 */ |
| 413 | // set out3 volume | 585 | ac97->build_ops = &patch_wolfson_wm9711_ops; |
| 414 | snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808); | 586 | |
| 587 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_MIC | | ||
| 588 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; | ||
| 589 | |||
| 415 | return 0; | 590 | return 0; |
| 416 | } | 591 | } |
| 417 | 592 | ||
| 418 | static const char* wm9713_mic_mixer[] = {"Stereo", "Mic1", "Mic2", "Mute"}; | 593 | static const char* wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"}; |
| 419 | static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; | 594 | static const char* wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"}; |
| 420 | static const char* wm9713_rec_src_l[] = {"Mic1", "Mic2", "Line L", "Mono In", "HP Mix L", "Spk Mix", "Mono Mix", "Zh"}; | 595 | static const char* wm9713_rec_src[] = |
| 421 | static const char* wm9713_rec_src_r[] = {"Mic1", "Mic2", "Line R", "Mono In", "HP Mix R", "Spk Mix", "Mono Mix", "Zh"}; | 596 | {"Mic 1", "Mic 2", "Line", "Mono In", "Headphone Mix", "Master Mix", |
| 597 | "Mono Mix", "Zh"}; | ||
| 598 | static const char* wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"}; | ||
| 599 | static const char* wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"}; | ||
| 600 | static const char* wm9713_mono_pga[] = {"Vmid", "Zh", "Mono Mix", "Inv 1"}; | ||
| 601 | static const char* wm9713_spk_pga[] = | ||
| 602 | {"Vmid", "Zh", "Headphone Mix", "Master Mix", "Inv", "NC", "NC", "NC"}; | ||
| 603 | static const char* wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone Mix", "NC"}; | ||
| 604 | static const char* wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "NC"}; | ||
| 605 | static const char* wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "NC"}; | ||
| 606 | static const char* wm9713_dac_inv[] = | ||
| 607 | {"Off", "Mono Mix", "Master Mix", "Headphone Mix L", "Headphone Mix R", | ||
| 608 | "Headphone Mix Mono", "NC", "Vmid"}; | ||
| 609 | static const char* wm9713_base[] = {"Linear Control", "Adaptive Boost"}; | ||
| 610 | static const char* wm9713_ng_type[] = {"Constant Gain", "Mute"}; | ||
| 422 | 611 | ||
| 423 | static const struct ac97_enum wm9713_enum[] = { | 612 | static const struct ac97_enum wm9713_enum[] = { |
| 424 | AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), | 613 | AC97_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), |
| 425 | AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), | 614 | AC97_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), |
| 426 | AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), | 615 | AC97_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux), |
| 427 | AC97_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src_l), | 616 | AC97_ENUM_DOUBLE(AC97_VIDEO, 3, 0, 8, wm9713_rec_src), |
| 428 | AC97_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src_r), | 617 | AC97_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), |
| 618 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), | ||
| 619 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), | ||
| 620 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 11, 8, 8, wm9713_spk_pga), | ||
| 621 | AC97_ENUM_DOUBLE(AC97_REC_GAIN, 6, 4, 4, wm9713_hp_pga), | ||
| 622 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), | ||
| 623 | AC97_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), | ||
| 624 | AC97_ENUM_DOUBLE(AC97_REC_GAIN_MIC, 13, 10, 8, wm9713_dac_inv), | ||
| 625 | AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_base), | ||
| 626 | AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), | ||
| 429 | }; | 627 | }; |
| 430 | 628 | ||
| 431 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_line_in[] = { | 629 | static const snd_kcontrol_new_t wm13_snd_ac97_controls[] = { |
| 432 | AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), | 630 | AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), |
| 433 | AC97_SINGLE("Line In to Headphone Mute", AC97_PC_BEEP, 15, 1, 1), | 631 | AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1), |
| 434 | AC97_SINGLE("Line In to Speaker Mute", AC97_PC_BEEP, 14, 1, 1), | 632 | AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1), |
| 435 | AC97_SINGLE("Line In to Mono Mute", AC97_PC_BEEP, 13, 1, 1), | 633 | AC97_SINGLE("Line In to Mono Switch", AC97_PC_BEEP, 13, 1, 1), |
| 634 | |||
| 635 | AC97_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), | ||
| 636 | AC97_SINGLE("PCM Playback to Headphone Switch", AC97_PHONE, 15, 1, 1), | ||
| 637 | AC97_SINGLE("PCM Playback to Master Switch", AC97_PHONE, 14, 1, 1), | ||
| 638 | AC97_SINGLE("PCM Playback to Mono Switch", AC97_PHONE, 13, 1, 1), | ||
| 639 | |||
| 640 | AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), | ||
| 641 | AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), | ||
| 642 | AC97_SINGLE("Mic 1 to Mono Switch", AC97_LINE, 7, 1, 1), | ||
| 643 | AC97_SINGLE("Mic 2 to Mono Switch", AC97_LINE, 6, 1, 1), | ||
| 644 | AC97_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), | ||
| 645 | AC97_ENUM("Mic to Headphone Mux", wm9713_enum[0]), | ||
| 646 | AC97_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), | ||
| 647 | |||
| 648 | AC97_SINGLE("Capture Switch", AC97_CD, 15, 1, 1), | ||
| 649 | AC97_ENUM("Capture Volume Steps", wm9713_enum[4]), | ||
| 650 | AC97_DOUBLE("Capture Volume", AC97_CD, 8, 0, 15, 0), | ||
| 651 | AC97_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), | ||
| 652 | |||
| 653 | AC97_ENUM("Capture to Headphone Mux", wm9713_enum[1]), | ||
| 654 | AC97_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), | ||
| 655 | AC97_ENUM("Capture to Mono Mux", wm9713_enum[2]), | ||
| 656 | AC97_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), | ||
| 657 | AC97_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), | ||
| 658 | AC97_ENUM("Capture Select", wm9713_enum[3]), | ||
| 659 | |||
| 660 | AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), | ||
| 661 | AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), | ||
| 662 | AC97_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), | ||
| 663 | AC97_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), | ||
| 664 | AC97_ENUM("ALC Function", wm9713_enum[5]), | ||
| 665 | AC97_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), | ||
| 666 | AC97_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0), | ||
| 667 | AC97_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0), | ||
| 668 | AC97_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0), | ||
| 669 | AC97_ENUM("ALC NG Type", wm9713_enum[13]), | ||
| 670 | AC97_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0), | ||
| 671 | |||
| 672 | AC97_DOUBLE("Master ZC Switch", AC97_MASTER, 14, 6, 1, 0), | ||
| 673 | AC97_DOUBLE("Headphone ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0), | ||
| 674 | AC97_DOUBLE("Out3/4 ZC Switch", AC97_MASTER_MONO, 14, 6, 1, 0), | ||
| 675 | AC97_SINGLE("Master Right Switch", AC97_MASTER, 7, 1, 1), | ||
| 676 | AC97_SINGLE("Headphone Right Switch", AC97_HEADPHONE, 7, 1, 1), | ||
| 677 | AC97_SINGLE("Out3/4 Right Switch", AC97_MASTER_MONO, 7, 1, 1), | ||
| 678 | |||
| 679 | AC97_SINGLE("Mono In to Headphone Switch", AC97_MASTER_TONE, 15, 1, 1), | ||
| 680 | AC97_SINGLE("Mono In to Master Switch", AC97_MASTER_TONE, 14, 1, 1), | ||
| 681 | AC97_SINGLE("Mono In Volume", AC97_MASTER_TONE, 8, 31, 1), | ||
| 682 | AC97_SINGLE("Mono Switch", AC97_MASTER_TONE, 7, 1, 1), | ||
| 683 | AC97_SINGLE("Mono ZC Switch", AC97_MASTER_TONE, 6, 1, 0), | ||
| 684 | AC97_SINGLE("Mono Volume", AC97_MASTER_TONE, 0, 31, 1), | ||
| 685 | |||
| 686 | AC97_SINGLE("PC Beep to Headphone Switch", AC97_AUX, 15, 1, 1), | ||
| 687 | AC97_SINGLE("PC Beep to Headphone Volume", AC97_AUX, 12, 7, 1), | ||
| 688 | AC97_SINGLE("PC Beep to Master Switch", AC97_AUX, 11, 1, 1), | ||
| 689 | AC97_SINGLE("PC Beep to Master Volume", AC97_AUX, 8, 7, 1), | ||
| 690 | AC97_SINGLE("PC Beep to Mono Switch", AC97_AUX, 7, 1, 1), | ||
| 691 | AC97_SINGLE("PC Beep to Mono Volume", AC97_AUX, 4, 7, 1), | ||
| 692 | |||
| 693 | AC97_SINGLE("Voice to Headphone Switch", AC97_PCM, 15, 1, 1), | ||
| 694 | AC97_SINGLE("Voice to Headphone Volume", AC97_PCM, 12, 7, 1), | ||
| 695 | AC97_SINGLE("Voice to Master Switch", AC97_PCM, 11, 1, 1), | ||
| 696 | AC97_SINGLE("Voice to Master Volume", AC97_PCM, 8, 7, 1), | ||
| 697 | AC97_SINGLE("Voice to Mono Switch", AC97_PCM, 7, 1, 1), | ||
| 698 | AC97_SINGLE("Voice to Mono Volume", AC97_PCM, 4, 7, 1), | ||
| 699 | |||
| 700 | AC97_SINGLE("Aux to Headphone Switch", AC97_REC_SEL, 15, 1, 1), | ||
| 701 | AC97_SINGLE("Aux to Headphone Volume", AC97_REC_SEL, 12, 7, 1), | ||
| 702 | AC97_SINGLE("Aux to Master Switch", AC97_REC_SEL, 11, 1, 1), | ||
| 703 | AC97_SINGLE("Aux to Master Volume", AC97_REC_SEL, 8, 7, 1), | ||
| 704 | AC97_SINGLE("Aux to Mono Switch", AC97_REC_SEL, 7, 1, 1), | ||
| 705 | AC97_SINGLE("Aux to Mono Volume", AC97_REC_SEL, 4, 7, 1), | ||
| 706 | |||
| 707 | AC97_ENUM("Mono Input Mux", wm9713_enum[6]), | ||
| 708 | AC97_ENUM("Master Input Mux", wm9713_enum[7]), | ||
| 709 | AC97_ENUM("Headphone Input Mux", wm9713_enum[8]), | ||
| 710 | AC97_ENUM("Out 3 Input Mux", wm9713_enum[9]), | ||
| 711 | AC97_ENUM("Out 4 Input Mux", wm9713_enum[10]), | ||
| 712 | |||
| 713 | AC97_ENUM("Bass Control", wm9713_enum[12]), | ||
| 714 | AC97_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), | ||
| 715 | AC97_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1), | ||
| 716 | AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0), | ||
| 717 | AC97_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1), | ||
| 718 | AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1), | ||
| 436 | }; | 719 | }; |
| 437 | 720 | ||
| 438 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_dac[] = { | 721 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_3d[] = { |
| 439 | AC97_DOUBLE("DAC Volume", AC97_PHONE, 8, 0, 31, 1), | 722 | AC97_ENUM("Inv Input Mux", wm9713_enum[11]), |
| 440 | AC97_SINGLE("DAC to Headphone Mute", AC97_PHONE, 15, 1, 1), | 723 | AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0), |
| 441 | AC97_SINGLE("DAC to Speaker Mute", AC97_PHONE, 14, 1, 1), | 724 | AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), |
| 442 | AC97_SINGLE("DAC to Mono Mute", AC97_PHONE, 13, 1, 1), | 725 | AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), |
| 443 | }; | 726 | }; |
| 444 | 727 | ||
| 445 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_mic[] = { | 728 | static int patch_wolfson_wm9713_3d (ac97_t * ac97) |
| 446 | AC97_SINGLE("MICA Volume", AC97_MIC, 8, 31, 1), | 729 | { |
| 447 | AC97_SINGLE("MICB Volume", AC97_MIC, 0, 31, 1), | 730 | int err, i; |
| 448 | AC97_SINGLE("MICA to Mono Mute", AC97_LINE, 7, 1, 1), | 731 | |
| 449 | AC97_SINGLE("MICB to Mono Mute", AC97_LINE, 6, 1, 1), | 732 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_3d); i++) { |
| 450 | AC97_SINGLE("MIC Boost (+20dB)", AC97_LINE, 5, 1, 1), | 733 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_3d[i], ac97))) < 0) |
| 451 | AC97_ENUM("MIC Headphone Routing", wm9713_enum[0]), | 734 | return err; |
| 452 | AC97_SINGLE("MIC Headphone Mixer Volume", AC97_LINE, 0, 7, 1) | 735 | } |
| 453 | }; | 736 | return 0; |
| 454 | 737 | } | |
| 455 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_adc[] = { | ||
| 456 | AC97_SINGLE("ADC Mute", AC97_CD, 15, 1, 1), | ||
| 457 | AC97_DOUBLE("Gain Step Size (1.5dB/0.75dB)", AC97_CD, 14, 6, 1, 1), | ||
| 458 | AC97_DOUBLE("ADC Volume",AC97_CD, 8, 0, 15, 0), | ||
| 459 | AC97_SINGLE("ADC Zero Cross", AC97_CD, 7, 1, 1), | ||
| 460 | }; | ||
| 461 | |||
| 462 | static const snd_kcontrol_new_t wm13_snd_ac97_controls_recsel[] = { | ||
| 463 | AC97_ENUM("Record to Headphone Path", wm9713_enum[1]), | ||
| 464 | AC97_SINGLE("Record to Headphone Volume", AC97_VIDEO, 11, 7, 0), | ||
| 465 | AC97_ENUM("Record to Mono Path", wm9713_enum[2]), | ||
| 466 | AC97_SINGLE("Record to Mono Boost (+20dB)", AC97_VIDEO, 8, 1, 0), | ||
| 467 | AC97_SINGLE("Record ADC Boost (+20dB)", AC97_VIDEO, 6, 1, 0), | ||
| 468 | AC97_ENUM("Record Select Left", wm9713_enum[3]), | ||
| 469 | AC97_ENUM("Record Select Right", wm9713_enum[4]), | ||
| 470 | }; | ||
| 471 | 738 | ||
| 472 | static int patch_wolfson_wm9713_specific(ac97_t * ac97) | 739 | static int patch_wolfson_wm9713_specific(ac97_t * ac97) |
| 473 | { | 740 | { |
| 474 | int err, i; | 741 | int err, i; |
| 475 | 742 | ||
| 476 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_line_in); i++) { | 743 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls); i++) { |
| 477 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_line_in[i], ac97))) < 0) | 744 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls[i], ac97))) < 0) |
| 478 | return err; | 745 | return err; |
| 479 | } | 746 | } |
| 480 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); | 747 | snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x0808); |
| 481 | |||
| 482 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_dac); i++) { | ||
| 483 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_dac[i], ac97))) < 0) | ||
| 484 | return err; | ||
| 485 | } | ||
| 486 | snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); | 748 | snd_ac97_write_cache(ac97, AC97_PHONE, 0x0808); |
| 487 | |||
| 488 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_mic); i++) { | ||
| 489 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_mic[i], ac97))) < 0) | ||
| 490 | return err; | ||
| 491 | } | ||
| 492 | snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); | 749 | snd_ac97_write_cache(ac97, AC97_MIC, 0x0808); |
| 493 | snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); | 750 | snd_ac97_write_cache(ac97, AC97_LINE, 0x00da); |
| 494 | |||
| 495 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_adc); i++) { | ||
| 496 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_adc[i], ac97))) < 0) | ||
| 497 | return err; | ||
| 498 | } | ||
| 499 | snd_ac97_write_cache(ac97, AC97_CD, 0x0808); | 751 | snd_ac97_write_cache(ac97, AC97_CD, 0x0808); |
| 500 | |||
| 501 | for (i = 0; i < ARRAY_SIZE(wm13_snd_ac97_controls_recsel); i++) { | ||
| 502 | if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&wm13_snd_ac97_controls_recsel[i], ac97))) < 0) | ||
| 503 | return err; | ||
| 504 | } | ||
| 505 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); | 752 | snd_ac97_write_cache(ac97, AC97_VIDEO, 0xd612); |
| 506 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); | 753 | snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x1ba0); |
| 507 | |||
| 508 | return 0; | 754 | return 0; |
| 509 | } | 755 | } |
| 510 | 756 | ||
| @@ -525,6 +771,7 @@ static void patch_wolfson_wm9713_resume (ac97_t * ac97) | |||
| 525 | 771 | ||
| 526 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | 772 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { |
| 527 | .build_specific = patch_wolfson_wm9713_specific, | 773 | .build_specific = patch_wolfson_wm9713_specific, |
| 774 | .build_3d = patch_wolfson_wm9713_3d, | ||
| 528 | #ifdef CONFIG_PM | 775 | #ifdef CONFIG_PM |
| 529 | .suspend = patch_wolfson_wm9713_suspend, | 776 | .suspend = patch_wolfson_wm9713_suspend, |
| 530 | .resume = patch_wolfson_wm9713_resume | 777 | .resume = patch_wolfson_wm9713_resume |
| @@ -533,10 +780,13 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | |||
| 533 | 780 | ||
| 534 | int patch_wolfson13(ac97_t * ac97) | 781 | int patch_wolfson13(ac97_t * ac97) |
| 535 | { | 782 | { |
| 783 | /* WM9713, WM9714 */ | ||
| 536 | ac97->build_ops = &patch_wolfson_wm9713_ops; | 784 | ac97->build_ops = &patch_wolfson_wm9713_ops; |
| 537 | 785 | ||
| 538 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | | 786 | ac97->flags |= AC97_HAS_NO_REC_GAIN | AC97_STEREO_MUTES | AC97_HAS_NO_PHONE | |
| 539 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD; | 787 | AC97_HAS_NO_PC_BEEP | AC97_HAS_NO_VIDEO | AC97_HAS_NO_CD | AC97_HAS_NO_TONE | |
| 788 | AC97_HAS_NO_STD_PCM; | ||
| 789 | ac97->scaps &= ~AC97_SCAP_MODEM; | ||
| 540 | 790 | ||
| 541 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); | 791 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00); |
| 542 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); | 792 | snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810); |
| @@ -1379,6 +1629,7 @@ static void check_ad1981_hp_jack_sense(ac97_t *ac97) | |||
| 1379 | u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; | 1629 | u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device; |
| 1380 | switch (subid) { | 1630 | switch (subid) { |
| 1381 | case 0x103c0890: /* HP nc6000 */ | 1631 | case 0x103c0890: /* HP nc6000 */ |
| 1632 | case 0x103c099c: /* HP nx6110 */ | ||
| 1382 | case 0x103c006d: /* HP nx9105 */ | 1633 | case 0x103c006d: /* HP nx9105 */ |
| 1383 | case 0x17340088: /* FSC Scenic-W */ | 1634 | case 0x17340088: /* FSC Scenic-W */ |
| 1384 | /* enable headphone jack sense */ | 1635 | /* enable headphone jack sense */ |
| @@ -1706,7 +1957,7 @@ static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { | |||
| 1706 | }; | 1957 | }; |
| 1707 | 1958 | ||
| 1708 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { | 1959 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { |
| 1709 | AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0), | 1960 | AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0), |
| 1710 | AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), | 1961 | AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), |
| 1711 | /* disable this controls since it doesn't work as expected */ | 1962 | /* disable this controls since it doesn't work as expected */ |
| 1712 | /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ | 1963 | /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ |
| @@ -1849,12 +2100,12 @@ static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ | |||
| 1849 | } | 2100 | } |
| 1850 | 2101 | ||
| 1851 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { | 2102 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = { |
| 1852 | AC97_PAGE_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0, 0), | 2103 | AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0), |
| 1853 | /* disable this controls since it doesn't work as expected */ | 2104 | /* disable this controls since it doesn't work as expected */ |
| 1854 | /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ | 2105 | /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */ |
| 1855 | { | 2106 | { |
| 1856 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2107 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1857 | .name = "IEC958 Playback Route", | 2108 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
| 1858 | .info = alc655_iec958_route_info, | 2109 | .info = alc655_iec958_route_info, |
| 1859 | .get = alc655_iec958_route_get, | 2110 | .get = alc655_iec958_route_get, |
| 1860 | .put = alc655_iec958_route_put, | 2111 | .put = alc655_iec958_route_put, |
| @@ -2416,6 +2667,16 @@ int patch_vt1616(ac97_t * ac97) | |||
| 2416 | } | 2667 | } |
| 2417 | 2668 | ||
| 2418 | /* | 2669 | /* |
| 2670 | * VT1617A codec | ||
| 2671 | */ | ||
| 2672 | int patch_vt1617a(ac97_t * ac97) | ||
| 2673 | { | ||
| 2674 | ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ | ||
| 2675 | ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; | ||
| 2676 | return 0; | ||
| 2677 | } | ||
| 2678 | |||
| 2679 | /* | ||
| 2419 | */ | 2680 | */ |
| 2420 | static void it2646_update_jacks(ac97_t *ac97) | 2681 | static void it2646_update_jacks(ac97_t *ac97) |
| 2421 | { | 2682 | { |
| @@ -2433,7 +2694,7 @@ static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = { | |||
| 2433 | }; | 2694 | }; |
| 2434 | 2695 | ||
| 2435 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { | 2696 | static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { |
| 2436 | AC97_SINGLE("IEC958 Capture Switch", 0x76, 11, 1, 0), | 2697 | AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0), |
| 2437 | AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), | 2698 | AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0), |
| 2438 | AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), | 2699 | AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0), |
| 2439 | }; | 2700 | }; |
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 7b7377d0f2ae..ec1811320106 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
| @@ -56,5 +56,6 @@ int patch_cm9739(ac97_t * ac97); | |||
| 56 | int patch_cm9761(ac97_t * ac97); | 56 | int patch_cm9761(ac97_t * ac97); |
| 57 | int patch_cm9780(ac97_t * ac97); | 57 | int patch_cm9780(ac97_t * ac97); |
| 58 | int patch_vt1616(ac97_t * ac97); | 58 | int patch_vt1616(ac97_t * ac97); |
| 59 | int patch_vt1617a(ac97_t * ac97); | ||
| 59 | int patch_it2646(ac97_t * ac97); | 60 | int patch_it2646(ac97_t * ac97); |
| 60 | int mpatch_si3036(ac97_t * ac97); | 61 | int mpatch_si3036(ac97_t * ac97); |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index f08ae71f902d..ce6c9fadb594 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
| @@ -1842,7 +1842,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr | |||
| 1842 | return 0; | 1842 | return 0; |
| 1843 | } | 1843 | } |
| 1844 | 1844 | ||
| 1845 | struct ali_pcm_description ali_pcms[] = { | 1845 | static struct ali_pcm_description ali_pcms[] = { |
| 1846 | { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, | 1846 | { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, |
| 1847 | { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops } | 1847 | { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops } |
| 1848 | }; | 1848 | }; |
| @@ -1959,9 +1959,9 @@ static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 1959 | static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = { | 1959 | static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = { |
| 1960 | /* spdif aplayback switch */ | 1960 | /* spdif aplayback switch */ |
| 1961 | /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */ | 1961 | /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */ |
| 1962 | ALI5451_SPDIF("IEC958 Output switch", 0, 0), | 1962 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 0, 0), |
| 1963 | /* spdif out to spdif channel */ | 1963 | /* spdif out to spdif channel */ |
| 1964 | ALI5451_SPDIF("IEC958 Channel Output Switch", 0, 1), | 1964 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Channel Output ",NONE,SWITCH), 0, 1), |
| 1965 | /* spdif in from spdif channel */ | 1965 | /* spdif in from spdif channel */ |
| 1966 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) | 1966 | ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) |
| 1967 | }; | 1967 | }; |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index cafab4af5c57..904d17394e1c 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
| @@ -248,6 +248,7 @@ struct snd_atiixp_dma { | |||
| 248 | unsigned int period_bytes, periods; | 248 | unsigned int period_bytes, periods; |
| 249 | int opened; | 249 | int opened; |
| 250 | int running; | 250 | int running; |
| 251 | int suspended; | ||
| 251 | int pcm_open_flag; | 252 | int pcm_open_flag; |
| 252 | int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */ | 253 | int ac97_pcm_type; /* index # of ac97_pcm to access, -1 = not used */ |
| 253 | unsigned int saved_curptr; | 254 | unsigned int saved_curptr; |
| @@ -699,12 +700,18 @@ static int snd_atiixp_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 699 | spin_lock(&chip->reg_lock); | 700 | spin_lock(&chip->reg_lock); |
| 700 | switch (cmd) { | 701 | switch (cmd) { |
| 701 | case SNDRV_PCM_TRIGGER_START: | 702 | case SNDRV_PCM_TRIGGER_START: |
| 703 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 704 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 702 | dma->ops->enable_transfer(chip, 1); | 705 | dma->ops->enable_transfer(chip, 1); |
| 703 | dma->running = 1; | 706 | dma->running = 1; |
| 707 | dma->suspended = 0; | ||
| 704 | break; | 708 | break; |
| 705 | case SNDRV_PCM_TRIGGER_STOP: | 709 | case SNDRV_PCM_TRIGGER_STOP: |
| 710 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 711 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 706 | dma->ops->enable_transfer(chip, 0); | 712 | dma->ops->enable_transfer(chip, 0); |
| 707 | dma->running = 0; | 713 | dma->running = 0; |
| 714 | dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND; | ||
| 708 | break; | 715 | break; |
| 709 | default: | 716 | default: |
| 710 | err = -EINVAL; | 717 | err = -EINVAL; |
| @@ -975,6 +982,7 @@ static snd_pcm_hardware_t snd_atiixp_pcm_hw = | |||
| 975 | { | 982 | { |
| 976 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 983 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 977 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 984 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 985 | SNDRV_PCM_INFO_PAUSE | | ||
| 978 | SNDRV_PCM_INFO_RESUME | | 986 | SNDRV_PCM_INFO_RESUME | |
| 979 | SNDRV_PCM_INFO_MMAP_VALID), | 987 | SNDRV_PCM_INFO_MMAP_VALID), |
| 980 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, | 988 | .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, |
| @@ -1443,7 +1451,7 @@ static int snd_atiixp_resume(snd_card_t *card) | |||
| 1443 | for (i = 0; i < NUM_ATI_PCMDEVS; i++) | 1451 | for (i = 0; i < NUM_ATI_PCMDEVS; i++) |
| 1444 | if (chip->pcmdevs[i]) { | 1452 | if (chip->pcmdevs[i]) { |
| 1445 | atiixp_dma_t *dma = &chip->dmas[i]; | 1453 | atiixp_dma_t *dma = &chip->dmas[i]; |
| 1446 | if (dma->substream && dma->running) { | 1454 | if (dma->substream && dma->suspended) { |
| 1447 | dma->ops->enable_dma(chip, 1); | 1455 | dma->ops->enable_dma(chip, 1); |
| 1448 | writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN, | 1456 | writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN, |
| 1449 | chip->remap_addr + dma->ops->llp_offset); | 1457 | chip->remap_addr + dma->ops->llp_offset); |
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 04dcefd8b8ff..38bd2b5dd434 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | /* hardware definition */ | 33 | /* hardware definition */ |
| 34 | static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { | 34 | static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { |
| 35 | .info = | 35 | .info = |
| 36 | (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | | 36 | (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ |
| 37 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | | 37 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | |
| 38 | SNDRV_PCM_INFO_MMAP_VALID), | 38 | SNDRV_PCM_INFO_MMAP_VALID), |
| 39 | .formats = | 39 | .formats = |
| @@ -58,7 +58,7 @@ static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { | |||
| 58 | #ifndef CHIP_AU8820 | 58 | #ifndef CHIP_AU8820 |
| 59 | static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = { | 59 | static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = { |
| 60 | .info = | 60 | .info = |
| 61 | (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | | 61 | (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ |
| 62 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | | 62 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | |
| 63 | SNDRV_PCM_INFO_MMAP_VALID), | 63 | SNDRV_PCM_INFO_MMAP_VALID), |
| 64 | .formats = | 64 | .formats = |
| @@ -78,7 +78,7 @@ static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = { | |||
| 78 | #endif | 78 | #endif |
| 79 | static snd_pcm_hardware_t snd_vortex_playback_hw_spdif = { | 79 | static snd_pcm_hardware_t snd_vortex_playback_hw_spdif = { |
| 80 | .info = | 80 | .info = |
| 81 | (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | | 81 | (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ |
| 82 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | | 82 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | |
| 83 | SNDRV_PCM_INFO_MMAP_VALID), | 83 | SNDRV_PCM_INFO_MMAP_VALID), |
| 84 | .formats = | 84 | .formats = |
| @@ -220,8 +220,10 @@ snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream, | |||
| 220 | vortex_adb_allocroute(chip, -1, | 220 | vortex_adb_allocroute(chip, -1, |
| 221 | params_channels(hw_params), | 221 | params_channels(hw_params), |
| 222 | substream->stream, type); | 222 | substream->stream, type); |
| 223 | if (dma < 0) | 223 | if (dma < 0) { |
| 224 | spin_unlock_irq(&chip->lock); | ||
| 224 | return dma; | 225 | return dma; |
| 226 | } | ||
| 225 | stream = substream->runtime->private_data = &chip->dma_adb[dma]; | 227 | stream = substream->runtime->private_data = &chip->dma_adb[dma]; |
| 226 | stream->substream = substream; | 228 | stream->substream = substream; |
| 227 | /* Setup Buffers. */ | 229 | /* Setup Buffers. */ |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 95c289284267..7e27bfc37439 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
| @@ -188,6 +188,14 @@ static ca0106_details_t ca0106_chip_details[] = { | |||
| 188 | .name = "MSI K8N Diamond MB [SB0438]", | 188 | .name = "MSI K8N Diamond MB [SB0438]", |
| 189 | .gpio_type = 1, | 189 | .gpio_type = 1, |
| 190 | .i2c_adc = 1 } , | 190 | .i2c_adc = 1 } , |
| 191 | /* Shuttle XPC SD31P which has an onboard Creative Labs Sound Blaster Live! 24-bit EAX | ||
| 192 | * high-definition 7.1 audio processor". | ||
| 193 | * Added using info from andrewvegan in alsa bug #1298 | ||
| 194 | */ | ||
| 195 | { .serial = 0x30381297, | ||
| 196 | .name = "Shuttle XPC SD31P [SD31P]", | ||
| 197 | .gpio_type = 1, | ||
| 198 | .i2c_adc = 1 } , | ||
| 191 | { .serial = 0, | 199 | { .serial = 0, |
| 192 | .name = "AudigyLS [Unknown]" } | 200 | .name = "AudigyLS [Unknown]" } |
| 193 | }; | 201 | }; |
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 0e5e9ce0ff28..b6b8882ce704 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c | |||
| @@ -297,7 +297,7 @@ static int snd_ca0106_spdif_put(snd_kcontrol_t * kcontrol, | |||
| 297 | static snd_kcontrol_new_t snd_ca0106_spdif_mask_control = | 297 | static snd_kcontrol_new_t snd_ca0106_spdif_mask_control = |
| 298 | { | 298 | { |
| 299 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 299 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 300 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 300 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 301 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | 301 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
| 302 | .count = 4, | 302 | .count = 4, |
| 303 | .info = snd_ca0106_spdif_info, | 303 | .info = snd_ca0106_spdif_info, |
| @@ -306,7 +306,7 @@ static snd_kcontrol_new_t snd_ca0106_spdif_mask_control = | |||
| 306 | 306 | ||
| 307 | static snd_kcontrol_new_t snd_ca0106_spdif_control = | 307 | static snd_kcontrol_new_t snd_ca0106_spdif_control = |
| 308 | { | 308 | { |
| 309 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 309 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 310 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 310 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
| 311 | .count = 4, | 311 | .count = 4, |
| 312 | .info = snd_ca0106_spdif_info, | 312 | .info = snd_ca0106_spdif_info, |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index f5a4ac1ceef9..b098b51099c2 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
| @@ -1029,7 +1029,7 @@ static int snd_cmipci_spdif_mask_get(snd_kcontrol_t * kcontrol, | |||
| 1029 | static snd_kcontrol_new_t snd_cmipci_spdif_mask __devinitdata = | 1029 | static snd_kcontrol_new_t snd_cmipci_spdif_mask __devinitdata = |
| 1030 | { | 1030 | { |
| 1031 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1031 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1032 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1032 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1033 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 1033 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), |
| 1034 | .info = snd_cmipci_spdif_mask_info, | 1034 | .info = snd_cmipci_spdif_mask_info, |
| 1035 | .get = snd_cmipci_spdif_mask_get, | 1035 | .get = snd_cmipci_spdif_mask_get, |
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index db212ecd792a..b9fff4ee6f9d 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c | |||
| @@ -113,7 +113,7 @@ static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci, | |||
| 113 | return err; | 113 | return err; |
| 114 | } | 114 | } |
| 115 | #endif | 115 | #endif |
| 116 | if ((err = snd_cs46xx_mixer(chip)) < 0) { | 116 | if ((err = snd_cs46xx_mixer(chip, 2)) < 0) { |
| 117 | snd_card_free(card); | 117 | snd_card_free(card); |
| 118 | return err; | 118 | return err; |
| 119 | } | 119 | } |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index ff28af1f658e..4b052158ee33 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
| @@ -1243,8 +1243,8 @@ static snd_pcm_hardware_t snd_cs46xx_playback = | |||
| 1243 | { | 1243 | { |
| 1244 | .info = (SNDRV_PCM_INFO_MMAP | | 1244 | .info = (SNDRV_PCM_INFO_MMAP | |
| 1245 | SNDRV_PCM_INFO_INTERLEAVED | | 1245 | SNDRV_PCM_INFO_INTERLEAVED | |
| 1246 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1246 | SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ |
| 1247 | SNDRV_PCM_INFO_RESUME), | 1247 | /*SNDRV_PCM_INFO_RESUME*/), |
| 1248 | .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | | 1248 | .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | |
| 1249 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | | 1249 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | |
| 1250 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE), | 1250 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE), |
| @@ -1265,8 +1265,8 @@ static snd_pcm_hardware_t snd_cs46xx_capture = | |||
| 1265 | { | 1265 | { |
| 1266 | .info = (SNDRV_PCM_INFO_MMAP | | 1266 | .info = (SNDRV_PCM_INFO_MMAP | |
| 1267 | SNDRV_PCM_INFO_INTERLEAVED | | 1267 | SNDRV_PCM_INFO_INTERLEAVED | |
| 1268 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1268 | SNDRV_PCM_INFO_BLOCK_TRANSFER /*|*/ |
| 1269 | SNDRV_PCM_INFO_RESUME), | 1269 | /*SNDRV_PCM_INFO_RESUME*/), |
| 1270 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1270 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 1271 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1271 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
| 1272 | .rate_min = 5500, | 1272 | .rate_min = 5500, |
| @@ -2231,7 +2231,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { | |||
| 2231 | }, | 2231 | }, |
| 2232 | { | 2232 | { |
| 2233 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2233 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 2234 | .name = "IEC958 Output Switch", | 2234 | .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), |
| 2235 | .info = snd_mixer_boolean_info, | 2235 | .info = snd_mixer_boolean_info, |
| 2236 | .get = snd_cs46xx_iec958_get, | 2236 | .get = snd_cs46xx_iec958_get, |
| 2237 | .put = snd_cs46xx_iec958_put, | 2237 | .put = snd_cs46xx_iec958_put, |
| @@ -2239,7 +2239,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { | |||
| 2239 | }, | 2239 | }, |
| 2240 | { | 2240 | { |
| 2241 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2241 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 2242 | .name = "IEC958 Input Switch", | 2242 | .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,SWITCH), |
| 2243 | .info = snd_mixer_boolean_info, | 2243 | .info = snd_mixer_boolean_info, |
| 2244 | .get = snd_cs46xx_iec958_get, | 2244 | .get = snd_cs46xx_iec958_get, |
| 2245 | .put = snd_cs46xx_iec958_put, | 2245 | .put = snd_cs46xx_iec958_put, |
| @@ -2249,7 +2249,7 @@ static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = { | |||
| 2249 | /* Input IEC958 volume does not work for the moment. (Benny) */ | 2249 | /* Input IEC958 volume does not work for the moment. (Benny) */ |
| 2250 | { | 2250 | { |
| 2251 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2251 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 2252 | .name = "IEC958 Input Volume", | 2252 | .name = SNDRV_CTL_NAME_IEC958("Input ",NONE,VOLUME), |
| 2253 | .info = snd_cs46xx_vol_info, | 2253 | .info = snd_cs46xx_vol_info, |
| 2254 | .get = snd_cs46xx_vol_iec958_get, | 2254 | .get = snd_cs46xx_vol_iec958_get, |
| 2255 | .put = snd_cs46xx_vol_iec958_put, | 2255 | .put = snd_cs46xx_vol_iec958_put, |
| @@ -2440,7 +2440,7 @@ static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec) | |||
| 2440 | return -ENXIO; | 2440 | return -ENXIO; |
| 2441 | } | 2441 | } |
| 2442 | 2442 | ||
| 2443 | int __devinit snd_cs46xx_mixer(cs46xx_t *chip) | 2443 | int __devinit snd_cs46xx_mixer(cs46xx_t *chip, int spdif_device) |
| 2444 | { | 2444 | { |
| 2445 | snd_card_t *card = chip->card; | 2445 | snd_card_t *card = chip->card; |
| 2446 | snd_ctl_elem_id_t id; | 2446 | snd_ctl_elem_id_t id; |
| @@ -2476,6 +2476,8 @@ int __devinit snd_cs46xx_mixer(cs46xx_t *chip) | |||
| 2476 | for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { | 2476 | for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { |
| 2477 | snd_kcontrol_t *kctl; | 2477 | snd_kcontrol_t *kctl; |
| 2478 | kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); | 2478 | kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); |
| 2479 | if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM) | ||
| 2480 | kctl->id.device = spdif_device; | ||
| 2479 | if ((err = snd_ctl_add(card, kctl)) < 0) | 2481 | if ((err = snd_ctl_add(card, kctl)) < 0) |
| 2480 | return err; | 2482 | return err; |
| 2481 | } | 2483 | } |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index b17142cabead..fc377c4b666c 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
| @@ -149,7 +149,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
| 149 | } | 149 | } |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | if ((err = snd_emu10k1_mixer(emu)) < 0) { | 152 | if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0) { |
| 153 | snd_card_free(card); | 153 | snd_card_free(card); |
| 154 | return err; | 154 | return err; |
| 155 | } | 155 | } |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 746b51ef3966..e69d5b739e80 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
| @@ -741,12 +741,20 @@ static emu_chip_details_t emu_chip_details[] = { | |||
| 741 | .emu10k1_chip = 1, | 741 | .emu10k1_chip = 1, |
| 742 | .ac97_chip = 1, | 742 | .ac97_chip = 1, |
| 743 | .sblive51 = 1} , | 743 | .sblive51 = 1} , |
| 744 | /* Tested by Thomas Zehetbauer 27th Aug 2005 */ | ||
| 745 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102, | ||
| 746 | .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", | ||
| 747 | .id = "Live", | ||
| 748 | .emu10k1_chip = 1, | ||
| 749 | .ac97_chip = 1, | ||
| 750 | .sblive51 = 1} , | ||
| 744 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, | 751 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, |
| 745 | .driver = "EMU10K1", .name = "SB Live 5.1", | 752 | .driver = "EMU10K1", .name = "SB Live 5.1", |
| 746 | .id = "Live", | 753 | .id = "Live", |
| 747 | .emu10k1_chip = 1, | 754 | .emu10k1_chip = 1, |
| 748 | .ac97_chip = 1, | 755 | .ac97_chip = 1, |
| 749 | .sblive51 = 1} , | 756 | .sblive51 = 1} , |
| 757 | /* Tested by alsa bugtrack user "hus" 12th Sept 2005 */ | ||
| 750 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, | 758 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, |
| 751 | .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", | 759 | .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", |
| 752 | .id = "Live", | 760 | .id = "Live", |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index e90c5ddd1d17..52c7826df440 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
| @@ -1183,7 +1183,7 @@ static int snd_emu10k1x_spdif_put(snd_kcontrol_t * kcontrol, | |||
| 1183 | static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control = | 1183 | static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control = |
| 1184 | { | 1184 | { |
| 1185 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1185 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1186 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1186 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1187 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | 1187 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
| 1188 | .count = 3, | 1188 | .count = 3, |
| 1189 | .info = snd_emu10k1x_spdif_info, | 1189 | .info = snd_emu10k1x_spdif_info, |
| @@ -1192,7 +1192,7 @@ static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control = | |||
| 1192 | 1192 | ||
| 1193 | static snd_kcontrol_new_t snd_emu10k1x_spdif_control = | 1193 | static snd_kcontrol_new_t snd_emu10k1x_spdif_control = |
| 1194 | { | 1194 | { |
| 1195 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1195 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1196 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 1196 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
| 1197 | .count = 3, | 1197 | .count = 3, |
| 1198 | .info = snd_emu10k1x_spdif_info, | 1198 | .info = snd_emu10k1x_spdif_info, |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 0529fb281125..637c555cfdb1 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
| @@ -1159,12 +1159,12 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
| 1159 | /* Optical SPDIF Playback Volume */ | 1159 | /* Optical SPDIF Playback Volume */ |
| 1160 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L); | 1160 | A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L); |
| 1161 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R); | 1161 | A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R); |
| 1162 | snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0); | 1162 | snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",PLAYBACK,VOLUME), gpr, 0); |
| 1163 | gpr += 2; | 1163 | gpr += 2; |
| 1164 | /* Optical SPDIF Capture Volume */ | 1164 | /* Optical SPDIF Capture Volume */ |
| 1165 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L); | 1165 | A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L); |
| 1166 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R); | 1166 | A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R); |
| 1167 | snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0); | 1167 | snd_emu10k1_init_stereo_control(&controls[nctl++], SNDRV_CTL_NAME_IEC958("Optical ",CAPTURE,VOLUME), gpr, 0); |
| 1168 | gpr += 2; | 1168 | gpr += 2; |
| 1169 | 1169 | ||
| 1170 | /* Line2 Playback Volume */ | 1170 | /* Line2 Playback Volume */ |
| @@ -1389,7 +1389,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | |||
| 1389 | A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000); | 1389 | A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000); |
| 1390 | } | 1390 | } |
| 1391 | } | 1391 | } |
| 1392 | snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0); | 1392 | snd_emu10k1_init_stereo_onoff_control(controls + nctl++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0); |
| 1393 | gpr += 2; | 1393 | gpr += 2; |
| 1394 | 1394 | ||
| 1395 | A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); | 1395 | A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); |
| @@ -1716,7 +1716,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1716 | /* IEC958 TTL Playback Volume */ | 1716 | /* IEC958 TTL Playback Volume */ |
| 1717 | for (z = 0; z < 2; z++) | 1717 | for (z = 0; z < 2; z++) |
| 1718 | VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z); | 1718 | VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z); |
| 1719 | snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0); | 1719 | snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",PLAYBACK,VOLUME), gpr, 0); |
| 1720 | gpr += 2; | 1720 | gpr += 2; |
| 1721 | 1721 | ||
| 1722 | /* IEC958 TTL Capture Volume + Switch */ | 1722 | /* IEC958 TTL Capture Volume + Switch */ |
| @@ -1724,8 +1724,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1724 | SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z); | 1724 | SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z); |
| 1725 | VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); | 1725 | VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); |
| 1726 | } | 1726 | } |
| 1727 | snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0); | 1727 | snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,VOLUME), gpr, 0); |
| 1728 | snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0); | 1728 | snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("TTL ",CAPTURE,SWITCH), gpr + 2, 0); |
| 1729 | gpr += 4; | 1729 | gpr += 4; |
| 1730 | } | 1730 | } |
| 1731 | 1731 | ||
| @@ -1750,7 +1750,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1750 | /* IEC958 Optical Playback Volume */ | 1750 | /* IEC958 Optical Playback Volume */ |
| 1751 | for (z = 0; z < 2; z++) | 1751 | for (z = 0; z < 2; z++) |
| 1752 | VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z); | 1752 | VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z); |
| 1753 | snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0); | 1753 | snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",PLAYBACK,VOLUME), gpr, 0); |
| 1754 | gpr += 2; | 1754 | gpr += 2; |
| 1755 | 1755 | ||
| 1756 | /* IEC958 Optical Capture Volume */ | 1756 | /* IEC958 Optical Capture Volume */ |
| @@ -1758,8 +1758,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1758 | SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z); | 1758 | SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z); |
| 1759 | VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); | 1759 | VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); |
| 1760 | } | 1760 | } |
| 1761 | snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0); | 1761 | snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,VOLUME), gpr, 0); |
| 1762 | snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0); | 1762 | snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("LiveDrive ",CAPTURE,SWITCH), gpr + 2, 0); |
| 1763 | gpr += 4; | 1763 | gpr += 4; |
| 1764 | } | 1764 | } |
| 1765 | 1765 | ||
| @@ -1784,7 +1784,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1784 | /* IEC958 Coax Playback Volume */ | 1784 | /* IEC958 Coax Playback Volume */ |
| 1785 | for (z = 0; z < 2; z++) | 1785 | for (z = 0; z < 2; z++) |
| 1786 | VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z); | 1786 | VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z); |
| 1787 | snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0); | 1787 | snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",PLAYBACK,VOLUME), gpr, 0); |
| 1788 | gpr += 2; | 1788 | gpr += 2; |
| 1789 | 1789 | ||
| 1790 | /* IEC958 Coax Capture Volume + Switch */ | 1790 | /* IEC958 Coax Capture Volume + Switch */ |
| @@ -1792,8 +1792,8 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1792 | SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z); | 1792 | SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z); |
| 1793 | VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); | 1793 | VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z); |
| 1794 | } | 1794 | } |
| 1795 | snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0); | 1795 | snd_emu10k1_init_stereo_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,VOLUME), gpr, 0); |
| 1796 | snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0); | 1796 | snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Coaxial ",CAPTURE,SWITCH), gpr + 2, 0); |
| 1797 | gpr += 4; | 1797 | gpr += 4; |
| 1798 | } | 1798 | } |
| 1799 | 1799 | ||
| @@ -1920,7 +1920,7 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) | |||
| 1920 | #endif | 1920 | #endif |
| 1921 | } | 1921 | } |
| 1922 | 1922 | ||
| 1923 | snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0); | 1923 | snd_emu10k1_init_stereo_onoff_control(controls + i++, SNDRV_CTL_NAME_IEC958("Optical Raw ",PLAYBACK,SWITCH), gpr, 0); |
| 1924 | gpr += 2; | 1924 | gpr += 2; |
| 1925 | } | 1925 | } |
| 1926 | 1926 | ||
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 6be82c5fe138..d71a72e84bcc 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
| @@ -181,7 +181,7 @@ static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol, | |||
| 181 | static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control = | 181 | static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control = |
| 182 | { | 182 | { |
| 183 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 183 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 184 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 184 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 185 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), | 185 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), |
| 186 | .count = 4, | 186 | .count = 4, |
| 187 | .info = snd_emu10k1_spdif_info, | 187 | .info = snd_emu10k1_spdif_info, |
| @@ -190,7 +190,7 @@ static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control = | |||
| 190 | 190 | ||
| 191 | static snd_kcontrol_new_t snd_emu10k1_spdif_control = | 191 | static snd_kcontrol_new_t snd_emu10k1_spdif_control = |
| 192 | { | 192 | { |
| 193 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 193 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 194 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 194 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
| 195 | .count = 4, | 195 | .count = 4, |
| 196 | .info = snd_emu10k1_spdif_info, | 196 | .info = snd_emu10k1_spdif_info, |
| @@ -295,7 +295,7 @@ static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol, | |||
| 295 | static snd_kcontrol_new_t snd_emu10k1_send_routing_control = | 295 | static snd_kcontrol_new_t snd_emu10k1_send_routing_control = |
| 296 | { | 296 | { |
| 297 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, | 297 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
| 298 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 298 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 299 | .name = "EMU10K1 PCM Send Routing", | 299 | .name = "EMU10K1 PCM Send Routing", |
| 300 | .count = 32, | 300 | .count = 32, |
| 301 | .info = snd_emu10k1_send_routing_info, | 301 | .info = snd_emu10k1_send_routing_info, |
| @@ -364,7 +364,7 @@ static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol, | |||
| 364 | static snd_kcontrol_new_t snd_emu10k1_send_volume_control = | 364 | static snd_kcontrol_new_t snd_emu10k1_send_volume_control = |
| 365 | { | 365 | { |
| 366 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, | 366 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
| 367 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 367 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 368 | .name = "EMU10K1 PCM Send Volume", | 368 | .name = "EMU10K1 PCM Send Volume", |
| 369 | .count = 32, | 369 | .count = 32, |
| 370 | .info = snd_emu10k1_send_volume_info, | 370 | .info = snd_emu10k1_send_volume_info, |
| @@ -427,7 +427,7 @@ static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol, | |||
| 427 | static snd_kcontrol_new_t snd_emu10k1_attn_control = | 427 | static snd_kcontrol_new_t snd_emu10k1_attn_control = |
| 428 | { | 428 | { |
| 429 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, | 429 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, |
| 430 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 430 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 431 | .name = "EMU10K1 PCM Volume", | 431 | .name = "EMU10K1 PCM Volume", |
| 432 | .count = 32, | 432 | .count = 32, |
| 433 | .info = snd_emu10k1_attn_info, | 433 | .info = snd_emu10k1_attn_info, |
| @@ -737,7 +737,8 @@ static int rename_ctl(snd_card_t *card, const char *src, const char *dst) | |||
| 737 | return -ENOENT; | 737 | return -ENOENT; |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | 740 | int __devinit snd_emu10k1_mixer(emu10k1_t *emu, |
| 741 | int pcm_device, int multi_device) | ||
| 741 | { | 742 | { |
| 742 | int err, pcm; | 743 | int err, pcm; |
| 743 | snd_kcontrol_t *kctl; | 744 | snd_kcontrol_t *kctl; |
| @@ -852,29 +853,35 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | |||
| 852 | 853 | ||
| 853 | if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL) | 854 | if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL) |
| 854 | return -ENOMEM; | 855 | return -ENOMEM; |
| 856 | kctl->id.device = pcm_device; | ||
| 855 | if ((err = snd_ctl_add(card, kctl))) | 857 | if ((err = snd_ctl_add(card, kctl))) |
| 856 | return err; | 858 | return err; |
| 857 | if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL) | 859 | if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL) |
| 858 | return -ENOMEM; | 860 | return -ENOMEM; |
| 861 | kctl->id.device = pcm_device; | ||
| 859 | if ((err = snd_ctl_add(card, kctl))) | 862 | if ((err = snd_ctl_add(card, kctl))) |
| 860 | return err; | 863 | return err; |
| 861 | if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL) | 864 | if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL) |
| 862 | return -ENOMEM; | 865 | return -ENOMEM; |
| 866 | kctl->id.device = pcm_device; | ||
| 863 | if ((err = snd_ctl_add(card, kctl))) | 867 | if ((err = snd_ctl_add(card, kctl))) |
| 864 | return err; | 868 | return err; |
| 865 | 869 | ||
| 866 | if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL) | 870 | if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL) |
| 867 | return -ENOMEM; | 871 | return -ENOMEM; |
| 872 | kctl->id.device = multi_device; | ||
| 868 | if ((err = snd_ctl_add(card, kctl))) | 873 | if ((err = snd_ctl_add(card, kctl))) |
| 869 | return err; | 874 | return err; |
| 870 | 875 | ||
| 871 | if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL) | 876 | if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL) |
| 872 | return -ENOMEM; | 877 | return -ENOMEM; |
| 878 | kctl->id.device = multi_device; | ||
| 873 | if ((err = snd_ctl_add(card, kctl))) | 879 | if ((err = snd_ctl_add(card, kctl))) |
| 874 | return err; | 880 | return err; |
| 875 | 881 | ||
| 876 | if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL) | 882 | if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL) |
| 877 | return -ENOMEM; | 883 | return -ENOMEM; |
| 884 | kctl->id.device = multi_device; | ||
| 878 | if ((err = snd_ctl_add(card, kctl))) | 885 | if ((err = snd_ctl_add(card, kctl))) |
| 879 | return err; | 886 | return err; |
| 880 | 887 | ||
| @@ -924,10 +931,14 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) | |||
| 924 | /* sb live! and audigy */ | 931 | /* sb live! and audigy */ |
| 925 | if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) | 932 | if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) |
| 926 | return -ENOMEM; | 933 | return -ENOMEM; |
| 934 | if (!emu->audigy) | ||
| 935 | kctl->id.device = emu->pcm_efx->device; | ||
| 927 | if ((err = snd_ctl_add(card, kctl))) | 936 | if ((err = snd_ctl_add(card, kctl))) |
| 928 | return err; | 937 | return err; |
| 929 | if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL) | 938 | if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL) |
| 930 | return -ENOMEM; | 939 | return -ENOMEM; |
| 940 | if (!emu->audigy) | ||
| 941 | kctl->id.device = emu->pcm_efx->device; | ||
| 931 | if ((err = snd_ctl_add(card, kctl))) | 942 | if ((err = snd_ctl_add(card, kctl))) |
| 932 | return err; | 943 | return err; |
| 933 | } | 944 | } |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 520b99af5f55..9c35f6dde1b5 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
| @@ -1682,6 +1682,7 @@ static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm) | |||
| 1682 | int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) | 1682 | int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm) |
| 1683 | { | 1683 | { |
| 1684 | snd_pcm_t *pcm; | 1684 | snd_pcm_t *pcm; |
| 1685 | snd_kcontrol_t *kctl; | ||
| 1685 | int err; | 1686 | int err; |
| 1686 | 1687 | ||
| 1687 | if (rpcm) | 1688 | if (rpcm) |
| @@ -1714,7 +1715,11 @@ int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm | |||
| 1714 | emu->efx_voices_mask[0] = 0xffff0000; | 1715 | emu->efx_voices_mask[0] = 0xffff0000; |
| 1715 | emu->efx_voices_mask[1] = 0; | 1716 | emu->efx_voices_mask[1] = 0; |
| 1716 | } | 1717 | } |
| 1717 | snd_ctl_add(emu->card, snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu)); | 1718 | kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); |
| 1719 | if (!kctl) | ||
| 1720 | return -ENOMEM; | ||
| 1721 | kctl->id.device = device; | ||
| 1722 | snd_ctl_add(emu->card, kctl); | ||
| 1718 | 1723 | ||
| 1719 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); | 1724 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024); |
| 1720 | 1725 | ||
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 78a81f3912a1..f06b95f41a1d 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
| @@ -1444,7 +1444,7 @@ static int snd_es1371_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 1444 | 1444 | ||
| 1445 | /* spdif controls */ | 1445 | /* spdif controls */ |
| 1446 | static snd_kcontrol_new_t snd_es1371_mixer_spdif[] __devinitdata = { | 1446 | static snd_kcontrol_new_t snd_es1371_mixer_spdif[] __devinitdata = { |
| 1447 | ES1371_SPDIF("IEC958 Playback Switch"), | 1447 | ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)), |
| 1448 | { | 1448 | { |
| 1449 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1449 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1450 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), | 1450 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index ff10e637a95e..36b2f62e8573 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
| @@ -1155,10 +1155,10 @@ FM801_SINGLE("FM Playback Switch", FM801_FM_VOL, 15, 1, 1), | |||
| 1155 | static snd_kcontrol_new_t snd_fm801_controls_multi[] __devinitdata = { | 1155 | static snd_kcontrol_new_t snd_fm801_controls_multi[] __devinitdata = { |
| 1156 | FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0), | 1156 | FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0), |
| 1157 | FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0), | 1157 | FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0), |
| 1158 | FM801_SINGLE("IEC958 Capture Switch", FM801_I2S_MODE, 8, 1, 0), | 1158 | FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0), |
| 1159 | FM801_SINGLE("IEC958 Raw Data Playback Switch", FM801_I2S_MODE, 9, 1, 0), | 1159 | FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",PLAYBACK,SWITCH), FM801_I2S_MODE, 9, 1, 0), |
| 1160 | FM801_SINGLE("IEC958 Raw Data Capture Switch", FM801_I2S_MODE, 10, 1, 0), | 1160 | FM801_SINGLE(SNDRV_CTL_NAME_IEC958("Raw Data ",CAPTURE,SWITCH), FM801_I2S_MODE, 10, 1, 0), |
| 1161 | FM801_SINGLE("IEC958 Playback Switch", FM801_GEN_CTRL, 2, 1, 0), | 1161 | FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), FM801_GEN_CTRL, 2, 1, 0), |
| 1162 | }; | 1162 | }; |
| 1163 | 1163 | ||
| 1164 | static void snd_fm801_mixer_free_ac97_bus(ac97_bus_t *bus) | 1164 | static void snd_fm801_mixer_free_ac97_bus(ac97_bus_t *bus) |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index bd8cb33c4fb4..ddfb5ff7fb8f 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | snd-hda-intel-objs := hda_intel.o | 1 | snd-hda-intel-objs := hda_intel.o |
| 2 | snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o | 2 | snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o |
| 3 | ifdef CONFIG_PROC_FS | 3 | ifdef CONFIG_PROC_FS |
| 4 | snd-hda-codec-objs += hda_proc.o | 4 | snd-hda-codec-objs += hda_proc.o |
| 5 | endif | 5 | endif |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e2cf02387289..20f7762f7144 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -432,22 +432,26 @@ void snd_hda_get_codec_name(struct hda_codec *codec, | |||
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | /* | 434 | /* |
| 435 | * look for an AFG node | 435 | * look for an AFG and MFG nodes |
| 436 | * | ||
| 437 | * return 0 if not found | ||
| 438 | */ | 436 | */ |
| 439 | static int look_for_afg_node(struct hda_codec *codec) | 437 | static void setup_fg_nodes(struct hda_codec *codec) |
| 440 | { | 438 | { |
| 441 | int i, total_nodes; | 439 | int i, total_nodes; |
| 442 | hda_nid_t nid; | 440 | hda_nid_t nid; |
| 443 | 441 | ||
| 444 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); | 442 | total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); |
| 445 | for (i = 0; i < total_nodes; i++, nid++) { | 443 | for (i = 0; i < total_nodes; i++, nid++) { |
| 446 | if ((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff) == | 444 | switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { |
| 447 | AC_GRP_AUDIO_FUNCTION) | 445 | case AC_GRP_AUDIO_FUNCTION: |
| 448 | return nid; | 446 | codec->afg = nid; |
| 447 | break; | ||
| 448 | case AC_GRP_MODEM_FUNCTION: | ||
| 449 | codec->mfg = nid; | ||
| 450 | break; | ||
| 451 | default: | ||
| 452 | break; | ||
| 453 | } | ||
| 449 | } | 454 | } |
| 450 | return 0; | ||
| 451 | } | 455 | } |
| 452 | 456 | ||
| 453 | /* | 457 | /* |
| @@ -507,10 +511,9 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
| 507 | codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); | 511 | codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); |
| 508 | codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); | 512 | codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); |
| 509 | 513 | ||
| 510 | /* FIXME: support for multiple AFGs? */ | 514 | setup_fg_nodes(codec); |
| 511 | codec->afg = look_for_afg_node(codec); | 515 | if (! codec->afg && ! codec->mfg) { |
| 512 | if (! codec->afg) { | 516 | snd_printdd("hda_codec: no AFG or MFG node found\n"); |
| 513 | snd_printdd("hda_codec: no AFG node found\n"); | ||
| 514 | snd_hda_codec_free(codec); | 517 | snd_hda_codec_free(codec); |
| 515 | return -ENODEV; | 518 | return -ENODEV; |
| 516 | } | 519 | } |
| @@ -749,12 +752,14 @@ int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t | |||
| 749 | long *valp = ucontrol->value.integer.value; | 752 | long *valp = ucontrol->value.integer.value; |
| 750 | int change = 0; | 753 | int change = 0; |
| 751 | 754 | ||
| 752 | if (chs & 1) | 755 | if (chs & 1) { |
| 753 | change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, | 756 | change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, |
| 754 | 0x7f, *valp); | 757 | 0x7f, *valp); |
| 758 | valp++; | ||
| 759 | } | ||
| 755 | if (chs & 2) | 760 | if (chs & 2) |
| 756 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, | 761 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, |
| 757 | 0x7f, valp[1]); | 762 | 0x7f, *valp); |
| 758 | return change; | 763 | return change; |
| 759 | } | 764 | } |
| 760 | 765 | ||
| @@ -796,12 +801,15 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t | |||
| 796 | long *valp = ucontrol->value.integer.value; | 801 | long *valp = ucontrol->value.integer.value; |
| 797 | int change = 0; | 802 | int change = 0; |
| 798 | 803 | ||
| 799 | if (chs & 1) | 804 | if (chs & 1) { |
| 800 | change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, | 805 | change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, |
| 801 | 0x80, *valp ? 0 : 0x80); | 806 | 0x80, *valp ? 0 : 0x80); |
| 807 | valp++; | ||
| 808 | } | ||
| 802 | if (chs & 2) | 809 | if (chs & 2) |
| 803 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, | 810 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, |
| 804 | 0x80, valp[1] ? 0 : 0x80); | 811 | 0x80, *valp ? 0 : 0x80); |
| 812 | |||
| 805 | return change; | 813 | return change; |
| 806 | } | 814 | } |
| 807 | 815 | ||
| @@ -1155,8 +1163,16 @@ int snd_hda_build_controls(struct hda_bus *bus) | |||
| 1155 | /* | 1163 | /* |
| 1156 | * stream formats | 1164 | * stream formats |
| 1157 | */ | 1165 | */ |
| 1158 | static unsigned int rate_bits[][3] = { | 1166 | struct hda_rate_tbl { |
| 1167 | unsigned int hz; | ||
| 1168 | unsigned int alsa_bits; | ||
| 1169 | unsigned int hda_fmt; | ||
| 1170 | }; | ||
| 1171 | |||
| 1172 | static struct hda_rate_tbl rate_bits[] = { | ||
| 1159 | /* rate in Hz, ALSA rate bitmask, HDA format value */ | 1173 | /* rate in Hz, ALSA rate bitmask, HDA format value */ |
| 1174 | |||
| 1175 | /* autodetected value used in snd_hda_query_supported_pcm */ | ||
| 1160 | { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ | 1176 | { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ |
| 1161 | { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ | 1177 | { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ |
| 1162 | { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ | 1178 | { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ |
| @@ -1168,7 +1184,11 @@ static unsigned int rate_bits[][3] = { | |||
| 1168 | { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ | 1184 | { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ |
| 1169 | { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ | 1185 | { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ |
| 1170 | { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ | 1186 | { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ |
| 1171 | { 0 } | 1187 | |
| 1188 | /* not autodetected value */ | ||
| 1189 | { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ | ||
| 1190 | |||
| 1191 | { 0 } /* terminator */ | ||
| 1172 | }; | 1192 | }; |
| 1173 | 1193 | ||
| 1174 | /** | 1194 | /** |
| @@ -1190,12 +1210,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, | |||
| 1190 | int i; | 1210 | int i; |
| 1191 | unsigned int val = 0; | 1211 | unsigned int val = 0; |
| 1192 | 1212 | ||
| 1193 | for (i = 0; rate_bits[i][0]; i++) | 1213 | for (i = 0; rate_bits[i].hz; i++) |
| 1194 | if (rate_bits[i][0] == rate) { | 1214 | if (rate_bits[i].hz == rate) { |
| 1195 | val = rate_bits[i][2]; | 1215 | val = rate_bits[i].hda_fmt; |
| 1196 | break; | 1216 | break; |
| 1197 | } | 1217 | } |
| 1198 | if (! rate_bits[i][0]) { | 1218 | if (! rate_bits[i].hz) { |
| 1199 | snd_printdd("invalid rate %d\n", rate); | 1219 | snd_printdd("invalid rate %d\n", rate); |
| 1200 | return 0; | 1220 | return 0; |
| 1201 | } | 1221 | } |
| @@ -1258,9 +1278,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
| 1258 | 1278 | ||
| 1259 | if (ratesp) { | 1279 | if (ratesp) { |
| 1260 | u32 rates = 0; | 1280 | u32 rates = 0; |
| 1261 | for (i = 0; rate_bits[i][0]; i++) { | 1281 | for (i = 0; rate_bits[i].hz; i++) { |
| 1262 | if (val & (1 << i)) | 1282 | if (val & (1 << i)) |
| 1263 | rates |= rate_bits[i][1]; | 1283 | rates |= rate_bits[i].alsa_bits; |
| 1264 | } | 1284 | } |
| 1265 | *ratesp = rates; | 1285 | *ratesp = rates; |
| 1266 | } | 1286 | } |
| @@ -1352,13 +1372,13 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
| 1352 | } | 1372 | } |
| 1353 | 1373 | ||
| 1354 | rate = format & 0xff00; | 1374 | rate = format & 0xff00; |
| 1355 | for (i = 0; rate_bits[i][0]; i++) | 1375 | for (i = 0; rate_bits[i].hz; i++) |
| 1356 | if (rate_bits[i][2] == rate) { | 1376 | if (rate_bits[i].hda_fmt == rate) { |
| 1357 | if (val & (1 << i)) | 1377 | if (val & (1 << i)) |
| 1358 | break; | 1378 | break; |
| 1359 | return 0; | 1379 | return 0; |
| 1360 | } | 1380 | } |
| 1361 | if (! rate_bits[i][0]) | 1381 | if (! rate_bits[i].hz) |
| 1362 | return 0; | 1382 | return 0; |
| 1363 | 1383 | ||
| 1364 | stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 1384 | stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); |
| @@ -1541,8 +1561,11 @@ int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_c | |||
| 1541 | for (c = tbl; c->modelname || c->pci_subvendor; c++) { | 1561 | for (c = tbl; c->modelname || c->pci_subvendor; c++) { |
| 1542 | if (c->pci_subvendor == subsystem_vendor && | 1562 | if (c->pci_subvendor == subsystem_vendor && |
| 1543 | (! c->pci_subdevice /* all match */|| | 1563 | (! c->pci_subdevice /* all match */|| |
| 1544 | (c->pci_subdevice == subsystem_device))) | 1564 | (c->pci_subdevice == subsystem_device))) { |
| 1565 | snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n", | ||
| 1566 | subsystem_vendor, subsystem_device, c->config); | ||
| 1545 | return c->config; | 1567 | return c->config; |
| 1568 | } | ||
| 1546 | } | 1569 | } |
| 1547 | } | 1570 | } |
| 1548 | return -1; | 1571 | return -1; |
| @@ -1803,11 +1826,25 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
| 1803 | cfg->line_out_pins[j] = nid; | 1826 | cfg->line_out_pins[j] = nid; |
| 1804 | } | 1827 | } |
| 1805 | 1828 | ||
| 1806 | /* Swap surround and CLFE: the association order is front/CLFE/surr/back */ | 1829 | /* Reorder the surround channels |
| 1807 | if (cfg->line_outs >= 3) { | 1830 | * ALSA sequence is front/surr/clfe/side |
| 1831 | * HDA sequence is: | ||
| 1832 | * 4-ch: front/surr => OK as it is | ||
| 1833 | * 6-ch: front/clfe/surr | ||
| 1834 | * 8-ch: front/clfe/side/surr | ||
| 1835 | */ | ||
| 1836 | switch (cfg->line_outs) { | ||
| 1837 | case 3: | ||
| 1808 | nid = cfg->line_out_pins[1]; | 1838 | nid = cfg->line_out_pins[1]; |
| 1809 | cfg->line_out_pins[1] = cfg->line_out_pins[2]; | 1839 | cfg->line_out_pins[1] = cfg->line_out_pins[2]; |
| 1810 | cfg->line_out_pins[2] = nid; | 1840 | cfg->line_out_pins[2] = nid; |
| 1841 | break; | ||
| 1842 | case 4: | ||
| 1843 | nid = cfg->line_out_pins[1]; | ||
| 1844 | cfg->line_out_pins[1] = cfg->line_out_pins[3]; | ||
| 1845 | cfg->line_out_pins[3] = cfg->line_out_pins[2]; | ||
| 1846 | cfg->line_out_pins[2] = nid; | ||
| 1847 | break; | ||
| 1811 | } | 1848 | } |
| 1812 | 1849 | ||
| 1813 | return 0; | 1850 | return 0; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index dd0d99d2ad27..63a29a8a2860 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -514,6 +514,7 @@ struct hda_codec { | |||
| 514 | struct list_head list; /* list point */ | 514 | struct list_head list; /* list point */ |
| 515 | 515 | ||
| 516 | hda_nid_t afg; /* AFG node id */ | 516 | hda_nid_t afg; /* AFG node id */ |
| 517 | hda_nid_t mfg; /* MFG node id */ | ||
| 517 | 518 | ||
| 518 | /* ids */ | 519 | /* ids */ |
| 519 | u32 vendor_id; | 520 | u32 vendor_id; |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 2d046abb5911..1229227af5b5 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
| @@ -881,6 +881,11 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec) | |||
| 881 | struct hda_gspec *spec; | 881 | struct hda_gspec *spec; |
| 882 | int err; | 882 | int err; |
| 883 | 883 | ||
| 884 | if(!codec->afg) { | ||
| 885 | snd_printdd("hda_generic: no generic modem yet\n"); | ||
| 886 | return -ENODEV; | ||
| 887 | } | ||
| 888 | |||
| 884 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 889 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); |
| 885 | if (spec == NULL) { | 890 | if (spec == NULL) { |
| 886 | printk(KERN_ERR "hda_generic: can't allocate spec\n"); | 891 | printk(KERN_ERR "hda_generic: can't allocate spec\n"); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 288ab0764830..15107df1f490 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -71,7 +71,9 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
| 71 | "{Intel, ESB2}," | 71 | "{Intel, ESB2}," |
| 72 | "{ATI, SB450}," | 72 | "{ATI, SB450}," |
| 73 | "{VIA, VT8251}," | 73 | "{VIA, VT8251}," |
| 74 | "{VIA, VT8237A}}"); | 74 | "{VIA, VT8237A}," |
| 75 | "{SiS, SIS966}," | ||
| 76 | "{ULI, M5461}}"); | ||
| 75 | MODULE_DESCRIPTION("Intel HDA driver"); | 77 | MODULE_DESCRIPTION("Intel HDA driver"); |
| 76 | 78 | ||
| 77 | #define SFX "hda-intel: " | 79 | #define SFX "hda-intel: " |
| @@ -141,9 +143,24 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
| 141 | */ | 143 | */ |
| 142 | 144 | ||
| 143 | /* max number of SDs */ | 145 | /* max number of SDs */ |
| 144 | #define MAX_ICH6_DEV 8 | 146 | /* ICH, ATI and VIA have 4 playback and 4 capture */ |
| 147 | #define ICH6_CAPTURE_INDEX 0 | ||
| 148 | #define ICH6_NUM_CAPTURE 4 | ||
| 149 | #define ICH6_PLAYBACK_INDEX 4 | ||
| 150 | #define ICH6_NUM_PLAYBACK 4 | ||
| 151 | |||
| 152 | /* ULI has 6 playback and 5 capture */ | ||
| 153 | #define ULI_CAPTURE_INDEX 0 | ||
| 154 | #define ULI_NUM_CAPTURE 5 | ||
| 155 | #define ULI_PLAYBACK_INDEX 5 | ||
| 156 | #define ULI_NUM_PLAYBACK 6 | ||
| 157 | |||
| 158 | /* this number is statically defined for simplicity */ | ||
| 159 | #define MAX_AZX_DEV 16 | ||
| 160 | |||
| 145 | /* max number of fragments - we may use more if allocating more pages for BDL */ | 161 | /* max number of fragments - we may use more if allocating more pages for BDL */ |
| 146 | #define AZX_MAX_FRAG (PAGE_SIZE / (MAX_ICH6_DEV * 16)) | 162 | #define BDL_SIZE PAGE_ALIGN(8192) |
| 163 | #define AZX_MAX_FRAG (BDL_SIZE / (MAX_AZX_DEV * 16)) | ||
| 147 | /* max buffer size - no h/w limit, you can increase as you like */ | 164 | /* max buffer size - no h/w limit, you can increase as you like */ |
| 148 | #define AZX_MAX_BUF_SIZE (1024*1024*1024) | 165 | #define AZX_MAX_BUF_SIZE (1024*1024*1024) |
| 149 | /* max number of PCM devics per card */ | 166 | /* max number of PCM devics per card */ |
| @@ -200,7 +217,6 @@ enum { | |||
| 200 | }; | 217 | }; |
| 201 | 218 | ||
| 202 | /* Defines for ATI HD Audio support in SB450 south bridge */ | 219 | /* Defines for ATI HD Audio support in SB450 south bridge */ |
| 203 | #define ATI_SB450_HDAUDIO_PCI_DEVICE_ID 0x437b | ||
| 204 | #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 | 220 | #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 |
| 205 | #define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 | 221 | #define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 |
| 206 | 222 | ||
| @@ -258,6 +274,14 @@ struct snd_azx { | |||
| 258 | snd_card_t *card; | 274 | snd_card_t *card; |
| 259 | struct pci_dev *pci; | 275 | struct pci_dev *pci; |
| 260 | 276 | ||
| 277 | /* chip type specific */ | ||
| 278 | int driver_type; | ||
| 279 | int playback_streams; | ||
| 280 | int playback_index_offset; | ||
| 281 | int capture_streams; | ||
| 282 | int capture_index_offset; | ||
| 283 | int num_streams; | ||
| 284 | |||
| 261 | /* pci resources */ | 285 | /* pci resources */ |
| 262 | unsigned long addr; | 286 | unsigned long addr; |
| 263 | void __iomem *remap_addr; | 287 | void __iomem *remap_addr; |
| @@ -267,8 +291,8 @@ struct snd_azx { | |||
| 267 | spinlock_t reg_lock; | 291 | spinlock_t reg_lock; |
| 268 | struct semaphore open_mutex; | 292 | struct semaphore open_mutex; |
| 269 | 293 | ||
| 270 | /* streams */ | 294 | /* streams (x num_streams) */ |
| 271 | azx_dev_t azx_dev[MAX_ICH6_DEV]; | 295 | azx_dev_t *azx_dev; |
| 272 | 296 | ||
| 273 | /* PCM */ | 297 | /* PCM */ |
| 274 | unsigned int pcm_devs; | 298 | unsigned int pcm_devs; |
| @@ -292,6 +316,23 @@ struct snd_azx { | |||
| 292 | unsigned int initialized: 1; | 316 | unsigned int initialized: 1; |
| 293 | }; | 317 | }; |
| 294 | 318 | ||
| 319 | /* driver types */ | ||
| 320 | enum { | ||
| 321 | AZX_DRIVER_ICH, | ||
| 322 | AZX_DRIVER_ATI, | ||
| 323 | AZX_DRIVER_VIA, | ||
| 324 | AZX_DRIVER_SIS, | ||
| 325 | AZX_DRIVER_ULI, | ||
| 326 | }; | ||
| 327 | |||
| 328 | static char *driver_short_names[] __devinitdata = { | ||
| 329 | [AZX_DRIVER_ICH] = "HDA Intel", | ||
| 330 | [AZX_DRIVER_ATI] = "HDA ATI SB", | ||
| 331 | [AZX_DRIVER_VIA] = "HDA VIA VT82xx", | ||
| 332 | [AZX_DRIVER_SIS] = "HDA SIS966", | ||
| 333 | [AZX_DRIVER_ULI] = "HDA ULI M5461" | ||
| 334 | }; | ||
| 335 | |||
| 295 | /* | 336 | /* |
| 296 | * macros for easy use | 337 | * macros for easy use |
| 297 | */ | 338 | */ |
| @@ -360,6 +401,8 @@ static void azx_init_cmd_io(azx_t *chip) | |||
| 360 | azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); | 401 | azx_writel(chip, CORBLBASE, (u32)chip->corb.addr); |
| 361 | azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr)); | 402 | azx_writel(chip, CORBUBASE, upper_32bit(chip->corb.addr)); |
| 362 | 403 | ||
| 404 | /* set the corb size to 256 entries (ULI requires explicitly) */ | ||
| 405 | azx_writeb(chip, CORBSIZE, 0x02); | ||
| 363 | /* set the corb write pointer to 0 */ | 406 | /* set the corb write pointer to 0 */ |
| 364 | azx_writew(chip, CORBWP, 0); | 407 | azx_writew(chip, CORBWP, 0); |
| 365 | /* reset the corb hw read pointer */ | 408 | /* reset the corb hw read pointer */ |
| @@ -373,6 +416,8 @@ static void azx_init_cmd_io(azx_t *chip) | |||
| 373 | azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); | 416 | azx_writel(chip, RIRBLBASE, (u32)chip->rirb.addr); |
| 374 | azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr)); | 417 | azx_writel(chip, RIRBUBASE, upper_32bit(chip->rirb.addr)); |
| 375 | 418 | ||
| 419 | /* set the rirb size to 256 entries (ULI requires explicitly) */ | ||
| 420 | azx_writeb(chip, RIRBSIZE, 0x02); | ||
| 376 | /* reset the rirb hw write pointer */ | 421 | /* reset the rirb hw write pointer */ |
| 377 | azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR); | 422 | azx_writew(chip, RIRBWP, ICH6_RBRWP_CLR); |
| 378 | /* set N=1, get RIRB response interrupt for new entry */ | 423 | /* set N=1, get RIRB response interrupt for new entry */ |
| @@ -596,7 +641,7 @@ static void azx_int_disable(azx_t *chip) | |||
| 596 | int i; | 641 | int i; |
| 597 | 642 | ||
| 598 | /* disable interrupts in stream descriptor */ | 643 | /* disable interrupts in stream descriptor */ |
| 599 | for (i = 0; i < MAX_ICH6_DEV; i++) { | 644 | for (i = 0; i < chip->num_streams; i++) { |
| 600 | azx_dev_t *azx_dev = &chip->azx_dev[i]; | 645 | azx_dev_t *azx_dev = &chip->azx_dev[i]; |
| 601 | azx_sd_writeb(azx_dev, SD_CTL, | 646 | azx_sd_writeb(azx_dev, SD_CTL, |
| 602 | azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK); | 647 | azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK); |
| @@ -616,7 +661,7 @@ static void azx_int_clear(azx_t *chip) | |||
| 616 | int i; | 661 | int i; |
| 617 | 662 | ||
| 618 | /* clear stream status */ | 663 | /* clear stream status */ |
| 619 | for (i = 0; i < MAX_ICH6_DEV; i++) { | 664 | for (i = 0; i < chip->num_streams; i++) { |
| 620 | azx_dev_t *azx_dev = &chip->azx_dev[i]; | 665 | azx_dev_t *azx_dev = &chip->azx_dev[i]; |
| 621 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 666 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
| 622 | } | 667 | } |
| @@ -686,8 +731,7 @@ static void azx_init_chip(azx_t *chip) | |||
| 686 | } | 731 | } |
| 687 | 732 | ||
| 688 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ | 733 | /* For ATI SB450 azalia HD audio, we need to enable snoop */ |
| 689 | if (chip->pci->vendor == PCI_VENDOR_ID_ATI && | 734 | if (chip->driver_type == AZX_DRIVER_ATI) { |
| 690 | chip->pci->device == ATI_SB450_HDAUDIO_PCI_DEVICE_ID) { | ||
| 691 | pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 735 | pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, |
| 692 | &ati_misc_cntl2); | 736 | &ati_misc_cntl2); |
| 693 | pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 737 | pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, |
| @@ -714,7 +758,7 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
| 714 | return IRQ_NONE; | 758 | return IRQ_NONE; |
| 715 | } | 759 | } |
| 716 | 760 | ||
| 717 | for (i = 0; i < MAX_ICH6_DEV; i++) { | 761 | for (i = 0; i < chip->num_streams; i++) { |
| 718 | azx_dev = &chip->azx_dev[i]; | 762 | azx_dev = &chip->azx_dev[i]; |
| 719 | if (status & azx_dev->sd_int_sta_mask) { | 763 | if (status & azx_dev->sd_int_sta_mask) { |
| 720 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 764 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
| @@ -879,9 +923,15 @@ static int __devinit azx_codec_create(azx_t *chip, const char *model) | |||
| 879 | /* assign a stream for the PCM */ | 923 | /* assign a stream for the PCM */ |
| 880 | static inline azx_dev_t *azx_assign_device(azx_t *chip, int stream) | 924 | static inline azx_dev_t *azx_assign_device(azx_t *chip, int stream) |
| 881 | { | 925 | { |
| 882 | int dev, i; | 926 | int dev, i, nums; |
| 883 | dev = stream == SNDRV_PCM_STREAM_PLAYBACK ? 4 : 0; | 927 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 884 | for (i = 0; i < 4; i++, dev++) | 928 | dev = chip->playback_index_offset; |
| 929 | nums = chip->playback_streams; | ||
| 930 | } else { | ||
| 931 | dev = chip->capture_index_offset; | ||
| 932 | nums = chip->capture_streams; | ||
| 933 | } | ||
| 934 | for (i = 0; i < nums; i++, dev++) | ||
| 885 | if (! chip->azx_dev[dev].opened) { | 935 | if (! chip->azx_dev[dev].opened) { |
| 886 | chip->azx_dev[dev].opened = 1; | 936 | chip->azx_dev[dev].opened = 1; |
| 887 | return &chip->azx_dev[dev]; | 937 | return &chip->azx_dev[dev]; |
| @@ -899,8 +949,8 @@ static snd_pcm_hardware_t azx_pcm_hw = { | |||
| 899 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 949 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 900 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 950 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 901 | SNDRV_PCM_INFO_MMAP_VALID | | 951 | SNDRV_PCM_INFO_MMAP_VALID | |
| 902 | SNDRV_PCM_INFO_PAUSE | | 952 | SNDRV_PCM_INFO_PAUSE /*|*/ |
| 903 | SNDRV_PCM_INFO_RESUME), | 953 | /*SNDRV_PCM_INFO_RESUME*/), |
| 904 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 954 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 905 | .rates = SNDRV_PCM_RATE_48000, | 955 | .rates = SNDRV_PCM_RATE_48000, |
| 906 | .rate_min = 48000, | 956 | .rate_min = 48000, |
| @@ -1049,6 +1099,7 @@ static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 1049 | azx_dev->running = 1; | 1099 | azx_dev->running = 1; |
| 1050 | break; | 1100 | break; |
| 1051 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 1101 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 1102 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 1052 | case SNDRV_PCM_TRIGGER_STOP: | 1103 | case SNDRV_PCM_TRIGGER_STOP: |
| 1053 | azx_stream_stop(chip, azx_dev); | 1104 | azx_stream_stop(chip, azx_dev); |
| 1054 | azx_dev->running = 0; | 1105 | azx_dev->running = 0; |
| @@ -1058,6 +1109,7 @@ static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 1058 | } | 1109 | } |
| 1059 | spin_unlock(&chip->reg_lock); | 1110 | spin_unlock(&chip->reg_lock); |
| 1060 | if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH || | 1111 | if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH || |
| 1112 | cmd == SNDRV_PCM_TRIGGER_SUSPEND || | ||
| 1061 | cmd == SNDRV_PCM_TRIGGER_STOP) { | 1113 | cmd == SNDRV_PCM_TRIGGER_STOP) { |
| 1062 | int timeout = 5000; | 1114 | int timeout = 5000; |
| 1063 | while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout) | 1115 | while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout) |
| @@ -1136,6 +1188,7 @@ static int __devinit create_codec_pcm(azx_t *chip, struct hda_codec *codec, | |||
| 1136 | snd_dma_pci_data(chip->pci), | 1188 | snd_dma_pci_data(chip->pci), |
| 1137 | 1024 * 64, 1024 * 128); | 1189 | 1024 * 64, 1024 * 128); |
| 1138 | chip->pcm[pcm_dev] = pcm; | 1190 | chip->pcm[pcm_dev] = pcm; |
| 1191 | chip->pcm_devs = pcm_dev + 1; | ||
| 1139 | 1192 | ||
| 1140 | return 0; | 1193 | return 0; |
| 1141 | } | 1194 | } |
| @@ -1186,7 +1239,7 @@ static int __devinit azx_init_stream(azx_t *chip) | |||
| 1186 | /* initialize each stream (aka device) | 1239 | /* initialize each stream (aka device) |
| 1187 | * assign the starting bdl address to each stream (device) and initialize | 1240 | * assign the starting bdl address to each stream (device) and initialize |
| 1188 | */ | 1241 | */ |
| 1189 | for (i = 0; i < MAX_ICH6_DEV; i++) { | 1242 | for (i = 0; i < chip->num_streams; i++) { |
| 1190 | unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4); | 1243 | unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4); |
| 1191 | azx_dev_t *azx_dev = &chip->azx_dev[i]; | 1244 | azx_dev_t *azx_dev = &chip->azx_dev[i]; |
| 1192 | azx_dev->bdl = (u32 *)(chip->bdl.area + off); | 1245 | azx_dev->bdl = (u32 *)(chip->bdl.area + off); |
| @@ -1245,7 +1298,7 @@ static int azx_free(azx_t *chip) | |||
| 1245 | if (chip->initialized) { | 1298 | if (chip->initialized) { |
| 1246 | int i; | 1299 | int i; |
| 1247 | 1300 | ||
| 1248 | for (i = 0; i < MAX_ICH6_DEV; i++) | 1301 | for (i = 0; i < chip->num_streams; i++) |
| 1249 | azx_stream_stop(chip, &chip->azx_dev[i]); | 1302 | azx_stream_stop(chip, &chip->azx_dev[i]); |
| 1250 | 1303 | ||
| 1251 | /* disable interrupts */ | 1304 | /* disable interrupts */ |
| @@ -1261,10 +1314,10 @@ static int azx_free(azx_t *chip) | |||
| 1261 | 1314 | ||
| 1262 | /* wait a little for interrupts to finish */ | 1315 | /* wait a little for interrupts to finish */ |
| 1263 | msleep(1); | 1316 | msleep(1); |
| 1264 | |||
| 1265 | iounmap(chip->remap_addr); | ||
| 1266 | } | 1317 | } |
| 1267 | 1318 | ||
| 1319 | if (chip->remap_addr) | ||
| 1320 | iounmap(chip->remap_addr); | ||
| 1268 | if (chip->irq >= 0) | 1321 | if (chip->irq >= 0) |
| 1269 | free_irq(chip->irq, (void*)chip); | 1322 | free_irq(chip->irq, (void*)chip); |
| 1270 | 1323 | ||
| @@ -1276,6 +1329,7 @@ static int azx_free(azx_t *chip) | |||
| 1276 | snd_dma_free_pages(&chip->posbuf); | 1329 | snd_dma_free_pages(&chip->posbuf); |
| 1277 | pci_release_regions(chip->pci); | 1330 | pci_release_regions(chip->pci); |
| 1278 | pci_disable_device(chip->pci); | 1331 | pci_disable_device(chip->pci); |
| 1332 | kfree(chip->azx_dev); | ||
| 1279 | kfree(chip); | 1333 | kfree(chip); |
| 1280 | 1334 | ||
| 1281 | return 0; | 1335 | return 0; |
| @@ -1290,7 +1344,8 @@ static int azx_dev_free(snd_device_t *device) | |||
| 1290 | * constructor | 1344 | * constructor |
| 1291 | */ | 1345 | */ |
| 1292 | static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | 1346 | static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, |
| 1293 | int posfix, azx_t **rchip) | 1347 | int posfix, int driver_type, |
| 1348 | azx_t **rchip) | ||
| 1294 | { | 1349 | { |
| 1295 | azx_t *chip; | 1350 | azx_t *chip; |
| 1296 | int err = 0; | 1351 | int err = 0; |
| @@ -1316,9 +1371,20 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | |||
| 1316 | chip->card = card; | 1371 | chip->card = card; |
| 1317 | chip->pci = pci; | 1372 | chip->pci = pci; |
| 1318 | chip->irq = -1; | 1373 | chip->irq = -1; |
| 1374 | chip->driver_type = driver_type; | ||
| 1319 | 1375 | ||
| 1320 | chip->position_fix = posfix; | 1376 | chip->position_fix = posfix; |
| 1321 | 1377 | ||
| 1378 | #if BITS_PER_LONG != 64 | ||
| 1379 | /* Fix up base address on ULI M5461 */ | ||
| 1380 | if (chip->driver_type == AZX_DRIVER_ULI) { | ||
| 1381 | u16 tmp3; | ||
| 1382 | pci_read_config_word(pci, 0x40, &tmp3); | ||
| 1383 | pci_write_config_word(pci, 0x40, tmp3 | 0x10); | ||
| 1384 | pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0); | ||
| 1385 | } | ||
| 1386 | #endif | ||
| 1387 | |||
| 1322 | if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) { | 1388 | if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) { |
| 1323 | kfree(chip); | 1389 | kfree(chip); |
| 1324 | pci_disable_device(pci); | 1390 | pci_disable_device(pci); |
| @@ -1344,16 +1410,37 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | |||
| 1344 | pci_set_master(pci); | 1410 | pci_set_master(pci); |
| 1345 | synchronize_irq(chip->irq); | 1411 | synchronize_irq(chip->irq); |
| 1346 | 1412 | ||
| 1413 | switch (chip->driver_type) { | ||
| 1414 | case AZX_DRIVER_ULI: | ||
| 1415 | chip->playback_streams = ULI_NUM_PLAYBACK; | ||
| 1416 | chip->capture_streams = ULI_NUM_CAPTURE; | ||
| 1417 | chip->playback_index_offset = ULI_PLAYBACK_INDEX; | ||
| 1418 | chip->capture_index_offset = ULI_CAPTURE_INDEX; | ||
| 1419 | break; | ||
| 1420 | default: | ||
| 1421 | chip->playback_streams = ICH6_NUM_PLAYBACK; | ||
| 1422 | chip->capture_streams = ICH6_NUM_CAPTURE; | ||
| 1423 | chip->playback_index_offset = ICH6_PLAYBACK_INDEX; | ||
| 1424 | chip->capture_index_offset = ICH6_CAPTURE_INDEX; | ||
| 1425 | break; | ||
| 1426 | } | ||
| 1427 | chip->num_streams = chip->playback_streams + chip->capture_streams; | ||
| 1428 | chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL); | ||
| 1429 | if (! chip->azx_dev) { | ||
| 1430 | snd_printk(KERN_ERR "cannot malloc azx_dev\n"); | ||
| 1431 | goto errout; | ||
| 1432 | } | ||
| 1433 | |||
| 1347 | /* allocate memory for the BDL for each stream */ | 1434 | /* allocate memory for the BDL for each stream */ |
| 1348 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | 1435 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), |
| 1349 | PAGE_SIZE, &chip->bdl)) < 0) { | 1436 | BDL_SIZE, &chip->bdl)) < 0) { |
| 1350 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); | 1437 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); |
| 1351 | goto errout; | 1438 | goto errout; |
| 1352 | } | 1439 | } |
| 1353 | if (chip->position_fix == POS_FIX_POSBUF) { | 1440 | if (chip->position_fix == POS_FIX_POSBUF) { |
| 1354 | /* allocate memory for the position buffer */ | 1441 | /* allocate memory for the position buffer */ |
| 1355 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), | 1442 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), |
| 1356 | MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) { | 1443 | chip->num_streams * 8, &chip->posbuf)) < 0) { |
| 1357 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); | 1444 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); |
| 1358 | goto errout; | 1445 | goto errout; |
| 1359 | } | 1446 | } |
| @@ -1382,6 +1469,10 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, | |||
| 1382 | goto errout; | 1469 | goto errout; |
| 1383 | } | 1470 | } |
| 1384 | 1471 | ||
| 1472 | strcpy(card->driver, "HDA-Intel"); | ||
| 1473 | strcpy(card->shortname, driver_short_names[chip->driver_type]); | ||
| 1474 | sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); | ||
| 1475 | |||
| 1385 | *rchip = chip; | 1476 | *rchip = chip; |
| 1386 | return 0; | 1477 | return 0; |
| 1387 | 1478 | ||
| @@ -1410,15 +1501,12 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * | |||
| 1410 | return -ENOMEM; | 1501 | return -ENOMEM; |
| 1411 | } | 1502 | } |
| 1412 | 1503 | ||
| 1413 | if ((err = azx_create(card, pci, position_fix[dev], &chip)) < 0) { | 1504 | if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data, |
| 1505 | &chip)) < 0) { | ||
| 1414 | snd_card_free(card); | 1506 | snd_card_free(card); |
| 1415 | return err; | 1507 | return err; |
| 1416 | } | 1508 | } |
| 1417 | 1509 | ||
| 1418 | strcpy(card->driver, "HDA-Intel"); | ||
| 1419 | strcpy(card->shortname, "HDA Intel"); | ||
| 1420 | sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq); | ||
| 1421 | |||
| 1422 | /* create codec instances */ | 1510 | /* create codec instances */ |
| 1423 | if ((err = azx_codec_create(chip, model[dev])) < 0) { | 1511 | if ((err = azx_codec_create(chip, model[dev])) < 0) { |
| 1424 | snd_card_free(card); | 1512 | snd_card_free(card); |
| @@ -1459,12 +1547,13 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
| 1459 | 1547 | ||
| 1460 | /* PCI IDs */ | 1548 | /* PCI IDs */ |
| 1461 | static struct pci_device_id azx_ids[] = { | 1549 | static struct pci_device_id azx_ids[] = { |
| 1462 | { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */ | 1550 | { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */ |
| 1463 | { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */ | 1551 | { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */ |
| 1464 | { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */ | 1552 | { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */ |
| 1465 | { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ATI SB450 */ | 1553 | { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */ |
| 1466 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* VIA VT8251/VT8237A */ | 1554 | { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ |
| 1467 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ALI 5461? */ | 1555 | { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ |
| 1556 | { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ | ||
| 1468 | { 0, } | 1557 | { 0, } |
| 1469 | }; | 1558 | }; |
| 1470 | MODULE_DEVICE_TABLE(pci, azx_ids); | 1559 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h index a5de684b6944..acaef3c811b8 100644 --- a/sound/pci/hda/hda_patch.h +++ b/sound/pci/hda/hda_patch.h | |||
| @@ -10,11 +10,14 @@ extern struct hda_codec_preset snd_hda_preset_cmedia[]; | |||
| 10 | extern struct hda_codec_preset snd_hda_preset_analog[]; | 10 | extern struct hda_codec_preset snd_hda_preset_analog[]; |
| 11 | /* SigmaTel codecs */ | 11 | /* SigmaTel codecs */ |
| 12 | extern struct hda_codec_preset snd_hda_preset_sigmatel[]; | 12 | extern struct hda_codec_preset snd_hda_preset_sigmatel[]; |
| 13 | /* SiLabs 3054/3055 modem codecs */ | ||
| 14 | extern struct hda_codec_preset snd_hda_preset_si3054[]; | ||
| 13 | 15 | ||
| 14 | static const struct hda_codec_preset *hda_preset_tables[] = { | 16 | static const struct hda_codec_preset *hda_preset_tables[] = { |
| 15 | snd_hda_preset_realtek, | 17 | snd_hda_preset_realtek, |
| 16 | snd_hda_preset_cmedia, | 18 | snd_hda_preset_cmedia, |
| 17 | snd_hda_preset_analog, | 19 | snd_hda_preset_analog, |
| 18 | snd_hda_preset_sigmatel, | 20 | snd_hda_preset_sigmatel, |
| 21 | snd_hda_preset_si3054, | ||
| 19 | NULL | 22 | NULL |
| 20 | }; | 23 | }; |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2fd05bb84136..bceb83a42a38 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -572,7 +572,7 @@ static snd_kcontrol_new_t ad1983_mixers[] = { | |||
| 572 | }, | 572 | }, |
| 573 | { | 573 | { |
| 574 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 574 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 575 | .name = "IEC958 Playback Route", | 575 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
| 576 | .info = ad1983_spdif_route_info, | 576 | .info = ad1983_spdif_route_info, |
| 577 | .get = ad1983_spdif_route_get, | 577 | .get = ad1983_spdif_route_get, |
| 578 | .put = ad1983_spdif_route_put, | 578 | .put = ad1983_spdif_route_put, |
| @@ -705,7 +705,7 @@ static snd_kcontrol_new_t ad1981_mixers[] = { | |||
| 705 | /* identical with AD1983 */ | 705 | /* identical with AD1983 */ |
| 706 | { | 706 | { |
| 707 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 707 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 708 | .name = "IEC958 Playback Route", | 708 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
| 709 | .info = ad1983_spdif_route_info, | 709 | .info = ad1983_spdif_route_info, |
| 710 | .get = ad1983_spdif_route_get, | 710 | .get = ad1983_spdif_route_get, |
| 711 | .put = ad1983_spdif_route_put, | 711 | .put = ad1983_spdif_route_put, |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 86f195f19eef..07fb4f5a54b3 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
| @@ -647,6 +647,7 @@ static struct hda_board_config cmi9880_cfg_tbl[] = { | |||
| 647 | { .modelname = "min_fp", .config = CMI_MIN_FP }, | 647 | { .modelname = "min_fp", .config = CMI_MIN_FP }, |
| 648 | { .modelname = "full", .config = CMI_FULL }, | 648 | { .modelname = "full", .config = CMI_FULL }, |
| 649 | { .modelname = "full_dig", .config = CMI_FULL_DIG }, | 649 | { .modelname = "full_dig", .config = CMI_FULL_DIG }, |
| 650 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x813d, .config = CMI_FULL_DIG }, /* ASUS P5AD2 */ | ||
| 650 | { .modelname = "allout", .config = CMI_ALLOUT }, | 651 | { .modelname = "allout", .config = CMI_ALLOUT }, |
| 651 | { .modelname = "auto", .config = CMI_AUTO }, | 652 | { .modelname = "auto", .config = CMI_AUTO }, |
| 652 | {} /* terminator */ | 653 | {} /* terminator */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9b8569900787..eeb900ab79af 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -687,6 +687,12 @@ static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = { | |||
| 687 | { } /* end */ | 687 | { } /* end */ |
| 688 | }; | 688 | }; |
| 689 | 689 | ||
| 690 | /* additional mixers to alc880_asus_mixer */ | ||
| 691 | static snd_kcontrol_new_t alc880_pcbeep_mixer[] = { | ||
| 692 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), | ||
| 693 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), | ||
| 694 | { } /* end */ | ||
| 695 | }; | ||
| 690 | 696 | ||
| 691 | /* | 697 | /* |
| 692 | * build control elements | 698 | * build control elements |
| @@ -1524,6 +1530,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
| 1524 | /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ | 1530 | /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ |
| 1525 | { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, | 1531 | { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, |
| 1526 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, | 1532 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, |
| 1533 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG }, | ||
| 1527 | 1534 | ||
| 1528 | /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ | 1535 | /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ |
| 1529 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, | 1536 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, |
| @@ -1734,7 +1741,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
| 1734 | .input_mux = &alc880_capture_source, | 1741 | .input_mux = &alc880_capture_source, |
| 1735 | }, | 1742 | }, |
| 1736 | [ALC880_UNIWILL_DIG] = { | 1743 | [ALC880_UNIWILL_DIG] = { |
| 1737 | .mixers = { alc880_asus_mixer }, | 1744 | .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, |
| 1738 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, | 1745 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, |
| 1739 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | 1746 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), |
| 1740 | .dac_nids = alc880_asus_dac_nids, | 1747 | .dac_nids = alc880_asus_dac_nids, |
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c new file mode 100644 index 000000000000..b0270d1b64ce --- /dev/null +++ b/sound/pci/hda/patch_si3054.c | |||
| @@ -0,0 +1,300 @@ | |||
| 1 | /* | ||
| 2 | * Universal Interface for Intel High Definition Audio Codec | ||
| 3 | * | ||
| 4 | * HD audio interface patch for Silicon Labs 3054/5 modem codec | ||
| 5 | * | ||
| 6 | * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com> | ||
| 7 | * Takashi Iwai <tiwai@suse.de> | ||
| 8 | * | ||
| 9 | * | ||
| 10 | * This driver is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This driver is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <sound/driver.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/delay.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/pci.h> | ||
| 30 | #include <sound/core.h> | ||
| 31 | #include "hda_codec.h" | ||
| 32 | #include "hda_local.h" | ||
| 33 | |||
| 34 | |||
| 35 | /* si3054 verbs */ | ||
| 36 | #define SI3054_VERB_READ_NODE 0x900 | ||
| 37 | #define SI3054_VERB_WRITE_NODE 0x100 | ||
| 38 | |||
| 39 | /* si3054 nodes (registers) */ | ||
| 40 | #define SI3054_EXTENDED_MID 2 | ||
| 41 | #define SI3054_LINE_RATE 3 | ||
| 42 | #define SI3054_LINE_LEVEL 4 | ||
| 43 | #define SI3054_GPIO_CFG 5 | ||
| 44 | #define SI3054_GPIO_POLARITY 6 | ||
| 45 | #define SI3054_GPIO_STICKY 7 | ||
| 46 | #define SI3054_GPIO_WAKEUP 8 | ||
| 47 | #define SI3054_GPIO_STATUS 9 | ||
| 48 | #define SI3054_GPIO_CONTROL 10 | ||
| 49 | #define SI3054_MISC_AFE 11 | ||
| 50 | #define SI3054_CHIPID 12 | ||
| 51 | #define SI3054_LINE_CFG1 13 | ||
| 52 | #define SI3054_LINE_STATUS 14 | ||
| 53 | #define SI3054_DC_TERMINATION 15 | ||
| 54 | #define SI3054_LINE_CONFIG 16 | ||
| 55 | #define SI3054_CALLPROG_ATT 17 | ||
| 56 | #define SI3054_SQ_CONTROL 18 | ||
| 57 | #define SI3054_MISC_CONTROL 19 | ||
| 58 | #define SI3054_RING_CTRL1 20 | ||
| 59 | #define SI3054_RING_CTRL2 21 | ||
| 60 | |||
| 61 | /* extended MID */ | ||
| 62 | #define SI3054_MEI_READY 0xf | ||
| 63 | |||
| 64 | /* line level */ | ||
| 65 | #define SI3054_ATAG_MASK 0x00f0 | ||
| 66 | #define SI3054_DTAG_MASK 0xf000 | ||
| 67 | |||
| 68 | /* GPIO bits */ | ||
| 69 | #define SI3054_GPIO_OH 0x0001 | ||
| 70 | #define SI3054_GPIO_CID 0x0002 | ||
| 71 | |||
| 72 | /* chipid and revisions */ | ||
| 73 | #define SI3054_CHIPID_CODEC_REV_MASK 0x000f | ||
| 74 | #define SI3054_CHIPID_DAA_REV_MASK 0x00f0 | ||
| 75 | #define SI3054_CHIPID_INTERNATIONAL 0x0100 | ||
| 76 | #define SI3054_CHIPID_DAA_ID 0x0f00 | ||
| 77 | #define SI3054_CHIPID_CODEC_ID (1<<12) | ||
| 78 | |||
| 79 | /* si3054 codec registers (nodes) access macros */ | ||
| 80 | #define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0)) | ||
| 81 | #define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val)) | ||
| 82 | |||
| 83 | |||
| 84 | struct si3054_spec { | ||
| 85 | unsigned international; | ||
| 86 | struct hda_pcm pcm; | ||
| 87 | }; | ||
| 88 | |||
| 89 | |||
| 90 | /* | ||
| 91 | * Modem mixer | ||
| 92 | */ | ||
| 93 | |||
| 94 | #define PRIVATE_VALUE(reg,mask) ((reg<<16)|(mask&0xffff)) | ||
| 95 | #define PRIVATE_REG(val) ((val>>16)&0xffff) | ||
| 96 | #define PRIVATE_MASK(val) (val&0xffff) | ||
| 97 | |||
| 98 | static int si3054_switch_info(snd_kcontrol_t *kcontrol, | ||
| 99 | snd_ctl_elem_info_t *uinfo) | ||
| 100 | { | ||
| 101 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
| 102 | uinfo->count = 1; | ||
| 103 | uinfo->value.integer.min = 0; | ||
| 104 | uinfo->value.integer.max = 1; | ||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int si3054_switch_get(snd_kcontrol_t *kcontrol, | ||
| 109 | snd_ctl_elem_value_t *uvalue) | ||
| 110 | { | ||
| 111 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 112 | u16 reg = PRIVATE_REG(kcontrol->private_value); | ||
| 113 | u16 mask = PRIVATE_MASK(kcontrol->private_value); | ||
| 114 | uvalue->value.integer.value[0] = (GET_REG(codec, reg)) & mask ? 1 : 0 ; | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int si3054_switch_put(snd_kcontrol_t *kcontrol, | ||
| 119 | snd_ctl_elem_value_t *uvalue) | ||
| 120 | { | ||
| 121 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 122 | u16 reg = PRIVATE_REG(kcontrol->private_value); | ||
| 123 | u16 mask = PRIVATE_MASK(kcontrol->private_value); | ||
| 124 | if (uvalue->value.integer.value[0]) | ||
| 125 | SET_REG(codec, reg, (GET_REG(codec, reg)) | mask); | ||
| 126 | else | ||
| 127 | SET_REG(codec, reg, (GET_REG(codec, reg)) & ~mask); | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | #define SI3054_KCONTROL(kname,reg,mask) { \ | ||
| 132 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
| 133 | .name = kname, \ | ||
| 134 | .info = si3054_switch_info, \ | ||
| 135 | .get = si3054_switch_get, \ | ||
| 136 | .put = si3054_switch_put, \ | ||
| 137 | .private_value = PRIVATE_VALUE(reg,mask), \ | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | static snd_kcontrol_new_t si3054_modem_mixer[] = { | ||
| 142 | SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), | ||
| 143 | SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), | ||
| 144 | {} | ||
| 145 | }; | ||
| 146 | |||
| 147 | static int si3054_build_controls(struct hda_codec *codec) | ||
| 148 | { | ||
| 149 | return snd_hda_add_new_ctls(codec, si3054_modem_mixer); | ||
| 150 | } | ||
| 151 | |||
| 152 | |||
| 153 | /* | ||
| 154 | * PCM callbacks | ||
| 155 | */ | ||
| 156 | |||
| 157 | static int si3054_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 158 | struct hda_codec *codec, | ||
| 159 | unsigned int stream_tag, | ||
| 160 | unsigned int format, | ||
| 161 | snd_pcm_substream_t *substream) | ||
| 162 | { | ||
| 163 | u16 val; | ||
| 164 | |||
| 165 | SET_REG(codec, SI3054_LINE_RATE, substream->runtime->rate); | ||
| 166 | val = GET_REG(codec, SI3054_LINE_LEVEL); | ||
| 167 | val &= 0xff << (8 * (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)); | ||
| 168 | val |= ((stream_tag & 0xf) << 4) << (8 * (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); | ||
| 169 | SET_REG(codec, SI3054_LINE_LEVEL, val); | ||
| 170 | |||
| 171 | snd_hda_codec_setup_stream(codec, hinfo->nid, | ||
| 172 | stream_tag, 0, format); | ||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | static int si3054_pcm_open(struct hda_pcm_stream *hinfo, | ||
| 177 | struct hda_codec *codec, | ||
| 178 | snd_pcm_substream_t *substream) | ||
| 179 | { | ||
| 180 | static unsigned int rates[] = { 8000, 9600, 16000 }; | ||
| 181 | static snd_pcm_hw_constraint_list_t hw_constraints_rates = { | ||
| 182 | .count = ARRAY_SIZE(rates), | ||
| 183 | .list = rates, | ||
| 184 | .mask = 0, | ||
| 185 | }; | ||
| 186 | substream->runtime->hw.period_bytes_min = 80; | ||
| 187 | return snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
| 188 | SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates); | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 192 | static struct hda_pcm_stream si3054_pcm = { | ||
| 193 | .substreams = 1, | ||
| 194 | .channels_min = 1, | ||
| 195 | .channels_max = 1, | ||
| 196 | .nid = 0x1, | ||
| 197 | .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_KNOT, | ||
| 198 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
| 199 | .maxbps = 16, | ||
| 200 | .ops = { | ||
| 201 | .open = si3054_pcm_open, | ||
| 202 | .prepare = si3054_pcm_prepare, | ||
| 203 | }, | ||
| 204 | }; | ||
| 205 | |||
| 206 | |||
| 207 | static int si3054_build_pcms(struct hda_codec *codec) | ||
| 208 | { | ||
| 209 | struct si3054_spec *spec = codec->spec; | ||
| 210 | struct hda_pcm *info = &spec->pcm; | ||
| 211 | si3054_pcm.nid = codec->mfg; | ||
| 212 | codec->num_pcms = 1; | ||
| 213 | codec->pcm_info = info; | ||
| 214 | info->name = "Si3054 Modem"; | ||
| 215 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; | ||
| 216 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; | ||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | |||
| 221 | /* | ||
| 222 | * Init part | ||
| 223 | */ | ||
| 224 | |||
| 225 | static int si3054_init(struct hda_codec *codec) | ||
| 226 | { | ||
| 227 | struct si3054_spec *spec = codec->spec; | ||
| 228 | unsigned wait_count; | ||
| 229 | u16 val; | ||
| 230 | |||
| 231 | snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0); | ||
| 232 | snd_hda_codec_write(codec, codec->mfg, 0, AC_VERB_SET_STREAM_FORMAT, 0); | ||
| 233 | SET_REG(codec, SI3054_LINE_RATE, 9600); | ||
| 234 | SET_REG(codec, SI3054_LINE_LEVEL, SI3054_DTAG_MASK|SI3054_ATAG_MASK); | ||
| 235 | SET_REG(codec, SI3054_EXTENDED_MID, 0); | ||
| 236 | |||
| 237 | wait_count = 10; | ||
| 238 | do { | ||
| 239 | msleep(2); | ||
| 240 | val = GET_REG(codec, SI3054_EXTENDED_MID); | ||
| 241 | } while ((val & SI3054_MEI_READY) != SI3054_MEI_READY && wait_count--); | ||
| 242 | |||
| 243 | if((val&SI3054_MEI_READY) != SI3054_MEI_READY) { | ||
| 244 | snd_printk(KERN_ERR "si3054: cannot initialize. EXT MID = %04x\n", val); | ||
| 245 | return -EACCES; | ||
| 246 | } | ||
| 247 | |||
| 248 | SET_REG(codec, SI3054_GPIO_POLARITY, 0xffff); | ||
| 249 | SET_REG(codec, SI3054_GPIO_CFG, 0x0); | ||
| 250 | SET_REG(codec, SI3054_MISC_AFE, 0); | ||
| 251 | SET_REG(codec, SI3054_LINE_CFG1,0x200); | ||
| 252 | |||
| 253 | if((GET_REG(codec,SI3054_LINE_STATUS) & (1<<6)) == 0) { | ||
| 254 | snd_printd("Link Frame Detect(FDT) is not ready (line status: %04x)\n", | ||
| 255 | GET_REG(codec,SI3054_LINE_STATUS)); | ||
| 256 | } | ||
| 257 | |||
| 258 | spec->international = GET_REG(codec, SI3054_CHIPID) & SI3054_CHIPID_INTERNATIONAL; | ||
| 259 | |||
| 260 | return 0; | ||
| 261 | } | ||
| 262 | |||
| 263 | static void si3054_free(struct hda_codec *codec) | ||
| 264 | { | ||
| 265 | kfree(codec->spec); | ||
| 266 | } | ||
| 267 | |||
| 268 | |||
| 269 | /* | ||
| 270 | */ | ||
| 271 | |||
| 272 | static struct hda_codec_ops si3054_patch_ops = { | ||
| 273 | .build_controls = si3054_build_controls, | ||
| 274 | .build_pcms = si3054_build_pcms, | ||
| 275 | .init = si3054_init, | ||
| 276 | .free = si3054_free, | ||
| 277 | #ifdef CONFIG_PM | ||
| 278 | //.suspend = si3054_suspend, | ||
| 279 | .resume = si3054_init, | ||
| 280 | #endif | ||
| 281 | }; | ||
| 282 | |||
| 283 | static int patch_si3054(struct hda_codec *codec) | ||
| 284 | { | ||
| 285 | struct si3054_spec *spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | ||
| 286 | if (spec == NULL) | ||
| 287 | return -ENOMEM; | ||
| 288 | codec->spec = spec; | ||
| 289 | codec->patch_ops = si3054_patch_ops; | ||
| 290 | return 0; | ||
| 291 | } | ||
| 292 | |||
| 293 | /* | ||
| 294 | * patch entries | ||
| 295 | */ | ||
| 296 | struct hda_codec_preset snd_hda_preset_si3054[] = { | ||
| 297 | { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, | ||
| 298 | {} | ||
| 299 | }; | ||
| 300 | |||
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index eb20f73be61a..39fbe662965d 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c | |||
| @@ -618,15 +618,15 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice) | |||
| 618 | */ | 618 | */ |
| 619 | 619 | ||
| 620 | static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata = | 620 | static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata = |
| 621 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); | 621 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); |
| 622 | static snd_kcontrol_new_t snd_ice1712_delta1010lt_wordclock_select __devinitdata = | 622 | static snd_kcontrol_new_t snd_ice1712_delta1010lt_wordclock_select __devinitdata = |
| 623 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); | 623 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); |
| 624 | static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata = | 624 | static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata = |
| 625 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); | 625 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); |
| 626 | static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata = | 626 | static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata = |
| 627 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); | 627 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); |
| 628 | static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata = | 628 | static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata = |
| 629 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); | 629 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); |
| 630 | 630 | ||
| 631 | 631 | ||
| 632 | static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice) | 632 | static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice) |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index a2545a5b26c4..b97f50d10ba3 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
| @@ -1422,7 +1422,7 @@ static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_switch __devinitdata | |||
| 1422 | 1422 | ||
| 1423 | static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = { | 1423 | static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = { |
| 1424 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1424 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1425 | .name = "IEC958 Multi Capture Switch", | 1425 | .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), |
| 1426 | .info = snd_ice1712_pro_mixer_switch_info, | 1426 | .info = snd_ice1712_pro_mixer_switch_info, |
| 1427 | .get = snd_ice1712_pro_mixer_switch_get, | 1427 | .get = snd_ice1712_pro_mixer_switch_get, |
| 1428 | .put = snd_ice1712_pro_mixer_switch_put, | 1428 | .put = snd_ice1712_pro_mixer_switch_put, |
| @@ -1441,7 +1441,7 @@ static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_volume __devinitdata | |||
| 1441 | 1441 | ||
| 1442 | static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = { | 1442 | static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = { |
| 1443 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1443 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1444 | .name = "IEC958 Multi Capture Volume", | 1444 | .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), |
| 1445 | .info = snd_ice1712_pro_mixer_volume_info, | 1445 | .info = snd_ice1712_pro_mixer_volume_info, |
| 1446 | .get = snd_ice1712_pro_mixer_volume_get, | 1446 | .get = snd_ice1712_pro_mixer_volume_get, |
| 1447 | .put = snd_ice1712_pro_mixer_volume_put, | 1447 | .put = snd_ice1712_pro_mixer_volume_put, |
| @@ -1715,7 +1715,7 @@ static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol, | |||
| 1715 | static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata = | 1715 | static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata = |
| 1716 | { | 1716 | { |
| 1717 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1717 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1718 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1718 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1719 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 1719 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), |
| 1720 | .info = snd_ice1712_spdif_info, | 1720 | .info = snd_ice1712_spdif_info, |
| 1721 | .get = snd_ice1712_spdif_maskc_get, | 1721 | .get = snd_ice1712_spdif_maskc_get, |
| @@ -1724,7 +1724,7 @@ static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata = | |||
| 1724 | static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata = | 1724 | static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata = |
| 1725 | { | 1725 | { |
| 1726 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1726 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1727 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1727 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1728 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), | 1728 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), |
| 1729 | .info = snd_ice1712_spdif_info, | 1729 | .info = snd_ice1712_spdif_info, |
| 1730 | .get = snd_ice1712_spdif_maskp_get, | 1730 | .get = snd_ice1712_spdif_maskp_get, |
| @@ -2203,7 +2203,7 @@ static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = { | |||
| 2203 | 2203 | ||
| 2204 | static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = { | 2204 | static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = { |
| 2205 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2205 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 2206 | .name = "IEC958 Playback Route", | 2206 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", |
| 2207 | .info = snd_ice1712_pro_route_info, | 2207 | .info = snd_ice1712_pro_route_info, |
| 2208 | .get = snd_ice1712_pro_route_spdif_get, | 2208 | .get = snd_ice1712_pro_route_spdif_get, |
| 2209 | .put = snd_ice1712_pro_route_spdif_put, | 2209 | .put = snd_ice1712_pro_route_spdif_put, |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 79b5f12e06fc..c7af5e5fee13 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
| @@ -1414,7 +1414,7 @@ static int snd_vt1724_spdif_maskp_get(snd_kcontrol_t * kcontrol, | |||
| 1414 | static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata = | 1414 | static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata = |
| 1415 | { | 1415 | { |
| 1416 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1416 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1417 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1417 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1418 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 1418 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), |
| 1419 | .info = snd_vt1724_spdif_info, | 1419 | .info = snd_vt1724_spdif_info, |
| 1420 | .get = snd_vt1724_spdif_maskc_get, | 1420 | .get = snd_vt1724_spdif_maskc_get, |
| @@ -1423,7 +1423,7 @@ static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata = | |||
| 1423 | static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata = | 1423 | static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata = |
| 1424 | { | 1424 | { |
| 1425 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1425 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1426 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1426 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1427 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), | 1427 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), |
| 1428 | .info = snd_vt1724_spdif_info, | 1428 | .info = snd_vt1724_spdif_info, |
| 1429 | .get = snd_vt1724_spdif_maskp_get, | 1429 | .get = snd_vt1724_spdif_maskp_get, |
| @@ -1466,7 +1466,7 @@ static snd_kcontrol_new_t snd_vt1724_spdif_switch __devinitdata = | |||
| 1466 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1466 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1467 | /* FIXME: the following conflict with IEC958 Playback Route */ | 1467 | /* FIXME: the following conflict with IEC958 Playback Route */ |
| 1468 | // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), | 1468 | // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), |
| 1469 | .name = "IEC958 Output Switch", | 1469 | .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), |
| 1470 | .info = snd_vt1724_spdif_sw_info, | 1470 | .info = snd_vt1724_spdif_sw_info, |
| 1471 | .get = snd_vt1724_spdif_sw_get, | 1471 | .get = snd_vt1724_spdif_sw_get, |
| 1472 | .put = snd_vt1724_spdif_sw_put | 1472 | .put = snd_vt1724_spdif_sw_put |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index d7af3e474432..7b548416dcef 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
| @@ -389,6 +389,7 @@ typedef struct { | |||
| 389 | struct ac97_pcm *pcm; | 389 | struct ac97_pcm *pcm; |
| 390 | int pcm_open_flag; | 390 | int pcm_open_flag; |
| 391 | unsigned int page_attr_changed: 1; | 391 | unsigned int page_attr_changed: 1; |
| 392 | unsigned int suspended: 1; | ||
| 392 | } ichdev_t; | 393 | } ichdev_t; |
| 393 | 394 | ||
| 394 | typedef struct _snd_intel8x0 intel8x0_t; | 395 | typedef struct _snd_intel8x0 intel8x0_t; |
| @@ -862,12 +863,16 @@ static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 862 | unsigned long port = ichdev->reg_offset; | 863 | unsigned long port = ichdev->reg_offset; |
| 863 | 864 | ||
| 864 | switch (cmd) { | 865 | switch (cmd) { |
| 865 | case SNDRV_PCM_TRIGGER_START: | ||
| 866 | case SNDRV_PCM_TRIGGER_RESUME: | 866 | case SNDRV_PCM_TRIGGER_RESUME: |
| 867 | ichdev->suspended = 0; | ||
| 868 | /* fallthru */ | ||
| 869 | case SNDRV_PCM_TRIGGER_START: | ||
| 867 | val = ICH_IOCE | ICH_STARTBM; | 870 | val = ICH_IOCE | ICH_STARTBM; |
| 868 | break; | 871 | break; |
| 869 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 870 | case SNDRV_PCM_TRIGGER_SUSPEND: | 872 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 873 | ichdev->suspended = 1; | ||
| 874 | /* fallthru */ | ||
| 875 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 871 | val = 0; | 876 | val = 0; |
| 872 | break; | 877 | break; |
| 873 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 878 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| @@ -899,9 +904,11 @@ static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 899 | 904 | ||
| 900 | val = igetdword(chip, ICHREG(ALI_DMACR)); | 905 | val = igetdword(chip, ICHREG(ALI_DMACR)); |
| 901 | switch (cmd) { | 906 | switch (cmd) { |
| 907 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 908 | ichdev->suspended = 0; | ||
| 909 | /* fallthru */ | ||
| 902 | case SNDRV_PCM_TRIGGER_START: | 910 | case SNDRV_PCM_TRIGGER_START: |
| 903 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 911 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 904 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 905 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 912 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 906 | /* clear FIFO for synchronization of channels */ | 913 | /* clear FIFO for synchronization of channels */ |
| 907 | fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]); | 914 | fifo = igetdword(chip, fiforeg[ichdev->ali_slot / 4]); |
| @@ -913,9 +920,11 @@ static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 913 | val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */ | 920 | val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */ |
| 914 | iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */ | 921 | iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */ |
| 915 | break; | 922 | break; |
| 923 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 924 | ichdev->suspended = 1; | ||
| 925 | /* fallthru */ | ||
| 916 | case SNDRV_PCM_TRIGGER_STOP: | 926 | case SNDRV_PCM_TRIGGER_STOP: |
| 917 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 927 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 918 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 919 | iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */ | 928 | iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */ |
| 920 | iputbyte(chip, port + ICH_REG_OFF_CR, 0); | 929 | iputbyte(chip, port + ICH_REG_OFF_CR, 0); |
| 921 | while (igetbyte(chip, port + ICH_REG_OFF_CR)) | 930 | while (igetbyte(chip, port + ICH_REG_OFF_CR)) |
| @@ -994,6 +1003,8 @@ static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip, | |||
| 994 | { | 1003 | { |
| 995 | unsigned int cnt; | 1004 | unsigned int cnt; |
| 996 | int dbl = runtime->rate > 48000; | 1005 | int dbl = runtime->rate > 48000; |
| 1006 | |||
| 1007 | spin_lock_irq(&chip->reg_lock); | ||
| 997 | switch (chip->device_type) { | 1008 | switch (chip->device_type) { |
| 998 | case DEVICE_ALI: | 1009 | case DEVICE_ALI: |
| 999 | cnt = igetdword(chip, ICHREG(ALI_SCR)); | 1010 | cnt = igetdword(chip, ICHREG(ALI_SCR)); |
| @@ -1037,6 +1048,7 @@ static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip, | |||
| 1037 | iputdword(chip, ICHREG(GLOB_CNT), cnt); | 1048 | iputdword(chip, ICHREG(GLOB_CNT), cnt); |
| 1038 | break; | 1049 | break; |
| 1039 | } | 1050 | } |
| 1051 | spin_unlock_irq(&chip->reg_lock); | ||
| 1040 | } | 1052 | } |
| 1041 | 1053 | ||
| 1042 | static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) | 1054 | static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) |
| @@ -1048,15 +1060,12 @@ static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream) | |||
| 1048 | ichdev->physbuf = runtime->dma_addr; | 1060 | ichdev->physbuf = runtime->dma_addr; |
| 1049 | ichdev->size = snd_pcm_lib_buffer_bytes(substream); | 1061 | ichdev->size = snd_pcm_lib_buffer_bytes(substream); |
| 1050 | ichdev->fragsize = snd_pcm_lib_period_bytes(substream); | 1062 | ichdev->fragsize = snd_pcm_lib_period_bytes(substream); |
| 1051 | spin_lock_irq(&chip->reg_lock); | ||
| 1052 | if (ichdev->ichd == ICHD_PCMOUT) { | 1063 | if (ichdev->ichd == ICHD_PCMOUT) { |
| 1053 | snd_intel8x0_setup_pcm_out(chip, runtime); | 1064 | snd_intel8x0_setup_pcm_out(chip, runtime); |
| 1054 | if (chip->device_type == DEVICE_INTEL_ICH4) { | 1065 | if (chip->device_type == DEVICE_INTEL_ICH4) |
| 1055 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; | 1066 | ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; |
| 1056 | } | ||
| 1057 | } | 1067 | } |
| 1058 | snd_intel8x0_setup_periods(chip, ichdev); | 1068 | snd_intel8x0_setup_periods(chip, ichdev); |
| 1059 | spin_unlock_irq(&chip->reg_lock); | ||
| 1060 | return 0; | 1069 | return 0; |
| 1061 | } | 1070 | } |
| 1062 | 1071 | ||
| @@ -1817,6 +1826,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
| 1817 | }, | 1826 | }, |
| 1818 | { | 1827 | { |
| 1819 | .subvendor = 0x103c, | 1828 | .subvendor = 0x103c, |
| 1829 | .subdevice = 0x0934, | ||
| 1830 | .name = "HP nx8220", | ||
| 1831 | .type = AC97_TUNE_MUTE_LED | ||
| 1832 | }, | ||
| 1833 | { | ||
| 1834 | .subvendor = 0x103c, | ||
| 1835 | .subdevice = 0x099c, | ||
| 1836 | .name = "HP nx6110", /* AD1981B */ | ||
| 1837 | .type = AC97_TUNE_HP_ONLY | ||
| 1838 | }, | ||
| 1839 | { | ||
| 1840 | .subvendor = 0x103c, | ||
| 1820 | .subdevice = 0x129d, | 1841 | .subdevice = 0x129d, |
| 1821 | .name = "HP xw8000", | 1842 | .name = "HP xw8000", |
| 1822 | .type = AC97_TUNE_HP_ONLY | 1843 | .type = AC97_TUNE_HP_ONLY |
| @@ -1870,6 +1891,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
| 1870 | .type = AC97_TUNE_HP_ONLY | 1891 | .type = AC97_TUNE_HP_ONLY |
| 1871 | }, | 1892 | }, |
| 1872 | { | 1893 | { |
| 1894 | .subvendor = 0x10cf, | ||
| 1895 | .subdevice = 0x12ec, | ||
| 1896 | .name = "Fujitsu-Siemens 4010", | ||
| 1897 | .type = AC97_TUNE_HP_ONLY | ||
| 1898 | }, | ||
| 1899 | { | ||
| 1873 | .subvendor = 0x10f1, | 1900 | .subvendor = 0x10f1, |
| 1874 | .subdevice = 0x2665, | 1901 | .subdevice = 0x2665, |
| 1875 | .name = "Fujitsu-Siemens Celsius", /* AD1981? */ | 1902 | .name = "Fujitsu-Siemens Celsius", /* AD1981? */ |
| @@ -2424,6 +2451,20 @@ static int intel8x0_resume(snd_card_t *card) | |||
| 2424 | } | 2451 | } |
| 2425 | } | 2452 | } |
| 2426 | 2453 | ||
| 2454 | /* resume status */ | ||
| 2455 | for (i = 0; i < chip->bdbars_count; i++) { | ||
| 2456 | ichdev_t *ichdev = &chip->ichd[i]; | ||
| 2457 | unsigned long port = ichdev->reg_offset; | ||
| 2458 | if (! ichdev->substream || ! ichdev->suspended) | ||
| 2459 | continue; | ||
| 2460 | if (ichdev->ichd == ICHD_PCMOUT) | ||
| 2461 | snd_intel8x0_setup_pcm_out(chip, ichdev->substream->runtime); | ||
| 2462 | iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr); | ||
| 2463 | iputbyte(chip, port + ICH_REG_OFF_LVI, ichdev->lvi); | ||
| 2464 | iputbyte(chip, port + ICH_REG_OFF_CIV, ichdev->civ); | ||
| 2465 | iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI); | ||
| 2466 | } | ||
| 2467 | |||
| 2427 | return 0; | 2468 | return 0; |
| 2428 | } | 2469 | } |
| 2429 | #endif /* CONFIG_PM */ | 2470 | #endif /* CONFIG_PM */ |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 79d8eda54f0d..d2aa9c82d41e 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
| @@ -2067,7 +2067,7 @@ static int snd_korg1212_control_sync_put(snd_kcontrol_t * kcontrol, snd_ctl_elem | |||
| 2067 | }, \ | 2067 | }, \ |
| 2068 | { \ | 2068 | { \ |
| 2069 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \ | 2069 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, \ |
| 2070 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ | 2070 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2071 | .name = c_name " Monitor Phase Invert", \ | 2071 | .name = c_name " Monitor Phase Invert", \ |
| 2072 | .info = snd_korg1212_control_phase_info, \ | 2072 | .info = snd_korg1212_control_phase_info, \ |
| 2073 | .get = snd_korg1212_control_phase_get, \ | 2073 | .get = snd_korg1212_control_phase_get, \ |
| @@ -2082,7 +2082,7 @@ static snd_kcontrol_new_t snd_korg1212_controls[] = { | |||
| 2082 | MON_MIXER(4, "ADAT-5"), MON_MIXER(5, "ADAT-6"), MON_MIXER(6, "ADAT-7"), MON_MIXER(7, "ADAT-8"), | 2082 | MON_MIXER(4, "ADAT-5"), MON_MIXER(5, "ADAT-6"), MON_MIXER(6, "ADAT-7"), MON_MIXER(7, "ADAT-8"), |
| 2083 | { | 2083 | { |
| 2084 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, | 2084 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE, |
| 2085 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 2085 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 2086 | .name = "Sync Source", | 2086 | .name = "Sync Source", |
| 2087 | .info = snd_korg1212_control_sync_info, | 2087 | .info = snd_korg1212_control_sync_info, |
| 2088 | .get = snd_korg1212_control_sync_get, | 2088 | .get = snd_korg1212_control_sync_get, |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 7eb20b8f89f6..2bbeb10ff7c4 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
| @@ -189,6 +189,7 @@ struct snd_nm256_stream { | |||
| 189 | nm256_t *chip; | 189 | nm256_t *chip; |
| 190 | snd_pcm_substream_t *substream; | 190 | snd_pcm_substream_t *substream; |
| 191 | int running; | 191 | int running; |
| 192 | int suspended; | ||
| 192 | 193 | ||
| 193 | u32 buf; /* offset from chip->buffer */ | 194 | u32 buf; /* offset from chip->buffer */ |
| 194 | int bufsize; /* buffer size in bytes */ | 195 | int bufsize; /* buffer size in bytes */ |
| @@ -231,8 +232,10 @@ struct snd_nm256 { | |||
| 231 | int mixer_status_mask; /* bit mask to test the mixer status */ | 232 | int mixer_status_mask; /* bit mask to test the mixer status */ |
| 232 | 233 | ||
| 233 | int irq; | 234 | int irq; |
| 235 | int irq_acks; | ||
| 234 | irqreturn_t (*interrupt)(int, void *, struct pt_regs *); | 236 | irqreturn_t (*interrupt)(int, void *, struct pt_regs *); |
| 235 | int badintrcount; /* counter to check bogus interrupts */ | 237 | int badintrcount; /* counter to check bogus interrupts */ |
| 238 | struct semaphore irq_mutex; | ||
| 236 | 239 | ||
| 237 | nm256_stream_t streams[2]; | 240 | nm256_stream_t streams[2]; |
| 238 | 241 | ||
| @@ -464,6 +467,37 @@ snd_nm256_set_format(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *subs | |||
| 464 | } | 467 | } |
| 465 | } | 468 | } |
| 466 | 469 | ||
| 470 | /* acquire interrupt */ | ||
| 471 | static int snd_nm256_acquire_irq(nm256_t *chip) | ||
| 472 | { | ||
| 473 | down(&chip->irq_mutex); | ||
| 474 | if (chip->irq < 0) { | ||
| 475 | if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, | ||
| 476 | chip->card->driver, (void*)chip)) { | ||
| 477 | snd_printk("unable to grab IRQ %d\n", chip->pci->irq); | ||
| 478 | up(&chip->irq_mutex); | ||
| 479 | return -EBUSY; | ||
| 480 | } | ||
| 481 | chip->irq = chip->pci->irq; | ||
| 482 | } | ||
| 483 | chip->irq_acks++; | ||
| 484 | up(&chip->irq_mutex); | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | /* release interrupt */ | ||
| 489 | static void snd_nm256_release_irq(nm256_t *chip) | ||
| 490 | { | ||
| 491 | down(&chip->irq_mutex); | ||
| 492 | if (chip->irq_acks > 0) | ||
| 493 | chip->irq_acks--; | ||
| 494 | if (chip->irq_acks == 0 && chip->irq >= 0) { | ||
| 495 | free_irq(chip->irq, (void*)chip); | ||
| 496 | chip->irq = -1; | ||
| 497 | } | ||
| 498 | up(&chip->irq_mutex); | ||
| 499 | } | ||
| 500 | |||
| 467 | /* | 501 | /* |
| 468 | * start / stop | 502 | * start / stop |
| 469 | */ | 503 | */ |
| @@ -538,15 +572,19 @@ snd_nm256_playback_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 538 | 572 | ||
| 539 | spin_lock(&chip->reg_lock); | 573 | spin_lock(&chip->reg_lock); |
| 540 | switch (cmd) { | 574 | switch (cmd) { |
| 541 | case SNDRV_PCM_TRIGGER_START: | ||
| 542 | case SNDRV_PCM_TRIGGER_RESUME: | 575 | case SNDRV_PCM_TRIGGER_RESUME: |
| 576 | s->suspended = 0; | ||
| 577 | /* fallthru */ | ||
| 578 | case SNDRV_PCM_TRIGGER_START: | ||
| 543 | if (! s->running) { | 579 | if (! s->running) { |
| 544 | snd_nm256_playback_start(chip, s, substream); | 580 | snd_nm256_playback_start(chip, s, substream); |
| 545 | s->running = 1; | 581 | s->running = 1; |
| 546 | } | 582 | } |
| 547 | break; | 583 | break; |
| 548 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 549 | case SNDRV_PCM_TRIGGER_SUSPEND: | 584 | case SNDRV_PCM_TRIGGER_SUSPEND: |
| 585 | s->suspended = 1; | ||
| 586 | /* fallthru */ | ||
| 587 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 550 | if (s->running) { | 588 | if (s->running) { |
| 551 | snd_nm256_playback_stop(chip); | 589 | snd_nm256_playback_stop(chip); |
| 552 | s->running = 0; | 590 | s->running = 0; |
| @@ -818,6 +856,8 @@ snd_nm256_playback_open(snd_pcm_substream_t *substream) | |||
| 818 | { | 856 | { |
| 819 | nm256_t *chip = snd_pcm_substream_chip(substream); | 857 | nm256_t *chip = snd_pcm_substream_chip(substream); |
| 820 | 858 | ||
| 859 | if (snd_nm256_acquire_irq(chip) < 0) | ||
| 860 | return -EBUSY; | ||
| 821 | snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK], | 861 | snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK], |
| 822 | substream, &snd_nm256_playback); | 862 | substream, &snd_nm256_playback); |
| 823 | return 0; | 863 | return 0; |
| @@ -828,6 +868,8 @@ snd_nm256_capture_open(snd_pcm_substream_t *substream) | |||
| 828 | { | 868 | { |
| 829 | nm256_t *chip = snd_pcm_substream_chip(substream); | 869 | nm256_t *chip = snd_pcm_substream_chip(substream); |
| 830 | 870 | ||
| 871 | if (snd_nm256_acquire_irq(chip) < 0) | ||
| 872 | return -EBUSY; | ||
| 831 | snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_CAPTURE], | 873 | snd_nm256_setup_stream(chip, &chip->streams[SNDRV_PCM_STREAM_CAPTURE], |
| 832 | substream, &snd_nm256_capture); | 874 | substream, &snd_nm256_capture); |
| 833 | return 0; | 875 | return 0; |
| @@ -839,6 +881,9 @@ snd_nm256_capture_open(snd_pcm_substream_t *substream) | |||
| 839 | static int | 881 | static int |
| 840 | snd_nm256_playback_close(snd_pcm_substream_t *substream) | 882 | snd_nm256_playback_close(snd_pcm_substream_t *substream) |
| 841 | { | 883 | { |
| 884 | nm256_t *chip = snd_pcm_substream_chip(substream); | ||
| 885 | |||
| 886 | snd_nm256_release_irq(chip); | ||
| 842 | return 0; | 887 | return 0; |
| 843 | } | 888 | } |
| 844 | 889 | ||
| @@ -846,6 +891,9 @@ snd_nm256_playback_close(snd_pcm_substream_t *substream) | |||
| 846 | static int | 891 | static int |
| 847 | snd_nm256_capture_close(snd_pcm_substream_t *substream) | 892 | snd_nm256_capture_close(snd_pcm_substream_t *substream) |
| 848 | { | 893 | { |
| 894 | nm256_t *chip = snd_pcm_substream_chip(substream); | ||
| 895 | |||
| 896 | snd_nm256_release_irq(chip); | ||
| 849 | return 0; | 897 | return 0; |
| 850 | } | 898 | } |
| 851 | 899 | ||
| @@ -915,18 +963,16 @@ snd_nm256_pcm(nm256_t *chip, int device) | |||
| 915 | static void | 963 | static void |
| 916 | snd_nm256_init_chip(nm256_t *chip) | 964 | snd_nm256_init_chip(nm256_t *chip) |
| 917 | { | 965 | { |
| 918 | spin_lock_irq(&chip->reg_lock); | ||
| 919 | /* Reset everything. */ | 966 | /* Reset everything. */ |
| 920 | snd_nm256_writeb(chip, 0x0, 0x11); | 967 | snd_nm256_writeb(chip, 0x0, 0x11); |
| 921 | snd_nm256_writew(chip, 0x214, 0); | 968 | snd_nm256_writew(chip, 0x214, 0); |
| 922 | /* stop sounds.. */ | 969 | /* stop sounds.. */ |
| 923 | //snd_nm256_playback_stop(chip); | 970 | //snd_nm256_playback_stop(chip); |
| 924 | //snd_nm256_capture_stop(chip); | 971 | //snd_nm256_capture_stop(chip); |
| 925 | spin_unlock_irq(&chip->reg_lock); | ||
| 926 | } | 972 | } |
| 927 | 973 | ||
| 928 | 974 | ||
| 929 | static inline void | 975 | static irqreturn_t |
| 930 | snd_nm256_intr_check(nm256_t *chip) | 976 | snd_nm256_intr_check(nm256_t *chip) |
| 931 | { | 977 | { |
| 932 | if (chip->badintrcount++ > 1000) { | 978 | if (chip->badintrcount++ > 1000) { |
| @@ -947,7 +993,9 @@ snd_nm256_intr_check(nm256_t *chip) | |||
| 947 | if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running) | 993 | if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running) |
| 948 | snd_nm256_capture_stop(chip); | 994 | snd_nm256_capture_stop(chip); |
| 949 | chip->badintrcount = 0; | 995 | chip->badintrcount = 0; |
| 996 | return IRQ_HANDLED; | ||
| 950 | } | 997 | } |
| 998 | return IRQ_NONE; | ||
| 951 | } | 999 | } |
| 952 | 1000 | ||
| 953 | /* | 1001 | /* |
| @@ -969,10 +1017,8 @@ snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy) | |||
| 969 | status = snd_nm256_readw(chip, NM_INT_REG); | 1017 | status = snd_nm256_readw(chip, NM_INT_REG); |
| 970 | 1018 | ||
| 971 | /* Not ours. */ | 1019 | /* Not ours. */ |
| 972 | if (status == 0) { | 1020 | if (status == 0) |
| 973 | snd_nm256_intr_check(chip); | 1021 | return snd_nm256_intr_check(chip); |
| 974 | return IRQ_NONE; | ||
| 975 | } | ||
| 976 | 1022 | ||
| 977 | chip->badintrcount = 0; | 1023 | chip->badintrcount = 0; |
| 978 | 1024 | ||
| @@ -1036,10 +1082,8 @@ snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy) | |||
| 1036 | status = snd_nm256_readl(chip, NM_INT_REG); | 1082 | status = snd_nm256_readl(chip, NM_INT_REG); |
| 1037 | 1083 | ||
| 1038 | /* Not ours. */ | 1084 | /* Not ours. */ |
| 1039 | if (status == 0) { | 1085 | if (status == 0) |
| 1040 | snd_nm256_intr_check(chip); | 1086 | return snd_nm256_intr_check(chip); |
| 1041 | return IRQ_NONE; | ||
| 1042 | } | ||
| 1043 | 1087 | ||
| 1044 | chip->badintrcount = 0; | 1088 | chip->badintrcount = 0; |
| 1045 | 1089 | ||
| @@ -1192,7 +1236,7 @@ snd_nm256_mixer(nm256_t *chip) | |||
| 1192 | AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE, AC97_CD, | 1236 | AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE, AC97_CD, |
| 1193 | AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL, | 1237 | AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL, |
| 1194 | AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL, | 1238 | AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL, |
| 1195 | AC97_EXTENDED_ID, | 1239 | /*AC97_EXTENDED_ID,*/ |
| 1196 | AC97_VENDOR_ID1, AC97_VENDOR_ID2, | 1240 | AC97_VENDOR_ID1, AC97_VENDOR_ID2, |
| 1197 | -1 | 1241 | -1 |
| 1198 | }; | 1242 | }; |
| @@ -1206,6 +1250,7 @@ snd_nm256_mixer(nm256_t *chip) | |||
| 1206 | for (i = 0; mixer_regs[i] >= 0; i++) | 1250 | for (i = 0; mixer_regs[i] >= 0; i++) |
| 1207 | set_bit(mixer_regs[i], ac97.reg_accessed); | 1251 | set_bit(mixer_regs[i], ac97.reg_accessed); |
| 1208 | ac97.private_data = chip; | 1252 | ac97.private_data = chip; |
| 1253 | pbus->no_vra = 1; | ||
| 1209 | err = snd_ac97_mixer(pbus, &ac97, &chip->ac97); | 1254 | err = snd_ac97_mixer(pbus, &ac97, &chip->ac97); |
| 1210 | if (err < 0) | 1255 | if (err < 0) |
| 1211 | return err; | 1256 | return err; |
| @@ -1281,6 +1326,7 @@ static int nm256_suspend(snd_card_t *card, pm_message_t state) | |||
| 1281 | static int nm256_resume(snd_card_t *card) | 1326 | static int nm256_resume(snd_card_t *card) |
| 1282 | { | 1327 | { |
| 1283 | nm256_t *chip = card->pm_private_data; | 1328 | nm256_t *chip = card->pm_private_data; |
| 1329 | int i; | ||
| 1284 | 1330 | ||
| 1285 | /* Perform a full reset on the hardware */ | 1331 | /* Perform a full reset on the hardware */ |
| 1286 | pci_enable_device(chip->pci); | 1332 | pci_enable_device(chip->pci); |
| @@ -1289,6 +1335,15 @@ static int nm256_resume(snd_card_t *card) | |||
| 1289 | /* restore ac97 */ | 1335 | /* restore ac97 */ |
| 1290 | snd_ac97_resume(chip->ac97); | 1336 | snd_ac97_resume(chip->ac97); |
| 1291 | 1337 | ||
| 1338 | for (i = 0; i < 2; i++) { | ||
| 1339 | nm256_stream_t *s = &chip->streams[i]; | ||
| 1340 | if (s->substream && s->suspended) { | ||
| 1341 | spin_lock_irq(&chip->reg_lock); | ||
| 1342 | snd_nm256_set_format(chip, s, s->substream); | ||
| 1343 | spin_unlock_irq(&chip->reg_lock); | ||
| 1344 | } | ||
| 1345 | } | ||
| 1346 | |||
| 1292 | return 0; | 1347 | return 0; |
| 1293 | } | 1348 | } |
| 1294 | #endif /* CONFIG_PM */ | 1349 | #endif /* CONFIG_PM */ |
| @@ -1360,6 +1415,7 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, | |||
| 1360 | chip->use_cache = usecache; | 1415 | chip->use_cache = usecache; |
| 1361 | spin_lock_init(&chip->reg_lock); | 1416 | spin_lock_init(&chip->reg_lock); |
| 1362 | chip->irq = -1; | 1417 | chip->irq = -1; |
| 1418 | init_MUTEX(&chip->irq_mutex); | ||
| 1363 | 1419 | ||
| 1364 | chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = play_bufsize; | 1420 | chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = play_bufsize; |
| 1365 | chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capt_bufsize; | 1421 | chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capt_bufsize; |
| @@ -1470,15 +1526,6 @@ snd_nm256_create(snd_card_t *card, struct pci_dev *pci, | |||
| 1470 | chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr; | 1526 | chip->coeff_buf[SNDRV_PCM_STREAM_CAPTURE] = addr; |
| 1471 | } | 1527 | } |
| 1472 | 1528 | ||
| 1473 | /* acquire interrupt */ | ||
| 1474 | if (request_irq(pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, | ||
| 1475 | card->driver, (void*)chip)) { | ||
| 1476 | err = -EBUSY; | ||
| 1477 | snd_printk("unable to grab IRQ %d\n", pci->irq); | ||
| 1478 | goto __error; | ||
| 1479 | } | ||
| 1480 | chip->irq = pci->irq; | ||
| 1481 | |||
| 1482 | /* Fixed setting. */ | 1529 | /* Fixed setting. */ |
| 1483 | chip->mixer_base = NM_MIXER_OFFSET; | 1530 | chip->mixer_base = NM_MIXER_OFFSET; |
| 1484 | 1531 | ||
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index b7b554df6705..456be39e8e4a 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
| @@ -1900,7 +1900,7 @@ static snd_kcontrol_new_t snd_rme32_controls[] = { | |||
| 1900 | }, | 1900 | }, |
| 1901 | { | 1901 | { |
| 1902 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1902 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1903 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1903 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1904 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), | 1904 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), |
| 1905 | .info = snd_rme32_control_spdif_mask_info, | 1905 | .info = snd_rme32_control_spdif_mask_info, |
| 1906 | .get = snd_rme32_control_spdif_mask_get, | 1906 | .get = snd_rme32_control_spdif_mask_get, |
| @@ -1908,7 +1908,7 @@ static snd_kcontrol_new_t snd_rme32_controls[] = { | |||
| 1908 | }, | 1908 | }, |
| 1909 | { | 1909 | { |
| 1910 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1910 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1911 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1911 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1912 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), | 1912 | .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), |
| 1913 | .info = snd_rme32_control_spdif_mask_info, | 1913 | .info = snd_rme32_control_spdif_mask_info, |
| 1914 | .get = snd_rme32_control_spdif_mask_get, | 1914 | .get = snd_rme32_control_spdif_mask_get, |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 10c4f45a913c..9645e9004a48 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
| @@ -2266,7 +2266,7 @@ static snd_kcontrol_new_t snd_rme96_controls[] = { | |||
| 2266 | }, | 2266 | }, |
| 2267 | { | 2267 | { |
| 2268 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 2268 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 2269 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2269 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 2270 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 2270 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), |
| 2271 | .info = snd_rme96_control_spdif_mask_info, | 2271 | .info = snd_rme96_control_spdif_mask_info, |
| 2272 | .get = snd_rme96_control_spdif_mask_get, | 2272 | .get = snd_rme96_control_spdif_mask_get, |
| @@ -2276,7 +2276,7 @@ static snd_kcontrol_new_t snd_rme96_controls[] = { | |||
| 2276 | }, | 2276 | }, |
| 2277 | { | 2277 | { |
| 2278 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 2278 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 2279 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2279 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 2280 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), | 2280 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), |
| 2281 | .info = snd_rme96_control_spdif_mask_info, | 2281 | .info = snd_rme96_control_spdif_mask_info, |
| 2282 | .get = snd_rme96_control_spdif_mask_get, | 2282 | .get = snd_rme96_control_spdif_mask_get, |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 796621de5009..6694866089b5 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
| @@ -1524,7 +1524,7 @@ static int snd_hdsp_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_el | |||
| 1524 | } | 1524 | } |
| 1525 | 1525 | ||
| 1526 | #define HDSP_SPDIF_IN(xname, xindex) \ | 1526 | #define HDSP_SPDIF_IN(xname, xindex) \ |
| 1527 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ | 1527 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1528 | .name = xname, \ | 1528 | .name = xname, \ |
| 1529 | .index = xindex, \ | 1529 | .index = xindex, \ |
| 1530 | .info = snd_hdsp_info_spdif_in, \ | 1530 | .info = snd_hdsp_info_spdif_in, \ |
| @@ -1584,7 +1584,7 @@ static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 1584 | } | 1584 | } |
| 1585 | 1585 | ||
| 1586 | #define HDSP_SPDIF_OUT(xname, xindex) \ | 1586 | #define HDSP_SPDIF_OUT(xname, xindex) \ |
| 1587 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ | 1587 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1588 | .info = snd_hdsp_info_spdif_bits, \ | 1588 | .info = snd_hdsp_info_spdif_bits, \ |
| 1589 | .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out } | 1589 | .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out } |
| 1590 | 1590 | ||
| @@ -1638,7 +1638,7 @@ static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
| 1638 | } | 1638 | } |
| 1639 | 1639 | ||
| 1640 | #define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \ | 1640 | #define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \ |
| 1641 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ | 1641 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1642 | .info = snd_hdsp_info_spdif_bits, \ | 1642 | .info = snd_hdsp_info_spdif_bits, \ |
| 1643 | .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional } | 1643 | .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional } |
| 1644 | 1644 | ||
| @@ -1683,7 +1683,7 @@ static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_el | |||
| 1683 | } | 1683 | } |
| 1684 | 1684 | ||
| 1685 | #define HDSP_SPDIF_EMPHASIS(xname, xindex) \ | 1685 | #define HDSP_SPDIF_EMPHASIS(xname, xindex) \ |
| 1686 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ | 1686 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1687 | .info = snd_hdsp_info_spdif_bits, \ | 1687 | .info = snd_hdsp_info_spdif_bits, \ |
| 1688 | .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis } | 1688 | .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis } |
| 1689 | 1689 | ||
| @@ -1728,7 +1728,7 @@ static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_v | |||
| 1728 | } | 1728 | } |
| 1729 | 1729 | ||
| 1730 | #define HDSP_SPDIF_NON_AUDIO(xname, xindex) \ | 1730 | #define HDSP_SPDIF_NON_AUDIO(xname, xindex) \ |
| 1731 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, .name = xname, .index = xindex, \ | 1731 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1732 | .info = snd_hdsp_info_spdif_bits, \ | 1732 | .info = snd_hdsp_info_spdif_bits, \ |
| 1733 | .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio } | 1733 | .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio } |
| 1734 | 1734 | ||
| @@ -1773,7 +1773,7 @@ static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_v | |||
| 1773 | } | 1773 | } |
| 1774 | 1774 | ||
| 1775 | #define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \ | 1775 | #define HDSP_SPDIF_SAMPLE_RATE(xname, xindex) \ |
| 1776 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1776 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1777 | .name = xname, \ | 1777 | .name = xname, \ |
| 1778 | .index = xindex, \ | 1778 | .index = xindex, \ |
| 1779 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1779 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1834,7 +1834,7 @@ static int snd_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_ele | |||
| 1834 | } | 1834 | } |
| 1835 | 1835 | ||
| 1836 | #define HDSP_SYSTEM_SAMPLE_RATE(xname, xindex) \ | 1836 | #define HDSP_SYSTEM_SAMPLE_RATE(xname, xindex) \ |
| 1837 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1837 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1838 | .name = xname, \ | 1838 | .name = xname, \ |
| 1839 | .index = xindex, \ | 1839 | .index = xindex, \ |
| 1840 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1840 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1858,7 +1858,7 @@ static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_el | |||
| 1858 | } | 1858 | } |
| 1859 | 1859 | ||
| 1860 | #define HDSP_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ | 1860 | #define HDSP_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ |
| 1861 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ | 1861 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1862 | .name = xname, \ | 1862 | .name = xname, \ |
| 1863 | .index = xindex, \ | 1863 | .index = xindex, \ |
| 1864 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1864 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1918,7 +1918,7 @@ static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_ | |||
| 1918 | } | 1918 | } |
| 1919 | 1919 | ||
| 1920 | #define HDSP_SYSTEM_CLOCK_MODE(xname, xindex) \ | 1920 | #define HDSP_SYSTEM_CLOCK_MODE(xname, xindex) \ |
| 1921 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1921 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1922 | .name = xname, \ | 1922 | .name = xname, \ |
| 1923 | .index = xindex, \ | 1923 | .index = xindex, \ |
| 1924 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1924 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1958,7 +1958,7 @@ static int snd_hdsp_get_system_clock_mode(snd_kcontrol_t * kcontrol, snd_ctl_ele | |||
| 1958 | } | 1958 | } |
| 1959 | 1959 | ||
| 1960 | #define HDSP_CLOCK_SOURCE(xname, xindex) \ | 1960 | #define HDSP_CLOCK_SOURCE(xname, xindex) \ |
| 1961 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ | 1961 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1962 | .name = xname, \ | 1962 | .name = xname, \ |
| 1963 | .index = xindex, \ | 1963 | .index = xindex, \ |
| 1964 | .info = snd_hdsp_info_clock_source, \ | 1964 | .info = snd_hdsp_info_clock_source, \ |
| @@ -2124,7 +2124,7 @@ static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_ele | |||
| 2124 | } | 2124 | } |
| 2125 | 2125 | ||
| 2126 | #define HDSP_DA_GAIN(xname, xindex) \ | 2126 | #define HDSP_DA_GAIN(xname, xindex) \ |
| 2127 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2127 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2128 | .name = xname, \ | 2128 | .name = xname, \ |
| 2129 | .index = xindex, \ | 2129 | .index = xindex, \ |
| 2130 | .info = snd_hdsp_info_da_gain, \ | 2130 | .info = snd_hdsp_info_da_gain, \ |
| @@ -2210,7 +2210,7 @@ static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 2210 | } | 2210 | } |
| 2211 | 2211 | ||
| 2212 | #define HDSP_AD_GAIN(xname, xindex) \ | 2212 | #define HDSP_AD_GAIN(xname, xindex) \ |
| 2213 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2213 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2214 | .name = xname, \ | 2214 | .name = xname, \ |
| 2215 | .index = xindex, \ | 2215 | .index = xindex, \ |
| 2216 | .info = snd_hdsp_info_ad_gain, \ | 2216 | .info = snd_hdsp_info_ad_gain, \ |
| @@ -2296,7 +2296,7 @@ static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 2296 | } | 2296 | } |
| 2297 | 2297 | ||
| 2298 | #define HDSP_PHONE_GAIN(xname, xindex) \ | 2298 | #define HDSP_PHONE_GAIN(xname, xindex) \ |
| 2299 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2299 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2300 | .name = xname, \ | 2300 | .name = xname, \ |
| 2301 | .index = xindex, \ | 2301 | .index = xindex, \ |
| 2302 | .info = snd_hdsp_info_phone_gain, \ | 2302 | .info = snd_hdsp_info_phone_gain, \ |
| @@ -2382,7 +2382,7 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value | |||
| 2382 | } | 2382 | } |
| 2383 | 2383 | ||
| 2384 | #define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \ | 2384 | #define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \ |
| 2385 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2385 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2386 | .name = xname, \ | 2386 | .name = xname, \ |
| 2387 | .index = xindex, \ | 2387 | .index = xindex, \ |
| 2388 | .info = snd_hdsp_info_xlr_breakout_cable, \ | 2388 | .info = snd_hdsp_info_xlr_breakout_cable, \ |
| @@ -2447,7 +2447,7 @@ static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_el | |||
| 2447 | Switching this on desactivates external ADAT | 2447 | Switching this on desactivates external ADAT |
| 2448 | */ | 2448 | */ |
| 2449 | #define HDSP_AEB(xname, xindex) \ | 2449 | #define HDSP_AEB(xname, xindex) \ |
| 2450 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2450 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2451 | .name = xname, \ | 2451 | .name = xname, \ |
| 2452 | .index = xindex, \ | 2452 | .index = xindex, \ |
| 2453 | .info = snd_hdsp_info_aeb, \ | 2453 | .info = snd_hdsp_info_aeb, \ |
| @@ -2508,7 +2508,7 @@ static int snd_hdsp_put_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uc | |||
| 2508 | } | 2508 | } |
| 2509 | 2509 | ||
| 2510 | #define HDSP_PREF_SYNC_REF(xname, xindex) \ | 2510 | #define HDSP_PREF_SYNC_REF(xname, xindex) \ |
| 2511 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2511 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2512 | .name = xname, \ | 2512 | .name = xname, \ |
| 2513 | .index = xindex, \ | 2513 | .index = xindex, \ |
| 2514 | .info = snd_hdsp_info_pref_sync_ref, \ | 2514 | .info = snd_hdsp_info_pref_sync_ref, \ |
| @@ -2641,7 +2641,7 @@ static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_va | |||
| 2641 | } | 2641 | } |
| 2642 | 2642 | ||
| 2643 | #define HDSP_AUTOSYNC_REF(xname, xindex) \ | 2643 | #define HDSP_AUTOSYNC_REF(xname, xindex) \ |
| 2644 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2644 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2645 | .name = xname, \ | 2645 | .name = xname, \ |
| 2646 | .index = xindex, \ | 2646 | .index = xindex, \ |
| 2647 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 2647 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -2697,7 +2697,7 @@ static int snd_hdsp_get_autosync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
| 2697 | } | 2697 | } |
| 2698 | 2698 | ||
| 2699 | #define HDSP_LINE_OUT(xname, xindex) \ | 2699 | #define HDSP_LINE_OUT(xname, xindex) \ |
| 2700 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2700 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2701 | .name = xname, \ | 2701 | .name = xname, \ |
| 2702 | .index = xindex, \ | 2702 | .index = xindex, \ |
| 2703 | .info = snd_hdsp_info_line_out, \ | 2703 | .info = snd_hdsp_info_line_out, \ |
| @@ -2757,7 +2757,7 @@ static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 2757 | } | 2757 | } |
| 2758 | 2758 | ||
| 2759 | #define HDSP_PRECISE_POINTER(xname, xindex) \ | 2759 | #define HDSP_PRECISE_POINTER(xname, xindex) \ |
| 2760 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2760 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ |
| 2761 | .name = xname, \ | 2761 | .name = xname, \ |
| 2762 | .index = xindex, \ | 2762 | .index = xindex, \ |
| 2763 | .info = snd_hdsp_info_precise_pointer, \ | 2763 | .info = snd_hdsp_info_precise_pointer, \ |
| @@ -2811,7 +2811,7 @@ static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_ | |||
| 2811 | } | 2811 | } |
| 2812 | 2812 | ||
| 2813 | #define HDSP_USE_MIDI_TASKLET(xname, xindex) \ | 2813 | #define HDSP_USE_MIDI_TASKLET(xname, xindex) \ |
| 2814 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2814 | { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ |
| 2815 | .name = xname, \ | 2815 | .name = xname, \ |
| 2816 | .index = xindex, \ | 2816 | .index = xindex, \ |
| 2817 | .info = snd_hdsp_info_use_midi_tasklet, \ | 2817 | .info = snd_hdsp_info_use_midi_tasklet, \ |
| @@ -2868,6 +2868,7 @@ static int snd_hdsp_put_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem | |||
| 2868 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2868 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
| 2869 | .name = xname, \ | 2869 | .name = xname, \ |
| 2870 | .index = xindex, \ | 2870 | .index = xindex, \ |
| 2871 | .device = 0, \ | ||
| 2871 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | 2872 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ |
| 2872 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 2873 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 2873 | .info = snd_hdsp_info_mixer, \ | 2874 | .info = snd_hdsp_info_mixer, \ |
| @@ -2939,7 +2940,7 @@ static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * | |||
| 2939 | } | 2940 | } |
| 2940 | 2941 | ||
| 2941 | #define HDSP_WC_SYNC_CHECK(xname, xindex) \ | 2942 | #define HDSP_WC_SYNC_CHECK(xname, xindex) \ |
| 2942 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2943 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2943 | .name = xname, \ | 2944 | .name = xname, \ |
| 2944 | .index = xindex, \ | 2945 | .index = xindex, \ |
| 2945 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 2946 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| @@ -2983,7 +2984,7 @@ static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_va | |||
| 2983 | } | 2984 | } |
| 2984 | 2985 | ||
| 2985 | #define HDSP_SPDIF_SYNC_CHECK(xname, xindex) \ | 2986 | #define HDSP_SPDIF_SYNC_CHECK(xname, xindex) \ |
| 2986 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2987 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2987 | .name = xname, \ | 2988 | .name = xname, \ |
| 2988 | .index = xindex, \ | 2989 | .index = xindex, \ |
| 2989 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 2990 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| @@ -3015,7 +3016,7 @@ static int snd_hdsp_get_spdif_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem | |||
| 3015 | } | 3016 | } |
| 3016 | 3017 | ||
| 3017 | #define HDSP_ADATSYNC_SYNC_CHECK(xname, xindex) \ | 3018 | #define HDSP_ADATSYNC_SYNC_CHECK(xname, xindex) \ |
| 3018 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 3019 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 3019 | .name = xname, \ | 3020 | .name = xname, \ |
| 3020 | .index = xindex, \ | 3021 | .index = xindex, \ |
| 3021 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 3022 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| @@ -3046,7 +3047,7 @@ static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_e | |||
| 3046 | } | 3047 | } |
| 3047 | 3048 | ||
| 3048 | #define HDSP_ADAT_SYNC_CHECK \ | 3049 | #define HDSP_ADAT_SYNC_CHECK \ |
| 3049 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 3050 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 3050 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 3051 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 3051 | .info = snd_hdsp_info_sync_check, \ | 3052 | .info = snd_hdsp_info_sync_check, \ |
| 3052 | .get = snd_hdsp_get_adat_sync_check \ | 3053 | .get = snd_hdsp_get_adat_sync_check \ |
| @@ -3119,7 +3120,7 @@ static snd_kcontrol_new_t snd_hdsp_controls[] = { | |||
| 3119 | }, | 3120 | }, |
| 3120 | { | 3121 | { |
| 3121 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 3122 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 3122 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3123 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 3123 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 3124 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), |
| 3124 | .info = snd_hdsp_control_spdif_mask_info, | 3125 | .info = snd_hdsp_control_spdif_mask_info, |
| 3125 | .get = snd_hdsp_control_spdif_mask_get, | 3126 | .get = snd_hdsp_control_spdif_mask_get, |
| @@ -3129,7 +3130,7 @@ static snd_kcontrol_new_t snd_hdsp_controls[] = { | |||
| 3129 | }, | 3130 | }, |
| 3130 | { | 3131 | { |
| 3131 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 3132 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 3132 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3133 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 3133 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), | 3134 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), |
| 3134 | .info = snd_hdsp_control_spdif_mask_info, | 3135 | .info = snd_hdsp_control_spdif_mask_info, |
| 3135 | .get = snd_hdsp_control_spdif_mask_get, | 3136 | .get = snd_hdsp_control_spdif_mask_get, |
| @@ -3146,8 +3147,6 @@ HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), | |||
| 3146 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 3147 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ |
| 3147 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), | 3148 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), |
| 3148 | { | 3149 | { |
| 3149 | /* FIXME: should be PCM or MIXER? */ | ||
| 3150 | /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ | ||
| 3151 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3150 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 3152 | .name = "Sample Clock Source Locking", | 3151 | .name = "Sample Clock Source Locking", |
| 3153 | .info = snd_hdsp_info_clock_source_lock, | 3152 | .info = snd_hdsp_info_clock_source_lock, |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 9e86d0eb41ce..5d786d113b25 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
| @@ -65,7 +65,7 @@ module_param_array(enable, bool, NULL, 0444); | |||
| 65 | MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); | 65 | MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards."); |
| 66 | 66 | ||
| 67 | module_param_array(precise_ptr, bool, NULL, 0444); | 67 | module_param_array(precise_ptr, bool, NULL, 0444); |
| 68 | MODULE_PARM_DESC(precise_ptr, "Enable precise pointer, or disable."); | 68 | MODULE_PARM_DESC(precise_ptr, "Enable or disable precise pointer."); |
| 69 | 69 | ||
| 70 | module_param_array(line_outs_monitor, bool, NULL, 0444); | 70 | module_param_array(line_outs_monitor, bool, NULL, 0444); |
| 71 | MODULE_PARM_DESC(line_outs_monitor, | 71 | MODULE_PARM_DESC(line_outs_monitor, |
| @@ -1104,14 +1104,14 @@ static int snd_hdspm_midi_output_close(snd_rawmidi_substream_t * substream) | |||
| 1104 | return 0; | 1104 | return 0; |
| 1105 | } | 1105 | } |
| 1106 | 1106 | ||
| 1107 | snd_rawmidi_ops_t snd_hdspm_midi_output = | 1107 | static snd_rawmidi_ops_t snd_hdspm_midi_output = |
| 1108 | { | 1108 | { |
| 1109 | .open = snd_hdspm_midi_output_open, | 1109 | .open = snd_hdspm_midi_output_open, |
| 1110 | .close = snd_hdspm_midi_output_close, | 1110 | .close = snd_hdspm_midi_output_close, |
| 1111 | .trigger = snd_hdspm_midi_output_trigger, | 1111 | .trigger = snd_hdspm_midi_output_trigger, |
| 1112 | }; | 1112 | }; |
| 1113 | 1113 | ||
| 1114 | snd_rawmidi_ops_t snd_hdspm_midi_input = | 1114 | static snd_rawmidi_ops_t snd_hdspm_midi_input = |
| 1115 | { | 1115 | { |
| 1116 | .open = snd_hdspm_midi_input_open, | 1116 | .open = snd_hdspm_midi_input_open, |
| 1117 | .close = snd_hdspm_midi_input_close, | 1117 | .close = snd_hdspm_midi_input_close, |
| @@ -1168,7 +1168,7 @@ static void hdspm_midi_tasklet(unsigned long arg) | |||
| 1168 | /* get the system sample rate which is set */ | 1168 | /* get the system sample rate which is set */ |
| 1169 | 1169 | ||
| 1170 | #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ | 1170 | #define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \ |
| 1171 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1171 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1172 | .name = xname, \ | 1172 | .name = xname, \ |
| 1173 | .index = xindex, \ | 1173 | .index = xindex, \ |
| 1174 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1174 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1195,7 +1195,7 @@ static int snd_hdspm_get_system_sample_rate(snd_kcontrol_t * kcontrol, | |||
| 1195 | } | 1195 | } |
| 1196 | 1196 | ||
| 1197 | #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ | 1197 | #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ |
| 1198 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ | 1198 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1199 | .name = xname, \ | 1199 | .name = xname, \ |
| 1200 | .index = xindex, \ | 1200 | .index = xindex, \ |
| 1201 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1201 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1264,7 +1264,7 @@ static int snd_hdspm_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, | |||
| 1264 | } | 1264 | } |
| 1265 | 1265 | ||
| 1266 | #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ | 1266 | #define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \ |
| 1267 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1267 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1268 | .name = xname, \ | 1268 | .name = xname, \ |
| 1269 | .index = xindex, \ | 1269 | .index = xindex, \ |
| 1270 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1270 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1310,7 +1310,7 @@ static int snd_hdspm_get_system_clock_mode(snd_kcontrol_t * kcontrol, | |||
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| 1312 | #define HDSPM_CLOCK_SOURCE(xname, xindex) \ | 1312 | #define HDSPM_CLOCK_SOURCE(xname, xindex) \ |
| 1313 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, \ | 1313 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1314 | .name = xname, \ | 1314 | .name = xname, \ |
| 1315 | .index = xindex, \ | 1315 | .index = xindex, \ |
| 1316 | .info = snd_hdspm_info_clock_source, \ | 1316 | .info = snd_hdspm_info_clock_source, \ |
| @@ -1457,7 +1457,7 @@ static int snd_hdspm_put_clock_source(snd_kcontrol_t * kcontrol, | |||
| 1457 | } | 1457 | } |
| 1458 | 1458 | ||
| 1459 | #define HDSPM_PREF_SYNC_REF(xname, xindex) \ | 1459 | #define HDSPM_PREF_SYNC_REF(xname, xindex) \ |
| 1460 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1460 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1461 | .name = xname, \ | 1461 | .name = xname, \ |
| 1462 | .index = xindex, \ | 1462 | .index = xindex, \ |
| 1463 | .info = snd_hdspm_info_pref_sync_ref, \ | 1463 | .info = snd_hdspm_info_pref_sync_ref, \ |
| @@ -1547,7 +1547,7 @@ static int snd_hdspm_put_pref_sync_ref(snd_kcontrol_t * kcontrol, | |||
| 1547 | } | 1547 | } |
| 1548 | 1548 | ||
| 1549 | #define HDSPM_AUTOSYNC_REF(xname, xindex) \ | 1549 | #define HDSPM_AUTOSYNC_REF(xname, xindex) \ |
| 1550 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1550 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1551 | .name = xname, \ | 1551 | .name = xname, \ |
| 1552 | .index = xindex, \ | 1552 | .index = xindex, \ |
| 1553 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ | 1553 | .access = SNDRV_CTL_ELEM_ACCESS_READ, \ |
| @@ -1604,7 +1604,7 @@ static int snd_hdspm_get_autosync_ref(snd_kcontrol_t * kcontrol, | |||
| 1604 | } | 1604 | } |
| 1605 | 1605 | ||
| 1606 | #define HDSPM_LINE_OUT(xname, xindex) \ | 1606 | #define HDSPM_LINE_OUT(xname, xindex) \ |
| 1607 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1607 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1608 | .name = xname, \ | 1608 | .name = xname, \ |
| 1609 | .index = xindex, \ | 1609 | .index = xindex, \ |
| 1610 | .info = snd_hdspm_info_line_out, \ | 1610 | .info = snd_hdspm_info_line_out, \ |
| @@ -1668,7 +1668,7 @@ static int snd_hdspm_put_line_out(snd_kcontrol_t * kcontrol, | |||
| 1668 | } | 1668 | } |
| 1669 | 1669 | ||
| 1670 | #define HDSPM_TX_64(xname, xindex) \ | 1670 | #define HDSPM_TX_64(xname, xindex) \ |
| 1671 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1671 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1672 | .name = xname, \ | 1672 | .name = xname, \ |
| 1673 | .index = xindex, \ | 1673 | .index = xindex, \ |
| 1674 | .info = snd_hdspm_info_tx_64, \ | 1674 | .info = snd_hdspm_info_tx_64, \ |
| @@ -1731,7 +1731,7 @@ static int snd_hdspm_put_tx_64(snd_kcontrol_t * kcontrol, | |||
| 1731 | } | 1731 | } |
| 1732 | 1732 | ||
| 1733 | #define HDSPM_C_TMS(xname, xindex) \ | 1733 | #define HDSPM_C_TMS(xname, xindex) \ |
| 1734 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1734 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1735 | .name = xname, \ | 1735 | .name = xname, \ |
| 1736 | .index = xindex, \ | 1736 | .index = xindex, \ |
| 1737 | .info = snd_hdspm_info_c_tms, \ | 1737 | .info = snd_hdspm_info_c_tms, \ |
| @@ -1794,7 +1794,7 @@ static int snd_hdspm_put_c_tms(snd_kcontrol_t * kcontrol, | |||
| 1794 | } | 1794 | } |
| 1795 | 1795 | ||
| 1796 | #define HDSPM_SAFE_MODE(xname, xindex) \ | 1796 | #define HDSPM_SAFE_MODE(xname, xindex) \ |
| 1797 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1797 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1798 | .name = xname, \ | 1798 | .name = xname, \ |
| 1799 | .index = xindex, \ | 1799 | .index = xindex, \ |
| 1800 | .info = snd_hdspm_info_safe_mode, \ | 1800 | .info = snd_hdspm_info_safe_mode, \ |
| @@ -1857,7 +1857,7 @@ static int snd_hdspm_put_safe_mode(snd_kcontrol_t * kcontrol, | |||
| 1857 | } | 1857 | } |
| 1858 | 1858 | ||
| 1859 | #define HDSPM_INPUT_SELECT(xname, xindex) \ | 1859 | #define HDSPM_INPUT_SELECT(xname, xindex) \ |
| 1860 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1860 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 1861 | .name = xname, \ | 1861 | .name = xname, \ |
| 1862 | .index = xindex, \ | 1862 | .index = xindex, \ |
| 1863 | .info = snd_hdspm_info_input_select, \ | 1863 | .info = snd_hdspm_info_input_select, \ |
| @@ -1941,6 +1941,7 @@ static int snd_hdspm_put_input_select(snd_kcontrol_t * kcontrol, | |||
| 1941 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 1941 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
| 1942 | .name = xname, \ | 1942 | .name = xname, \ |
| 1943 | .index = xindex, \ | 1943 | .index = xindex, \ |
| 1944 | .device = 0, \ | ||
| 1944 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | 1945 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ |
| 1945 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 1946 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 1946 | .info = snd_hdspm_info_mixer, \ | 1947 | .info = snd_hdspm_info_mixer, \ |
| @@ -2124,7 +2125,7 @@ static int snd_hdspm_put_playback_mixer(snd_kcontrol_t * kcontrol, | |||
| 2124 | } | 2125 | } |
| 2125 | 2126 | ||
| 2126 | #define HDSPM_WC_SYNC_CHECK(xname, xindex) \ | 2127 | #define HDSPM_WC_SYNC_CHECK(xname, xindex) \ |
| 2127 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2128 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2128 | .name = xname, \ | 2129 | .name = xname, \ |
| 2129 | .index = xindex, \ | 2130 | .index = xindex, \ |
| 2130 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 2131 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| @@ -2170,7 +2171,7 @@ static int snd_hdspm_get_wc_sync_check(snd_kcontrol_t * kcontrol, | |||
| 2170 | 2171 | ||
| 2171 | 2172 | ||
| 2172 | #define HDSPM_MADI_SYNC_CHECK(xname, xindex) \ | 2173 | #define HDSPM_MADI_SYNC_CHECK(xname, xindex) \ |
| 2173 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2174 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| 2174 | .name = xname, \ | 2175 | .name = xname, \ |
| 2175 | .index = xindex, \ | 2176 | .index = xindex, \ |
| 2176 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 2177 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 1bc9d0df8516..8ee4d6fd6ea7 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c | |||
| @@ -893,7 +893,7 @@ static int snd_rme9652_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl | |||
| 893 | } | 893 | } |
| 894 | 894 | ||
| 895 | #define RME9652_ADAT1_IN(xname, xindex) \ | 895 | #define RME9652_ADAT1_IN(xname, xindex) \ |
| 896 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 896 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 897 | .info = snd_rme9652_info_adat1_in, \ | 897 | .info = snd_rme9652_info_adat1_in, \ |
| 898 | .get = snd_rme9652_get_adat1_in, \ | 898 | .get = snd_rme9652_get_adat1_in, \ |
| 899 | .put = snd_rme9652_put_adat1_in } | 899 | .put = snd_rme9652_put_adat1_in } |
| @@ -971,7 +971,7 @@ static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu | |||
| 971 | } | 971 | } |
| 972 | 972 | ||
| 973 | #define RME9652_SPDIF_IN(xname, xindex) \ | 973 | #define RME9652_SPDIF_IN(xname, xindex) \ |
| 974 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 974 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 975 | .info = snd_rme9652_info_spdif_in, \ | 975 | .info = snd_rme9652_info_spdif_in, \ |
| 976 | .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in } | 976 | .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in } |
| 977 | 977 | ||
| @@ -1042,7 +1042,7 @@ static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu | |||
| 1042 | } | 1042 | } |
| 1043 | 1043 | ||
| 1044 | #define RME9652_SPDIF_OUT(xname, xindex) \ | 1044 | #define RME9652_SPDIF_OUT(xname, xindex) \ |
| 1045 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1045 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1046 | .info = snd_rme9652_info_spdif_out, \ | 1046 | .info = snd_rme9652_info_spdif_out, \ |
| 1047 | .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out } | 1047 | .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out } |
| 1048 | 1048 | ||
| @@ -1110,7 +1110,7 @@ static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
| 1110 | } | 1110 | } |
| 1111 | 1111 | ||
| 1112 | #define RME9652_SYNC_MODE(xname, xindex) \ | 1112 | #define RME9652_SYNC_MODE(xname, xindex) \ |
| 1113 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1113 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1114 | .info = snd_rme9652_info_sync_mode, \ | 1114 | .info = snd_rme9652_info_sync_mode, \ |
| 1115 | .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode } | 1115 | .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode } |
| 1116 | 1116 | ||
| @@ -1195,7 +1195,7 @@ static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
| 1195 | } | 1195 | } |
| 1196 | 1196 | ||
| 1197 | #define RME9652_SYNC_PREF(xname, xindex) \ | 1197 | #define RME9652_SYNC_PREF(xname, xindex) \ |
| 1198 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1198 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1199 | .info = snd_rme9652_info_sync_pref, \ | 1199 | .info = snd_rme9652_info_sync_pref, \ |
| 1200 | .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref } | 1200 | .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref } |
| 1201 | 1201 | ||
| @@ -1340,7 +1340,7 @@ static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t | |||
| 1340 | } | 1340 | } |
| 1341 | 1341 | ||
| 1342 | #define RME9652_PASSTHRU(xname, xindex) \ | 1342 | #define RME9652_PASSTHRU(xname, xindex) \ |
| 1343 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1343 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1344 | .info = snd_rme9652_info_passthru, \ | 1344 | .info = snd_rme9652_info_passthru, \ |
| 1345 | .put = snd_rme9652_put_passthru, \ | 1345 | .put = snd_rme9652_put_passthru, \ |
| 1346 | .get = snd_rme9652_get_passthru } | 1346 | .get = snd_rme9652_get_passthru } |
| @@ -1386,7 +1386,7 @@ static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu | |||
| 1386 | /* Read-only switches */ | 1386 | /* Read-only switches */ |
| 1387 | 1387 | ||
| 1388 | #define RME9652_SPDIF_RATE(xname, xindex) \ | 1388 | #define RME9652_SPDIF_RATE(xname, xindex) \ |
| 1389 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1389 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1390 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 1390 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 1391 | .info = snd_rme9652_info_spdif_rate, \ | 1391 | .info = snd_rme9652_info_spdif_rate, \ |
| 1392 | .get = snd_rme9652_get_spdif_rate } | 1392 | .get = snd_rme9652_get_spdif_rate } |
| @@ -1411,7 +1411,7 @@ static int snd_rme9652_get_spdif_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_va | |||
| 1411 | } | 1411 | } |
| 1412 | 1412 | ||
| 1413 | #define RME9652_ADAT_SYNC(xname, xindex, xidx) \ | 1413 | #define RME9652_ADAT_SYNC(xname, xindex, xidx) \ |
| 1414 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1414 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1415 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 1415 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 1416 | .info = snd_rme9652_info_adat_sync, \ | 1416 | .info = snd_rme9652_info_adat_sync, \ |
| 1417 | .get = snd_rme9652_get_adat_sync, .private_value = xidx } | 1417 | .get = snd_rme9652_get_adat_sync, .private_value = xidx } |
| @@ -1447,7 +1447,7 @@ static int snd_rme9652_get_adat_sync(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
| 1447 | } | 1447 | } |
| 1448 | 1448 | ||
| 1449 | #define RME9652_TC_VALID(xname, xindex) \ | 1449 | #define RME9652_TC_VALID(xname, xindex) \ |
| 1450 | { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, .index = xindex, \ | 1450 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ |
| 1451 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | 1451 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ |
| 1452 | .info = snd_rme9652_info_tc_valid, \ | 1452 | .info = snd_rme9652_info_tc_valid, \ |
| 1453 | .get = snd_rme9652_get_tc_valid } | 1453 | .get = snd_rme9652_get_tc_valid } |
| @@ -1545,7 +1545,7 @@ static snd_kcontrol_new_t snd_rme9652_controls[] = { | |||
| 1545 | }, | 1545 | }, |
| 1546 | { | 1546 | { |
| 1547 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1547 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1548 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1548 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1549 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), | 1549 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), |
| 1550 | .info = snd_rme9652_control_spdif_mask_info, | 1550 | .info = snd_rme9652_control_spdif_mask_info, |
| 1551 | .get = snd_rme9652_control_spdif_mask_get, | 1551 | .get = snd_rme9652_control_spdif_mask_get, |
| @@ -1555,7 +1555,7 @@ static snd_kcontrol_new_t snd_rme9652_controls[] = { | |||
| 1555 | }, | 1555 | }, |
| 1556 | { | 1556 | { |
| 1557 | .access = SNDRV_CTL_ELEM_ACCESS_READ, | 1557 | .access = SNDRV_CTL_ELEM_ACCESS_READ, |
| 1558 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1558 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
| 1559 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), | 1559 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), |
| 1560 | .info = snd_rme9652_control_spdif_mask_info, | 1560 | .info = snd_rme9652_control_spdif_mask_info, |
| 1561 | .get = snd_rme9652_control_spdif_mask_get, | 1561 | .get = snd_rme9652_control_spdif_mask_get, |
| @@ -1568,7 +1568,7 @@ RME9652_SPDIF_OUT("IEC958 Output also on ADAT1", 0), | |||
| 1568 | RME9652_SYNC_MODE("Sync Mode", 0), | 1568 | RME9652_SYNC_MODE("Sync Mode", 0), |
| 1569 | RME9652_SYNC_PREF("Preferred Sync Source", 0), | 1569 | RME9652_SYNC_PREF("Preferred Sync Source", 0), |
| 1570 | { | 1570 | { |
| 1571 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | 1571 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1572 | .name = "Channels Thru", | 1572 | .name = "Channels Thru", |
| 1573 | .index = 0, | 1573 | .index = 0, |
| 1574 | .info = snd_rme9652_info_thru, | 1574 | .info = snd_rme9652_info_thru, |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 29d89bfba0a4..f30d9d947862 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
| @@ -1689,7 +1689,7 @@ static snd_pcm_hardware_t snd_trident_playback = | |||
| 1689 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1689 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1690 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1690 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1691 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | | 1691 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | |
| 1692 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), | 1692 | SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), |
| 1693 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1693 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | |
| 1694 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), | 1694 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), |
| 1695 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1695 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
| @@ -1714,7 +1714,7 @@ static snd_pcm_hardware_t snd_trident_capture = | |||
| 1714 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1714 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1715 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1715 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1716 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | | 1716 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | |
| 1717 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), | 1717 | SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), |
| 1718 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | | 1718 | .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | |
| 1719 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), | 1719 | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), |
| 1720 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, | 1720 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
| @@ -1739,7 +1739,7 @@ static snd_pcm_hardware_t snd_trident_foldback = | |||
| 1739 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1739 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1740 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1740 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1741 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | | 1741 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | |
| 1742 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), | 1742 | SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), |
| 1743 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1743 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 1744 | .rates = SNDRV_PCM_RATE_48000, | 1744 | .rates = SNDRV_PCM_RATE_48000, |
| 1745 | .rate_min = 48000, | 1745 | .rate_min = 48000, |
| @@ -1763,7 +1763,7 @@ static snd_pcm_hardware_t snd_trident_spdif = | |||
| 1763 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1763 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1764 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1764 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1765 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | | 1765 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | |
| 1766 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), | 1766 | SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), |
| 1767 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1767 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 1768 | .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | | 1768 | .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | |
| 1769 | SNDRV_PCM_RATE_48000), | 1769 | SNDRV_PCM_RATE_48000), |
| @@ -1784,7 +1784,7 @@ static snd_pcm_hardware_t snd_trident_spdif_7018 = | |||
| 1784 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1784 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1785 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1785 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1786 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | | 1786 | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | |
| 1787 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), | 1787 | SNDRV_PCM_INFO_PAUSE /* | SNDRV_PCM_INFO_RESUME */), |
| 1788 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1788 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 1789 | .rates = SNDRV_PCM_RATE_48000, | 1789 | .rates = SNDRV_PCM_RATE_48000, |
| 1790 | .rate_min = 48000, | 1790 | .rate_min = 48000, |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 4889600387c8..56c6e52d7264 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
| @@ -663,10 +663,12 @@ static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd) | |||
| 663 | val = 0; | 663 | val = 0; |
| 664 | switch (cmd) { | 664 | switch (cmd) { |
| 665 | case SNDRV_PCM_TRIGGER_START: | 665 | case SNDRV_PCM_TRIGGER_START: |
| 666 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 666 | val |= VIA_REG_CTRL_START; | 667 | val |= VIA_REG_CTRL_START; |
| 667 | viadev->running = 1; | 668 | viadev->running = 1; |
| 668 | break; | 669 | break; |
| 669 | case SNDRV_PCM_TRIGGER_STOP: | 670 | case SNDRV_PCM_TRIGGER_STOP: |
| 671 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 670 | val = VIA_REG_CTRL_TERMINATE; | 672 | val = VIA_REG_CTRL_TERMINATE; |
| 671 | viadev->running = 0; | 673 | viadev->running = 0; |
| 672 | break; | 674 | break; |
| @@ -929,12 +931,12 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) | |||
| 929 | 931 | ||
| 930 | if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0) | 932 | if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0) |
| 931 | return rate_changed; | 933 | return rate_changed; |
| 932 | if (rate_changed) { | 934 | if (rate_changed) |
| 933 | snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, | 935 | snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, |
| 934 | chip->no_vra ? 48000 : runtime->rate); | 936 | chip->no_vra ? 48000 : runtime->rate); |
| 935 | snd_ac97_set_rate(chip->ac97, AC97_SPDIF, | 937 | if (chip->spdif_on && viadev->reg_offset == 0x30) |
| 936 | chip->no_vra ? 48000 : runtime->rate); | 938 | snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); |
| 937 | } | 939 | |
| 938 | if (runtime->rate == 48000) | 940 | if (runtime->rate == 48000) |
| 939 | rbits = 0xfffff; | 941 | rbits = 0xfffff; |
| 940 | else | 942 | else |
| @@ -1035,7 +1037,7 @@ static snd_pcm_hardware_t snd_via82xx_hw = | |||
| 1035 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1037 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1036 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1038 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1037 | SNDRV_PCM_INFO_MMAP_VALID | | 1039 | SNDRV_PCM_INFO_MMAP_VALID | |
| 1038 | SNDRV_PCM_INFO_RESUME | | 1040 | /* SNDRV_PCM_INFO_RESUME | */ |
| 1039 | SNDRV_PCM_INFO_PAUSE), | 1041 | SNDRV_PCM_INFO_PAUSE), |
| 1040 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, | 1042 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, |
| 1041 | .rates = SNDRV_PCM_RATE_48000, | 1043 | .rates = SNDRV_PCM_RATE_48000, |
| @@ -1484,7 +1486,7 @@ static int snd_via8233_dxs3_spdif_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val | |||
| 1484 | } | 1486 | } |
| 1485 | 1487 | ||
| 1486 | static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = { | 1488 | static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = { |
| 1487 | .name = "IEC958 Output Switch", | 1489 | .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), |
| 1488 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1490 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
| 1489 | .info = snd_via8233_dxs3_spdif_info, | 1491 | .info = snd_via8233_dxs3_spdif_info, |
| 1490 | .get = snd_via8233_dxs3_spdif_get, | 1492 | .get = snd_via8233_dxs3_spdif_get, |
| @@ -2153,6 +2155,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) | |||
| 2153 | { .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */ | 2155 | { .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */ |
| 2154 | { .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */ | 2156 | { .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */ |
| 2155 | { .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */ | 2157 | { .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */ |
| 2158 | { .subvendor = 0x1025, .subdevice = 0x0046, .action = VIA_DXS_SRC }, /* Acer Aspire 1524 WLMi */ | ||
| 2156 | { .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ | 2159 | { .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ |
| 2157 | { .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ | 2160 | { .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ |
| 2158 | { .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ | 2161 | { .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ |
| @@ -2168,10 +2171,12 @@ static int __devinit check_dxs_list(struct pci_dev *pci) | |||
| 2168 | { .subvendor = 0x1297, .subdevice = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */ | 2171 | { .subvendor = 0x1297, .subdevice = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */ |
| 2169 | { .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */ | 2172 | { .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */ |
| 2170 | { .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */ | 2173 | { .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */ |
| 2174 | { .subvendor = 0x1462, .subdevice = 0x0430, .action = VIA_DXS_SRC }, /* MSI 7142 (K8MM-V) */ | ||
| 2171 | { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ | 2175 | { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ |
| 2172 | { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ | 2176 | { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ |
| 2173 | { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ | 2177 | { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ |
| 2174 | { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ | 2178 | { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */ |
| 2179 | { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */ | ||
| 2175 | { .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */ | 2180 | { .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */ |
| 2176 | { .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */ | 2181 | { .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */ |
| 2177 | { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ | 2182 | { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 4a9779cc9733..5872d438a04a 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
| @@ -521,6 +521,7 @@ static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd) | |||
| 521 | 521 | ||
| 522 | switch (cmd) { | 522 | switch (cmd) { |
| 523 | case SNDRV_PCM_TRIGGER_START: | 523 | case SNDRV_PCM_TRIGGER_START: |
| 524 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 524 | val |= VIA_REG_CTRL_START; | 525 | val |= VIA_REG_CTRL_START; |
| 525 | viadev->running = 1; | 526 | viadev->running = 1; |
| 526 | break; | 527 | break; |
| @@ -697,7 +698,7 @@ static snd_pcm_hardware_t snd_via82xx_hw = | |||
| 697 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 698 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 698 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 699 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 699 | SNDRV_PCM_INFO_MMAP_VALID | | 700 | SNDRV_PCM_INFO_MMAP_VALID | |
| 700 | SNDRV_PCM_INFO_RESUME | | 701 | /* SNDRV_PCM_INFO_RESUME | */ |
| 701 | SNDRV_PCM_INFO_PAUSE), | 702 | SNDRV_PCM_INFO_PAUSE), |
| 702 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, | 703 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, |
| 703 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT, | 704 | .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT, |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index d54f88a1b525..054836412dc4 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
| @@ -321,6 +321,26 @@ static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice) | |||
| 321 | snd_pcm_period_elapsed(ypcm->substream); | 321 | snd_pcm_period_elapsed(ypcm->substream); |
| 322 | spin_lock(&chip->reg_lock); | 322 | spin_lock(&chip->reg_lock); |
| 323 | } | 323 | } |
| 324 | |||
| 325 | if (unlikely(ypcm->update_pcm_vol)) { | ||
| 326 | unsigned int subs = ypcm->substream->number; | ||
| 327 | unsigned int next_bank = 1 - chip->active_bank; | ||
| 328 | snd_ymfpci_playback_bank_t *bank; | ||
| 329 | u32 volume; | ||
| 330 | |||
| 331 | bank = &voice->bank[next_bank]; | ||
| 332 | volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15); | ||
| 333 | bank->left_gain_end = volume; | ||
| 334 | if (ypcm->output_rear) | ||
| 335 | bank->eff2_gain_end = volume; | ||
| 336 | if (ypcm->voices[1]) | ||
| 337 | bank = &ypcm->voices[1]->bank[next_bank]; | ||
| 338 | volume = cpu_to_le32(chip->pcm_mixer[subs].right << 15); | ||
| 339 | bank->right_gain_end = volume; | ||
| 340 | if (ypcm->output_rear) | ||
| 341 | bank->eff3_gain_end = volume; | ||
| 342 | ypcm->update_pcm_vol--; | ||
| 343 | } | ||
| 324 | } | 344 | } |
| 325 | spin_unlock(&chip->reg_lock); | 345 | spin_unlock(&chip->reg_lock); |
| 326 | } | 346 | } |
| @@ -451,87 +471,74 @@ static int snd_ymfpci_pcm_voice_alloc(ymfpci_pcm_t *ypcm, int voices) | |||
| 451 | return 0; | 471 | return 0; |
| 452 | } | 472 | } |
| 453 | 473 | ||
| 454 | static void snd_ymfpci_pcm_init_voice(ymfpci_voice_t *voice, int stereo, | 474 | static void snd_ymfpci_pcm_init_voice(ymfpci_pcm_t *ypcm, unsigned int voiceidx, |
| 455 | int rate, int w_16, unsigned long addr, | 475 | snd_pcm_runtime_t *runtime, |
| 456 | unsigned int end, | 476 | int has_pcm_volume) |
| 457 | int output_front, int output_rear) | ||
| 458 | { | 477 | { |
| 478 | ymfpci_voice_t *voice = ypcm->voices[voiceidx]; | ||
| 459 | u32 format; | 479 | u32 format; |
| 460 | u32 delta = snd_ymfpci_calc_delta(rate); | 480 | u32 delta = snd_ymfpci_calc_delta(runtime->rate); |
| 461 | u32 lpfQ = snd_ymfpci_calc_lpfQ(rate); | 481 | u32 lpfQ = snd_ymfpci_calc_lpfQ(runtime->rate); |
| 462 | u32 lpfK = snd_ymfpci_calc_lpfK(rate); | 482 | u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate); |
| 463 | snd_ymfpci_playback_bank_t *bank; | 483 | snd_ymfpci_playback_bank_t *bank; |
| 464 | unsigned int nbank; | 484 | unsigned int nbank; |
| 485 | u32 vol_left, vol_right; | ||
| 486 | u8 use_left, use_right; | ||
| 465 | 487 | ||
| 466 | snd_assert(voice != NULL, return); | 488 | snd_assert(voice != NULL, return); |
| 467 | format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000); | 489 | if (runtime->channels == 1) { |
| 490 | use_left = 1; | ||
| 491 | use_right = 1; | ||
| 492 | } else { | ||
| 493 | use_left = (voiceidx & 1) == 0; | ||
| 494 | use_right = !use_left; | ||
| 495 | } | ||
| 496 | if (has_pcm_volume) { | ||
| 497 | vol_left = cpu_to_le32(ypcm->chip->pcm_mixer | ||
| 498 | [ypcm->substream->number].left << 15); | ||
| 499 | vol_right = cpu_to_le32(ypcm->chip->pcm_mixer | ||
| 500 | [ypcm->substream->number].right << 15); | ||
| 501 | } else { | ||
| 502 | vol_left = cpu_to_le32(0x40000000); | ||
| 503 | vol_right = cpu_to_le32(0x40000000); | ||
| 504 | } | ||
| 505 | format = runtime->channels == 2 ? 0x00010000 : 0; | ||
| 506 | if (snd_pcm_format_width(runtime->format) == 8) | ||
| 507 | format |= 0x80000000; | ||
| 508 | if (runtime->channels == 2 && (voiceidx & 1) != 0) | ||
| 509 | format |= 1; | ||
| 468 | for (nbank = 0; nbank < 2; nbank++) { | 510 | for (nbank = 0; nbank < 2; nbank++) { |
| 469 | bank = &voice->bank[nbank]; | 511 | bank = &voice->bank[nbank]; |
| 512 | memset(bank, 0, sizeof(*bank)); | ||
| 470 | bank->format = cpu_to_le32(format); | 513 | bank->format = cpu_to_le32(format); |
| 471 | bank->loop_default = 0; | 514 | bank->base = cpu_to_le32(runtime->dma_addr); |
| 472 | bank->base = cpu_to_le32(addr); | 515 | bank->loop_end = cpu_to_le32(ypcm->buffer_size); |
| 473 | bank->loop_start = 0; | ||
| 474 | bank->loop_end = cpu_to_le32(end); | ||
| 475 | bank->loop_frac = 0; | ||
| 476 | bank->eg_gain_end = cpu_to_le32(0x40000000); | ||
| 477 | bank->lpfQ = cpu_to_le32(lpfQ); | 516 | bank->lpfQ = cpu_to_le32(lpfQ); |
| 478 | bank->status = 0; | ||
| 479 | bank->num_of_frames = 0; | ||
| 480 | bank->loop_count = 0; | ||
| 481 | bank->start = 0; | ||
| 482 | bank->start_frac = 0; | ||
| 483 | bank->delta = | 517 | bank->delta = |
| 484 | bank->delta_end = cpu_to_le32(delta); | 518 | bank->delta_end = cpu_to_le32(delta); |
| 485 | bank->lpfK = | 519 | bank->lpfK = |
| 486 | bank->lpfK_end = cpu_to_le32(lpfK); | 520 | bank->lpfK_end = cpu_to_le32(lpfK); |
| 487 | bank->eg_gain = cpu_to_le32(0x40000000); | 521 | bank->eg_gain = |
| 488 | bank->lpfD1 = | 522 | bank->eg_gain_end = cpu_to_le32(0x40000000); |
| 489 | bank->lpfD2 = 0; | 523 | |
| 490 | 524 | if (ypcm->output_front) { | |
| 491 | bank->left_gain = | 525 | if (use_left) { |
| 492 | bank->right_gain = | 526 | bank->left_gain = |
| 493 | bank->left_gain_end = | 527 | bank->left_gain_end = vol_left; |
| 494 | bank->right_gain_end = | 528 | } |
| 495 | bank->eff1_gain = | 529 | if (use_right) { |
| 496 | bank->eff2_gain = | ||
| 497 | bank->eff3_gain = | ||
| 498 | bank->eff1_gain_end = | ||
| 499 | bank->eff2_gain_end = | ||
| 500 | bank->eff3_gain_end = 0; | ||
| 501 | |||
| 502 | if (!stereo) { | ||
| 503 | if (output_front) { | ||
| 504 | bank->left_gain = | ||
| 505 | bank->right_gain = | 530 | bank->right_gain = |
| 506 | bank->left_gain_end = | 531 | bank->right_gain_end = vol_right; |
| 507 | bank->right_gain_end = cpu_to_le32(0x40000000); | ||
| 508 | } | 532 | } |
| 509 | if (output_rear) { | 533 | } |
| 534 | if (ypcm->output_rear) { | ||
| 535 | if (use_left) { | ||
| 510 | bank->eff2_gain = | 536 | bank->eff2_gain = |
| 511 | bank->eff2_gain_end = | 537 | bank->eff2_gain_end = vol_left; |
| 512 | bank->eff3_gain = | ||
| 513 | bank->eff3_gain_end = cpu_to_le32(0x40000000); | ||
| 514 | } | ||
| 515 | } else { | ||
| 516 | if (output_front) { | ||
| 517 | if ((voice->number & 1) == 0) { | ||
| 518 | bank->left_gain = | ||
| 519 | bank->left_gain_end = cpu_to_le32(0x40000000); | ||
| 520 | } else { | ||
| 521 | bank->format |= cpu_to_le32(1); | ||
| 522 | bank->right_gain = | ||
| 523 | bank->right_gain_end = cpu_to_le32(0x40000000); | ||
| 524 | } | ||
| 525 | } | 538 | } |
| 526 | if (output_rear) { | 539 | if (use_right) { |
| 527 | if ((voice->number & 1) == 0) { | 540 | bank->eff3_gain = |
| 528 | bank->eff3_gain = | 541 | bank->eff3_gain_end = vol_right; |
| 529 | bank->eff3_gain_end = cpu_to_le32(0x40000000); | ||
| 530 | } else { | ||
| 531 | bank->format |= cpu_to_le32(1); | ||
| 532 | bank->eff2_gain = | ||
| 533 | bank->eff2_gain_end = cpu_to_le32(0x40000000); | ||
| 534 | } | ||
| 535 | } | 542 | } |
| 536 | } | 543 | } |
| 537 | } | 544 | } |
| @@ -613,7 +620,7 @@ static int snd_ymfpci_playback_hw_free(snd_pcm_substream_t * substream) | |||
| 613 | 620 | ||
| 614 | static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) | 621 | static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) |
| 615 | { | 622 | { |
| 616 | // ymfpci_t *chip = snd_pcm_substream_chip(substream); | 623 | ymfpci_t *chip = snd_pcm_substream_chip(substream); |
| 617 | snd_pcm_runtime_t *runtime = substream->runtime; | 624 | snd_pcm_runtime_t *runtime = substream->runtime; |
| 618 | ymfpci_pcm_t *ypcm = runtime->private_data; | 625 | ymfpci_pcm_t *ypcm = runtime->private_data; |
| 619 | unsigned int nvoice; | 626 | unsigned int nvoice; |
| @@ -623,14 +630,8 @@ static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) | |||
| 623 | ypcm->period_pos = 0; | 630 | ypcm->period_pos = 0; |
| 624 | ypcm->last_pos = 0; | 631 | ypcm->last_pos = 0; |
| 625 | for (nvoice = 0; nvoice < runtime->channels; nvoice++) | 632 | for (nvoice = 0; nvoice < runtime->channels; nvoice++) |
| 626 | snd_ymfpci_pcm_init_voice(ypcm->voices[nvoice], | 633 | snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, |
| 627 | runtime->channels == 2, | 634 | substream->pcm == chip->pcm); |
| 628 | runtime->rate, | ||
| 629 | snd_pcm_format_width(runtime->format) == 16, | ||
| 630 | runtime->dma_addr, | ||
| 631 | ypcm->buffer_size, | ||
| 632 | ypcm->output_front, | ||
| 633 | ypcm->output_rear); | ||
| 634 | return 0; | 635 | return 0; |
| 635 | } | 636 | } |
| 636 | 637 | ||
| @@ -882,6 +883,7 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) | |||
| 882 | ymfpci_t *chip = snd_pcm_substream_chip(substream); | 883 | ymfpci_t *chip = snd_pcm_substream_chip(substream); |
| 883 | snd_pcm_runtime_t *runtime = substream->runtime; | 884 | snd_pcm_runtime_t *runtime = substream->runtime; |
| 884 | ymfpci_pcm_t *ypcm; | 885 | ymfpci_pcm_t *ypcm; |
| 886 | snd_kcontrol_t *kctl; | ||
| 885 | int err; | 887 | int err; |
| 886 | 888 | ||
| 887 | if ((err = snd_ymfpci_playback_open_1(substream)) < 0) | 889 | if ((err = snd_ymfpci_playback_open_1(substream)) < 0) |
| @@ -895,6 +897,10 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) | |||
| 895 | chip->rear_opened++; | 897 | chip->rear_opened++; |
| 896 | } | 898 | } |
| 897 | spin_unlock_irq(&chip->reg_lock); | 899 | spin_unlock_irq(&chip->reg_lock); |
| 900 | |||
| 901 | kctl = chip->pcm_mixer[substream->number].ctl; | ||
| 902 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
| 903 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); | ||
| 898 | return 0; | 904 | return 0; |
| 899 | } | 905 | } |
| 900 | 906 | ||
| @@ -987,6 +993,7 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) | |||
| 987 | { | 993 | { |
| 988 | ymfpci_t *chip = snd_pcm_substream_chip(substream); | 994 | ymfpci_t *chip = snd_pcm_substream_chip(substream); |
| 989 | ymfpci_pcm_t *ypcm = substream->runtime->private_data; | 995 | ymfpci_pcm_t *ypcm = substream->runtime->private_data; |
| 996 | snd_kcontrol_t *kctl; | ||
| 990 | 997 | ||
| 991 | spin_lock_irq(&chip->reg_lock); | 998 | spin_lock_irq(&chip->reg_lock); |
| 992 | if (ypcm->output_rear && chip->rear_opened > 0) { | 999 | if (ypcm->output_rear && chip->rear_opened > 0) { |
| @@ -994,6 +1001,9 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) | |||
| 994 | ymfpci_close_extension(chip); | 1001 | ymfpci_close_extension(chip); |
| 995 | } | 1002 | } |
| 996 | spin_unlock_irq(&chip->reg_lock); | 1003 | spin_unlock_irq(&chip->reg_lock); |
| 1004 | kctl = chip->pcm_mixer[substream->number].ctl; | ||
| 1005 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
| 1006 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); | ||
| 997 | return snd_ymfpci_playback_close_1(substream); | 1007 | return snd_ymfpci_playback_close_1(substream); |
| 998 | } | 1008 | } |
| 999 | 1009 | ||
| @@ -1665,6 +1675,66 @@ static snd_kcontrol_new_t snd_ymfpci_rear_shared __devinitdata = { | |||
| 1665 | .private_value = 2, | 1675 | .private_value = 2, |
| 1666 | }; | 1676 | }; |
| 1667 | 1677 | ||
| 1678 | /* | ||
| 1679 | * PCM voice volume | ||
| 1680 | */ | ||
| 1681 | |||
| 1682 | static int snd_ymfpci_pcm_vol_info(snd_kcontrol_t *kcontrol, | ||
| 1683 | snd_ctl_elem_info_t *uinfo) | ||
| 1684 | { | ||
| 1685 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
| 1686 | uinfo->count = 2; | ||
| 1687 | uinfo->value.integer.min = 0; | ||
| 1688 | uinfo->value.integer.max = 0x8000; | ||
| 1689 | return 0; | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | static int snd_ymfpci_pcm_vol_get(snd_kcontrol_t *kcontrol, | ||
| 1693 | snd_ctl_elem_value_t *ucontrol) | ||
| 1694 | { | ||
| 1695 | ymfpci_t *chip = snd_kcontrol_chip(kcontrol); | ||
| 1696 | unsigned int subs = kcontrol->id.subdevice; | ||
| 1697 | |||
| 1698 | ucontrol->value.integer.value[0] = chip->pcm_mixer[subs].left; | ||
| 1699 | ucontrol->value.integer.value[1] = chip->pcm_mixer[subs].right; | ||
| 1700 | return 0; | ||
| 1701 | } | ||
| 1702 | |||
| 1703 | static int snd_ymfpci_pcm_vol_put(snd_kcontrol_t *kcontrol, | ||
| 1704 | snd_ctl_elem_value_t *ucontrol) | ||
| 1705 | { | ||
| 1706 | ymfpci_t *chip = snd_kcontrol_chip(kcontrol); | ||
| 1707 | unsigned int subs = kcontrol->id.subdevice; | ||
| 1708 | snd_pcm_substream_t *substream; | ||
| 1709 | unsigned long flags; | ||
| 1710 | |||
| 1711 | if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left || | ||
| 1712 | ucontrol->value.integer.value[1] != chip->pcm_mixer[subs].right) { | ||
| 1713 | chip->pcm_mixer[subs].left = ucontrol->value.integer.value[0]; | ||
| 1714 | chip->pcm_mixer[subs].right = ucontrol->value.integer.value[1]; | ||
| 1715 | |||
| 1716 | substream = (snd_pcm_substream_t *)kcontrol->private_value; | ||
| 1717 | spin_lock_irqsave(&chip->voice_lock, flags); | ||
| 1718 | if (substream->runtime && substream->runtime->private_data) { | ||
| 1719 | ymfpci_pcm_t *ypcm = substream->runtime->private_data; | ||
| 1720 | ypcm->update_pcm_vol = 2; | ||
| 1721 | } | ||
| 1722 | spin_unlock_irqrestore(&chip->voice_lock, flags); | ||
| 1723 | return 1; | ||
| 1724 | } | ||
| 1725 | return 0; | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | static snd_kcontrol_new_t snd_ymfpci_pcm_volume __devinitdata = { | ||
| 1729 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
| 1730 | .name = "PCM Playback Volume", | ||
| 1731 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
| 1732 | SNDRV_CTL_ELEM_ACCESS_INACTIVE, | ||
| 1733 | .info = snd_ymfpci_pcm_vol_info, | ||
| 1734 | .get = snd_ymfpci_pcm_vol_get, | ||
| 1735 | .put = snd_ymfpci_pcm_vol_put, | ||
| 1736 | }; | ||
| 1737 | |||
| 1668 | 1738 | ||
| 1669 | /* | 1739 | /* |
| 1670 | * Mixer routines | 1740 | * Mixer routines |
| @@ -1686,6 +1756,7 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) | |||
| 1686 | { | 1756 | { |
| 1687 | ac97_template_t ac97; | 1757 | ac97_template_t ac97; |
| 1688 | snd_kcontrol_t *kctl; | 1758 | snd_kcontrol_t *kctl; |
| 1759 | snd_pcm_substream_t *substream; | ||
| 1689 | unsigned int idx; | 1760 | unsigned int idx; |
| 1690 | int err; | 1761 | int err; |
| 1691 | static ac97_bus_ops_t ops = { | 1762 | static ac97_bus_ops_t ops = { |
| @@ -1739,6 +1810,23 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) | |||
| 1739 | return err; | 1810 | return err; |
| 1740 | } | 1811 | } |
| 1741 | 1812 | ||
| 1813 | /* per-voice volume */ | ||
| 1814 | substream = chip->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | ||
| 1815 | for (idx = 0; idx < 32; ++idx) { | ||
| 1816 | kctl = snd_ctl_new1(&snd_ymfpci_pcm_volume, chip); | ||
| 1817 | if (!kctl) | ||
| 1818 | return -ENOMEM; | ||
| 1819 | kctl->id.device = chip->pcm->device; | ||
| 1820 | kctl->id.subdevice = idx; | ||
| 1821 | kctl->private_value = (unsigned long)substream; | ||
| 1822 | if ((err = snd_ctl_add(chip->card, kctl)) < 0) | ||
| 1823 | return err; | ||
| 1824 | chip->pcm_mixer[idx].left = 0x8000; | ||
| 1825 | chip->pcm_mixer[idx].right = 0x8000; | ||
| 1826 | chip->pcm_mixer[idx].ctl = kctl; | ||
| 1827 | substream = substream->next; | ||
| 1828 | } | ||
| 1829 | |||
| 1742 | return 0; | 1830 | return 0; |
| 1743 | } | 1831 | } |
| 1744 | 1832 | ||
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 3a82161d3b24..1e8f16b4c073 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
| @@ -297,6 +297,7 @@ static void vxpocket_config(dev_link_t *link) | |||
| 297 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); | 297 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); |
| 298 | 298 | ||
| 299 | chip->dev = &handle_to_dev(link->handle); | 299 | chip->dev = &handle_to_dev(link->handle); |
| 300 | snd_card_set_dev(chip->card, chip->dev); | ||
| 300 | 301 | ||
| 301 | if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) | 302 | if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) |
| 302 | goto failed; | 303 | goto failed; |
| @@ -376,7 +377,7 @@ static int vxpocket_event(event_t event, int priority, event_callback_args_t *ar | |||
| 376 | 377 | ||
| 377 | /* | 378 | /* |
| 378 | */ | 379 | */ |
| 379 | static dev_link_t *vxp_attach(void) | 380 | static dev_link_t *vxpocket_attach(void) |
| 380 | { | 381 | { |
| 381 | snd_card_t *card; | 382 | snd_card_t *card; |
| 382 | struct snd_vxpocket *vxp; | 383 | struct snd_vxpocket *vxp; |
| @@ -407,7 +408,7 @@ static dev_link_t *vxp_attach(void) | |||
| 407 | return NULL; | 408 | return NULL; |
| 408 | } | 409 | } |
| 409 | 410 | ||
| 410 | vxp->index = index[i]; | 411 | vxp->index = i; |
| 411 | card_alloc |= 1 << i; | 412 | card_alloc |= 1 << i; |
| 412 | 413 | ||
| 413 | /* Chain drivers */ | 414 | /* Chain drivers */ |
| @@ -417,7 +418,7 @@ static dev_link_t *vxp_attach(void) | |||
| 417 | return &vxp->link; | 418 | return &vxp->link; |
| 418 | } | 419 | } |
| 419 | 420 | ||
| 420 | static void vxp_detach(dev_link_t *link) | 421 | static void vxpocket_detach(dev_link_t *link) |
| 421 | { | 422 | { |
| 422 | struct snd_vxpocket *vxp; | 423 | struct snd_vxpocket *vxp; |
| 423 | vx_core_t *chip; | 424 | vx_core_t *chip; |
| @@ -458,8 +459,9 @@ static struct pcmcia_driver vxp_cs_driver = { | |||
| 458 | .drv = { | 459 | .drv = { |
| 459 | .name = "snd-vxpocket", | 460 | .name = "snd-vxpocket", |
| 460 | }, | 461 | }, |
| 461 | .attach = vxp_attach, | 462 | .attach = vxpocket_attach, |
| 462 | .detach = vxp_detach, | 463 | .detach = vxpocket_detach, |
| 464 | .event = vxpocket_event, | ||
| 463 | .id_table = vxp_ids, | 465 | .id_table = vxp_ids, |
| 464 | }; | 466 | }; |
| 465 | 467 | ||
diff --git a/sound/sound_core.c b/sound/sound_core.c index 21a69e096225..954f994592ab 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c | |||
| @@ -153,7 +153,7 @@ static DEFINE_SPINLOCK(sound_loader_lock); | |||
| 153 | * list. Acquires locks as needed | 153 | * list. Acquires locks as needed |
| 154 | */ | 154 | */ |
| 155 | 155 | ||
| 156 | static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode) | 156 | static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev) |
| 157 | { | 157 | { |
| 158 | struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL); | 158 | struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL); |
| 159 | int r; | 159 | int r; |
| @@ -175,7 +175,7 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f | |||
| 175 | devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor), | 175 | devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor), |
| 176 | S_IFCHR | mode, s->name); | 176 | S_IFCHR | mode, s->name); |
| 177 | class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor), | 177 | class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor), |
| 178 | NULL, s->name+6); | 178 | dev, s->name+6); |
| 179 | return r; | 179 | return r; |
| 180 | 180 | ||
| 181 | fail: | 181 | fail: |
| @@ -227,16 +227,18 @@ static void sound_remove_unit(struct sound_unit **list, int unit) | |||
| 227 | static struct sound_unit *chains[SOUND_STEP]; | 227 | static struct sound_unit *chains[SOUND_STEP]; |
| 228 | 228 | ||
| 229 | /** | 229 | /** |
| 230 | * register_sound_special - register a special sound node | 230 | * register_sound_special_device - register a special sound node |
| 231 | * @fops: File operations for the driver | 231 | * @fops: File operations for the driver |
| 232 | * @unit: Unit number to allocate | 232 | * @unit: Unit number to allocate |
| 233 | * @dev: device pointer | ||
| 233 | * | 234 | * |
| 234 | * Allocate a special sound device by minor number from the sound | 235 | * Allocate a special sound device by minor number from the sound |
| 235 | * subsystem. The allocated number is returned on succes. On failure | 236 | * subsystem. The allocated number is returned on succes. On failure |
| 236 | * a negative error code is returned. | 237 | * a negative error code is returned. |
| 237 | */ | 238 | */ |
| 238 | 239 | ||
| 239 | int register_sound_special(struct file_operations *fops, int unit) | 240 | int register_sound_special_device(struct file_operations *fops, int unit, |
| 241 | struct device *dev) | ||
| 240 | { | 242 | { |
| 241 | const int chain = unit % SOUND_STEP; | 243 | const int chain = unit % SOUND_STEP; |
| 242 | int max_unit = 128 + chain; | 244 | int max_unit = 128 + chain; |
| @@ -294,9 +296,16 @@ int register_sound_special(struct file_operations *fops, int unit) | |||
| 294 | break; | 296 | break; |
| 295 | } | 297 | } |
| 296 | return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit, | 298 | return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit, |
| 297 | name, S_IRUSR | S_IWUSR); | 299 | name, S_IRUSR | S_IWUSR, dev); |
| 298 | } | 300 | } |
| 299 | 301 | ||
| 302 | EXPORT_SYMBOL(register_sound_special_device); | ||
| 303 | |||
| 304 | int register_sound_special(struct file_operations *fops, int unit) | ||
| 305 | { | ||
| 306 | return register_sound_special_device(fops, unit, NULL); | ||
| 307 | } | ||
| 308 | |||
| 300 | EXPORT_SYMBOL(register_sound_special); | 309 | EXPORT_SYMBOL(register_sound_special); |
| 301 | 310 | ||
| 302 | /** | 311 | /** |
| @@ -312,7 +321,7 @@ EXPORT_SYMBOL(register_sound_special); | |||
| 312 | int register_sound_mixer(struct file_operations *fops, int dev) | 321 | int register_sound_mixer(struct file_operations *fops, int dev) |
| 313 | { | 322 | { |
| 314 | return sound_insert_unit(&chains[0], fops, dev, 0, 128, | 323 | return sound_insert_unit(&chains[0], fops, dev, 0, 128, |
| 315 | "mixer", S_IRUSR | S_IWUSR); | 324 | "mixer", S_IRUSR | S_IWUSR, NULL); |
| 316 | } | 325 | } |
| 317 | 326 | ||
| 318 | EXPORT_SYMBOL(register_sound_mixer); | 327 | EXPORT_SYMBOL(register_sound_mixer); |
| @@ -330,7 +339,7 @@ EXPORT_SYMBOL(register_sound_mixer); | |||
| 330 | int register_sound_midi(struct file_operations *fops, int dev) | 339 | int register_sound_midi(struct file_operations *fops, int dev) |
| 331 | { | 340 | { |
| 332 | return sound_insert_unit(&chains[2], fops, dev, 2, 130, | 341 | return sound_insert_unit(&chains[2], fops, dev, 2, 130, |
| 333 | "midi", S_IRUSR | S_IWUSR); | 342 | "midi", S_IRUSR | S_IWUSR, NULL); |
| 334 | } | 343 | } |
| 335 | 344 | ||
| 336 | EXPORT_SYMBOL(register_sound_midi); | 345 | EXPORT_SYMBOL(register_sound_midi); |
| @@ -356,7 +365,7 @@ EXPORT_SYMBOL(register_sound_midi); | |||
| 356 | int register_sound_dsp(struct file_operations *fops, int dev) | 365 | int register_sound_dsp(struct file_operations *fops, int dev) |
| 357 | { | 366 | { |
| 358 | return sound_insert_unit(&chains[3], fops, dev, 3, 131, | 367 | return sound_insert_unit(&chains[3], fops, dev, 3, 131, |
| 359 | "dsp", S_IWUSR | S_IRUSR); | 368 | "dsp", S_IWUSR | S_IRUSR, NULL); |
| 360 | } | 369 | } |
| 361 | 370 | ||
| 362 | EXPORT_SYMBOL(register_sound_dsp); | 371 | EXPORT_SYMBOL(register_sound_dsp); |
| @@ -375,7 +384,7 @@ EXPORT_SYMBOL(register_sound_dsp); | |||
| 375 | int register_sound_synth(struct file_operations *fops, int dev) | 384 | int register_sound_synth(struct file_operations *fops, int dev) |
| 376 | { | 385 | { |
| 377 | return sound_insert_unit(&chains[9], fops, dev, 9, 137, | 386 | return sound_insert_unit(&chains[9], fops, dev, 9, 137, |
| 378 | "synth", S_IRUSR | S_IWUSR); | 387 | "synth", S_IRUSR | S_IWUSR, NULL); |
| 379 | } | 388 | } |
| 380 | 389 | ||
| 381 | EXPORT_SYMBOL(register_sound_synth); | 390 | EXPORT_SYMBOL(register_sound_synth); |
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c index f13b038329eb..751bf1272af3 100644 --- a/sound/synth/emux/emux_synth.c +++ b/sound/synth/emux/emux_synth.c | |||
| @@ -98,7 +98,6 @@ snd_emux_note_on(void *p, int note, int vel, snd_midi_channel_t *chan) | |||
| 98 | vp = emu->ops.get_voice(emu, port); | 98 | vp = emu->ops.get_voice(emu, port); |
| 99 | if (vp == NULL || vp->ch < 0) | 99 | if (vp == NULL || vp->ch < 0) |
| 100 | continue; | 100 | continue; |
| 101 | snd_assert(vp->emu != NULL && vp->hw != NULL, return); | ||
| 102 | if (STATE_IS_PLAYING(vp->state)) | 101 | if (STATE_IS_PLAYING(vp->state)) |
| 103 | emu->ops.terminate(vp); | 102 | emu->ops.terminate(vp); |
| 104 | 103 | ||
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8298c462c291..5aa5fe651a8a 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
| @@ -41,10 +41,12 @@ | |||
| 41 | #include <sound/driver.h> | 41 | #include <sound/driver.h> |
| 42 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
| 43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
| 44 | #include <linux/interrupt.h> | ||
| 44 | #include <linux/list.h> | 45 | #include <linux/list.h> |
| 45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
| 46 | #include <linux/string.h> | 47 | #include <linux/string.h> |
| 47 | #include <linux/usb.h> | 48 | #include <linux/usb.h> |
| 49 | #include <linux/vmalloc.h> | ||
| 48 | #include <linux/moduleparam.h> | 50 | #include <linux/moduleparam.h> |
| 49 | #include <sound/core.h> | 51 | #include <sound/core.h> |
| 50 | #include <sound/info.h> | 52 | #include <sound/info.h> |
| @@ -79,7 +81,7 @@ module_param_array(vid, int, NULL, 0444); | |||
| 79 | MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device."); | 81 | MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device."); |
| 80 | module_param_array(pid, int, NULL, 0444); | 82 | module_param_array(pid, int, NULL, 0444); |
| 81 | MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); | 83 | MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); |
| 82 | module_param(nrpacks, int, 0444); | 84 | module_param(nrpacks, int, 0644); |
| 83 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); | 85 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); |
| 84 | module_param(async_unlink, bool, 0444); | 86 | module_param(async_unlink, bool, 0444); |
| 85 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | 87 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); |
| @@ -97,7 +99,7 @@ MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | |||
| 97 | 99 | ||
| 98 | #define MAX_PACKS 10 | 100 | #define MAX_PACKS 10 |
| 99 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ | 101 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ |
| 100 | #define MAX_URBS 5 /* max. 20ms long packets */ | 102 | #define MAX_URBS 8 |
| 101 | #define SYNC_URBS 4 /* always four urbs for sync */ | 103 | #define SYNC_URBS 4 /* always four urbs for sync */ |
| 102 | #define MIN_PACKS_URB 1 /* minimum 1 packet per urb */ | 104 | #define MIN_PACKS_URB 1 /* minimum 1 packet per urb */ |
| 103 | 105 | ||
| @@ -126,11 +128,10 @@ struct audioformat { | |||
| 126 | 128 | ||
| 127 | struct snd_urb_ctx { | 129 | struct snd_urb_ctx { |
| 128 | struct urb *urb; | 130 | struct urb *urb; |
| 131 | unsigned int buffer_size; /* size of data buffer, if data URB */ | ||
| 129 | snd_usb_substream_t *subs; | 132 | snd_usb_substream_t *subs; |
| 130 | int index; /* index for urb array */ | 133 | int index; /* index for urb array */ |
| 131 | int packets; /* number of packets per urb */ | 134 | int packets; /* number of packets per urb */ |
| 132 | int transfer; /* transferred size */ | ||
| 133 | char *buf; /* buffer for capture */ | ||
| 134 | }; | 135 | }; |
| 135 | 136 | ||
| 136 | struct snd_urb_ops { | 137 | struct snd_urb_ops { |
| @@ -165,12 +166,11 @@ struct snd_usb_substream { | |||
| 165 | unsigned int curframesize; /* current packet size in frames (for capture) */ | 166 | unsigned int curframesize; /* current packet size in frames (for capture) */ |
| 166 | unsigned int fill_max: 1; /* fill max packet size always */ | 167 | unsigned int fill_max: 1; /* fill max packet size always */ |
| 167 | unsigned int fmt_type; /* USB audio format type (1-3) */ | 168 | unsigned int fmt_type; /* USB audio format type (1-3) */ |
| 169 | unsigned int packs_per_ms; /* packets per millisecond (for playback) */ | ||
| 168 | 170 | ||
| 169 | unsigned int running: 1; /* running status */ | 171 | unsigned int running: 1; /* running status */ |
| 170 | 172 | ||
| 171 | unsigned int hwptr; /* free frame position in the buffer (only for playback) */ | ||
| 172 | unsigned int hwptr_done; /* processed frame position in the buffer */ | 173 | unsigned int hwptr_done; /* processed frame position in the buffer */ |
| 173 | unsigned int transfer_sched; /* scheduled frames since last period (for playback) */ | ||
| 174 | unsigned int transfer_done; /* processed frames since last period update */ | 174 | unsigned int transfer_done; /* processed frames since last period update */ |
| 175 | unsigned long active_mask; /* bitmask of active urbs */ | 175 | unsigned long active_mask; /* bitmask of active urbs */ |
| 176 | unsigned long unlink_mask; /* bitmask of unlinked urbs */ | 176 | unsigned long unlink_mask; /* bitmask of unlinked urbs */ |
| @@ -178,13 +178,14 @@ struct snd_usb_substream { | |||
| 178 | unsigned int nurbs; /* # urbs */ | 178 | unsigned int nurbs; /* # urbs */ |
| 179 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ | 179 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ |
| 180 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ | 180 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ |
| 181 | char syncbuf[SYNC_URBS * 4]; /* sync buffer; it's so small - let's get static */ | 181 | char *syncbuf; /* sync buffer for all sync URBs */ |
| 182 | char *tmpbuf; /* temporary buffer for playback */ | 182 | dma_addr_t sync_dma; /* DMA address of syncbuf */ |
| 183 | 183 | ||
| 184 | u64 formats; /* format bitmasks (all or'ed) */ | 184 | u64 formats; /* format bitmasks (all or'ed) */ |
| 185 | unsigned int num_formats; /* number of supported audio formats (list) */ | 185 | unsigned int num_formats; /* number of supported audio formats (list) */ |
| 186 | struct list_head fmt_list; /* format list */ | 186 | struct list_head fmt_list; /* format list */ |
| 187 | spinlock_t lock; | 187 | spinlock_t lock; |
| 188 | struct tasklet_struct start_period_elapsed; /* for start trigger */ | ||
| 188 | 189 | ||
| 189 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ | 190 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ |
| 190 | }; | 191 | }; |
| @@ -311,27 +312,17 @@ static int prepare_capture_urb(snd_usb_substream_t *subs, | |||
| 311 | struct urb *urb) | 312 | struct urb *urb) |
| 312 | { | 313 | { |
| 313 | int i, offs; | 314 | int i, offs; |
| 314 | unsigned long flags; | ||
| 315 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 315 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
| 316 | 316 | ||
| 317 | offs = 0; | 317 | offs = 0; |
| 318 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 318 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
| 319 | urb->number_of_packets = 0; | ||
| 320 | spin_lock_irqsave(&subs->lock, flags); | ||
| 321 | for (i = 0; i < ctx->packets; i++) { | 319 | for (i = 0; i < ctx->packets; i++) { |
| 322 | urb->iso_frame_desc[i].offset = offs; | 320 | urb->iso_frame_desc[i].offset = offs; |
| 323 | urb->iso_frame_desc[i].length = subs->curpacksize; | 321 | urb->iso_frame_desc[i].length = subs->curpacksize; |
| 324 | offs += subs->curpacksize; | 322 | offs += subs->curpacksize; |
| 325 | urb->number_of_packets++; | ||
| 326 | subs->transfer_sched += subs->curframesize; | ||
| 327 | if (subs->transfer_sched >= runtime->period_size) { | ||
| 328 | subs->transfer_sched -= runtime->period_size; | ||
| 329 | break; | ||
| 330 | } | ||
| 331 | } | 323 | } |
| 332 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 333 | urb->transfer_buffer = ctx->buf; | ||
| 334 | urb->transfer_buffer_length = offs; | 324 | urb->transfer_buffer_length = offs; |
| 325 | urb->number_of_packets = ctx->packets; | ||
| 335 | #if 0 // for check | 326 | #if 0 // for check |
| 336 | if (! urb->bandwidth) { | 327 | if (! urb->bandwidth) { |
| 337 | int bustime; | 328 | int bustime; |
| @@ -359,6 +350,7 @@ static int retire_capture_urb(snd_usb_substream_t *subs, | |||
| 359 | unsigned char *cp; | 350 | unsigned char *cp; |
| 360 | int i; | 351 | int i; |
| 361 | unsigned int stride, len, oldptr; | 352 | unsigned int stride, len, oldptr; |
| 353 | int period_elapsed = 0; | ||
| 362 | 354 | ||
| 363 | stride = runtime->frame_bits >> 3; | 355 | stride = runtime->frame_bits >> 3; |
| 364 | 356 | ||
| @@ -378,6 +370,10 @@ static int retire_capture_urb(snd_usb_substream_t *subs, | |||
| 378 | if (subs->hwptr_done >= runtime->buffer_size) | 370 | if (subs->hwptr_done >= runtime->buffer_size) |
| 379 | subs->hwptr_done -= runtime->buffer_size; | 371 | subs->hwptr_done -= runtime->buffer_size; |
| 380 | subs->transfer_done += len; | 372 | subs->transfer_done += len; |
| 373 | if (subs->transfer_done >= runtime->period_size) { | ||
| 374 | subs->transfer_done -= runtime->period_size; | ||
| 375 | period_elapsed = 1; | ||
| 376 | } | ||
| 381 | spin_unlock_irqrestore(&subs->lock, flags); | 377 | spin_unlock_irqrestore(&subs->lock, flags); |
| 382 | /* copy a data chunk */ | 378 | /* copy a data chunk */ |
| 383 | if (oldptr + len > runtime->buffer_size) { | 379 | if (oldptr + len > runtime->buffer_size) { |
| @@ -388,15 +384,9 @@ static int retire_capture_urb(snd_usb_substream_t *subs, | |||
| 388 | } else { | 384 | } else { |
| 389 | memcpy(runtime->dma_area + oldptr * stride, cp, len * stride); | 385 | memcpy(runtime->dma_area + oldptr * stride, cp, len * stride); |
| 390 | } | 386 | } |
| 391 | /* update the pointer, call callback if necessary */ | ||
| 392 | spin_lock_irqsave(&subs->lock, flags); | ||
| 393 | if (subs->transfer_done >= runtime->period_size) { | ||
| 394 | subs->transfer_done -= runtime->period_size; | ||
| 395 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 396 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 397 | } else | ||
| 398 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 399 | } | 387 | } |
| 388 | if (period_elapsed) | ||
| 389 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 400 | return 0; | 390 | return 0; |
| 401 | } | 391 | } |
| 402 | 392 | ||
| @@ -492,12 +482,10 @@ static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs, | |||
| 492 | /* | 482 | /* |
| 493 | * prepare urb for playback data pipe | 483 | * prepare urb for playback data pipe |
| 494 | * | 484 | * |
| 495 | * we copy the data directly from the pcm buffer. | 485 | * Since a URB can handle only a single linear buffer, we must use double |
| 496 | * the current position to be copied is held in hwptr field. | 486 | * buffering when the data to be transferred overflows the buffer boundary. |
| 497 | * since a urb can handle only a single linear buffer, if the total | 487 | * To avoid inconsistencies when updating hwptr_done, we use double buffering |
| 498 | * transferred area overflows the buffer boundary, we cannot send | 488 | * for all URBs. |
| 499 | * it directly from the buffer. thus the data is once copied to | ||
| 500 | * a temporary buffer and urb points to that. | ||
| 501 | */ | 489 | */ |
| 502 | static int prepare_playback_urb(snd_usb_substream_t *subs, | 490 | static int prepare_playback_urb(snd_usb_substream_t *subs, |
| 503 | snd_pcm_runtime_t *runtime, | 491 | snd_pcm_runtime_t *runtime, |
| @@ -506,6 +494,7 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, | |||
| 506 | int i, stride, offs; | 494 | int i, stride, offs; |
| 507 | unsigned int counts; | 495 | unsigned int counts; |
| 508 | unsigned long flags; | 496 | unsigned long flags; |
| 497 | int period_elapsed = 0; | ||
| 509 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 498 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
| 510 | 499 | ||
| 511 | stride = runtime->frame_bits >> 3; | 500 | stride = runtime->frame_bits >> 3; |
| @@ -530,80 +519,85 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, | |||
| 530 | urb->iso_frame_desc[i].length = counts * stride; | 519 | urb->iso_frame_desc[i].length = counts * stride; |
| 531 | offs += counts; | 520 | offs += counts; |
| 532 | urb->number_of_packets++; | 521 | urb->number_of_packets++; |
| 533 | subs->transfer_sched += counts; | 522 | subs->transfer_done += counts; |
| 534 | if (subs->transfer_sched >= runtime->period_size) { | 523 | if (subs->transfer_done >= runtime->period_size) { |
| 535 | subs->transfer_sched -= runtime->period_size; | 524 | subs->transfer_done -= runtime->period_size; |
| 525 | period_elapsed = 1; | ||
| 536 | if (subs->fmt_type == USB_FORMAT_TYPE_II) { | 526 | if (subs->fmt_type == USB_FORMAT_TYPE_II) { |
| 537 | if (subs->transfer_sched > 0) { | 527 | if (subs->transfer_done > 0) { |
| 538 | /* FIXME: fill-max mode is not supported yet */ | 528 | /* FIXME: fill-max mode is not |
| 539 | offs -= subs->transfer_sched; | 529 | * supported yet */ |
| 540 | counts -= subs->transfer_sched; | 530 | offs -= subs->transfer_done; |
| 541 | urb->iso_frame_desc[i].length = counts * stride; | 531 | counts -= subs->transfer_done; |
| 542 | subs->transfer_sched = 0; | 532 | urb->iso_frame_desc[i].length = |
| 533 | counts * stride; | ||
| 534 | subs->transfer_done = 0; | ||
| 543 | } | 535 | } |
| 544 | i++; | 536 | i++; |
| 545 | if (i < ctx->packets) { | 537 | if (i < ctx->packets) { |
| 546 | /* add a transfer delimiter */ | 538 | /* add a transfer delimiter */ |
| 547 | urb->iso_frame_desc[i].offset = offs * stride; | 539 | urb->iso_frame_desc[i].offset = |
| 540 | offs * stride; | ||
| 548 | urb->iso_frame_desc[i].length = 0; | 541 | urb->iso_frame_desc[i].length = 0; |
| 549 | urb->number_of_packets++; | 542 | urb->number_of_packets++; |
| 550 | } | 543 | } |
| 544 | break; | ||
| 551 | } | 545 | } |
| 552 | break; | ||
| 553 | } | 546 | } |
| 547 | /* finish at the frame boundary at/after the period boundary */ | ||
| 548 | if (period_elapsed && | ||
| 549 | (i & (subs->packs_per_ms - 1)) == subs->packs_per_ms - 1) | ||
| 550 | break; | ||
| 554 | } | 551 | } |
| 555 | if (subs->hwptr + offs > runtime->buffer_size) { | 552 | if (subs->hwptr_done + offs > runtime->buffer_size) { |
| 556 | /* err, the transferred area goes over buffer boundary. | 553 | /* err, the transferred area goes over buffer boundary. */ |
| 557 | * copy the data to the temp buffer. | 554 | unsigned int len = runtime->buffer_size - subs->hwptr_done; |
| 558 | */ | 555 | memcpy(urb->transfer_buffer, |
| 559 | int len; | 556 | runtime->dma_area + subs->hwptr_done * stride, |
| 560 | len = runtime->buffer_size - subs->hwptr; | 557 | len * stride); |
| 561 | urb->transfer_buffer = subs->tmpbuf; | 558 | memcpy(urb->transfer_buffer + len * stride, |
| 562 | memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * stride, len * stride); | 559 | runtime->dma_area, |
| 563 | memcpy(subs->tmpbuf + len * stride, runtime->dma_area, (offs - len) * stride); | 560 | (offs - len) * stride); |
| 564 | subs->hwptr += offs; | ||
| 565 | subs->hwptr -= runtime->buffer_size; | ||
| 566 | } else { | 561 | } else { |
| 567 | /* set the buffer pointer */ | 562 | memcpy(urb->transfer_buffer, |
| 568 | urb->transfer_buffer = runtime->dma_area + subs->hwptr * stride; | 563 | runtime->dma_area + subs->hwptr_done * stride, |
| 569 | subs->hwptr += offs; | 564 | offs * stride); |
| 570 | if (subs->hwptr == runtime->buffer_size) | ||
| 571 | subs->hwptr = 0; | ||
| 572 | } | 565 | } |
| 566 | subs->hwptr_done += offs; | ||
| 567 | if (subs->hwptr_done >= runtime->buffer_size) | ||
| 568 | subs->hwptr_done -= runtime->buffer_size; | ||
| 573 | spin_unlock_irqrestore(&subs->lock, flags); | 569 | spin_unlock_irqrestore(&subs->lock, flags); |
| 574 | urb->transfer_buffer_length = offs * stride; | 570 | urb->transfer_buffer_length = offs * stride; |
| 575 | ctx->transfer = offs; | 571 | if (period_elapsed) { |
| 576 | 572 | if (likely(subs->running)) | |
| 573 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 574 | else | ||
| 575 | tasklet_hi_schedule(&subs->start_period_elapsed); | ||
| 576 | } | ||
| 577 | return 0; | 577 | return 0; |
| 578 | } | 578 | } |
| 579 | 579 | ||
| 580 | /* | 580 | /* |
| 581 | * process after playback data complete | 581 | * process after playback data complete |
| 582 | * | 582 | * - nothing to do |
| 583 | * update the current position and call callback if a period is processed. | ||
| 584 | */ | 583 | */ |
| 585 | static int retire_playback_urb(snd_usb_substream_t *subs, | 584 | static int retire_playback_urb(snd_usb_substream_t *subs, |
| 586 | snd_pcm_runtime_t *runtime, | 585 | snd_pcm_runtime_t *runtime, |
| 587 | struct urb *urb) | 586 | struct urb *urb) |
| 588 | { | 587 | { |
| 589 | unsigned long flags; | ||
| 590 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | ||
| 591 | |||
| 592 | spin_lock_irqsave(&subs->lock, flags); | ||
| 593 | subs->transfer_done += ctx->transfer; | ||
| 594 | subs->hwptr_done += ctx->transfer; | ||
| 595 | ctx->transfer = 0; | ||
| 596 | if (subs->hwptr_done >= runtime->buffer_size) | ||
| 597 | subs->hwptr_done -= runtime->buffer_size; | ||
| 598 | if (subs->transfer_done >= runtime->period_size) { | ||
| 599 | subs->transfer_done -= runtime->period_size; | ||
| 600 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 601 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 602 | } else | ||
| 603 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 604 | return 0; | 588 | return 0; |
| 605 | } | 589 | } |
| 606 | 590 | ||
| 591 | /* | ||
| 592 | * Delay the snd_pcm_period_elapsed() call until after the start trigger | ||
| 593 | * callback so that we're not longer in the substream's lock. | ||
| 594 | */ | ||
| 595 | static void start_period_elapsed(unsigned long data) | ||
| 596 | { | ||
| 597 | snd_usb_substream_t *subs = (snd_usb_substream_t *)data; | ||
| 598 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 599 | } | ||
| 600 | |||
| 607 | 601 | ||
| 608 | /* | 602 | /* |
| 609 | */ | 603 | */ |
| @@ -683,6 +677,42 @@ static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs) | |||
| 683 | } | 677 | } |
| 684 | 678 | ||
| 685 | 679 | ||
| 680 | /* get the physical page pointer at the given offset */ | ||
| 681 | static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs, | ||
| 682 | unsigned long offset) | ||
| 683 | { | ||
| 684 | void *pageptr = subs->runtime->dma_area + offset; | ||
| 685 | return vmalloc_to_page(pageptr); | ||
| 686 | } | ||
| 687 | |||
| 688 | /* allocate virtual buffer; may be called more than once */ | ||
| 689 | static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size) | ||
| 690 | { | ||
| 691 | snd_pcm_runtime_t *runtime = subs->runtime; | ||
| 692 | if (runtime->dma_area) { | ||
| 693 | if (runtime->dma_bytes >= size) | ||
| 694 | return 0; /* already large enough */ | ||
| 695 | vfree_nocheck(runtime->dma_area); | ||
| 696 | } | ||
| 697 | runtime->dma_area = vmalloc_nocheck(size); | ||
| 698 | if (! runtime->dma_area) | ||
| 699 | return -ENOMEM; | ||
| 700 | runtime->dma_bytes = size; | ||
| 701 | return 0; | ||
| 702 | } | ||
| 703 | |||
| 704 | /* free virtual buffer; may be called more than once */ | ||
| 705 | static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs) | ||
| 706 | { | ||
| 707 | snd_pcm_runtime_t *runtime = subs->runtime; | ||
| 708 | if (runtime->dma_area) { | ||
| 709 | vfree_nocheck(runtime->dma_area); | ||
| 710 | runtime->dma_area = NULL; | ||
| 711 | } | ||
| 712 | return 0; | ||
| 713 | } | ||
| 714 | |||
| 715 | |||
| 686 | /* | 716 | /* |
| 687 | * unlink active urbs. | 717 | * unlink active urbs. |
| 688 | */ | 718 | */ |
| @@ -824,8 +854,14 @@ static int wait_clear_urbs(snd_usb_substream_t *subs) | |||
| 824 | */ | 854 | */ |
| 825 | static snd_pcm_uframes_t snd_usb_pcm_pointer(snd_pcm_substream_t *substream) | 855 | static snd_pcm_uframes_t snd_usb_pcm_pointer(snd_pcm_substream_t *substream) |
| 826 | { | 856 | { |
| 827 | snd_usb_substream_t *subs = (snd_usb_substream_t *)substream->runtime->private_data; | 857 | snd_usb_substream_t *subs; |
| 828 | return subs->hwptr_done; | 858 | snd_pcm_uframes_t hwptr_done; |
| 859 | |||
| 860 | subs = (snd_usb_substream_t *)substream->runtime->private_data; | ||
| 861 | spin_lock(&subs->lock); | ||
| 862 | hwptr_done = subs->hwptr_done; | ||
| 863 | spin_unlock(&subs->lock); | ||
| 864 | return hwptr_done; | ||
| 829 | } | 865 | } |
| 830 | 866 | ||
| 831 | 867 | ||
| @@ -858,11 +894,13 @@ static int snd_usb_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | |||
| 858 | static void release_urb_ctx(snd_urb_ctx_t *u) | 894 | static void release_urb_ctx(snd_urb_ctx_t *u) |
| 859 | { | 895 | { |
| 860 | if (u->urb) { | 896 | if (u->urb) { |
| 897 | if (u->buffer_size) | ||
| 898 | usb_buffer_free(u->subs->dev, u->buffer_size, | ||
| 899 | u->urb->transfer_buffer, | ||
| 900 | u->urb->transfer_dma); | ||
| 861 | usb_free_urb(u->urb); | 901 | usb_free_urb(u->urb); |
| 862 | u->urb = NULL; | 902 | u->urb = NULL; |
| 863 | } | 903 | } |
| 864 | kfree(u->buf); | ||
| 865 | u->buf = NULL; | ||
| 866 | } | 904 | } |
| 867 | 905 | ||
| 868 | /* | 906 | /* |
| @@ -880,8 +918,9 @@ static void release_substream_urbs(snd_usb_substream_t *subs, int force) | |||
| 880 | release_urb_ctx(&subs->dataurb[i]); | 918 | release_urb_ctx(&subs->dataurb[i]); |
| 881 | for (i = 0; i < SYNC_URBS; i++) | 919 | for (i = 0; i < SYNC_URBS; i++) |
| 882 | release_urb_ctx(&subs->syncurb[i]); | 920 | release_urb_ctx(&subs->syncurb[i]); |
| 883 | kfree(subs->tmpbuf); | 921 | usb_buffer_free(subs->dev, SYNC_URBS * 4, |
| 884 | subs->tmpbuf = NULL; | 922 | subs->syncbuf, subs->sync_dma); |
| 923 | subs->syncbuf = NULL; | ||
| 885 | subs->nurbs = 0; | 924 | subs->nurbs = 0; |
| 886 | } | 925 | } |
| 887 | 926 | ||
| @@ -893,7 +932,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
| 893 | { | 932 | { |
| 894 | unsigned int maxsize, n, i; | 933 | unsigned int maxsize, n, i; |
| 895 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; | 934 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; |
| 896 | unsigned int npacks[MAX_URBS], urb_packs, total_packs; | 935 | unsigned int npacks[MAX_URBS], urb_packs, total_packs, packs_per_ms; |
| 897 | 936 | ||
| 898 | /* calculate the frequency in 16.16 format */ | 937 | /* calculate the frequency in 16.16 format */ |
| 899 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | 938 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
| @@ -920,24 +959,40 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
| 920 | else | 959 | else |
| 921 | subs->curpacksize = maxsize; | 960 | subs->curpacksize = maxsize; |
| 922 | 961 | ||
| 923 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | 962 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) |
| 924 | urb_packs = nrpacks; | 963 | packs_per_ms = 8 >> subs->datainterval; |
| 925 | else | 964 | else |
| 926 | urb_packs = (nrpacks * 8) >> subs->datainterval; | 965 | packs_per_ms = 1; |
| 966 | subs->packs_per_ms = packs_per_ms; | ||
| 927 | 967 | ||
| 928 | /* allocate a temporary buffer for playback */ | ||
| 929 | if (is_playback) { | 968 | if (is_playback) { |
| 930 | subs->tmpbuf = kmalloc(maxsize * urb_packs, GFP_KERNEL); | 969 | urb_packs = nrpacks; |
| 931 | if (! subs->tmpbuf) { | 970 | urb_packs = max(urb_packs, (unsigned int)MIN_PACKS_URB); |
| 932 | snd_printk(KERN_ERR "cannot malloc tmpbuf\n"); | 971 | urb_packs = min(urb_packs, (unsigned int)MAX_PACKS); |
| 933 | return -ENOMEM; | 972 | } else |
| 934 | } | 973 | urb_packs = 1; |
| 935 | } | 974 | urb_packs *= packs_per_ms; |
| 936 | 975 | ||
| 937 | /* decide how many packets to be used */ | 976 | /* decide how many packets to be used */ |
| 938 | total_packs = (period_bytes + maxsize - 1) / maxsize; | 977 | if (is_playback) { |
| 939 | if (total_packs < 2 * MIN_PACKS_URB) | 978 | unsigned int minsize; |
| 940 | total_packs = 2 * MIN_PACKS_URB; | 979 | /* determine how small a packet can be */ |
| 980 | minsize = (subs->freqn >> (16 - subs->datainterval)) | ||
| 981 | * (frame_bits >> 3); | ||
| 982 | /* with sync from device, assume it can be 12% lower */ | ||
| 983 | if (subs->syncpipe) | ||
| 984 | minsize -= minsize >> 3; | ||
| 985 | minsize = max(minsize, 1u); | ||
| 986 | total_packs = (period_bytes + minsize - 1) / minsize; | ||
| 987 | /* round up to multiple of packs_per_ms */ | ||
| 988 | total_packs = (total_packs + packs_per_ms - 1) | ||
| 989 | & ~(packs_per_ms - 1); | ||
| 990 | /* we need at least two URBs for queueing */ | ||
| 991 | if (total_packs < 2 * MIN_PACKS_URB * packs_per_ms) | ||
| 992 | total_packs = 2 * MIN_PACKS_URB * packs_per_ms; | ||
| 993 | } else { | ||
| 994 | total_packs = MAX_URBS * urb_packs; | ||
| 995 | } | ||
| 941 | subs->nurbs = (total_packs + urb_packs - 1) / urb_packs; | 996 | subs->nurbs = (total_packs + urb_packs - 1) / urb_packs; |
| 942 | if (subs->nurbs > MAX_URBS) { | 997 | if (subs->nurbs > MAX_URBS) { |
| 943 | /* too much... */ | 998 | /* too much... */ |
| @@ -956,7 +1011,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
| 956 | subs->nurbs = 2; | 1011 | subs->nurbs = 2; |
| 957 | npacks[0] = (total_packs + 1) / 2; | 1012 | npacks[0] = (total_packs + 1) / 2; |
| 958 | npacks[1] = total_packs - npacks[0]; | 1013 | npacks[1] = total_packs - npacks[0]; |
| 959 | } else if (npacks[subs->nurbs-1] < MIN_PACKS_URB) { | 1014 | } else if (npacks[subs->nurbs-1] < MIN_PACKS_URB * packs_per_ms) { |
| 960 | /* the last packet is too small.. */ | 1015 | /* the last packet is too small.. */ |
| 961 | if (subs->nurbs > 2) { | 1016 | if (subs->nurbs > 2) { |
| 962 | /* merge to the first one */ | 1017 | /* merge to the first one */ |
| @@ -975,27 +1030,20 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
| 975 | snd_urb_ctx_t *u = &subs->dataurb[i]; | 1030 | snd_urb_ctx_t *u = &subs->dataurb[i]; |
| 976 | u->index = i; | 1031 | u->index = i; |
| 977 | u->subs = subs; | 1032 | u->subs = subs; |
| 978 | u->transfer = 0; | ||
| 979 | u->packets = npacks[i]; | 1033 | u->packets = npacks[i]; |
| 1034 | u->buffer_size = maxsize * u->packets; | ||
| 980 | if (subs->fmt_type == USB_FORMAT_TYPE_II) | 1035 | if (subs->fmt_type == USB_FORMAT_TYPE_II) |
| 981 | u->packets++; /* for transfer delimiter */ | 1036 | u->packets++; /* for transfer delimiter */ |
| 982 | if (! is_playback) { | ||
| 983 | /* allocate a capture buffer per urb */ | ||
| 984 | u->buf = kmalloc(maxsize * u->packets, GFP_KERNEL); | ||
| 985 | if (! u->buf) { | ||
| 986 | release_substream_urbs(subs, 0); | ||
| 987 | return -ENOMEM; | ||
| 988 | } | ||
| 989 | } | ||
| 990 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | 1037 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); |
| 991 | if (! u->urb) { | 1038 | if (! u->urb) |
| 992 | release_substream_urbs(subs, 0); | 1039 | goto out_of_memory; |
| 993 | return -ENOMEM; | 1040 | u->urb->transfer_buffer = |
| 994 | } | 1041 | usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL, |
| 995 | u->urb->dev = subs->dev; | 1042 | &u->urb->transfer_dma); |
| 1043 | if (! u->urb->transfer_buffer) | ||
| 1044 | goto out_of_memory; | ||
| 996 | u->urb->pipe = subs->datapipe; | 1045 | u->urb->pipe = subs->datapipe; |
| 997 | u->urb->transfer_flags = URB_ISO_ASAP; | 1046 | u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; |
| 998 | u->urb->number_of_packets = u->packets; | ||
| 999 | u->urb->interval = 1 << subs->datainterval; | 1047 | u->urb->interval = 1 << subs->datainterval; |
| 1000 | u->urb->context = u; | 1048 | u->urb->context = u; |
| 1001 | u->urb->complete = snd_usb_complete_callback(snd_complete_urb); | 1049 | u->urb->complete = snd_usb_complete_callback(snd_complete_urb); |
| @@ -1003,21 +1051,24 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
| 1003 | 1051 | ||
| 1004 | if (subs->syncpipe) { | 1052 | if (subs->syncpipe) { |
| 1005 | /* allocate and initialize sync urbs */ | 1053 | /* allocate and initialize sync urbs */ |
| 1054 | subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4, | ||
| 1055 | GFP_KERNEL, &subs->sync_dma); | ||
| 1056 | if (! subs->syncbuf) | ||
| 1057 | goto out_of_memory; | ||
| 1006 | for (i = 0; i < SYNC_URBS; i++) { | 1058 | for (i = 0; i < SYNC_URBS; i++) { |
| 1007 | snd_urb_ctx_t *u = &subs->syncurb[i]; | 1059 | snd_urb_ctx_t *u = &subs->syncurb[i]; |
| 1008 | u->index = i; | 1060 | u->index = i; |
| 1009 | u->subs = subs; | 1061 | u->subs = subs; |
| 1010 | u->packets = 1; | 1062 | u->packets = 1; |
| 1011 | u->urb = usb_alloc_urb(1, GFP_KERNEL); | 1063 | u->urb = usb_alloc_urb(1, GFP_KERNEL); |
| 1012 | if (! u->urb) { | 1064 | if (! u->urb) |
| 1013 | release_substream_urbs(subs, 0); | 1065 | goto out_of_memory; |
| 1014 | return -ENOMEM; | ||
| 1015 | } | ||
| 1016 | u->urb->transfer_buffer = subs->syncbuf + i * 4; | 1066 | u->urb->transfer_buffer = subs->syncbuf + i * 4; |
| 1067 | u->urb->transfer_dma = subs->sync_dma + i * 4; | ||
| 1017 | u->urb->transfer_buffer_length = 4; | 1068 | u->urb->transfer_buffer_length = 4; |
| 1018 | u->urb->dev = subs->dev; | ||
| 1019 | u->urb->pipe = subs->syncpipe; | 1069 | u->urb->pipe = subs->syncpipe; |
| 1020 | u->urb->transfer_flags = URB_ISO_ASAP; | 1070 | u->urb->transfer_flags = URB_ISO_ASAP | |
| 1071 | URB_NO_TRANSFER_DMA_MAP; | ||
| 1021 | u->urb->number_of_packets = 1; | 1072 | u->urb->number_of_packets = 1; |
| 1022 | u->urb->interval = 1 << subs->syncinterval; | 1073 | u->urb->interval = 1 << subs->syncinterval; |
| 1023 | u->urb->context = u; | 1074 | u->urb->context = u; |
| @@ -1025,6 +1076,10 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
| 1025 | } | 1076 | } |
| 1026 | } | 1077 | } |
| 1027 | return 0; | 1078 | return 0; |
| 1079 | |||
| 1080 | out_of_memory: | ||
| 1081 | release_substream_urbs(subs, 0); | ||
| 1082 | return -ENOMEM; | ||
| 1028 | } | 1083 | } |
| 1029 | 1084 | ||
| 1030 | 1085 | ||
| @@ -1293,7 +1348,8 @@ static int snd_usb_hw_params(snd_pcm_substream_t *substream, | |||
| 1293 | unsigned int channels, rate, format; | 1348 | unsigned int channels, rate, format; |
| 1294 | int ret, changed; | 1349 | int ret, changed; |
| 1295 | 1350 | ||
| 1296 | ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 1351 | ret = snd_pcm_alloc_vmalloc_buffer(substream, |
| 1352 | params_buffer_bytes(hw_params)); | ||
| 1297 | if (ret < 0) | 1353 | if (ret < 0) |
| 1298 | return ret; | 1354 | return ret; |
| 1299 | 1355 | ||
| @@ -1349,7 +1405,7 @@ static int snd_usb_hw_free(snd_pcm_substream_t *substream) | |||
| 1349 | subs->cur_rate = 0; | 1405 | subs->cur_rate = 0; |
| 1350 | subs->period_bytes = 0; | 1406 | subs->period_bytes = 0; |
| 1351 | release_substream_urbs(subs, 0); | 1407 | release_substream_urbs(subs, 0); |
| 1352 | return snd_pcm_lib_free_pages(substream); | 1408 | return snd_pcm_free_vmalloc_buffer(substream); |
| 1353 | } | 1409 | } |
| 1354 | 1410 | ||
| 1355 | /* | 1411 | /* |
| @@ -1372,9 +1428,7 @@ static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream) | |||
| 1372 | subs->curframesize = bytes_to_frames(runtime, subs->curpacksize); | 1428 | subs->curframesize = bytes_to_frames(runtime, subs->curpacksize); |
| 1373 | 1429 | ||
| 1374 | /* reset the pointer */ | 1430 | /* reset the pointer */ |
| 1375 | subs->hwptr = 0; | ||
| 1376 | subs->hwptr_done = 0; | 1431 | subs->hwptr_done = 0; |
| 1377 | subs->transfer_sched = 0; | ||
| 1378 | subs->transfer_done = 0; | 1432 | subs->transfer_done = 0; |
| 1379 | subs->phase = 0; | 1433 | subs->phase = 0; |
| 1380 | 1434 | ||
| @@ -1390,7 +1444,7 @@ static snd_pcm_hardware_t snd_usb_playback = | |||
| 1390 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1444 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1391 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1445 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1392 | SNDRV_PCM_INFO_MMAP_VALID), | 1446 | SNDRV_PCM_INFO_MMAP_VALID), |
| 1393 | .buffer_bytes_max = (128*1024), | 1447 | .buffer_bytes_max = (256*1024), |
| 1394 | .period_bytes_min = 64, | 1448 | .period_bytes_min = 64, |
| 1395 | .period_bytes_max = (128*1024), | 1449 | .period_bytes_max = (128*1024), |
| 1396 | .periods_min = 2, | 1450 | .periods_min = 2, |
| @@ -1402,7 +1456,7 @@ static snd_pcm_hardware_t snd_usb_capture = | |||
| 1402 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1456 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
| 1403 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1457 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 1404 | SNDRV_PCM_INFO_MMAP_VALID), | 1458 | SNDRV_PCM_INFO_MMAP_VALID), |
| 1405 | .buffer_bytes_max = (128*1024), | 1459 | .buffer_bytes_max = (256*1024), |
| 1406 | .period_bytes_min = 64, | 1460 | .period_bytes_min = 64, |
| 1407 | .period_bytes_max = (128*1024), | 1461 | .period_bytes_max = (128*1024), |
| 1408 | .periods_min = 2, | 1462 | .periods_min = 2, |
| @@ -1794,6 +1848,7 @@ static snd_pcm_ops_t snd_usb_playback_ops = { | |||
| 1794 | .prepare = snd_usb_pcm_prepare, | 1848 | .prepare = snd_usb_pcm_prepare, |
| 1795 | .trigger = snd_usb_pcm_trigger, | 1849 | .trigger = snd_usb_pcm_trigger, |
| 1796 | .pointer = snd_usb_pcm_pointer, | 1850 | .pointer = snd_usb_pcm_pointer, |
| 1851 | .page = snd_pcm_get_vmalloc_page, | ||
| 1797 | }; | 1852 | }; |
| 1798 | 1853 | ||
| 1799 | static snd_pcm_ops_t snd_usb_capture_ops = { | 1854 | static snd_pcm_ops_t snd_usb_capture_ops = { |
| @@ -1805,6 +1860,7 @@ static snd_pcm_ops_t snd_usb_capture_ops = { | |||
| 1805 | .prepare = snd_usb_pcm_prepare, | 1860 | .prepare = snd_usb_pcm_prepare, |
| 1806 | .trigger = snd_usb_pcm_trigger, | 1861 | .trigger = snd_usb_pcm_trigger, |
| 1807 | .pointer = snd_usb_pcm_pointer, | 1862 | .pointer = snd_usb_pcm_pointer, |
| 1863 | .page = snd_pcm_get_vmalloc_page, | ||
| 1808 | }; | 1864 | }; |
| 1809 | 1865 | ||
| 1810 | 1866 | ||
| @@ -2021,6 +2077,9 @@ static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat | |||
| 2021 | 2077 | ||
| 2022 | INIT_LIST_HEAD(&subs->fmt_list); | 2078 | INIT_LIST_HEAD(&subs->fmt_list); |
| 2023 | spin_lock_init(&subs->lock); | 2079 | spin_lock_init(&subs->lock); |
| 2080 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 2081 | tasklet_init(&subs->start_period_elapsed, start_period_elapsed, | ||
| 2082 | (unsigned long)subs); | ||
| 2024 | 2083 | ||
| 2025 | subs->stream = as; | 2084 | subs->stream = as; |
| 2026 | subs->direction = stream; | 2085 | subs->direction = stream; |
| @@ -2029,10 +2088,6 @@ static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat | |||
| 2029 | subs->ops = audio_urb_ops[stream]; | 2088 | subs->ops = audio_urb_ops[stream]; |
| 2030 | else | 2089 | else |
| 2031 | subs->ops = audio_urb_ops_high_speed[stream]; | 2090 | subs->ops = audio_urb_ops_high_speed[stream]; |
| 2032 | snd_pcm_lib_preallocate_pages(as->pcm->streams[stream].substream, | ||
| 2033 | SNDRV_DMA_TYPE_CONTINUOUS, | ||
| 2034 | snd_dma_continuous_data(GFP_KERNEL), | ||
| 2035 | 64 * 1024, 128 * 1024); | ||
| 2036 | snd_pcm_set_ops(as->pcm, stream, | 2091 | snd_pcm_set_ops(as->pcm, stream, |
| 2037 | stream == SNDRV_PCM_STREAM_PLAYBACK ? | 2092 | stream == SNDRV_PCM_STREAM_PLAYBACK ? |
| 2038 | &snd_usb_playback_ops : &snd_usb_capture_ops); | 2093 | &snd_usb_playback_ops : &snd_usb_capture_ops); |
| @@ -2078,7 +2133,6 @@ static void snd_usb_audio_pcm_free(snd_pcm_t *pcm) | |||
| 2078 | snd_usb_stream_t *stream = pcm->private_data; | 2133 | snd_usb_stream_t *stream = pcm->private_data; |
| 2079 | if (stream) { | 2134 | if (stream) { |
| 2080 | stream->pcm = NULL; | 2135 | stream->pcm = NULL; |
| 2081 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
| 2082 | snd_usb_audio_stream_free(stream); | 2136 | snd_usb_audio_stream_free(stream); |
| 2083 | } | 2137 | } |
| 2084 | } | 2138 | } |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 5778a9b725ec..93dedde3c428 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/string.h> | 44 | #include <linux/string.h> |
| 45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
| 46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
| 47 | #include <linux/timer.h> | ||
| 47 | #include <linux/usb.h> | 48 | #include <linux/usb.h> |
| 48 | #include <sound/core.h> | 49 | #include <sound/core.h> |
| 49 | #include <sound/minors.h> | 50 | #include <sound/minors.h> |
| @@ -56,6 +57,12 @@ | |||
| 56 | */ | 57 | */ |
| 57 | /* #define DUMP_PACKETS */ | 58 | /* #define DUMP_PACKETS */ |
| 58 | 59 | ||
| 60 | /* | ||
| 61 | * how long to wait after some USB errors, so that khubd can disconnect() us | ||
| 62 | * without too many spurious errors | ||
| 63 | */ | ||
| 64 | #define ERROR_DELAY_JIFFIES (HZ / 10) | ||
| 65 | |||
| 59 | 66 | ||
| 60 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 67 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
| 61 | MODULE_DESCRIPTION("USB Audio/MIDI helper module"); | 68 | MODULE_DESCRIPTION("USB Audio/MIDI helper module"); |
| @@ -100,6 +107,7 @@ struct snd_usb_midi { | |||
| 100 | snd_rawmidi_t* rmidi; | 107 | snd_rawmidi_t* rmidi; |
| 101 | struct usb_protocol_ops* usb_protocol_ops; | 108 | struct usb_protocol_ops* usb_protocol_ops; |
| 102 | struct list_head list; | 109 | struct list_head list; |
| 110 | struct timer_list error_timer; | ||
| 103 | 111 | ||
| 104 | struct snd_usb_midi_endpoint { | 112 | struct snd_usb_midi_endpoint { |
| 105 | snd_usb_midi_out_endpoint_t *out; | 113 | snd_usb_midi_out_endpoint_t *out; |
| @@ -141,7 +149,8 @@ struct snd_usb_midi_in_endpoint { | |||
| 141 | struct usbmidi_in_port { | 149 | struct usbmidi_in_port { |
| 142 | snd_rawmidi_substream_t* substream; | 150 | snd_rawmidi_substream_t* substream; |
| 143 | } ports[0x10]; | 151 | } ports[0x10]; |
| 144 | int seen_f5; | 152 | u8 seen_f5; |
| 153 | u8 error_resubmit; | ||
| 145 | int current_port; | 154 | int current_port; |
| 146 | }; | 155 | }; |
| 147 | 156 | ||
| @@ -167,14 +176,22 @@ static int snd_usbmidi_submit_urb(struct urb* urb, int flags) | |||
| 167 | */ | 176 | */ |
| 168 | static int snd_usbmidi_urb_error(int status) | 177 | static int snd_usbmidi_urb_error(int status) |
| 169 | { | 178 | { |
| 170 | if (status == -ENOENT) | 179 | switch (status) { |
| 171 | return status; /* killed */ | 180 | /* manually unlinked, or device gone */ |
| 172 | if (status == -EILSEQ || | 181 | case -ENOENT: |
| 173 | status == -ECONNRESET || | 182 | case -ECONNRESET: |
| 174 | status == -ETIMEDOUT) | 183 | case -ESHUTDOWN: |
| 175 | return -ENODEV; /* device removed/shutdown */ | 184 | case -ENODEV: |
| 176 | snd_printk(KERN_ERR "urb status %d\n", status); | 185 | return -ENODEV; |
| 177 | return 0; /* continue */ | 186 | /* errors that might occur during unplugging */ |
| 187 | case -EPROTO: /* EHCI */ | ||
| 188 | case -ETIMEDOUT: /* OHCI */ | ||
| 189 | case -EILSEQ: /* UHCI */ | ||
| 190 | return -EIO; | ||
| 191 | default: | ||
| 192 | snd_printk(KERN_ERR "urb status %d\n", status); | ||
| 193 | return 0; /* continue */ | ||
| 194 | } | ||
| 178 | } | 195 | } |
| 179 | 196 | ||
| 180 | /* | 197 | /* |
| @@ -218,8 +235,15 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) | |||
| 218 | ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer, | 235 | ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer, |
| 219 | urb->actual_length); | 236 | urb->actual_length); |
| 220 | } else { | 237 | } else { |
| 221 | if (snd_usbmidi_urb_error(urb->status) < 0) | 238 | int err = snd_usbmidi_urb_error(urb->status); |
| 239 | if (err < 0) { | ||
| 240 | if (err != -ENODEV) { | ||
| 241 | ep->error_resubmit = 1; | ||
| 242 | mod_timer(&ep->umidi->error_timer, | ||
| 243 | jiffies + ERROR_DELAY_JIFFIES); | ||
| 244 | } | ||
| 222 | return; | 245 | return; |
| 246 | } | ||
| 223 | } | 247 | } |
| 224 | 248 | ||
| 225 | if (usb_pipe_needs_resubmit(urb->pipe)) { | 249 | if (usb_pipe_needs_resubmit(urb->pipe)) { |
| @@ -236,8 +260,13 @@ static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs) | |||
| 236 | ep->urb_active = 0; | 260 | ep->urb_active = 0; |
| 237 | spin_unlock(&ep->buffer_lock); | 261 | spin_unlock(&ep->buffer_lock); |
| 238 | if (urb->status < 0) { | 262 | if (urb->status < 0) { |
| 239 | if (snd_usbmidi_urb_error(urb->status) < 0) | 263 | int err = snd_usbmidi_urb_error(urb->status); |
| 264 | if (err < 0) { | ||
| 265 | if (err != -ENODEV) | ||
| 266 | mod_timer(&ep->umidi->error_timer, | ||
| 267 | jiffies + ERROR_DELAY_JIFFIES); | ||
| 240 | return; | 268 | return; |
| 269 | } | ||
| 241 | } | 270 | } |
| 242 | snd_usbmidi_do_output(ep); | 271 | snd_usbmidi_do_output(ep); |
| 243 | } | 272 | } |
| @@ -276,6 +305,24 @@ static void snd_usbmidi_out_tasklet(unsigned long data) | |||
| 276 | snd_usbmidi_do_output(ep); | 305 | snd_usbmidi_do_output(ep); |
| 277 | } | 306 | } |
| 278 | 307 | ||
| 308 | /* called after transfers had been interrupted due to some USB error */ | ||
| 309 | static void snd_usbmidi_error_timer(unsigned long data) | ||
| 310 | { | ||
| 311 | snd_usb_midi_t *umidi = (snd_usb_midi_t *)data; | ||
| 312 | int i; | ||
| 313 | |||
| 314 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
| 315 | snd_usb_midi_in_endpoint_t *in = umidi->endpoints[i].in; | ||
| 316 | if (in && in->error_resubmit) { | ||
| 317 | in->error_resubmit = 0; | ||
| 318 | in->urb->dev = umidi->chip->dev; | ||
| 319 | snd_usbmidi_submit_urb(in->urb, GFP_ATOMIC); | ||
| 320 | } | ||
| 321 | if (umidi->endpoints[i].out) | ||
| 322 | snd_usbmidi_do_output(umidi->endpoints[i].out); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 279 | /* helper function to send static data that may not DMA-able */ | 326 | /* helper function to send static data that may not DMA-able */ |
| 280 | static int send_bulk_static_data(snd_usb_midi_out_endpoint_t* ep, | 327 | static int send_bulk_static_data(snd_usb_midi_out_endpoint_t* ep, |
| 281 | const void *data, int len) | 328 | const void *data, int len) |
| @@ -594,17 +641,20 @@ static void snd_usbmidi_emagic_finish_out(snd_usb_midi_out_endpoint_t* ep) | |||
| 594 | static void snd_usbmidi_emagic_input(snd_usb_midi_in_endpoint_t* ep, | 641 | static void snd_usbmidi_emagic_input(snd_usb_midi_in_endpoint_t* ep, |
| 595 | uint8_t* buffer, int buffer_length) | 642 | uint8_t* buffer, int buffer_length) |
| 596 | { | 643 | { |
| 597 | /* ignore padding bytes at end of buffer */ | 644 | int i; |
| 598 | while (buffer_length > 0 && buffer[buffer_length - 1] == 0xff) | 645 | |
| 599 | --buffer_length; | 646 | /* FF indicates end of valid data */ |
| 647 | for (i = 0; i < buffer_length; ++i) | ||
| 648 | if (buffer[i] == 0xff) { | ||
| 649 | buffer_length = i; | ||
| 650 | break; | ||
| 651 | } | ||
| 600 | 652 | ||
| 601 | /* handle F5 at end of last buffer */ | 653 | /* handle F5 at end of last buffer */ |
| 602 | if (ep->seen_f5) | 654 | if (ep->seen_f5) |
| 603 | goto switch_port; | 655 | goto switch_port; |
| 604 | 656 | ||
| 605 | while (buffer_length > 0) { | 657 | while (buffer_length > 0) { |
| 606 | int i; | ||
| 607 | |||
| 608 | /* determine size of data until next F5 */ | 658 | /* determine size of data until next F5 */ |
| 609 | for (i = 0; i < buffer_length; ++i) | 659 | for (i = 0; i < buffer_length; ++i) |
| 610 | if (buffer[i] == 0xf5) | 660 | if (buffer[i] == 0xf5) |
| @@ -671,6 +721,10 @@ static void snd_usbmidi_emagic_output(snd_usb_midi_out_endpoint_t* ep) | |||
| 671 | break; | 721 | break; |
| 672 | } | 722 | } |
| 673 | } | 723 | } |
| 724 | if (buf_free < ep->max_transfer && buf_free > 0) { | ||
| 725 | *buf = 0xff; | ||
| 726 | --buf_free; | ||
| 727 | } | ||
| 674 | ep->urb->transfer_buffer_length = ep->max_transfer - buf_free; | 728 | ep->urb->transfer_buffer_length = ep->max_transfer - buf_free; |
| 675 | } | 729 | } |
| 676 | 730 | ||
| @@ -765,7 +819,10 @@ static snd_rawmidi_ops_t snd_usbmidi_input_ops = { | |||
| 765 | static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) | 819 | static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) |
| 766 | { | 820 | { |
| 767 | if (ep->urb) { | 821 | if (ep->urb) { |
| 768 | kfree(ep->urb->transfer_buffer); | 822 | usb_buffer_free(ep->umidi->chip->dev, |
| 823 | ep->urb->transfer_buffer_length, | ||
| 824 | ep->urb->transfer_buffer, | ||
| 825 | ep->urb->transfer_dma); | ||
| 769 | usb_free_urb(ep->urb); | 826 | usb_free_urb(ep->urb); |
| 770 | } | 827 | } |
| 771 | kfree(ep); | 828 | kfree(ep); |
| @@ -799,7 +856,8 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, | |||
| 799 | else | 856 | else |
| 800 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); | 857 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); |
| 801 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); | 858 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); |
| 802 | buffer = kmalloc(length, GFP_KERNEL); | 859 | buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL, |
| 860 | &ep->urb->transfer_dma); | ||
| 803 | if (!buffer) { | 861 | if (!buffer) { |
| 804 | snd_usbmidi_in_endpoint_delete(ep); | 862 | snd_usbmidi_in_endpoint_delete(ep); |
| 805 | return -ENOMEM; | 863 | return -ENOMEM; |
| @@ -812,6 +870,7 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, | |||
| 812 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, | 870 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, |
| 813 | snd_usb_complete_callback(snd_usbmidi_in_urb_complete), | 871 | snd_usb_complete_callback(snd_usbmidi_in_urb_complete), |
| 814 | ep); | 872 | ep); |
| 873 | ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | ||
| 815 | 874 | ||
| 816 | rep->in = ep; | 875 | rep->in = ep; |
| 817 | return 0; | 876 | return 0; |
| @@ -832,10 +891,10 @@ static unsigned int snd_usbmidi_count_bits(unsigned int x) | |||
| 832 | */ | 891 | */ |
| 833 | static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep) | 892 | static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep) |
| 834 | { | 893 | { |
| 835 | if (ep->tasklet.func) | ||
| 836 | tasklet_kill(&ep->tasklet); | ||
| 837 | if (ep->urb) { | 894 | if (ep->urb) { |
| 838 | kfree(ep->urb->transfer_buffer); | 895 | usb_buffer_free(ep->umidi->chip->dev, ep->max_transfer, |
| 896 | ep->urb->transfer_buffer, | ||
| 897 | ep->urb->transfer_dma); | ||
| 839 | usb_free_urb(ep->urb); | 898 | usb_free_urb(ep->urb); |
| 840 | } | 899 | } |
| 841 | kfree(ep); | 900 | kfree(ep); |
| @@ -867,7 +926,8 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, | |||
| 867 | /* we never use interrupt output pipes */ | 926 | /* we never use interrupt output pipes */ |
| 868 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); | 927 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); |
| 869 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | 928 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); |
| 870 | buffer = kmalloc(ep->max_transfer, GFP_KERNEL); | 929 | buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, |
| 930 | GFP_KERNEL, &ep->urb->transfer_dma); | ||
| 871 | if (!buffer) { | 931 | if (!buffer) { |
| 872 | snd_usbmidi_out_endpoint_delete(ep); | 932 | snd_usbmidi_out_endpoint_delete(ep); |
| 873 | return -ENOMEM; | 933 | return -ENOMEM; |
| @@ -875,6 +935,7 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, | |||
| 875 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, | 935 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, |
| 876 | ep->max_transfer, | 936 | ep->max_transfer, |
| 877 | snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep); | 937 | snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep); |
| 938 | ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | ||
| 878 | 939 | ||
| 879 | spin_lock_init(&ep->buffer_lock); | 940 | spin_lock_init(&ep->buffer_lock); |
| 880 | tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); | 941 | tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); |
| @@ -918,8 +979,11 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
| 918 | int i; | 979 | int i; |
| 919 | 980 | ||
| 920 | umidi = list_entry(p, snd_usb_midi_t, list); | 981 | umidi = list_entry(p, snd_usb_midi_t, list); |
| 982 | del_timer_sync(&umidi->error_timer); | ||
| 921 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | 983 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { |
| 922 | snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; | 984 | snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; |
| 985 | if (ep->out) | ||
| 986 | tasklet_kill(&ep->out->tasklet); | ||
| 923 | if (ep->out && ep->out->urb) { | 987 | if (ep->out && ep->out->urb) { |
| 924 | usb_kill_urb(ep->out->urb); | 988 | usb_kill_urb(ep->out->urb); |
| 925 | if (umidi->usb_protocol_ops->finish_out_endpoint) | 989 | if (umidi->usb_protocol_ops->finish_out_endpoint) |
| @@ -1480,6 +1544,9 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, | |||
| 1480 | umidi->iface = iface; | 1544 | umidi->iface = iface; |
| 1481 | umidi->quirk = quirk; | 1545 | umidi->quirk = quirk; |
| 1482 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | 1546 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; |
| 1547 | init_timer(&umidi->error_timer); | ||
| 1548 | umidi->error_timer.function = snd_usbmidi_error_timer; | ||
| 1549 | umidi->error_timer.data = (unsigned long)umidi; | ||
| 1483 | 1550 | ||
| 1484 | /* detect the endpoint(s) to use */ | 1551 | /* detect the endpoint(s) to use */ |
| 1485 | memset(endpoints, 0, sizeof(endpoints)); | 1552 | memset(endpoints, 0, sizeof(endpoints)); |
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index ef28061287f2..d0199c4e5551 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c | |||
| @@ -624,7 +624,7 @@ static int usX2Y_pcms_lock_check(snd_card_t *card) | |||
| 624 | for (s = 0; s < 2; ++s) { | 624 | for (s = 0; s < 2; ++s) { |
| 625 | snd_pcm_substream_t *substream; | 625 | snd_pcm_substream_t *substream; |
| 626 | substream = pcm->streams[s].substream; | 626 | substream = pcm->streams[s].substream; |
| 627 | if (substream && substream->open_flag) | 627 | if (substream && substream->ffile != NULL) |
| 628 | err = -EBUSY; | 628 | err = -EBUSY; |
| 629 | } | 629 | } |
| 630 | } | 630 | } |
