diff --git a/[refs] b/[refs] index dea7e3263bd7..ae396617177b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bbc0274e9bb2e3f1d724d445a2bd32566b9b66f7 +refs/heads/master: dcefb396c2af4d52fba48dc58b4021794b042046 diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 226013035d72..71ef0498d5e0 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -615,11 +615,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-hda-intel -------------------- - Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450, - VIA VT8251/VT8237A + Module for Intel HD Audio (ICH6, ICH6M, ICH7) model - force the model name - position_fix - Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF) Module supports up to 8 cards. @@ -637,7 +635,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 5stack 5-jack in back, 2-jack in front 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out w810 3-jack - z71v 3-jack (HP shared SPDIF) CMI9880 minimal 3-jack in back @@ -646,14 +643,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. full_dig 6-jack in back, 2-jack in front, SPDIF I/O allout 5-jack in back, 2-jack in front, SPDIF out - Note 2: If you get click noises on output, try the module option - position_fix=1 or 2. position_fix=1 will use the SD_LPIB - register value without FIFO size correction as the current - DMA pointer. position_fix=2 will make the driver to use - the position buffer instead of reading SD_LPIB register. - (Usually SD_LPLIB register is more accurate than the - position buffer.) - Module snd-hdsp --------------- @@ -688,19 +677,15 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * TerraTec EWS 88D * TerraTec EWX 24/96 * TerraTec DMX 6Fire - * TerraTec Phase 88 * Hoontech SoundTrack DSP 24 * Hoontech SoundTrack DSP 24 Value * Hoontech SoundTrack DSP 24 Media 7.1 - * Event Electronics, EZ8 * Digigram VX442 - * Lionstracs, Mediastaton model - Use the given board model, one of the following: delta1010, dio2496, delta66, delta44, audiophile, delta410, delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d, - dmx6fire, dsp24, dsp24_value, dsp24_71, ez8, - phase88, mediastation + dmx6fire, dsp24, dsp24_value, dsp24_71, ez8 omni - Omni I/O support for MidiMan M-Audio Delta44/66 cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever) in msec resolution, default value is 500 (0.5 sec) @@ -709,46 +694,20 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. is not used with all Envy24 based cards (for example in the MidiMan Delta serie). - Note: The supported board is detected by reading EEPROM or PCI - SSID (if EEPROM isn't available). You can override the - model by passing "model" module option in case that the - driver isn't configured properly or you want to try another - type for testing. - Module snd-ice1724 ------------------ - Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. + Module for Envy24HT (VT/ICE1724) based PCI sound cards. * MidiMan M Audio Revolution 7.1 * AMP Ltd AUDIO2000 - * TerraTec Aureon 5.1 Sky - * TerraTec Aureon 7.1 Space - * TerraTec Aureon 7.1 Universe - * TerraTec Phase 22 - * TerraTec Phase 28 - * AudioTrak Prodigy 7.1 - * AudioTrak Prodigy 192 - * Pontis MS300 - * Albatron K8X800 Pro II - * Chaintech ZNF3-150 - * Chaintech ZNF3-250 - * Chaintech 9CJS - * Chaintech AV-710 - * Shuttle SN25P + * TerraTec Aureon Sky-5.1, Space-7.1 model - Use the given board model, one of the following: - revo71, amp2000, prodigy71, prodigy192, aureon51, - aureon71, universe, k8x800, phase22, phase28, ms300, - av710 + revo71, amp2000, prodigy71, aureon51, aureon71, + k8x800 Module supports up to 8 cards and autoprobe. - Note: The supported board is detected by reading EEPROM or PCI - SSID (if EEPROM isn't available). You can override the - model by passing "model" module option in case that the - driver isn't configured properly or you want to try another - type for testing. - Module snd-intel8x0 ------------------- @@ -1252,18 +1211,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ------------------ Module for AC'97 motherboards based on VIA 82C686A/686B, 8233, - 8233A, 8233C, 8235, 8237 (south) bridge. + 8233A, 8233C, 8235 (south) bridge. mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup [VIA686A/686B only] joystick - Enable joystick (default off) [VIA686A/686B only] ac97_clock - AC'97 codec clock base (default 48000Hz) dxs_support - support DXS channels, - 0 = auto (default), 1 = enable, 2 = disable, - 3 = 48k only, 4 = no VRA, 5 = enable any sample - rate and different sample rates on different - channels - [VIA8233/C, 8235, 8237 only] + 0 = auto (defalut), 1 = enable, 2 = disable, + 3 = 48k only, 4 = no VRA + [VIA8233/C,8235 only] ac97_quirk - AC'97 workaround for strange hardware See the description of intel8x0 module for details. @@ -1275,23 +1232,18 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. default value 1.4. Then the interrupt number will be assigned under 15. You might also upgrade your BIOS. - Note: VIA8233/5/7 (not VIA8233A) can support DXS (direct sound) + Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound) channels as the first PCM. On these channels, up to 4 - streams can be played at the same time, and the controller - can perform sample rate conversion with separate rates for - each channel. + streams can be played at the same time. As default (dxs_support = 0), 48k fixed rate is chosen except for the known devices since the output is often noisy except for 48k on some mother boards due to the bug of BIOS. - Please try once dxs_support=5 and if it works on other + Please try once dxs_support=1 and if it works on other sample rates (e.g. 44.1kHz of mp3 playback), please let us know the PCI subsystem vendor/device id's (output of "lspci -nv"). - If dxs_support=5 does not work, try dxs_support=4; if it - doesn't work too, try dxs_support=1. (dxs_support=1 is - usually for old motherboards. The correct implementated - board should work with 4 or 5.) If it still doesn't + If it doesn't work, try dxs_support=4. If it still doesn't work and the default setting is ok, dxs_support=3 is the right choice. If the default setting doesn't work at all, try dxs_support=2 to disable the DXS channels. diff --git a/trunk/Documentation/sound/alsa/CMIPCI.txt b/trunk/Documentation/sound/alsa/CMIPCI.txt index 1872e24442a4..4a7df771b806 100644 --- a/trunk/Documentation/sound/alsa/CMIPCI.txt +++ b/trunk/Documentation/sound/alsa/CMIPCI.txt @@ -89,22 +89,19 @@ and use the interleaved 4 channel data. There are some control switchs affecting to the speaker connections: -"Line-In Mode" - an enum control to change the behavior of line-in - jack. Either "Line-In", "Rear Output" or "Bass Output" can - be selected. The last item is available only with model 039 - or newer. - When "Rear Output" is chosen, the surround channels 3 and 4 - are output to line-in jack. -"Mic-In Mode" - an enum control to change the behavior of mic-in - jack. Either "Mic-In" or "Center/LFE Output" can be - selected. - When "Center/LFE Output" is chosen, the center and bass - channels (channels 5 and 6) are output to mic-in jack. +"Line-In As Rear" - As mentioned above, the line-in jack is used + for the rear (3th and 4th channels) output. +"Line-In As Bass" - The line-in jack is used for the bass (5th + and 6th channels) output. +"Mic As Center/LFE" - The mic jack is used for the bass output. + If this switch is on, you cannot use a microphone as a capture + source, of course. + Digital I/O ----------- -The CM8x38 provides the excellent SPDIF capability with very cheap +The CM8x38 provides the excellent SPDIF capability with very chip price (yes, that's the reason I bought the card :) The SPDIF playback and capture are done via the third PCM device @@ -125,9 +122,8 @@ respectively, so you cannot playback both analog and digital streams simultaneously. To enable SPDIF output, you need to turn on "IEC958 Output Switch" -control via mixer or alsactl ("IEC958" is the official name of -so-called S/PDIF). Then you'll see the red light on from the card so -you know that's working obviously :) +control via mixer or alsactl. Then you'll see the red light on from +the card so you know that's working obviously :) The SPDIF input is always enabled, so you can hear SPDIF input data from line-out with "IEC958 In Monitor" switch at any time (see below). @@ -209,10 +205,9 @@ In addition to the standard SB mixer, CM8x38 provides more functions. MIDI CONTROLLER --------------- -The MPU401-UART interface is disabled as default. You need to set -module option "mpu_port" with a valid I/O port address to enable the -MIDI support. The valid I/O ports are 0x300, 0x310, 0x320 and 0x330. -Choose the value which doesn't conflict with other cards. +The MPU401-UART interface is enabled as default only for the first +(CMIPCI) card. You need to set module option "midi_port" properly +for the 2nd (CMIPCI) card. There is _no_ hardware wavetable function on this chip (except for OPL3 synth below). @@ -234,11 +229,9 @@ I don't know why.. Joystick and Modem ------------------ -The legacy joystick is supported. To enable the joystick support, pass -joystick_port=1 module option. The value 1 means the auto-detection. -If the auto-detection fails, try to pass the exact I/O address. - -The modem is enabled dynamically via a card control switch "Modem". +The joystick and modem should be available by enabling the control +switch "Joystick" and "Modem" respectively. But I myself have never +tested them yet. Debugging Information diff --git a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index db0b7d2dc477..e789475304b6 100644 --- a/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/trunk/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl @@ -371,7 +371,7 @@ create probe() callback. create remove() callback. create pci_driver table which contains the three pointers above. - create init() function just calling pci_register_driver() to register the pci_driver table defined above. + create init() function just calling pci_module_init() to register the pci_driver table defined above. create exit() function to call pci_unregister_driver() function. @@ -1198,7 +1198,7 @@ /* initialization of the module */ static int __init alsa_card_mychip_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } /* clean up the module */ @@ -1654,7 +1654,7 @@ center, 0x12 -> lfe */ unsigned char spdif_bug; /* Has Spdif phasing bug */ unsigned char ac97_chip; /* Has an AC97 chip */ unsigned char ecard; /* APS EEPROM */ - const char *driver; - const char *name; - const char *id; /* for backward compatibility - can be NULL if not needed */ + char * driver; + char * name; } emu_chip_details_t; struct _snd_emu10k1 { int irq; unsigned long port; /* I/O port number */ - unsigned int tos_link: 1, /* tos link detected */ - rear_ac97: 1; /* rear channels are on AC'97 */ + unsigned int APS: 1, /* APS flag */ + no_ac97: 1, /* no AC'97 */ + tos_link: 1, /* tos link detected */ + rear_ac97: 1, /* rear channels are on AC'97 */ + spk71:1; /* 7.1 configuration (Audigy 2 ZS) */ const emu_chip_details_t *card_capabilities; /* Contains profile of card capabilities */ unsigned int audigy; /* is Audigy? */ unsigned int revision; /* chip revision */ @@ -1127,10 +1109,7 @@ struct _snd_emu10k1 { emu10k1_voice_t voices[NUM_G]; emu10k1_voice_t p16v_voices[4]; - emu10k1_voice_t p16v_capture_voice; int p16v_device_offset; - u32 p16v_capture_source; - u32 p16v_capture_channel; emu10k1_pcm_mixer_t pcm_mixer[32]; emu10k1_pcm_mixer_t efx_pcm_mixer[NUM_EFX_PLAYBACK]; snd_kcontrol_t *ctl_send_routing; @@ -1474,6 +1453,7 @@ int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu, #endif typedef struct { + unsigned int card; /* card type */ unsigned int internal_tram_size; /* in samples */ unsigned int external_tram_size; /* in samples */ char fxbus_names[16][32]; /* names of FXBUSes */ diff --git a/trunk/include/sound/gus.h b/trunk/include/sound/gus.h index b4b461ca173d..8b6287a6fff5 100644 --- a/trunk/include/sound/gus.h +++ b/trunk/include/sound/gus.h @@ -526,6 +526,9 @@ extern void snd_gf1_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigne extern void snd_gf1_dram_addr(snd_gus_card_t * gus, unsigned int addr); extern void snd_gf1_poke(snd_gus_card_t * gus, unsigned int addr, unsigned char data); extern unsigned char snd_gf1_peek(snd_gus_card_t * gus, unsigned int addr); +extern void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data); +extern unsigned short snd_gf1_peekw(snd_gus_card_t * gus, unsigned int addr); +extern void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr, unsigned short value, unsigned int count); extern void snd_gf1_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit); extern unsigned int snd_gf1_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit); extern void snd_gf1_i_ctrl_stop(snd_gus_card_t * gus, unsigned char reg); @@ -541,6 +544,9 @@ extern inline unsigned short snd_gf1_i_read16(snd_gus_card_t * gus, unsigned cha { return snd_gf1_i_look16(gus, reg | 0x80); } +extern void snd_gf1_i_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigned char data); +extern void snd_gf1_i_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit); +extern unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit); extern void snd_gf1_select_active_voices(snd_gus_card_t * gus); @@ -574,6 +580,10 @@ extern void snd_gf1_lfo_command(snd_gus_card_t * gus, int voice, unsigned char * void snd_gf1_mem_lock(snd_gf1_mem_t * alloc, int xup); int snd_gf1_mem_xfree(snd_gf1_mem_t * alloc, snd_gf1_mem_block_t * block); +snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc, + unsigned int address); +snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc, + unsigned int *share_id); snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner, char *name, int size, int w_16, int align, unsigned int *share_id); @@ -598,13 +608,23 @@ int snd_gf1_dma_transfer_block(snd_gus_card_t * gus, /* gus_volume.c */ unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol); +unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol); +unsigned int snd_gf1_calc_ramp_rate(snd_gus_card_t * gus, + unsigned short start, + unsigned short end, + unsigned int us); unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq2); +unsigned short snd_gf1_compute_pitchbend(unsigned short pitchbend, unsigned short sens); +unsigned short snd_gf1_compute_freq(unsigned int freq, + unsigned int rate, + unsigned short mix_rate); /* gus_reset.c */ void snd_gf1_set_default_handlers(snd_gus_card_t * gus, unsigned int what); void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice); void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice); +void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max); void snd_gf1_stop_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max); snd_gus_voice_t *snd_gf1_alloc_voice(snd_gus_card_t * gus, int type, int client, int port); void snd_gf1_free_voice(snd_gus_card_t * gus, snd_gus_voice_t *voice); @@ -621,6 +641,9 @@ int snd_gf1_pcm_new(snd_gus_card_t * gus, int pcm_dev, int control_index, snd_pc #ifdef CONFIG_SND_DEBUG extern void snd_gf1_print_voice_registers(snd_gus_card_t * gus); +extern void snd_gf1_print_global_registers(snd_gus_card_t * gus); +extern void snd_gf1_print_setup_registers(snd_gus_card_t * gus); +extern void snd_gf1_peek_print_block(snd_gus_card_t * gus, unsigned int addr, int count, int w_16bit); #endif /* gus.c */ diff --git a/trunk/include/sound/pcm.h b/trunk/include/sound/pcm.h index d935417575b5..53fc04d75bad 100644 --- a/trunk/include/sound/pcm.h +++ b/trunk/include/sound/pcm.h @@ -848,6 +848,23 @@ int snd_interval_ratnum(snd_interval_t *i, void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params); void _snd_pcm_hw_param_setempty(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var); +int snd_pcm_hw_param_min(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, + unsigned int val, int *dir); +int snd_pcm_hw_param_max(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, + unsigned int val, int *dir); +int snd_pcm_hw_param_setinteger(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var); +int snd_pcm_hw_param_first(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir); +int snd_pcm_hw_param_last(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir); int snd_pcm_hw_param_near(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, @@ -859,6 +876,7 @@ int snd_pcm_hw_param_set(snd_pcm_substream_t *pcm, int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params); int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params); +int snd_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params); int snd_pcm_hw_constraints_init(snd_pcm_substream_t *substream); int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream); @@ -904,22 +922,8 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format); int snd_pcm_format_linear(snd_pcm_format_t format); int snd_pcm_format_little_endian(snd_pcm_format_t format); int snd_pcm_format_big_endian(snd_pcm_format_t format); -/** - * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian - * @format: the format to check - * - * Returns 1 if the given PCM format is CPU-endian, 0 if - * opposite, or a negative error code if endian not specified. - */ -/* int snd_pcm_format_cpu_endian(snd_pcm_format_t format); */ -#ifdef SNDRV_LITTLE_ENDIAN -#define snd_pcm_format_cpu_endian snd_pcm_format_little_endian -#else -#define snd_pcm_format_cpu_endian snd_pcm_format_big_endian -#endif int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */ int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */ -ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples); const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format); int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames); snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian); diff --git a/trunk/include/sound/seq_midi_event.h b/trunk/include/sound/seq_midi_event.h index 8857e2bd31a5..4357cac07500 100644 --- a/trunk/include/sound/seq_midi_event.h +++ b/trunk/include/sound/seq_midi_event.h @@ -41,7 +41,9 @@ struct snd_midi_event_t { }; int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev); +int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize); void snd_midi_event_free(snd_midi_event_t *dev); +void snd_midi_event_init(snd_midi_event_t *dev); void snd_midi_event_reset_encode(snd_midi_event_t *dev); void snd_midi_event_reset_decode(snd_midi_event_t *dev); void snd_midi_event_no_status(snd_midi_event_t *dev, int on); diff --git a/trunk/include/sound/seq_virmidi.h b/trunk/include/sound/seq_virmidi.h index 1ad27e859af3..cf4e2388103f 100644 --- a/trunk/include/sound/seq_virmidi.h +++ b/trunk/include/sound/seq_virmidi.h @@ -79,5 +79,6 @@ struct _snd_virmidi_dev { #define SNDRV_VIRMIDI_SEQ_DISPATCH 2 int snd_virmidi_new(snd_card_t *card, int device, snd_rawmidi_t **rrmidi); +int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev); #endif /* __SOUND_SEQ_VIRMIDI */ diff --git a/trunk/include/sound/timer.h b/trunk/include/sound/timer.h index 1898511a0f38..57fde990606e 100644 --- a/trunk/include/sound/timer.h +++ b/trunk/include/sound/timer.h @@ -152,4 +152,6 @@ extern int snd_timer_pause(snd_timer_instance_t * timeri); extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left); +extern unsigned int snd_timer_system_resolution(void); + #endif /* __SOUND_TIMER_H */ diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index 46acfa8c9988..98b4230778ed 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by configure. */ -#define CONFIG_SND_VERSION "1.0.9" -#define CONFIG_SND_DATE " (Sun May 29 07:31:02 2005 UTC)" +#define CONFIG_SND_VERSION "1.0.9rc2" +#define CONFIG_SND_DATE " (Thu Mar 24 10:33:39 2005 UTC)" diff --git a/trunk/sound/Kconfig b/trunk/sound/Kconfig index ee794ae06040..047d59ea0573 100644 --- a/trunk/sound/Kconfig +++ b/trunk/sound/Kconfig @@ -42,11 +42,6 @@ menu "Advanced Linux Sound Architecture" config SND tristate "Advanced Linux Sound Architecture" depends on SOUND - help - Say 'Y' or 'M' to enable ALSA (Advanced Linux Sound Architecture), - the new base sound system. - - For more information, see source "sound/core/Kconfig" diff --git a/trunk/sound/arm/Kconfig b/trunk/sound/arm/Kconfig index 34c1740aa6e9..cdacf4d3a387 100644 --- a/trunk/sound/arm/Kconfig +++ b/trunk/sound/arm/Kconfig @@ -14,11 +14,5 @@ config SND_SA11XX_UDA1341 To compile this driver as a module, choose M here: the module will be called snd-sa11xx-uda1341. -config SND_ARMAACI - tristate "ARM PrimeCell PL041 AC Link support" - depends on SND && ARM_AMBA - select SND_PCM - select SND_AC97_CODEC - endmenu diff --git a/trunk/sound/arm/Makefile b/trunk/sound/arm/Makefile index f74ec28e1068..d7e7dc0c3cdf 100644 --- a/trunk/sound/arm/Makefile +++ b/trunk/sound/arm/Makefile @@ -6,6 +6,3 @@ snd-sa11xx-uda1341-objs := sa11xx-uda1341.o # Toplevel Module Dependency obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o - -obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o -snd-aaci-objs := aaci.o devdma.o diff --git a/trunk/sound/arm/aaci.c b/trunk/sound/arm/aaci.c deleted file mode 100644 index 08cc3ddca96f..000000000000 --- a/trunk/sound/arm/aaci.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver - * - * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Documentation: ARM DDI 0173B - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "aaci.h" -#include "devdma.h" - -#define DRIVER_NAME "aaci-pl041" - -/* - * PM support is not complete. Turn it off. - */ -#undef CONFIG_PM - -static void aaci_ac97_select_codec(struct aaci *aaci, ac97_t *ac97) -{ - u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num); - - /* - * Ensure that the slot 1/2 RX registers are empty. - */ - v = readl(aaci->base + AACI_SLFR); - if (v & SLFR_2RXV) - readl(aaci->base + AACI_SL2RX); - if (v & SLFR_1RXV) - readl(aaci->base + AACI_SL1RX); - - writel(maincr, aaci->base + AACI_MAINCR); -} - -/* - * P29: - * The recommended use of programming the external codec through slot 1 - * and slot 2 data is to use the channels during setup routines and the - * slot register at any other time. The data written into slot 1, slot 2 - * and slot 12 registers is transmitted only when their corresponding - * SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR - * register. - */ -static void aaci_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) -{ - struct aaci *aaci = ac97->private_data; - u32 v; - - if (ac97->num >= 4) - return; - - down(&aaci->ac97_sem); - - aaci_ac97_select_codec(aaci, ac97); - - /* - * P54: You must ensure that AACI_SL2TX is always written - * to, if required, before data is written to AACI_SL1TX. - */ - writel(val << 4, aaci->base + AACI_SL2TX); - writel(reg << 12, aaci->base + AACI_SL1TX); - - /* - * Wait for the transmission of both slots to complete. - */ - do { - v = readl(aaci->base + AACI_SLFR); - } while (v & (SLFR_1TXB|SLFR_2TXB)); - - up(&aaci->ac97_sem); -} - -/* - * Read an AC'97 register. - */ -static unsigned short aaci_ac97_read(ac97_t *ac97, unsigned short reg) -{ - struct aaci *aaci = ac97->private_data; - u32 v; - - if (ac97->num >= 4) - return ~0; - - down(&aaci->ac97_sem); - - aaci_ac97_select_codec(aaci, ac97); - - /* - * Write the register address to slot 1. - */ - writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX); - - /* - * Wait for the transmission to complete. - */ - do { - v = readl(aaci->base + AACI_SLFR); - } while (v & SLFR_1TXB); - - /* - * Give the AC'97 codec more than enough time - * to respond. (42us = ~2 frames at 48kHz.) - */ - udelay(42); - - /* - * Wait for slot 2 to indicate data. - */ - do { - cond_resched(); - v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); - } while (v != (SLFR_1RXV|SLFR_2RXV)); - - v = readl(aaci->base + AACI_SL1RX) >> 12; - if (v == reg) { - v = readl(aaci->base + AACI_SL2RX) >> 4; - } else { - dev_err(&aaci->dev->dev, - "wrong ac97 register read back (%x != %x)\n", - v, reg); - v = ~0; - } - - up(&aaci->ac97_sem); - return v; -} - -static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun) -{ - u32 val; - int timeout = 5000; - - do { - val = readl(aacirun->base + AACI_SR); - } while (val & (SR_TXB|SR_RXB) && timeout--); -} - - - -/* - * Interrupt support. - */ -static void aaci_fifo_irq(struct aaci *aaci, u32 mask) -{ - if (mask & ISR_URINTR) { - writel(ICLR_TXUEC1, aaci->base + AACI_INTCLR); - } - - if (mask & ISR_TXINTR) { - struct aaci_runtime *aacirun = &aaci->playback; - void *ptr; - - if (!aacirun->substream || !aacirun->start) { - dev_warn(&aaci->dev->dev, "TX interrupt???"); - writel(0, aacirun->base + AACI_IE); - return; - } - - ptr = aacirun->ptr; - do { - unsigned int len = aacirun->fifosz; - u32 val; - - if (aacirun->bytes <= 0) { - aacirun->bytes += aacirun->period; - aacirun->ptr = ptr; - spin_unlock(&aaci->lock); - snd_pcm_period_elapsed(aacirun->substream); - spin_lock(&aaci->lock); - } - if (!(aacirun->cr & TXCR_TXEN)) - break; - - val = readl(aacirun->base + AACI_SR); - if (!(val & SR_TXHE)) - break; - if (!(val & SR_TXFE)) - len >>= 1; - - aacirun->bytes -= len; - - /* writing 16 bytes at a time */ - for ( ; len > 0; len -= 16) { - asm( - "ldmia %0!, {r0, r1, r2, r3}\n\t" - "stmia %1, {r0, r1, r2, r3}" - : "+r" (ptr) - : "r" (aacirun->fifo) - : "r0", "r1", "r2", "r3", "cc"); - - if (ptr >= aacirun->end) - ptr = aacirun->start; - } - } while (1); - - aacirun->ptr = ptr; - } -} - -static irqreturn_t aaci_irq(int irq, void *devid, struct pt_regs *regs) -{ - struct aaci *aaci = devid; - u32 mask; - int i; - - spin_lock(&aaci->lock); - mask = readl(aaci->base + AACI_ALLINTS); - if (mask) { - u32 m = mask; - for (i = 0; i < 4; i++, m >>= 7) { - if (m & 0x7f) { - aaci_fifo_irq(aaci, m); - } - } - } - spin_unlock(&aaci->lock); - - return mask ? IRQ_HANDLED : IRQ_NONE; -} - - - -/* - * ALSA support. - */ - -struct aaci_stream { - unsigned char codec_idx; - unsigned char rate_idx; -}; - -static struct aaci_stream aaci_streams[] = { - [ACSTREAM_FRONT] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_FRONT_DAC, - }, - [ACSTREAM_SURROUND] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_SURR_DAC, - }, - [ACSTREAM_LFE] = { - .codec_idx = 0, - .rate_idx = AC97_RATES_LFE_DAC, - }, -}; - -static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid) -{ - struct aaci_stream *s = aaci_streams + streamid; - return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx]; -} - -static unsigned int rate_list[] = { - 5512, 8000, 11025, 16000, 22050, 32000, 44100, - 48000, 64000, 88200, 96000, 176400, 192000 -}; - -/* - * Double-rate rule: we can support double rate iff channels == 2 - * (unimplemented) - */ -static int -aaci_rule_rate_by_channels(snd_pcm_hw_params_t *p, snd_pcm_hw_rule_t *rule) -{ - struct aaci *aaci = rule->private; - unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512; - snd_interval_t *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS); - - switch (c->max) { - case 6: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE); - case 4: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND); - case 2: - rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT); - } - - return snd_interval_list(hw_param_interval(p, rule->var), - ARRAY_SIZE(rate_list), rate_list, - rate_mask); -} - -static snd_pcm_hardware_t aaci_hw_info = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_RESUME, - - /* - * ALSA doesn't support 18-bit or 20-bit packed into 32-bit - * words. It also doesn't support 12-bit at all. - */ - .formats = SNDRV_PCM_FMTBIT_S16_LE, - - /* should this be continuous or knot? */ - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_max = 48000, - .rate_min = 4000, - .channels_min = 2, - .channels_max = 6, - .buffer_bytes_max = 64 * 1024, - .period_bytes_min = 256, - .period_bytes_max = PAGE_SIZE, - .periods_min = 4, - .periods_max = PAGE_SIZE / 16, -}; - -static int aaci_pcm_open(struct aaci *aaci, snd_pcm_substream_t *substream, - struct aaci_runtime *aacirun) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - int ret; - - aacirun->substream = substream; - runtime->private_data = aacirun; - runtime->hw = aaci_hw_info; - - /* - * FIXME: ALSA specifies fifo_size in bytes. If we're in normal - * mode, each 32-bit word contains one sample. If we're in - * compact mode, each 32-bit word contains two samples, effectively - * halving the FIFO size. However, we don't know for sure which - * we'll be using at this point. We set this to the lower limit. - */ - runtime->hw.fifo_size = aaci->fifosize * 2; - - /* - * Add rule describing hardware rate dependency - * on the number of channels. - */ - ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - aaci_rule_rate_by_channels, aaci, - SNDRV_PCM_HW_PARAM_CHANNELS, - SNDRV_PCM_HW_PARAM_RATE, -1); - if (ret) - goto out; - - ret = request_irq(aaci->dev->irq[0], aaci_irq, SA_SHIRQ|SA_INTERRUPT, - DRIVER_NAME, aaci); - if (ret) - goto out; - - return 0; - - out: - return ret; -} - - -/* - * Common ALSA stuff - */ -static int aaci_pcm_close(snd_pcm_substream_t *substream) -{ - struct aaci *aaci = substream->private_data; - struct aaci_runtime *aacirun = substream->runtime->private_data; - - WARN_ON(aacirun->cr & TXCR_TXEN); - - aacirun->substream = NULL; - free_irq(aaci->dev->irq[0], aaci); - - return 0; -} - -static int aaci_pcm_hw_free(snd_pcm_substream_t *substream) -{ - struct aaci_runtime *aacirun = substream->runtime->private_data; - - /* - * This must not be called with the device enabled. - */ - WARN_ON(aacirun->cr & TXCR_TXEN); - - if (aacirun->pcm_open) - snd_ac97_pcm_close(aacirun->pcm); - aacirun->pcm_open = 0; - - /* - * Clear out the DMA and any allocated buffers. - */ - devdma_hw_free(NULL, substream); - - return 0; -} - -static int aaci_pcm_hw_params(snd_pcm_substream_t *substream, - struct aaci_runtime *aacirun, - snd_pcm_hw_params_t *params) -{ - int err; - - aaci_pcm_hw_free(substream); - - err = devdma_hw_alloc(NULL, substream, - params_buffer_bytes(params)); - if (err < 0) - goto out; - - err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), - params_channels(params), - aacirun->pcm->r[0].slots); - if (err) - goto out; - - aacirun->pcm_open = 1; - - out: - return err; -} - -static int aaci_pcm_prepare(snd_pcm_substream_t *substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - struct aaci_runtime *aacirun = runtime->private_data; - - aacirun->start = (void *)runtime->dma_area; - aacirun->end = aacirun->start + runtime->dma_bytes; - aacirun->ptr = aacirun->start; - aacirun->period = - aacirun->bytes = frames_to_bytes(runtime, runtime->period_size); - - return 0; -} - -static snd_pcm_uframes_t aaci_pcm_pointer(snd_pcm_substream_t *substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - struct aaci_runtime *aacirun = runtime->private_data; - ssize_t bytes = aacirun->ptr - aacirun->start; - - return bytes_to_frames(runtime, bytes); -} - -static int aaci_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma) -{ - return devdma_mmap(NULL, substream, vma); -} - - -/* - * Playback specific ALSA stuff - */ -static const u32 channels_to_txmask[] = { - [2] = TXCR_TX3 | TXCR_TX4, - [4] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8, - [6] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8 | TXCR_TX6 | TXCR_TX9, -}; - -/* - * We can support two and four channel audio. Unfortunately - * six channel audio requires a non-standard channel ordering: - * 2 -> FL(3), FR(4) - * 4 -> FL(3), FR(4), SL(7), SR(8) - * 6 -> FL(3), FR(4), SL(7), SR(8), C(6), LFE(9) (required) - * FL(3), FR(4), C(6), SL(7), SR(8), LFE(9) (actual) - * This requires an ALSA configuration file to correct. - */ -static unsigned int channel_list[] = { 2, 4, 6 }; - -static int -aaci_rule_channels(snd_pcm_hw_params_t *p, snd_pcm_hw_rule_t *rule) -{ - struct aaci *aaci = rule->private; - unsigned int chan_mask = 1 << 0, slots; - - /* - * pcms[0] is the our 5.1 PCM instance. - */ - slots = aaci->ac97_bus->pcms[0].r[0].slots; - if (slots & (1 << AC97_SLOT_PCM_SLEFT)) { - chan_mask |= 1 << 1; - if (slots & (1 << AC97_SLOT_LFE)) - chan_mask |= 1 << 2; - } - - return snd_interval_list(hw_param_interval(p, rule->var), - ARRAY_SIZE(channel_list), channel_list, - chan_mask); -} - -static int aaci_pcm_playback_open(snd_pcm_substream_t *substream) -{ - struct aaci *aaci = substream->private_data; - int ret; - - /* - * Add rule describing channel dependency. - */ - ret = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - aaci_rule_channels, aaci, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); - if (ret) - return ret; - - return aaci_pcm_open(aaci, substream, &aaci->playback); -} - -static int aaci_pcm_playback_hw_params(snd_pcm_substream_t *substream, - snd_pcm_hw_params_t *params) -{ - struct aaci *aaci = substream->private_data; - struct aaci_runtime *aacirun = substream->runtime->private_data; - unsigned int channels = params_channels(params); - int ret; - - WARN_ON(channels >= ARRAY_SIZE(channels_to_txmask) || - !channels_to_txmask[channels]); - - ret = aaci_pcm_hw_params(substream, aacirun, params); - - /* - * Enable FIFO, compact mode, 16 bits per sample. - * FIXME: double rate slots? - */ - if (ret >= 0) { - aacirun->cr = TXCR_FEN | TXCR_COMPACT | TXCR_TSZ16; - aacirun->cr |= channels_to_txmask[channels]; - - aacirun->fifosz = aaci->fifosize * 4; - if (aacirun->cr & TXCR_COMPACT) - aacirun->fifosz >>= 1; - } - return ret; -} - -static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun) -{ - u32 ie; - - ie = readl(aacirun->base + AACI_IE); - ie &= ~(IE_URIE|IE_TXIE); - writel(ie, aacirun->base + AACI_IE); - aacirun->cr &= ~TXCR_TXEN; - aaci_chan_wait_ready(aacirun); - writel(aacirun->cr, aacirun->base + AACI_TXCR); -} - -static void aaci_pcm_playback_start(struct aaci_runtime *aacirun) -{ - u32 ie; - - aaci_chan_wait_ready(aacirun); - aacirun->cr |= TXCR_TXEN; - - ie = readl(aacirun->base + AACI_IE); - ie |= IE_URIE | IE_TXIE; - writel(ie, aacirun->base + AACI_IE); - writel(aacirun->cr, aacirun->base + AACI_TXCR); -} - -static int aaci_pcm_playback_trigger(snd_pcm_substream_t *substream, int cmd) -{ - struct aaci *aaci = substream->private_data; - struct aaci_runtime *aacirun = substream->runtime->private_data; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&aaci->lock, flags); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - aaci_pcm_playback_start(aacirun); - break; - - case SNDRV_PCM_TRIGGER_RESUME: - aaci_pcm_playback_start(aacirun); - break; - - case SNDRV_PCM_TRIGGER_STOP: - aaci_pcm_playback_stop(aacirun); - break; - - case SNDRV_PCM_TRIGGER_SUSPEND: - aaci_pcm_playback_stop(aacirun); - break; - - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - break; - - default: - ret = -EINVAL; - } - spin_unlock_irqrestore(&aaci->lock, flags); - - return ret; -} - -static snd_pcm_ops_t aaci_playback_ops = { - .open = aaci_pcm_playback_open, - .close = aaci_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = aaci_pcm_playback_hw_params, - .hw_free = aaci_pcm_hw_free, - .prepare = aaci_pcm_prepare, - .trigger = aaci_pcm_playback_trigger, - .pointer = aaci_pcm_pointer, - .mmap = aaci_pcm_mmap, -}; - - - -/* - * Power Management. - */ -#ifdef CONFIG_PM -static int aaci_do_suspend(snd_card_t *card, unsigned int state) -{ - struct aaci *aaci = card->private_data; - if (aaci->card->power_state != SNDRV_CTL_POWER_D3cold) { - snd_pcm_suspend_all(aaci->pcm); - snd_power_change_state(aaci->card, SNDRV_CTL_POWER_D3cold); - } - return 0; -} - -static int aaci_do_resume(snd_card_t *card, unsigned int state) -{ - struct aaci *aaci = card->private_data; - if (aaci->card->power_state != SNDRV_CTL_POWER_D0) { - snd_power_change_state(aaci->card, SNDRV_CTL_POWER_D0); - } - return 0; -} - -static int aaci_suspend(struct amba_device *dev, u32 state) -{ - snd_card_t *card = amba_get_drvdata(dev); - return card ? aaci_do_suspend(card) : 0; -} - -static int aaci_resume(struct amba_device *dev) -{ - snd_card_t *card = amba_get_drvdata(dev); - return card ? aaci_do_resume(card) : 0; -} -#else -#define aaci_do_suspend NULL -#define aaci_do_resume NULL -#define aaci_suspend NULL -#define aaci_resume NULL -#endif - - -static struct ac97_pcm ac97_defs[] __devinitdata = { - [0] = { /* Front PCM */ - .exclusive = 1, - .r = { - [0] = { - .slots = (1 << AC97_SLOT_PCM_LEFT) | - (1 << AC97_SLOT_PCM_RIGHT) | - (1 << AC97_SLOT_PCM_CENTER) | - (1 << AC97_SLOT_PCM_SLEFT) | - (1 << AC97_SLOT_PCM_SRIGHT) | - (1 << AC97_SLOT_LFE), - }, - }, - }, - [1] = { /* PCM in */ - .stream = 1, - .exclusive = 1, - .r = { - [0] = { - .slots = (1 << AC97_SLOT_PCM_LEFT) | - (1 << AC97_SLOT_PCM_RIGHT), - }, - }, - }, - [2] = { /* Mic in */ - .stream = 1, - .exclusive = 1, - .r = { - [0] = { - .slots = (1 << AC97_SLOT_MIC), - }, - }, - } -}; - -static ac97_bus_ops_t aaci_bus_ops = { - .write = aaci_ac97_write, - .read = aaci_ac97_read, -}; - -static int __devinit aaci_probe_ac97(struct aaci *aaci) -{ - ac97_template_t ac97_template; - ac97_bus_t *ac97_bus; - ac97_t *ac97; - int ret; - - /* - * Assert AACIRESET for 2us - */ - writel(0, aaci->base + AACI_RESET); - udelay(2); - writel(RESET_NRST, aaci->base + AACI_RESET); - - /* - * Give the AC'97 codec more than enough time - * to wake up. (42us = ~2 frames at 48kHz.) - */ - udelay(42); - - ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); - if (ret) - goto out; - - ac97_bus->clock = 48000; - aaci->ac97_bus = ac97_bus; - - memset(&ac97_template, 0, sizeof(ac97_template_t)); - ac97_template.private_data = aaci; - ac97_template.num = 0; - ac97_template.scaps = AC97_SCAP_SKIP_MODEM; - - ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97); - if (ret) - goto out; - - /* - * Disable AC97 PC Beep input on audio codecs. - */ - if (ac97_is_audio(ac97)) - snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x801e); - - ret = snd_ac97_pcm_assign(ac97_bus, ARRAY_SIZE(ac97_defs), ac97_defs); - if (ret) - goto out; - - aaci->playback.pcm = &ac97_bus->pcms[0]; - - out: - return ret; -} - -static void aaci_free_card(snd_card_t *card) -{ - struct aaci *aaci = card->private_data; - if (aaci->base) - iounmap(aaci->base); -} - -static struct aaci * __devinit aaci_init_card(struct amba_device *dev) -{ - struct aaci *aaci; - snd_card_t *card; - - card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, sizeof(struct aaci)); - if (card == NULL) - return ERR_PTR(-ENOMEM); - - card->private_free = aaci_free_card; - snd_card_set_pm_callback(card, aaci_do_suspend, aaci_do_resume, NULL); - - strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver)); - strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname)); - snprintf(card->longname, sizeof(card->longname), - "%s at 0x%08lx, irq %d", - card->shortname, dev->res.start, dev->irq[0]); - - aaci = card->private_data; - init_MUTEX(&aaci->ac97_sem); - spin_lock_init(&aaci->lock); - aaci->card = card; - aaci->dev = dev; - - /* Set MAINCR to allow slot 1 and 2 data IO */ - aaci->maincr = MAINCR_IE | MAINCR_SL1RXEN | MAINCR_SL1TXEN | - MAINCR_SL2RXEN | MAINCR_SL2TXEN; - - return aaci; -} - -static int __devinit aaci_init_pcm(struct aaci *aaci) -{ - snd_pcm_t *pcm; - int ret; - - ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm); - if (ret == 0) { - aaci->pcm = pcm; - pcm->private_data = aaci; - pcm->info_flags = 0; - - strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); - } - - return ret; -} - -static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) -{ - void *base = aaci->base + AACI_CSCH1; - int i; - - writel(TXCR_FEN | TXCR_TSZ16 | TXCR_TXEN, base + AACI_TXCR); - - for (i = 0; !(readl(base + AACI_SR) & SR_TXFF) && i < 4096; i++) - writel(0, aaci->base + AACI_DR1); - - writel(0, base + AACI_TXCR); - - /* - * Re-initialise the AACI after the FIFO depth test, to - * ensure that the FIFOs are empty. Unfortunately, merely - * disabling the channel doesn't clear the FIFO. - */ - writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR); - writel(aaci->maincr, aaci->base + AACI_MAINCR); - - /* - * If we hit 4096, we failed. Go back to the specified - * fifo depth. - */ - if (i == 4096) - i = 8; - - return i; -} - -static int __devinit aaci_probe(struct amba_device *dev, void *id) -{ - struct aaci *aaci; - int ret, i; - - ret = amba_request_regions(dev, NULL); - if (ret) - return ret; - - aaci = aaci_init_card(dev); - if (IS_ERR(aaci)) { - ret = PTR_ERR(aaci); - goto out; - } - - aaci->base = ioremap(dev->res.start, SZ_4K); - if (!aaci->base) { - ret = -ENOMEM; - goto out; - } - - /* - * Playback uses AACI channel 0 - */ - aaci->playback.base = aaci->base + AACI_CSCH1; - aaci->playback.fifo = aaci->base + AACI_DR1; - - for (i = 0; i < 4; i++) { - void *base = aaci->base + i * 0x14; - - writel(0, base + AACI_IE); - writel(0, base + AACI_TXCR); - writel(0, base + AACI_RXCR); - } - - writel(0x1fff, aaci->base + AACI_INTCLR); - writel(aaci->maincr, aaci->base + AACI_MAINCR); - - /* - * Size the FIFOs. - */ - aaci->fifosize = aaci_size_fifo(aaci); - - ret = aaci_probe_ac97(aaci); - if (ret) - goto out; - - ret = aaci_init_pcm(aaci); - if (ret) - goto out; - - ret = snd_card_register(aaci->card); - if (ret == 0) { - dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname, - aaci->fifosize); - amba_set_drvdata(dev, aaci->card); - return ret; - } - - out: - if (aaci) - snd_card_free(aaci->card); - amba_release_regions(dev); - return ret; -} - -static int __devexit aaci_remove(struct amba_device *dev) -{ - snd_card_t *card = amba_get_drvdata(dev); - - amba_set_drvdata(dev, NULL); - - if (card) { - struct aaci *aaci = card->private_data; - writel(0, aaci->base + AACI_MAINCR); - - snd_card_free(card); - amba_release_regions(dev); - } - - return 0; -} - -static struct amba_id aaci_ids[] = { - { - .id = 0x00041041, - .mask = 0x000fffff, - }, - { 0, 0 }, -}; - -static struct amba_driver aaci_driver = { - .drv = { - .name = DRIVER_NAME, - }, - .probe = aaci_probe, - .remove = __devexit_p(aaci_remove), - .suspend = aaci_suspend, - .resume = aaci_resume, - .id_table = aaci_ids, -}; - -static int __init aaci_init(void) -{ - return amba_driver_register(&aaci_driver); -} - -static void __exit aaci_exit(void) -{ - amba_driver_unregister(&aaci_driver); -} - -module_init(aaci_init); -module_exit(aaci_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver"); diff --git a/trunk/sound/arm/aaci.h b/trunk/sound/arm/aaci.h deleted file mode 100644 index d752e6426894..000000000000 --- a/trunk/sound/arm/aaci.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver - * - * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef AACI_H -#define AACI_H - -/* - * Control and status register offsets - * P39. - */ -#define AACI_CSCH1 0x000 -#define AACI_CSCH2 0x014 -#define AACI_CSCH3 0x028 -#define AACI_CSCH4 0x03c - -#define AACI_RXCR 0x000 /* 29 bits Control Rx FIFO */ -#define AACI_TXCR 0x004 /* 17 bits Control Tx FIFO */ -#define AACI_SR 0x008 /* 12 bits Status */ -#define AACI_ISR 0x00c /* 7 bits Int Status */ -#define AACI_IE 0x010 /* 7 bits Int Enable */ - -/* - * Other registers - */ -#define AACI_SL1RX 0x050 -#define AACI_SL1TX 0x054 -#define AACI_SL2RX 0x058 -#define AACI_SL2TX 0x05c -#define AACI_SL12RX 0x060 -#define AACI_SL12TX 0x064 -#define AACI_SLFR 0x068 /* slot flags */ -#define AACI_SLISTAT 0x06c /* slot interrupt status */ -#define AACI_SLIEN 0x070 /* slot interrupt enable */ -#define AACI_INTCLR 0x074 /* interrupt clear */ -#define AACI_MAINCR 0x078 /* main control */ -#define AACI_RESET 0x07c /* reset control */ -#define AACI_SYNC 0x080 /* sync control */ -#define AACI_ALLINTS 0x084 /* all fifo interrupt status */ -#define AACI_MAINFR 0x088 /* main flag register */ -#define AACI_DR1 0x090 /* data read/written fifo 1 */ -#define AACI_DR2 0x0b0 /* data read/written fifo 2 */ -#define AACI_DR3 0x0d0 /* data read/written fifo 3 */ -#define AACI_DR4 0x0f0 /* data read/written fifo 4 */ - -/* - * transmit fifo control register. P48 - */ -#define TXCR_FEN (1 << 16) /* fifo enable */ -#define TXCR_COMPACT (1 << 15) /* compact mode */ -#define TXCR_TSZ16 (0 << 13) /* 16 bits */ -#define TXCR_TSZ18 (1 << 13) /* 18 bits */ -#define TXCR_TSZ20 (2 << 13) /* 20 bits */ -#define TXCR_TSZ12 (3 << 13) /* 12 bits */ -#define TXCR_TX12 (1 << 12) /* transmits slot 12 */ -#define TXCR_TX11 (1 << 11) /* transmits slot 12 */ -#define TXCR_TX10 (1 << 10) /* transmits slot 12 */ -#define TXCR_TX9 (1 << 9) /* transmits slot 12 */ -#define TXCR_TX8 (1 << 8) /* transmits slot 12 */ -#define TXCR_TX7 (1 << 7) /* transmits slot 12 */ -#define TXCR_TX6 (1 << 6) /* transmits slot 12 */ -#define TXCR_TX5 (1 << 5) /* transmits slot 12 */ -#define TXCR_TX4 (1 << 4) /* transmits slot 12 */ -#define TXCR_TX3 (1 << 3) /* transmits slot 12 */ -#define TXCR_TX2 (1 << 2) /* transmits slot 12 */ -#define TXCR_TX1 (1 << 1) /* transmits slot 12 */ -#define TXCR_TXEN (1 << 0) /* transmit enable */ - -/* - * status register bits. P49 - */ -#define SR_RXTOFE (1 << 11) /* rx timeout fifo empty */ -#define SR_TXTO (1 << 10) /* rx timeout fifo nonempty */ -#define SR_TXU (1 << 9) /* tx underrun */ -#define SR_RXO (1 << 8) /* rx overrun */ -#define SR_TXB (1 << 7) /* tx busy */ -#define SR_RXB (1 << 6) /* rx busy */ -#define SR_TXFF (1 << 5) /* tx fifo full */ -#define SR_RXFF (1 << 4) /* rx fifo full */ -#define SR_TXHE (1 << 3) /* tx fifo half empty */ -#define SR_RXHF (1 << 2) /* rx fifo half full */ -#define SR_TXFE (1 << 1) /* tx fifo empty */ -#define SR_RXFE (1 << 0) /* rx fifo empty */ - -/* - * interrupt status register bits. - */ -#define ISR_RXTOFEINTR (1 << 6) /* rx fifo empty */ -#define ISR_URINTR (1 << 5) /* tx underflow */ -#define ISR_ORINTR (1 << 4) /* rx overflow */ -#define ISR_RXINTR (1 << 3) /* rx fifo */ -#define ISR_TXINTR (1 << 2) /* tx fifo intr */ -#define ISR_RXTOINTR (1 << 1) /* tx timeout */ -#define ISR_TXCINTR (1 << 0) /* tx complete */ - -/* - * interrupt enable register bits. - */ -#define IE_RXTOIE (1 << 6) -#define IE_URIE (1 << 5) -#define IE_ORIE (1 << 4) -#define IE_RXIE (1 << 3) -#define IE_TXIE (1 << 2) -#define IE_RXTIE (1 << 1) -#define IE_TXCIE (1 << 0) - -/* - * interrupt status. P51 - */ -#define ISR_RXTOFE (1 << 6) /* rx timeout fifo empty */ -#define ISR_UR (1 << 5) /* tx fifo underrun */ -#define ISR_OR (1 << 4) /* rx fifo overrun */ -#define ISR_RX (1 << 3) /* rx interrupt status */ -#define ISR_TX (1 << 2) /* tx interrupt status */ -#define ISR_RXTO (1 << 1) /* rx timeout */ -#define ISR_TXC (1 << 0) /* tx complete */ - -/* - * interrupt enable. P52 - */ -#define IE_RXTOFE (1 << 6) /* rx timeout fifo empty */ -#define IE_UR (1 << 5) /* tx fifo underrun */ -#define IE_OR (1 << 4) /* rx fifo overrun */ -#define IE_RX (1 << 3) /* rx interrupt status */ -#define IE_TX (1 << 2) /* tx interrupt status */ -#define IE_RXTO (1 << 1) /* rx timeout */ -#define IE_TXC (1 << 0) /* tx complete */ - -/* - * slot flag register bits. P56 - */ -#define SLFR_RWIS (1 << 13) /* raw wake-up interrupt status */ -#define SLFR_RGPIOINTR (1 << 12) /* raw gpio interrupt */ -#define SLFR_12TXE (1 << 11) /* slot 12 tx empty */ -#define SLFR_12RXV (1 << 10) /* slot 12 rx valid */ -#define SLFR_2TXE (1 << 9) /* slot 2 tx empty */ -#define SLFR_2RXV (1 << 8) /* slot 2 rx valid */ -#define SLFR_1TXE (1 << 7) /* slot 1 tx empty */ -#define SLFR_1RXV (1 << 6) /* slot 1 rx valid */ -#define SLFR_12TXB (1 << 5) /* slot 12 tx busy */ -#define SLFR_12RXB (1 << 4) /* slot 12 rx busy */ -#define SLFR_2TXB (1 << 3) /* slot 2 tx busy */ -#define SLFR_2RXB (1 << 2) /* slot 2 rx busy */ -#define SLFR_1TXB (1 << 1) /* slot 1 tx busy */ -#define SLFR_1RXB (1 << 0) /* slot 1 rx busy */ - -/* - * Interrupt clear register. - */ -#define ICLR_RXTOFEC4 (1 << 12) -#define ICLR_RXTOFEC3 (1 << 11) -#define ICLR_RXTOFEC2 (1 << 10) -#define ICLR_RXTOFEC1 (1 << 9) -#define ICLR_TXUEC4 (1 << 8) -#define ICLR_TXUEC3 (1 << 7) -#define ICLR_TXUEC2 (1 << 6) -#define ICLR_TXUEC1 (1 << 5) -#define ICLR_RXOEC4 (1 << 4) -#define ICLR_RXOEC3 (1 << 3) -#define ICLR_RXOEC2 (1 << 2) -#define ICLR_RXOEC1 (1 << 1) -#define ICLR_WISC (1 << 0) - -/* - * Main control register bits. P62 - */ -#define MAINCR_SCRA(x) ((x) << 10) /* secondary codec reg access */ -#define MAINCR_DMAEN (1 << 9) /* dma enable */ -#define MAINCR_SL12TXEN (1 << 8) /* slot 12 transmit enable */ -#define MAINCR_SL12RXEN (1 << 7) /* slot 12 receive enable */ -#define MAINCR_SL2TXEN (1 << 6) /* slot 2 transmit enable */ -#define MAINCR_SL2RXEN (1 << 5) /* slot 2 receive enable */ -#define MAINCR_SL1TXEN (1 << 4) /* slot 1 transmit enable */ -#define MAINCR_SL1RXEN (1 << 3) /* slot 1 receive enable */ -#define MAINCR_LPM (1 << 2) /* low power mode */ -#define MAINCR_LOOPBK (1 << 1) /* loopback */ -#define MAINCR_IE (1 << 0) /* aaci interface enable */ - -/* - * Reset register bits. P65 - */ -#define RESET_NRST (1 << 0) - -/* - * Sync register bits. P65 - */ -#define SYNC_FORCE (1 << 0) - -/* - * Main flag register bits. P66 - */ -#define MAINFR_TXB (1 << 1) /* transmit busy */ -#define MAINFR_RXB (1 << 0) /* receive busy */ - - - -struct aaci_runtime { - void *base; - void *fifo; - - struct ac97_pcm *pcm; - int pcm_open; - - u32 cr; - snd_pcm_substream_t *substream; - - /* - * PIO support - */ - void *start; - void *end; - void *ptr; - int bytes; - unsigned int period; - unsigned int fifosz; -}; - -struct aaci { - struct amba_device *dev; - snd_card_t *card; - void *base; - unsigned int fifosize; - - /* AC'97 */ - struct semaphore ac97_sem; - ac97_bus_t *ac97_bus; - - u32 maincr; - spinlock_t lock; - - struct aaci_runtime playback; - struct aaci_runtime capture; - - snd_pcm_t *pcm; -}; - -#define ACSTREAM_FRONT 0 -#define ACSTREAM_SURROUND 1 -#define ACSTREAM_LFE 2 - -#endif diff --git a/trunk/sound/arm/devdma.c b/trunk/sound/arm/devdma.c deleted file mode 100644 index 60826a5324b4..000000000000 --- a/trunk/sound/arm/devdma.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * linux/sound/arm/devdma.c - * - * Copyright (C) 2003-2004 Russell King, All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * ARM DMA shim for ALSA. - */ -#include -#include - -#include -#include -#include - -#include "devdma.h" - -void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - struct snd_dma_buffer *buf = runtime->dma_buffer_p; - - if (runtime->dma_area == NULL) - return; - - if (buf != &substream->dma_buffer) { - dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr); - kfree(runtime->dma_buffer_p); - } - - snd_pcm_set_runtime_buffer(substream, NULL); -} - -int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - struct snd_dma_buffer *buf = runtime->dma_buffer_p; - int ret = 0; - - if (buf) { - if (buf->bytes >= size) - goto out; - devdma_hw_free(dev, substream); - } - - if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) { - buf = &substream->dma_buffer; - } else { - buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL); - if (!buf) - goto nomem; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = dev; - buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL); - buf->bytes = size; - buf->private_data = NULL; - - if (!buf->area) - goto free; - } - snd_pcm_set_runtime_buffer(substream, buf); - ret = 1; - out: - runtime->dma_bytes = size; - return ret; - - free: - kfree(buf); - nomem: - return -ENOMEM; -} - -int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); -} diff --git a/trunk/sound/arm/devdma.h b/trunk/sound/arm/devdma.h deleted file mode 100644 index 5a33b6bacc34..000000000000 --- a/trunk/sound/arm/devdma.h +++ /dev/null @@ -1,3 +0,0 @@ -void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream); -int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size); -int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma); diff --git a/trunk/sound/core/control.c b/trunk/sound/core/control.c index 4e39a2103d0a..f4ea6bff1dd3 100644 --- a/trunk/sound/core/control.c +++ b/trunk/sound/core/control.c @@ -1102,7 +1102,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg } } up_read(&snd_ioctl_rwsem); - snd_printdd("unknown ioctl = 0x%x\n", cmd); + snd_printd("unknown ioctl = 0x%x\n", cmd); return -ENOTTY; } diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 468fca8894d9..1a805020f57a 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -125,26 +125,17 @@ int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin) static long snd_pcm_oss_bytes(snd_pcm_substream_t *substream, long frames) { snd_pcm_runtime_t *runtime = substream->runtime; - long buffer_size = snd_pcm_lib_buffer_bytes(substream); - long bytes = frames_to_bytes(runtime, frames); + snd_pcm_uframes_t buffer_size = snd_pcm_lib_buffer_bytes(substream); + frames = frames_to_bytes(runtime, frames); if (buffer_size == runtime->oss.buffer_bytes) - return bytes; -#if BITS_PER_LONG >= 64 - return runtime->oss.buffer_bytes * bytes / buffer_size; -#else - { - u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes; - u32 rem; - div64_32(&bsize, buffer_size, &rem); - return (long)bsize; - } -#endif + return frames; + return (runtime->oss.buffer_bytes * frames) / buffer_size; } static long snd_pcm_alsa_frames(snd_pcm_substream_t *substream, long bytes) { snd_pcm_runtime_t *runtime = substream->runtime; - long buffer_size = snd_pcm_lib_buffer_bytes(substream); + snd_pcm_uframes_t buffer_size = snd_pcm_lib_buffer_bytes(substream); if (buffer_size == runtime->oss.buffer_bytes) return bytes_to_frames(runtime, bytes); return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); @@ -473,8 +464,7 @@ static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream) sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; sw_params->period_step = 1; sw_params->sleep_min = 0; - sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - 1 : runtime->period_size; + sw_params->avail_min = 1; sw_params->xfer_align = 1; if (atomic_read(&runtime->mmap_count) || (substream->oss.setup && substream->oss.setup->nosilence)) { diff --git a/trunk/sound/core/oss/pcm_plugin.c b/trunk/sound/core/oss/pcm_plugin.c index 6430410c6c04..6bb31009f0b4 100644 --- a/trunk/sound/core/oss/pcm_plugin.c +++ b/trunk/sound/core/oss/pcm_plugin.c @@ -663,7 +663,10 @@ static int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug, bitset_t *dstmask = bs; int err; bitset_one(dstmask, schannels); - + if (plugin == NULL) { + bitset_and(client_vmask, dstmask, schannels); + return 0; + } while (1) { err = plugin->src_channels_mask(plugin, dstmask, &srcmask); if (err < 0) diff --git a/trunk/sound/core/pcm.c b/trunk/sound/core/pcm.c index 9f4c9209b271..8d94325529a8 100644 --- a/trunk/sound/core/pcm.c +++ b/trunk/sound/core/pcm.c @@ -451,7 +451,6 @@ static int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr) entry->c.text.read = snd_pcm_xrun_debug_read; entry->c.text.write_size = 64; entry->c.text.write = snd_pcm_xrun_debug_write; - entry->mode |= S_IWUSR; entry->private_data = pstr; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -1049,6 +1048,7 @@ EXPORT_SYMBOL(snd_pcm_release_substream); EXPORT_SYMBOL(snd_pcm_format_name); /* pcm_native.c */ EXPORT_SYMBOL(snd_pcm_link_rwlock); +EXPORT_SYMBOL(snd_pcm_start); #ifdef CONFIG_PM EXPORT_SYMBOL(snd_pcm_suspend); EXPORT_SYMBOL(snd_pcm_suspend_all); @@ -1068,7 +1068,6 @@ EXPORT_SYMBOL(snd_pcm_format_little_endian); EXPORT_SYMBOL(snd_pcm_format_big_endian); EXPORT_SYMBOL(snd_pcm_format_width); EXPORT_SYMBOL(snd_pcm_format_physical_width); -EXPORT_SYMBOL(snd_pcm_format_size); EXPORT_SYMBOL(snd_pcm_format_silence_64); EXPORT_SYMBOL(snd_pcm_format_set_silence); EXPORT_SYMBOL(snd_pcm_build_linear_format); diff --git a/trunk/sound/core/pcm_lib.c b/trunk/sound/core/pcm_lib.c index c5bfd0918cff..151fd99ca2c9 100644 --- a/trunk/sound/core/pcm_lib.c +++ b/trunk/sound/core/pcm_lib.c @@ -1143,8 +1143,7 @@ int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime, #define INT_MIN ((int)((unsigned int)INT_MAX+1)) #endif -static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var) +void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var) { if (hw_is_mask(var)) { snd_mask_any(hw_param_mask(params, var)); @@ -1161,7 +1160,6 @@ static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_BUG(); } -#if 0 /** * snd_pcm_hw_param_any */ @@ -1171,7 +1169,6 @@ int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, _snd_pcm_hw_param_any(params, var); return snd_pcm_hw_refine(pcm, params); } -#endif /* 0 */ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params) { @@ -1184,7 +1181,6 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params) params->info = ~0U; } -#if 0 /** * snd_pcm_hw_params_any * @@ -1195,7 +1191,6 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) _snd_pcm_hw_params_any(params); return snd_pcm_hw_refine(pcm, params); } -#endif /* 0 */ /** * snd_pcm_hw_param_value @@ -1203,8 +1198,8 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) * Return the value for field PAR if it's fixed in configuration space * defined by PARAMS. Return -EINVAL otherwise */ -static int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir) { if (hw_is_mask(var)) { const snd_mask_t *mask = hw_param_mask_c(params, var); @@ -1301,7 +1296,6 @@ int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params, return changed; } -#if 0 /** * snd_pcm_hw_param_setinteger * @@ -1323,10 +1317,9 @@ int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, } return 0; } -#endif /* 0 */ -static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var) +int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var) { int changed; if (hw_is_mask(var)) @@ -1352,9 +1345,9 @@ static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, * values > minimum. Reduce configuration space accordingly. * Return the minimum. */ -static int snd_pcm_hw_param_first(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +int snd_pcm_hw_param_first(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir) { int changed = _snd_pcm_hw_param_first(params, var); if (changed < 0) @@ -1366,8 +1359,8 @@ static int snd_pcm_hw_param_first(snd_pcm_t *pcm, return snd_pcm_hw_param_value(params, var, dir); } -static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var) +int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var) { int changed; if (hw_is_mask(var)) @@ -1393,9 +1386,9 @@ static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, * values < maximum. Reduce configuration space accordingly. * Return the maximum. */ -static int snd_pcm_hw_param_last(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +int snd_pcm_hw_param_last(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir) { int changed = _snd_pcm_hw_param_last(params, var); if (changed < 0) @@ -1444,9 +1437,8 @@ int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, * values < VAL. Reduce configuration space accordingly. * Return new minimum or -EINVAL if the configuration space is empty */ -static int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, - int *dir) +int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, int *dir) { int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0); if (changed < 0) @@ -1459,9 +1451,8 @@ static int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, return snd_pcm_hw_param_value_min(params, var, dir); } -static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, - int dir) +int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, int dir) { int changed; int open = 0; @@ -1499,9 +1490,8 @@ static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, * values >= VAL + 1. Reduce configuration space accordingly. * Return new maximum or -EINVAL if the configuration space is empty */ -static int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, - int *dir) +int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, int *dir) { int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0); if (changed < 0) @@ -2574,6 +2564,9 @@ snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream, EXPORT_SYMBOL(snd_interval_refine); EXPORT_SYMBOL(snd_interval_list); EXPORT_SYMBOL(snd_interval_ratnum); +EXPORT_SYMBOL(snd_interval_muldivk); +EXPORT_SYMBOL(snd_interval_mulkdiv); +EXPORT_SYMBOL(snd_interval_div); EXPORT_SYMBOL(_snd_pcm_hw_params_any); EXPORT_SYMBOL(_snd_pcm_hw_param_min); EXPORT_SYMBOL(_snd_pcm_hw_param_set); @@ -2587,6 +2580,7 @@ EXPORT_SYMBOL(snd_pcm_hw_param_last); EXPORT_SYMBOL(snd_pcm_hw_param_near); EXPORT_SYMBOL(snd_pcm_hw_param_set); EXPORT_SYMBOL(snd_pcm_hw_refine); +EXPORT_SYMBOL(snd_pcm_hw_params); EXPORT_SYMBOL(snd_pcm_hw_constraints_init); EXPORT_SYMBOL(snd_pcm_hw_constraints_complete); EXPORT_SYMBOL(snd_pcm_hw_constraint_list); diff --git a/trunk/sound/core/pcm_memory.c b/trunk/sound/core/pcm_memory.c index 9a174fb96565..f1d5f7a6ee0c 100644 --- a/trunk/sound/core/pcm_memory.c +++ b/trunk/sound/core/pcm_memory.c @@ -204,7 +204,6 @@ static int snd_pcm_lib_preallocate_pages1(snd_pcm_substream_t *substream, entry->c.text.read = snd_pcm_lib_preallocate_proc_read; entry->c.text.write_size = 64; entry->c.text.write = snd_pcm_lib_preallocate_proc_write; - entry->mode |= S_IWUSR; entry->private_data = substream; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); diff --git a/trunk/sound/core/pcm_misc.c b/trunk/sound/core/pcm_misc.c index 1453743e4da0..422b8db14154 100644 --- a/trunk/sound/core/pcm_misc.c +++ b/trunk/sound/core/pcm_misc.c @@ -269,6 +269,22 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format) return !val; } +/** + * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian + * @format: the format to check + * + * Returns 1 if the given PCM format is CPU-endian, 0 if + * opposite, or a negative error code if endian not specified. + */ +int snd_pcm_format_cpu_endian(snd_pcm_format_t format) +{ +#ifdef SNDRV_LITTLE_ENDIAN + return snd_pcm_format_little_endian(format); +#else + return snd_pcm_format_big_endian(format); +#endif +} + /** * snd_pcm_format_width - return the bit-width of the format * @format: the format to check diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 4e582415a086..cad9bbde9986 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -337,8 +337,8 @@ static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_pa return err; } -static int snd_pcm_hw_params(snd_pcm_substream_t *substream, - snd_pcm_hw_params_t *params) +int snd_pcm_hw_params(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params) { snd_pcm_runtime_t *runtime; int err; diff --git a/trunk/sound/core/seq/seq_midi.c b/trunk/sound/core/seq/seq_midi.c index 57be9155eb62..18247db45db6 100644 --- a/trunk/sound/core/seq/seq_midi.c +++ b/trunk/sound/core/seq/seq_midi.c @@ -414,8 +414,6 @@ snd_seq_midisynth_register_port(snd_seq_device_t *dev) if (newclient) synths[card->number] = client; up(®ister_mutex); - kfree(info); - kfree(port); return 0; /* success */ __nomem: diff --git a/trunk/sound/core/seq/seq_midi_event.c b/trunk/sound/core/seq/seq_midi_event.c index df1e2bb39745..21e569062bc3 100644 --- a/trunk/sound/core/seq/seq_midi_event.c +++ b/trunk/sound/core/seq/seq_midi_event.c @@ -171,13 +171,11 @@ void snd_midi_event_reset_decode(snd_midi_event_t *dev) spin_unlock_irqrestore(&dev->lock, flags); } -#if 0 void snd_midi_event_init(snd_midi_event_t *dev) { snd_midi_event_reset_encode(dev); snd_midi_event_reset_decode(dev); } -#endif /* 0 */ void snd_midi_event_no_status(snd_midi_event_t *dev, int on) { @@ -187,7 +185,6 @@ void snd_midi_event_no_status(snd_midi_event_t *dev, int on) /* * resize buffer */ -#if 0 int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize) { unsigned char *new_buf, *old_buf; @@ -207,7 +204,6 @@ int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize) kfree(old_buf); return 0; } -#endif /* 0 */ /* * read bytes and encode to sequencer event if finished @@ -521,6 +517,8 @@ static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int coun EXPORT_SYMBOL(snd_midi_event_new); EXPORT_SYMBOL(snd_midi_event_free); +EXPORT_SYMBOL(snd_midi_event_resize_buffer); +EXPORT_SYMBOL(snd_midi_event_init); EXPORT_SYMBOL(snd_midi_event_reset_encode); EXPORT_SYMBOL(snd_midi_event_reset_decode); EXPORT_SYMBOL(snd_midi_event_no_status); diff --git a/trunk/sound/core/seq/seq_queue.c b/trunk/sound/core/seq/seq_queue.c index 98de2e711fde..3afc7cc0c9a7 100644 --- a/trunk/sound/core/seq/seq_queue.c +++ b/trunk/sound/core/seq/seq_queue.c @@ -672,8 +672,7 @@ static void queue_broadcast_event(queue_t *q, snd_seq_event_t *ev, int atomic, i * process a received queue-control event. * this function is exported for seq_sync.c. */ -static void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, - int atomic, int hop) +void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, int atomic, int hop) { switch (ev->type) { case SNDRV_SEQ_EVENT_START: diff --git a/trunk/sound/core/seq/seq_queue.h b/trunk/sound/core/seq/seq_queue.h index ea3c54216ea8..b1bf5519fb3b 100644 --- a/trunk/sound/core/seq/seq_queue.h +++ b/trunk/sound/core/seq/seq_queue.h @@ -111,6 +111,7 @@ int snd_seq_queue_use(int queueid, int client, int use); int snd_seq_queue_is_used(int queueid, int client); int snd_seq_control_queue(snd_seq_event_t *ev, int atomic, int hop); +void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, int atomic, int hop); /* * 64bit division - for sync stuff.. diff --git a/trunk/sound/core/seq/seq_timer.c b/trunk/sound/core/seq/seq_timer.c index a7f76fc95280..753f1c0863cc 100644 --- a/trunk/sound/core/seq/seq_timer.c +++ b/trunk/sound/core/seq/seq_timer.c @@ -36,8 +36,7 @@ extern int seq_default_timer_resolution; #define SKEW_BASE 0x10000 /* 16bit shift */ -static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, - int tempo, int ppq, int nticks) +void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, int tempo, int ppq, int nticks) { if (tempo < 1000000) tick->resolution = (tempo * 1000) / ppq; diff --git a/trunk/sound/core/seq/seq_timer.h b/trunk/sound/core/seq/seq_timer.h index 287ed68591de..4c0872df8931 100644 --- a/trunk/sound/core/seq/seq_timer.h +++ b/trunk/sound/core/seq/seq_timer.h @@ -64,6 +64,8 @@ extern seq_timer_t *snd_seq_timer_new(void); /* delete timer (destructor) */ extern void snd_seq_timer_delete(seq_timer_t **tmr); +void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, int tempo, int ppq, int nticks); + /* */ static inline void snd_seq_timer_update_tick(seq_timer_tick_t *tick, unsigned long resolution) { diff --git a/trunk/sound/core/seq/seq_virmidi.c b/trunk/sound/core/seq/seq_virmidi.c index a66484b5cf0e..6b4e630ace54 100644 --- a/trunk/sound/core/seq/seq_virmidi.c +++ b/trunk/sound/core/seq/seq_virmidi.c @@ -110,7 +110,7 @@ static int snd_virmidi_dev_receive_event(snd_virmidi_dev_t *rdev, snd_seq_event_ * handler of a remote port which is attached to the virmidi via * SNDRV_VIRMIDI_SEQ_ATTACH. */ -#if 0 +/* exported */ int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev) { snd_virmidi_dev_t *rdev; @@ -118,7 +118,6 @@ int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev) rdev = rmidi->private_data; return snd_virmidi_dev_receive_event(rdev, ev); } -#endif /* 0 */ /* * event handler of virmidi port @@ -385,7 +384,7 @@ static int snd_virmidi_dev_attach_seq(snd_virmidi_dev_t *rdev) info->client = client; info->type = KERNEL_CLIENT; sprintf(info->name, "%s %d-%d", rdev->rmidi->name, rdev->card->number, rdev->device); - snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, info); + snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &info); /* create a port */ memset(pinfo, 0, sizeof(*pinfo)); @@ -406,7 +405,7 @@ static int snd_virmidi_dev_attach_seq(snd_virmidi_dev_t *rdev) pcallbacks.unuse = snd_virmidi_unuse; pcallbacks.event_input = snd_virmidi_event_input; pinfo->kernel = &pcallbacks; - err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, pinfo); + err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, &pinfo); if (err < 0) { snd_seq_delete_kernel_client(client); rdev->client = -1; @@ -549,3 +548,4 @@ module_init(alsa_virmidi_init) module_exit(alsa_virmidi_exit) EXPORT_SYMBOL(snd_virmidi_new); +EXPORT_SYMBOL(snd_virmidi_receive); diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index fa92e660ec2c..88e052079f85 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -431,6 +431,7 @@ EXPORT_SYMBOL(snd_card_pci_resume); EXPORT_SYMBOL(snd_device_new); EXPORT_SYMBOL(snd_device_register); EXPORT_SYMBOL(snd_device_free); +EXPORT_SYMBOL(snd_device_free_all); /* isadma.c */ #ifdef CONFIG_ISA EXPORT_SYMBOL(snd_dma_program); diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index d67a5e91a108..fa762ca439be 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -69,7 +69,6 @@ typedef struct { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct semaphore tread_sem; } snd_timer_user_t; /* list of timers */ @@ -845,7 +844,7 @@ int snd_timer_dev_register(snd_device_t *dev) return 0; } -static int snd_timer_unregister(snd_timer_t *timer) +int snd_timer_unregister(snd_timer_t *timer) { struct list_head *p, *n; snd_timer_instance_t *ti; @@ -946,6 +945,11 @@ struct snd_timer_system_private { unsigned long correction; }; +unsigned int snd_timer_system_resolution(void) +{ + return 1000000000L / HZ; +} + static void snd_timer_s_function(unsigned long data) { snd_timer_t *timer = (snd_timer_t *)data; @@ -1204,7 +1208,6 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - init_MUTEX(&tu->tread_sem); tu->ticks = 1; tu->queue_size = 128; tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); @@ -1451,23 +1454,18 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * snd_timer_user_t *tu; snd_timer_select_t tselect; char str[32]; - int err = 0; + int err; tu = file->private_data; - down(&tu->tread_sem); - if (tu->timeri) { + if (tu->timeri) snd_timer_close(tu->timeri); - tu->timeri = NULL; - } - if (copy_from_user(&tselect, _tselect, sizeof(tselect))) { - err = -EFAULT; - goto __err; - } + if (copy_from_user(&tselect, _tselect, sizeof(tselect))) + return -EFAULT; sprintf(str, "application %i", current->pid); if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) - goto __err; + return err; if (tu->queue) { kfree(tu->queue); @@ -1479,27 +1477,23 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * } if (tu->tread) { tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); - if (tu->tqueue == NULL) - err = -ENOMEM; + if (tu->tqueue == NULL) { + snd_timer_close(tu->timeri); + return -ENOMEM; + } } else { tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); - if (tu->queue == NULL) - err = -ENOMEM; + if (tu->queue == NULL) { + snd_timer_close(tu->timeri); + return -ENOMEM; + } } - if (err < 0) { - snd_timer_close(tu->timeri); - tu->timeri = NULL; - } else { - tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; - tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; - tu->timeri->ccallback = snd_timer_user_ccallback; - tu->timeri->callback_data = (void *)tu; - } - - __err: - up(&tu->tread_sem); - return err; + tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; + tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; + tu->timeri->ccallback = snd_timer_user_ccallback; + tu->timeri->callback_data = (void *)tu; + return 0; } static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) @@ -1675,23 +1669,6 @@ static int snd_timer_user_continue(struct file *file) return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; } -static int snd_timer_user_pause(struct file *file) -{ - int err; - snd_timer_user_t *tu; - - tu = file->private_data; - snd_assert(tu->timeri != NULL, return -ENXIO); - return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; -} - -enum { - SNDRV_TIMER_IOCTL_START_OLD = _IO('T', 0x20), - SNDRV_TIMER_IOCTL_STOP_OLD = _IO('T', 0x21), - SNDRV_TIMER_IOCTL_CONTINUE_OLD = _IO('T', 0x22), - SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), -}; - static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { snd_timer_user_t *tu; @@ -1708,17 +1685,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l { int xarg; - down(&tu->tread_sem); - if (tu->timeri) { /* too late */ - up(&tu->tread_sem); + if (tu->timeri) /* too late */ return -EBUSY; - } - if (get_user(xarg, p)) { - up(&tu->tread_sem); + if (get_user(xarg, p)) return -EFAULT; - } tu->tread = xarg ? 1 : 0; - up(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: @@ -1736,17 +1707,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l case SNDRV_TIMER_IOCTL_STATUS: return snd_timer_user_status(file, argp); case SNDRV_TIMER_IOCTL_START: - case SNDRV_TIMER_IOCTL_START_OLD: return snd_timer_user_start(file); case SNDRV_TIMER_IOCTL_STOP: - case SNDRV_TIMER_IOCTL_STOP_OLD: return snd_timer_user_stop(file); case SNDRV_TIMER_IOCTL_CONTINUE: - case SNDRV_TIMER_IOCTL_CONTINUE_OLD: return snd_timer_user_continue(file); - case SNDRV_TIMER_IOCTL_PAUSE: - case SNDRV_TIMER_IOCTL_PAUSE_OLD: - return snd_timer_user_pause(file); } return -ENOTTY; } @@ -1933,3 +1898,4 @@ EXPORT_SYMBOL(snd_timer_global_free); EXPORT_SYMBOL(snd_timer_global_register); EXPORT_SYMBOL(snd_timer_global_unregister); EXPORT_SYMBOL(snd_timer_interrupt); +EXPORT_SYMBOL(snd_timer_system_resolution); diff --git a/trunk/sound/core/timer_compat.c b/trunk/sound/core/timer_compat.c index 3de552dfe80f..9fbc3957a22d 100644 --- a/trunk/sound/core/timer_compat.c +++ b/trunk/sound/core/timer_compat.c @@ -106,13 +106,8 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns case SNDRV_TIMER_IOCTL_SELECT: case SNDRV_TIMER_IOCTL_PARAMS: case SNDRV_TIMER_IOCTL_START: - case SNDRV_TIMER_IOCTL_START_OLD: case SNDRV_TIMER_IOCTL_STOP: - case SNDRV_TIMER_IOCTL_STOP_OLD: case SNDRV_TIMER_IOCTL_CONTINUE: - case SNDRV_TIMER_IOCTL_CONTINUE_OLD: - case SNDRV_TIMER_IOCTL_PAUSE: - case SNDRV_TIMER_IOCTL_PAUSE_OLD: case SNDRV_TIMER_IOCTL_NEXT_DEVICE: return snd_timer_user_ioctl(file, cmd, (unsigned long)argp); case SNDRV_TIMER_IOCTL_INFO32: diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index 148a856a43ad..3a3228b18726 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -179,7 +179,6 @@ config SND_INTERWAVE_STB select SND_RAWMIDI select SND_CS4231_LIB select SND_GUS_SYNTH - select ISAPNP help Say Y here to include support for AMD InterWave based soundcards with a TEA6330T bass and treble regulator diff --git a/trunk/sound/isa/ad1816a/ad1816a.c b/trunk/sound/isa/ad1816a/ad1816a.c index 563296d02894..9fa7a78da6c3 100644 --- a/trunk/sound/isa/ad1816a/ad1816a.c +++ b/trunk/sound/isa/ad1816a/ad1816a.c @@ -83,8 +83,6 @@ struct snd_card_ad1816a { static struct pnp_card_device_id snd_ad1816a_pnpids[] = { /* Analog Devices AD1815 */ { .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } }, - /* Analog Device AD1816? */ - { .id = "ADS7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, /* Analog Devices AD1816A - added by Kenneth Platz */ { .id = "ADS7181", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } }, /* Analog Devices AD1816A - Aztech/Newcom SC-16 3D */ diff --git a/trunk/sound/isa/gus/gus_io.c b/trunk/sound/isa/gus/gus_io.c index 337b0e2a8a36..f0570f2bf75f 100644 --- a/trunk/sound/isa/gus/gus_io.c +++ b/trunk/sound/isa/gus/gus_io.c @@ -244,8 +244,6 @@ unsigned short snd_gf1_i_look16(snd_gus_card_t * gus, unsigned char reg) return res; } -#if 0 - void snd_gf1_i_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigned char data) @@ -267,8 +265,6 @@ void snd_gf1_i_write_addr(snd_gus_card_t * gus, unsigned char reg, spin_unlock_irqrestore(&gus->reg_lock, flags); } -#endif /* 0 */ - unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit) { @@ -333,8 +329,6 @@ unsigned char snd_gf1_peek(snd_gus_card_t * gus, unsigned int addr) return res; } -#if 0 - void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data) { unsigned long flags; @@ -411,7 +405,9 @@ void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr, spin_unlock_irqrestore(&gus->reg_lock, flags); } -#endif /* 0 */ +/* + + */ void snd_gf1_select_active_voices(snd_gus_card_t * gus) { @@ -473,8 +469,6 @@ void snd_gf1_print_voice_registers(snd_gus_card_t * gus) printk(" -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c)); } -#if 0 - void snd_gf1_print_global_registers(snd_gus_card_t * gus) { unsigned char global_mode = 0x00; @@ -534,6 +528,4 @@ void snd_gf1_peek_print_block(snd_gus_card_t * gus, unsigned int addr, int count } } -#endif /* 0 */ - #endif diff --git a/trunk/sound/isa/gus/gus_main.c b/trunk/sound/isa/gus/gus_main.c index 94bbd344be5e..73f81c14f768 100644 --- a/trunk/sound/isa/gus/gus_main.c +++ b/trunk/sound/isa/gus/gus_main.c @@ -459,6 +459,7 @@ EXPORT_SYMBOL(snd_gf1_write16); EXPORT_SYMBOL(snd_gf1_look16); EXPORT_SYMBOL(snd_gf1_i_write8); EXPORT_SYMBOL(snd_gf1_i_look8); +EXPORT_SYMBOL(snd_gf1_i_write16); EXPORT_SYMBOL(snd_gf1_i_look16); EXPORT_SYMBOL(snd_gf1_dram_addr); EXPORT_SYMBOL(snd_gf1_write_addr); @@ -469,6 +470,8 @@ EXPORT_SYMBOL(snd_gf1_alloc_voice); EXPORT_SYMBOL(snd_gf1_free_voice); EXPORT_SYMBOL(snd_gf1_ctrl_stop); EXPORT_SYMBOL(snd_gf1_stop_voice); +EXPORT_SYMBOL(snd_gf1_start); +EXPORT_SYMBOL(snd_gf1_stop); /* gus_mixer.c */ EXPORT_SYMBOL(snd_gf1_new_mixer); /* gus_pcm.c */ diff --git a/trunk/sound/isa/gus/gus_mem.c b/trunk/sound/isa/gus/gus_mem.c index 609838e8ef67..bfc2b91001d5 100644 --- a/trunk/sound/isa/gus/gus_mem.c +++ b/trunk/sound/isa/gus/gus_mem.c @@ -39,8 +39,8 @@ void snd_gf1_mem_lock(snd_gf1_mem_t * alloc, int xup) } } -static snd_gf1_mem_block_t *snd_gf1_mem_xalloc(snd_gf1_mem_t * alloc, - snd_gf1_mem_block_t * block) +snd_gf1_mem_block_t *snd_gf1_mem_xalloc(snd_gf1_mem_t * alloc, + snd_gf1_mem_block_t * block) { snd_gf1_mem_block_t *pblock, *nblock; @@ -105,8 +105,8 @@ int snd_gf1_mem_xfree(snd_gf1_mem_t * alloc, snd_gf1_mem_block_t * block) return 0; } -static snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc, - unsigned int address) +snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc, + unsigned int address) { snd_gf1_mem_block_t *block; @@ -118,8 +118,8 @@ static snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc, return NULL; } -static snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc, - unsigned int *share_id) +snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc, + unsigned int *share_id) { snd_gf1_mem_block_t *block; diff --git a/trunk/sound/isa/gus/gus_reset.c b/trunk/sound/isa/gus/gus_reset.c index ef687abc7070..b4e66f6a10ae 100644 --- a/trunk/sound/isa/gus/gus_reset.c +++ b/trunk/sound/isa/gus/gus_reset.c @@ -161,8 +161,7 @@ void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice) #endif } -static void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min, - unsigned short v_max) +void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max) { unsigned long flags; unsigned int daddr; diff --git a/trunk/sound/isa/gus/gus_synth.c b/trunk/sound/isa/gus/gus_synth.c index f51c386ee192..66552e6013a4 100644 --- a/trunk/sound/isa/gus/gus_synth.c +++ b/trunk/sound/isa/gus/gus_synth.c @@ -99,8 +99,7 @@ static void snd_gus_synth_free_private_instruments(snd_gus_port_t *p, int client snd_seq_instr_list_free_cond(p->gus->gf1.ilist, &ifree, client, 0); } -static int snd_gus_synth_event_input(snd_seq_event_t *ev, int direct, - void *private_data, int atomic, int hop) +int snd_gus_synth_event_input(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop) { snd_gus_port_t * p = (snd_gus_port_t *) private_data; diff --git a/trunk/sound/isa/gus/gus_tables.h b/trunk/sound/isa/gus/gus_tables.h index 4adf098d3269..ed8e9d85ad31 100644 --- a/trunk/sound/isa/gus/gus_tables.h +++ b/trunk/sound/isa/gus/gus_tables.h @@ -23,8 +23,6 @@ #ifdef __GUS_TABLES_ALLOC__ -#if 0 - unsigned int snd_gf1_scale_table[SNDRV_GF1_SCALE_TABLE_SIZE] = { 8372, 8870, 9397, 9956, 10548, 11175, @@ -51,8 +49,6 @@ unsigned int snd_gf1_scale_table[SNDRV_GF1_SCALE_TABLE_SIZE] = 12123977, 12844906 }; -#endif /* 0 */ - unsigned short snd_gf1_atten_table[SNDRV_GF1_ATTEN_TABLE_SIZE] = { 4095 /* 0 */,1789 /* 1 */,1533 /* 2 */,1383 /* 3 */,1277 /* 4 */, 1195 /* 5 */,1127 /* 6 */,1070 /* 7 */,1021 /* 8 */,978 /* 9 */, diff --git a/trunk/sound/isa/gus/gus_volume.c b/trunk/sound/isa/gus/gus_volume.c index 3d36f6c8ee6a..b72bcfb28617 100644 --- a/trunk/sound/isa/gus/gus_volume.c +++ b/trunk/sound/isa/gus/gus_volume.c @@ -55,8 +55,6 @@ unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol) return (e << 8) | m; } -#if 0 - unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol) { unsigned int rvol; @@ -110,8 +108,6 @@ unsigned int snd_gf1_calc_ramp_rate(snd_gus_card_t * gus, return (range << 6) | (increment & 0x3f); } -#endif /* 0 */ - unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq16) { freq16 >>= 3; @@ -124,8 +120,6 @@ unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq16) return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq; } -#if 0 - short snd_gf1_compute_vibrato(short cents, unsigned short fc_register) { static short vibrato_table[] = @@ -214,5 +208,3 @@ unsigned short snd_gf1_compute_freq(unsigned int freq, } return (unsigned short) fc; } - -#endif /* 0 */ diff --git a/trunk/sound/pci/ac97/ac97_codec.c b/trunk/sound/pci/ac97/ac97_codec.c index 36a33ae9ae03..0b024ec1f709 100644 --- a/trunk/sound/pci/ac97/ac97_codec.c +++ b/trunk/sound/pci/ac97/ac97_codec.c @@ -120,7 +120,6 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { { 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL }, { 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL }, { 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL }, -{ 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL }, { 0x434d4978, 0xffffffff, "CMI9761", patch_cm9761, NULL }, { 0x434d4982, 0xffffffff, "CMI9761", patch_cm9761, NULL }, { 0x434d4983, 0xffffffff, "CMI9761", patch_cm9761, NULL }, @@ -463,14 +462,12 @@ int snd_ac97_get_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * u { ac97_t *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; - unsigned short val, bitmask; + unsigned short val; - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; val = snd_ac97_read_cache(ac97, e->reg); - ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1); + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (e->mask - 1); if (e->shift_l != e->shift_r) - ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (bitmask - 1); + ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (e->mask - 1); return 0; } @@ -480,19 +477,17 @@ int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * u ac97_t *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; unsigned short val; - unsigned short mask, bitmask; + unsigned short mask; - for (bitmask = 1; bitmask < e->mask; bitmask <<= 1) - ; if (ucontrol->value.enumerated.item[0] > e->mask - 1) return -EINVAL; val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; + mask = (e->mask - 1) << e->shift_l; if (e->shift_l != e->shift_r) { if (ucontrol->value.enumerated.item[1] > e->mask - 1) return -EINVAL; val |= ucontrol->value.enumerated.item[1] << e->shift_r; - mask |= (bitmask - 1) << e->shift_r; + mask |= (e->mask - 1) << e->shift_r; } return snd_ac97_update_bits(ac97, e->reg, mask, val); } @@ -663,6 +658,11 @@ AC97_SINGLE("LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 1, 1), AC97_SINGLE("LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 31, 1) }; +static const snd_kcontrol_new_t snd_ac97_controls_surround[2] = { +AC97_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1), +AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), +}; + static const snd_kcontrol_new_t snd_ac97_control_eapd = AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1); @@ -1072,9 +1072,9 @@ static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max unsigned short val; snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); val = snd_ac97_read(ac97, reg); - if (! *lo_max && (val & 0x7f) == cbit[i]) + if (! *lo_max && (val & cbit[i])) *lo_max = max[i]; - if (! *hi_max && ((val >> 8) & 0x7f) == cbit[i]) + if (! *hi_max && (val & (cbit[i] << 8))) *hi_max = max[i]; if (*lo_max && *hi_max) break; @@ -1872,11 +1872,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) goto __access_ok; } - /* reset to defaults */ - if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO)) - snd_ac97_write(ac97, AC97_RESET, 0); - if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM)) - snd_ac97_write(ac97, AC97_EXTENDED_MID, 0); + snd_ac97_write(ac97, AC97_RESET, 0); /* reset to defaults */ if (bus->ops->wait) bus->ops->wait(ac97); else { @@ -1968,21 +1964,21 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) /* note: it's important to set the rate at first */ tmp = AC97_MEA_GPIO; if (ac97->ext_mid & AC97_MEI_LINE1) { - snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 8000); + snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 12000); tmp |= AC97_MEA_ADC1 | AC97_MEA_DAC1; } if (ac97->ext_mid & AC97_MEI_LINE2) { - snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 8000); + snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 12000); tmp |= AC97_MEA_ADC2 | AC97_MEA_DAC2; } if (ac97->ext_mid & AC97_MEI_HANDSET) { - snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 8000); + snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 12000); tmp |= AC97_MEA_HADC | AC97_MEA_HDAC; } - snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0); + snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8)); udelay(100); /* nothing should be in powerdown mode */ - snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0); + snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8)); end_time = jiffies + (HZ / 10); do { if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp) diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index b81064133c61..13c34a5d8206 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -64,116 +64,6 @@ static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned shor return ret; } -/* - * shared line-in/mic controls - */ -static int ac97_enum_text_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo, - const char **texts, unsigned int nums) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = nums; - if (uinfo->value.enumerated.item > nums - 1) - uinfo->value.enumerated.item = nums - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int ac97_surround_jack_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - static const char *texts[] = { "Shared", "Independent" }; - return ac97_enum_text_info(kcontrol, uinfo, texts, 2); -} - -static int ac97_surround_jack_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ac97_t *ac97 = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = ac97->indep_surround; - return 0; -} - -static int ac97_surround_jack_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ac97_t *ac97 = snd_kcontrol_chip(kcontrol); - unsigned char indep = !!ucontrol->value.enumerated.item[0]; - - if (indep != ac97->indep_surround) { - ac97->indep_surround = indep; - if (ac97->build_ops->update_jacks) - ac97->build_ops->update_jacks(ac97); - return 1; - } - return 0; -} - -static int ac97_channel_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - static const char *texts[] = { "2ch", "4ch", "6ch" }; - if (kcontrol->private_value) - return ac97_enum_text_info(kcontrol, uinfo, texts, 2); /* 4ch only */ - return ac97_enum_text_info(kcontrol, uinfo, texts, 3); -} - -static int ac97_channel_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ac97_t *ac97 = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = ac97->channel_mode; - return 0; -} - -static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ac97_t *ac97 = snd_kcontrol_chip(kcontrol); - unsigned char mode = ucontrol->value.enumerated.item[0]; - - if (mode != ac97->channel_mode) { - ac97->channel_mode = mode; - if (ac97->build_ops->update_jacks) - ac97->build_ops->update_jacks(ac97); - return 1; - } - return 0; -} - -#define AC97_SURROUND_JACK_MODE_CTL \ - { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = "Surround Jack Mode", \ - .info = ac97_surround_jack_mode_info, \ - .get = ac97_surround_jack_mode_get, \ - .put = ac97_surround_jack_mode_put, \ - } -#define AC97_CHANNEL_MODE_CTL \ - { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = "Channel Mode", \ - .info = ac97_channel_mode_info, \ - .get = ac97_channel_mode_get, \ - .put = ac97_channel_mode_put, \ - } -#define AC97_CHANNEL_MODE_4CH_CTL \ - { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = "Channel Mode", \ - .info = ac97_channel_mode_info, \ - .get = ac97_channel_mode_get, \ - .put = ac97_channel_mode_put, \ - .private_value = 1, \ - } - -static inline int is_shared_linein(ac97_t *ac97) -{ - return ! ac97->indep_surround && ac97->channel_mode >= 1; -} - -static inline int is_shared_micin(ac97_t *ac97) -{ - return ! ac97->indep_surround && ac97->channel_mode >= 2; -} - - /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */ @@ -1500,16 +1390,6 @@ static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val); } -static void ad1888_update_jacks(ac97_t *ac97) -{ - /* shared Line-In */ - snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12, - is_shared_linein(ac97) ? 0 : 1 << 12); - /* shared Mic */ - snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11, - is_shared_micin(ac97) ? 0 : 1 << 11); -} - static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1526,8 +1406,8 @@ static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { .get = snd_ac97_ad1888_downmix_get, .put = snd_ac97_ad1888_downmix_put }, - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, + AC97_SINGLE("Surround Jack as Input", AC97_AD_MISC, 12, 1, 0), + AC97_SINGLE("Center/LFE Jack as Input", AC97_AD_MISC, 11, 1, 0), }; static int patch_ad1888_specific(ac97_t *ac97) @@ -1542,9 +1422,8 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1888_specific, #ifdef CONFIG_PM - .resume = ad18xx_resume, + .resume = ad18xx_resume #endif - .update_jacks = ad1888_update_jacks, }; int patch_ad1888(ac97_t * ac97) @@ -1580,9 +1459,8 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1980_specific, #ifdef CONFIG_PM - .resume = ad18xx_resume, + .resume = ad18xx_resume #endif - .update_jacks = ad1888_update_jacks, }; int patch_ad1980(ac97_t * ac97) @@ -1593,21 +1471,10 @@ int patch_ad1980(ac97_t * ac97) } static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = { + AC97_SINGLE("Center/LFE Jack as Mic", AC97_AD_SERIAL_CFG, 9, 1, 0), AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0) }; -static void ad1985_update_jacks(ac97_t *ac97) -{ - /* shared Line-In */ - snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12, - is_shared_linein(ac97) ? 0 : 1 << 12); - /* shared Mic */ - snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11, - is_shared_micin(ac97) ? 0 : 1 << 11); - snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9, - is_shared_micin(ac97) ? 0 : 1 << 9); -} - static int patch_ad1985_specific(ac97_t *ac97) { int err; @@ -1621,9 +1488,8 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = { .build_post_spdif = patch_ad198x_post_spdif, .build_specific = patch_ad1985_specific, #ifdef CONFIG_PM - .resume = ad18xx_resume, + .resume = ad18xx_resume #endif - .update_jacks = ad1985_update_jacks, }; int patch_ad1985(ac97_t * ac97) @@ -1655,25 +1521,31 @@ int patch_ad1985(ac97_t * ac97) /* * realtek ALC65x/850 codecs */ -static void alc650_update_jacks(ac97_t *ac97) +static int snd_ac97_alc650_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) { - int shared; - - /* shared Line-In */ - shared = is_shared_linein(ac97); - snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9, - shared ? (1 << 9) : 0); - /* update shared Mic */ - shared = is_shared_micin(ac97); - /* disable/enable vref */ - snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, - shared ? (1 << 12) : 0); - /* turn on/off center-on-mic */ - snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10, - shared ? (1 << 10) : 0); - /* GPIO0 high for mic */ - snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100, - shared ? 0 : 0x100); + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1; + return 0; +} + +static int snd_ac97_alc650_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + int change, val; + val = !!(snd_ac97_read(ac97, AC97_ALC650_MULTICH) & (1 << 10)); + change = (ucontrol->value.integer.value[0] != val); + if (change) { + /* disable/enable vref */ + snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, + ucontrol->value.integer.value[0] ? (1 << 12) : 0); + /* turn on/off center-on-mic */ + snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10, + ucontrol->value.integer.value[0] ? (1 << 10) : 0); + /* GPIO0 high for mic */ + snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100, + ucontrol->value.integer.value[0] ? 0 : 0x100); + } + return change; } static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { @@ -1686,8 +1558,8 @@ static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { /* 6: Independent Master Volume Right */ /* 7: Independent Master Volume Left */ /* 8: reserved */ - /* 9: Line-In/Surround share */ - /* 10: Mic/CLFE share */ + AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0), + /* 10: mic, see below */ /* 11-13: in IEC958 controls */ AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0), #if 0 /* always set in patch_alc650 */ @@ -1698,8 +1570,14 @@ static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = { AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1), AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1), #endif - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic As Center/LFE", + .info = snd_ac97_info_volsw, + .get = snd_ac97_alc650_mic_get, + .put = snd_ac97_alc650_mic_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ + }, }; static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { @@ -1723,8 +1601,7 @@ static int patch_alc650_specific(ac97_t * ac97) } static struct snd_ac97_build_ops patch_alc650_ops = { - .build_specific = patch_alc650_specific, - .update_jacks = alc650_update_jacks + .build_specific = patch_alc650_specific }; int patch_alc650(ac97_t * ac97) @@ -1782,27 +1659,37 @@ int patch_alc650(ac97_t * ac97) return 0; } -static void alc655_update_jacks(ac97_t *ac97) +static int snd_ac97_alc655_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) { - int shared; - - /* shared Line-In */ - shared = is_shared_linein(ac97); - ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9, - shared ? (1 << 9) : 0, 0); - /* update shared mic */ - shared = is_shared_micin(ac97); + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1; + return 0; +} + +static int snd_ac97_alc655_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + /* misc control; vrefout disable */ snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, - shared ? (1 << 12) : 0); - ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10, - shared ? (1 << 10) : 0, 0); + ucontrol->value.integer.value[0] ? (1 << 12) : 0); + return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10, + ucontrol->value.integer.value[0] ? (1 << 10) : 0, + 0); } + static const snd_kcontrol_new_t snd_ac97_controls_alc655[] = { AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, + AC97_PAGE_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic As Center/LFE", + .info = snd_ac97_info_volsw, + .get = snd_ac97_alc655_mic_get, + .put = snd_ac97_alc655_mic_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ + }, }; static int alc655_iec958_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) @@ -1872,8 +1759,7 @@ static int patch_alc655_specific(ac97_t * ac97) } static struct snd_ac97_build_ops patch_alc655_ops = { - .build_specific = patch_alc655_specific, - .update_jacks = alc655_update_jacks + .build_specific = patch_alc655_specific }; int patch_alc655(ac97_t * ac97) @@ -1912,33 +1798,63 @@ int patch_alc655(ac97_t * ac97) #define AC97_ALC850_JACK_SELECT 0x76 #define AC97_ALC850_MISC1 0x7a -static void alc850_update_jacks(ac97_t *ac97) +static int ac97_alc850_surround_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) { - int shared; - - /* shared Line-In */ - shared = is_shared_linein(ac97); + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 12) & 7) == 2; + return 0; +} + +static int ac97_alc850_surround_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + /* SURR 1kOhm (bit4), Amp (bit5) */ snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5), - shared ? (1<<5) : (1<<4)); + ucontrol->value.integer.value[0] ? (1<<5) : (1<<4)); /* LINE-IN = 0, SURROUND = 2 */ - snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12, - shared ? (2<<12) : (0<<12)); - /* update shared mic */ - shared = is_shared_micin(ac97); + return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12, + ucontrol->value.integer.value[0] ? (2<<12) : (0<<12)); +} + +static int ac97_alc850_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 4) & 7) == 2; + return 0; +} + +static int ac97_alc850_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + /* Vref disable (bit12), 1kOhm (bit13) */ snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13), - shared ? (1<<12) : (1<<13)); + ucontrol->value.integer.value[0] ? (1<<12) : (1<<13)); /* MIC-IN = 1, CENTER-LFE = 2 */ - snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4, - shared ? (2<<4) : (1<<4)); + return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4, + ucontrol->value.integer.value[0] ? (2<<4) : (1<<4)); } static const snd_kcontrol_new_t snd_ac97_controls_alc850[] = { AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), - AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1), - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line-In As Surround", + .info = snd_ac97_info_volsw, + .get = ac97_alc850_surround_get, + .put = ac97_alc850_surround_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic As Center/LFE", + .info = snd_ac97_info_volsw, + .get = ac97_alc850_mic_get, + .put = ac97_alc850_mic_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ + }, + }; static int patch_alc850_specific(ac97_t *ac97) @@ -1955,8 +1871,7 @@ static int patch_alc850_specific(ac97_t *ac97) } static struct snd_ac97_build_ops patch_alc850_ops = { - .build_specific = patch_alc850_specific, - .update_jacks = alc850_update_jacks + .build_specific = patch_alc850_specific }; int patch_alc850(ac97_t *ac97) @@ -1996,17 +1911,9 @@ int patch_alc850(ac97_t *ac97) /* * C-Media CM97xx codecs */ -static void cm9738_update_jacks(ac97_t *ac97) -{ - /* shared Line-In */ - snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10, - is_shared_linein(ac97) ? (1 << 10) : 0); -} - static const snd_kcontrol_new_t snd_ac97_cm9738_controls[] = { + AC97_SINGLE("Line-In As Surround", AC97_CM9738_VENDOR_CTRL, 10, 1, 0), AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0), - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_4CH_CTL, }; static int patch_cm9738_specific(ac97_t * ac97) @@ -2015,8 +1922,7 @@ static int patch_cm9738_specific(ac97_t * ac97) } static struct snd_ac97_build_ops patch_cm9738_ops = { - .build_specific = patch_cm9738_specific, - .update_jacks = cm9738_update_jacks + .build_specific = patch_cm9738_specific }; int patch_cm9738(ac97_t * ac97) @@ -2080,19 +1986,34 @@ static const snd_kcontrol_new_t snd_ac97_cm9739_controls_spdif[] = { /* BIT 8: SPD32 - 32bit SPDIF - not supported yet */ }; -static void cm9739_update_jacks(ac97_t *ac97) +static int snd_ac97_cm9739_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - /* shared Line-In */ - snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10, - is_shared_linein(ac97) ? (1 << 10) : 0); - /* shared Mic */ - snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000, - is_shared_micin(ac97) ? 0x1000 : 0x2000); + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + return 0; +} + +static int snd_ac97_cm9739_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000, + ucontrol->value.integer.value[0] ? + 0x1000 : 0x2000); } static const snd_kcontrol_new_t snd_ac97_cm9739_controls[] = { - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, + AC97_SINGLE("Line-In As Surround", AC97_CM9739_MULTI_CHAN, 10, 1, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic As Center/LFE", + .info = snd_ac97_info_volsw, + .get = snd_ac97_cm9739_center_mic_get, + .put = snd_ac97_cm9739_center_mic_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ + }, }; static int patch_cm9739_specific(ac97_t * ac97) @@ -2107,8 +2028,7 @@ static int patch_cm9739_post_spdif(ac97_t * ac97) static struct snd_ac97_build_ops patch_cm9739_ops = { .build_specific = patch_cm9739_specific, - .build_post_spdif = patch_cm9739_post_spdif, - .update_jacks = cm9739_update_jacks + .build_post_spdif = patch_cm9739_post_spdif }; int patch_cm9739(ac97_t * ac97) @@ -2167,97 +2087,71 @@ int patch_cm9739(ac97_t * ac97) } #define AC97_CM9761_MULTI_CHAN 0x64 -#define AC97_CM9761_FUNC 0x66 #define AC97_CM9761_SPDIF_CTRL 0x6c -static void cm9761_update_jacks(ac97_t *ac97) +static int snd_ac97_cm9761_linein_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - unsigned short surr_vals[2][2] = { - { 0x0008, 0x0400 }, /* off, on */ - { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */ - }; - unsigned short clfe_vals[2][2] = { - { 0x2000, 0x1880 }, /* off, on */ - { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */ - }; - - /* shared Line-In */ - snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408, - surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]); - /* shared Mic */ - snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880, - clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]); + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x0400) + ucontrol->value.integer.value[0] = 1; + else + ucontrol->value.integer.value[0] = 0; + return 0; } -static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = { - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, -}; - -static int cm9761_spdif_out_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +static int snd_ac97_cm9761_linein_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - if (uinfo->value.enumerated.item > 2) - uinfo->value.enumerated.item = 2; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + unsigned short vals[2][2] = { + { 0x0008, 0x0400 }, /* off, on */ + { 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */ + }; + return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x0408, + vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]); } -static int cm9761_spdif_out_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +static int snd_ac97_cm9761_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ac97_t *ac97 = snd_kcontrol_chip(kcontrol); - - if (ac97->regs[AC97_CM9761_FUNC] & 0x1) - ucontrol->value.enumerated.item[0] = 2; /* SPDIF-loopback */ - else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2) - ucontrol->value.enumerated.item[0] = 1; /* ADC loopback */ + if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000) + ucontrol->value.integer.value[0] = 1; else - ucontrol->value.enumerated.item[0] = 0; /* AC-link */ + ucontrol->value.integer.value[0] = 0; + if (ac97->spec.dev_flags) /* 9761-82 rev.B */ + ucontrol->value.integer.value[0] = !ucontrol->value.integer.value[0]; return 0; } -static int cm9761_spdif_out_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +static int snd_ac97_cm9761_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ac97_t *ac97 = snd_kcontrol_chip(kcontrol); - - if (ucontrol->value.enumerated.item[0] == 2) - return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1); - snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0); - return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2, - ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0); + unsigned short vals[2][2] = { + { 0x2000, 0x1880 }, /* off, on */ + { 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */ + }; + return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3880, + vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]); } -static const char *cm9761_dac_clock[] = { "AC-Link", "SPDIF-In", "Both" }; -static const struct ac97_enum cm9761_dac_clock_enum = - AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock); - -static const snd_kcontrol_new_t snd_ac97_cm9761_controls_spdif[] = { - { /* BIT 1: SPDIFS */ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", - .info = cm9761_spdif_out_source_info, - .get = cm9761_spdif_out_source_get, - .put = cm9761_spdif_out_source_put, +static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line-In As Surround", + .info = snd_ac97_info_volsw, + .get = snd_ac97_cm9761_linein_rear_get, + .put = snd_ac97_cm9761_linein_rear_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic As Center/LFE", + .info = snd_ac97_info_volsw, + .get = snd_ac97_cm9761_center_mic_get, + .put = snd_ac97_cm9761_center_mic_put, + .private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */ }, - /* BIT 2: IG_SPIV */ - AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0), - /* BIT 3: SPI2F */ - AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0), - /* BIT 4: SPI2SDI */ - AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0), - /* BIT 9-10: DAC_CTL */ - AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum), }; -static int patch_cm9761_post_spdif(ac97_t * ac97) -{ - return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif)); -} - static int patch_cm9761_specific(ac97_t * ac97) { return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls)); @@ -2265,8 +2159,7 @@ static int patch_cm9761_specific(ac97_t * ac97) static struct snd_ac97_build_ops patch_cm9761_ops = { .build_specific = patch_cm9761_specific, - .build_post_spdif = patch_cm9761_post_spdif, - .update_jacks = cm9761_update_jacks + .build_post_spdif = patch_cm9739_post_spdif /* hope it's identical... */ }; int patch_cm9761(ac97_t *ac97) @@ -2300,25 +2193,24 @@ int patch_cm9761(ac97_t *ac97) /* to be sure: we overwrite the ext status bits */ snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0); /* Don't set 0x0200 here. This results in the silent analog output */ - snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001); /* enable spdif-in */ + snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0009); ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ /* set-up multi channel */ /* bit 15: pc master beep off - * bit 14: pin47 = EAPD/SPDIF + * bit 14: ?? * bit 13: vref ctl [= cm9739] - * bit 12: CLFE control (reverted on rev B) - * bit 11: Mic/center share (reverted on rev B) - * bit 10: suddound/line share - * bit 9: Analog-in mix -> surround - * bit 8: Analog-in mix -> CLFE - * bit 7: Mic/LFE share (mic/center/lfe) - * bit 5: vref select (9761A) - * bit 4: front control - * bit 3: surround control (revereted with rev B) - * bit 2: front mic - * bit 1: stereo mic - * bit 0: mic boost level (0=20dB, 1=30dB) + * bit 12: center/mic [= cm9739] (reverted on rev B) + * bit 11: ?? (mic/center/lfe) (reverted on rev B) + * bit 10: suddound/line [= cm9739] + * bit 9: mix 2 surround + * bit 8: ? + * bit 7: ?? (mic/center/lfe) + * bit 4: ?? (front) + * bit 3: ?? (line-in/rear share) (revereted with rev B) + * bit 2: ?? (surround) + * bit 1: front mic + * bit 0: mic boost */ #if 0 @@ -2338,47 +2230,6 @@ int patch_cm9761(ac97_t *ac97) return 0; } -#define AC97_CM9780_SIDE 0x60 -#define AC97_CM9780_JACK 0x62 -#define AC97_CM9780_MIXER 0x64 -#define AC97_CM9780_MULTI_CHAN 0x66 -#define AC97_CM9780_SPDIF 0x6c - -static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" }; -static const struct ac97_enum cm9780_ch_select_enum = - AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select); -static const snd_kcontrol_new_t cm9780_controls[] = { - AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1), - AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0), - AC97_ENUM("Side Playback Route", cm9780_ch_select_enum), -}; - -static int patch_cm9780_specific(ac97_t *ac97) -{ - return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls)); -} - -static struct snd_ac97_build_ops patch_cm9780_ops = { - .build_specific = patch_cm9780_specific, - .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ -}; - -int patch_cm9780(ac97_t *ac97) -{ - unsigned short val; - - ac97->build_ops = &patch_cm9780_ops; - - /* enable spdif */ - if (ac97->ext_id & AC97_EI_SPDIF) { - ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */ - val = snd_ac97_read(ac97, AC97_CM9780_SPDIF); - val |= 0x1; /* SPDI_EN */ - snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val); - } - - return 0; -} /* * VIA VT1616 codec @@ -2412,21 +2263,9 @@ int patch_vt1616(ac97_t * ac97) return 0; } -/* - */ -static void it2646_update_jacks(ac97_t *ac97) -{ - /* shared Line-In */ - snd_ac97_update_bits(ac97, 0x76, 1 << 9, - is_shared_linein(ac97) ? (1<<9) : 0); - /* shared Mic */ - snd_ac97_update_bits(ac97, 0x76, 1 << 10, - is_shared_micin(ac97) ? (1<<10) : 0); -} - static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = { - AC97_SURROUND_JACK_MODE_CTL, - AC97_CHANNEL_MODE_CTL, + AC97_SINGLE("Line-In As Surround", 0x76, 9, 1, 0), + AC97_SINGLE("Mic As Center/LFE", 0x76, 10, 1, 0), }; static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = { @@ -2446,8 +2285,7 @@ static int patch_it2646_specific(ac97_t * ac97) } static struct snd_ac97_build_ops patch_it2646_ops = { - .build_specific = patch_it2646_specific, - .update_jacks = it2646_update_jacks + .build_specific = patch_it2646_specific }; int patch_it2646(ac97_t * ac97) diff --git a/trunk/sound/pci/ac97/ac97_patch.h b/trunk/sound/pci/ac97/ac97_patch.h index 7b7377d0f2ae..6db51c96f5d0 100644 --- a/trunk/sound/pci/ac97/ac97_patch.h +++ b/trunk/sound/pci/ac97/ac97_patch.h @@ -54,7 +54,6 @@ int patch_alc850(ac97_t * ac97); int patch_cm9738(ac97_t * ac97); int patch_cm9739(ac97_t * ac97); int patch_cm9761(ac97_t * ac97); -int patch_cm9780(ac97_t * ac97); int patch_vt1616(ac97_t * ac97); int patch_it2646(ac97_t * ac97); int mpatch_si3036(ac97_t * ac97); diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index 038f56ad42f1..984d5d4ba4e1 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -2270,7 +2270,7 @@ static struct pci_driver driver = { static int __init alsa_card_ali_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_ali_exit(void) diff --git a/trunk/sound/pci/als4000.c b/trunk/sound/pci/als4000.c index ca28b229c704..f1a5f5723ee6 100644 --- a/trunk/sound/pci/als4000.c +++ b/trunk/sound/pci/als4000.c @@ -367,7 +367,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs * if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */ snd_pcm_period_elapsed(chip->capture_substream); if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); + snd_mpu401_uart_interrupt(irq, chip->rmidi, regs); /* release the gcr */ outb(gcr_status, chip->alt_port + 0xe); @@ -777,7 +777,7 @@ static struct pci_driver driver = { static int __init alsa_card_als4000_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_als4000_exit(void) diff --git a/trunk/sound/pci/atiixp.c b/trunk/sound/pci/atiixp.c index 06551a69fb40..6b04c0acc6f7 100644 --- a/trunk/sound/pci/atiixp.c +++ b/trunk/sound/pci/atiixp.c @@ -1645,7 +1645,7 @@ static struct pci_driver driver = { static int __init alsa_card_atiixp_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_atiixp_exit(void) diff --git a/trunk/sound/pci/atiixp_modem.c b/trunk/sound/pci/atiixp_modem.c index 9220aae632b0..fb7cecea846d 100644 --- a/trunk/sound/pci/atiixp_modem.c +++ b/trunk/sound/pci/atiixp_modem.c @@ -1332,7 +1332,7 @@ static struct pci_driver driver = { static int __init alsa_card_atiixp_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_atiixp_exit(void) diff --git a/trunk/sound/pci/au88x0/au88x0.c b/trunk/sound/pci/au88x0/au88x0.c index f6236c63aaaa..889b4a1a51a1 100644 --- a/trunk/sound/pci/au88x0/au88x0.c +++ b/trunk/sound/pci/au88x0/au88x0.c @@ -375,7 +375,7 @@ static struct pci_driver driver = { // initialization of the module static int __init alsa_card_vortex_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } // clean up the module diff --git a/trunk/sound/pci/azt3328.c b/trunk/sound/pci/azt3328.c index 72bba7b2d983..b8ae534125c1 100644 --- a/trunk/sound/pci/azt3328.c +++ b/trunk/sound/pci/azt3328.c @@ -1520,7 +1520,7 @@ static int __init alsa_card_azf3328_init(void) { int err; snd_azf3328_dbgcallenter(); - err = pci_register_driver(&driver); + err = pci_module_init(&driver); snd_azf3328_dbgcallleave(); return err; } diff --git a/trunk/sound/pci/bt87x.c b/trunk/sound/pci/bt87x.c index defdc5a459f0..89a7ffe5e7d7 100644 --- a/trunk/sound/pci/bt87x.c +++ b/trunk/sound/pci/bt87x.c @@ -918,7 +918,7 @@ static int __init alsa_card_bt87x_init(void) { if (load_all) driver.id_table = snd_bt87x_default_ids; - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_bt87x_exit(void) diff --git a/trunk/sound/pci/ca0106/ca0106.h b/trunk/sound/pci/ca0106/ca0106.h index c623858428cd..deb028851056 100644 --- a/trunk/sound/pci/ca0106/ca0106.h +++ b/trunk/sound/pci/ca0106/ca0106.h @@ -508,17 +508,9 @@ struct snd_ca0106_pcm { unsigned short running; }; -typedef struct { - u32 serial; - char * name; - int ac97; - int gpio_type; -} ca0106_details_t; - // definition of the chip-specific record struct snd_ca0106 { snd_card_t *card; - ca0106_details_t *details; struct pci_dev *pci; unsigned long port; diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index a56e68ea87bc..82533b45bc8c 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -161,29 +161,18 @@ MODULE_PARM_DESC(enable, "Enable the CA0106 soundcard."); #include "ca0106.h" -static ca0106_details_t ca0106_chip_details[] = { - /* AudigyLS[SB0310] */ - { .serial = 0x10021102, - .name = "AudigyLS [SB0310]", - .ac97 = 1 } , - /* Unknown AudigyLS that also says SB0310 on it */ - { .serial = 0x10051102, - .name = "AudigyLS [SB0310b]", - .ac97 = 1 } , - /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */ - { .serial = 0x10061102, - .name = "Live! 7.1 24bit [SB0410]", - .gpio_type = 1 } , - /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */ - { .serial = 0x10071102, - .name = "Live! 7.1 24bit [SB0413]", - .gpio_type = 1 } , - /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ - { .serial = 0x10091462, - .name = "MSI K8N Diamond MB [SB0438]", - .gpio_type = 1 } , - { .serial = 0, - .name = "AudigyLS [Unknown]" } +typedef struct { + u32 serial; + char * name; +} ca0106_names_t; + +static ca0106_names_t ca0106_chip_names[] = { + { 0x10021102, "AudigyLS [SB0310]"} , + { 0x10051102, "AudigyLS [SB0310b]"} , /* Unknown AudigyLS that also says SB0310 on it */ + { 0x10061102, "Live! 7.1 24bit [SB0410]"} , /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */ + { 0x10071102, "Live! 7.1 24bit [SB0413]"} , /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */ + { 0x10091462, "MSI K8N Diamond MB [SB0438]"}, /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ + { 0, "AudigyLS [Unknown]" } }; /* hardware definition */ @@ -821,7 +810,6 @@ static int snd_ca0106_ac97(ca0106_t *chip) memset(&ac97, 0, sizeof(ac97)); ac97.private_data = chip; - ac97.scaps = AC97_SCAP_NO_SPDIF; return snd_ac97_mixer(pbus, &ac97, &chip->ac97); } @@ -1005,7 +993,6 @@ static int __devinit snd_ca0106_create(snd_card_t *card, ca0106_t **rchip) { ca0106_t *chip; - ca0106_details_t *c; int err; int ch; static snd_device_ops_t ops = { @@ -1067,15 +1054,6 @@ static int __devinit snd_ca0106_create(snd_card_t *card, printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model, chip->revision, chip->serial); #endif - strcpy(card->driver, "CA0106"); - strcpy(card->shortname, "CA0106"); - - for (c=ca0106_chip_details; c->serial; c++) { - if (c->serial == chip->serial) break; - } - chip->details = c; - sprintf(card->longname, "%s at 0x%lx irq %i", - c->name, chip->port, chip->irq); outl(0, chip->port + INTE); @@ -1135,7 +1113,7 @@ static int __devinit snd_ca0106_create(snd_card_t *card, //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */ /* Analog or Digital output */ snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf); - snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */ + snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000b0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers */ chip->spdif_enable = 0; /* Set digital SPDIF output off */ chip->capture_source = 3; /* Set CAPTURE_SOURCE */ //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */ @@ -1160,11 +1138,13 @@ static int __devinit snd_ca0106_create(snd_card_t *card, snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ chip->capture_source = 3; /* Set CAPTURE_SOURCE */ - if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ + if ((chip->serial == 0x10061102) || + (chip->serial == 0x10071102) || + (chip->serial == 0x10091462)) { /* The SB0410 and SB0413 use GPIO differently. */ /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ outl(0x0, chip->port+GPIO); //outl(0x00f0e000, chip->port+GPIO); /* Analog */ - outl(0x005f4301, chip->port+GPIO); /* Analog */ + outl(0x005f4300, chip->port+GPIO); /* Analog */ } else { outl(0x0, chip->port+GPIO); outl(0x005f03a3, chip->port+GPIO); /* Analog */ @@ -1192,6 +1172,7 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, static int dev; snd_card_t *card; ca0106_t *chip; + ca0106_names_t *c; int err; if (dev >= SNDRV_CARDS) @@ -1226,7 +1207,9 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, snd_card_free(card); return err; } - if (chip->details->ac97 == 1) { /* The SB0410 and SB0413 do not have an AC97 chip. */ + if ((chip->serial != 0x10061102) && + (chip->serial != 0x10071102) && + (chip->serial != 0x10091462) ) { /* The SB0410 and SB0413 do not have an ac97 chip. */ if ((err = snd_ca0106_ac97(chip)) < 0) { snd_card_free(card); return err; @@ -1239,6 +1222,15 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci, snd_ca0106_proc_init(chip); + strcpy(card->driver, "CA0106"); + strcpy(card->shortname, "CA0106"); + + for (c=ca0106_chip_names; c->serial; c++) { + if (c->serial == chip->serial) break; + } + sprintf(card->longname, "%s at 0x%lx irq %i", + c->name, chip->port, chip->irq); + if ((err = snd_card_register(card)) < 0) { snd_card_free(card); return err; @@ -1275,7 +1267,7 @@ static int __init alsa_card_ca0106_init(void) { int err; - if ((err = pci_register_driver(&driver)) > 0) + if ((err = pci_module_init(&driver)) > 0) return err; return 0; diff --git a/trunk/sound/pci/ca0106/ca0106_mixer.c b/trunk/sound/pci/ca0106/ca0106_mixer.c index 48e248608244..97bed1b0899d 100644 --- a/trunk/sound/pci/ca0106/ca0106_mixer.c +++ b/trunk/sound/pci/ca0106/ca0106_mixer.c @@ -113,7 +113,7 @@ static int snd_ca0106_shared_spdif_put(snd_kcontrol_t * kcontrol, } else { /* Analog */ snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf); - snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000); + snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000b0000); snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000); mask = inl(emu->port + GPIO) | 0x101; @@ -437,7 +437,7 @@ static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe = static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Analog Side Volume", + .name = "Analog Unknown Volume", .info = snd_ca0106_volume_info, .get = snd_ca0106_volume_get_analog_unknown, .put = snd_ca0106_volume_put_analog_unknown @@ -620,6 +620,11 @@ int __devinit snd_ca0106_mixer(ca0106_t *emu) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; + if ((kctl = ctl_find(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT))) != NULL) { + /* already defined by ac97, remove it */ + /* FIXME: or do we need both controls? */ + remove_ctl(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT)); + } if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_control, emu)) == NULL) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) diff --git a/trunk/sound/pci/ca0106/ca0106_proc.c b/trunk/sound/pci/ca0106/ca0106_proc.c index 3e5161a32363..afb711421e47 100644 --- a/trunk/sound/pci/ca0106/ca0106_proc.c +++ b/trunk/sound/pci/ca0106/ca0106_proc.c @@ -95,7 +95,7 @@ static struct snd_ca0106_category_str snd_ca0106_con_category[] = { }; -static void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value) +void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value) { int i; u32 status[4]; @@ -418,7 +418,6 @@ int __devinit snd_ca0106_proc_init(ca0106_t * emu) snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read32); entry->c.text.write_size = 64; entry->c.text.write = snd_ca0106_proc_reg_write32; - entry->mode |= S_IWUSR; } if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry)) snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read16); @@ -428,7 +427,6 @@ int __devinit snd_ca0106_proc_init(ca0106_t * emu) snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read1); entry->c.text.write_size = 64; entry->c.text.write = snd_ca0106_proc_reg_write; - entry->mode |= S_IWUSR; // entry->private_data = emu; } if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) diff --git a/trunk/sound/pci/cmipci.c b/trunk/sound/pci/cmipci.c index b4503385ea69..113208fbde1b 100644 --- a/trunk/sound/pci/cmipci.c +++ b/trunk/sound/pci/cmipci.c @@ -519,50 +519,40 @@ inline static unsigned char snd_cmipci_read_b(cmipci_t *cm, unsigned int cmd) } /* bit operations for dword register */ -static int snd_cmipci_set_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag) +static void snd_cmipci_set_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag) { - unsigned int val, oval; - val = oval = inl(cm->iobase + cmd); + unsigned int val; + val = inl(cm->iobase + cmd); val |= flag; - if (val == oval) - return 0; outl(val, cm->iobase + cmd); - return 1; } -static int snd_cmipci_clear_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag) +static void snd_cmipci_clear_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag) { - unsigned int val, oval; - val = oval = inl(cm->iobase + cmd); + unsigned int val; + val = inl(cm->iobase + cmd); val &= ~flag; - if (val == oval) - return 0; outl(val, cm->iobase + cmd); - return 1; } +#if 0 // not used /* bit operations for byte register */ -static int snd_cmipci_set_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag) +static void snd_cmipci_set_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag) { - unsigned char val, oval; - val = oval = inb(cm->iobase + cmd); + unsigned char val; + val = inb(cm->iobase + cmd); val |= flag; - if (val == oval) - return 0; outb(val, cm->iobase + cmd); - return 1; } -static int snd_cmipci_clear_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag) +static void snd_cmipci_clear_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag) { - unsigned char val, oval; - val = oval = inb(cm->iobase + cmd); + unsigned char val; + val = inb(cm->iobase + cmd); val &= ~flag; - if (val == oval) - return 0; outb(val, cm->iobase + cmd); - return 1; } +#endif /* @@ -2260,8 +2250,8 @@ DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, 0, 0, 0); /* rever DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0); #endif DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0); -// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0); -// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0); +DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0); +DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0); // DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */ DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0); @@ -2310,114 +2300,10 @@ static int snd_cmipci_spdout_enable_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_v } -static int snd_cmipci_line_in_mode_info(snd_kcontrol_t *kcontrol, - snd_ctl_elem_info_t *uinfo) -{ - cmipci_t *cm = snd_kcontrol_chip(kcontrol); - static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static inline unsigned int get_line_in_mode(cmipci_t *cm) -{ - unsigned int val; - if (cm->chip_version >= 39) { - val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL); - if (val & CM_LINE_AS_BASS) - return 2; - } - val = snd_cmipci_read_b(cm, CM_REG_MIXER1); - if (val & CM_SPK4) - return 1; - return 0; -} - -static int snd_cmipci_line_in_mode_get(snd_kcontrol_t *kcontrol, - snd_ctl_elem_value_t *ucontrol) -{ - cmipci_t *cm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&cm->reg_lock); - ucontrol->value.enumerated.item[0] = get_line_in_mode(cm); - spin_unlock_irq(&cm->reg_lock); - return 0; -} - -static int snd_cmipci_line_in_mode_put(snd_kcontrol_t *kcontrol, - snd_ctl_elem_value_t *ucontrol) -{ - cmipci_t *cm = snd_kcontrol_chip(kcontrol); - int change; - - spin_lock_irq(&cm->reg_lock); - if (ucontrol->value.enumerated.item[0] == 2) - change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS); - else - change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS); - if (ucontrol->value.enumerated.item[0] == 1) - change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_SPK4); - else - change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_SPK4); - spin_unlock_irq(&cm->reg_lock); - return change; -} - -static int snd_cmipci_mic_in_mode_info(snd_kcontrol_t *kcontrol, - snd_ctl_elem_info_t *uinfo) -{ - static char *texts[2] = { "Mic-In", "Center/LFE Output" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_cmipci_mic_in_mode_get(snd_kcontrol_t *kcontrol, - snd_ctl_elem_value_t *ucontrol) -{ - cmipci_t *cm = snd_kcontrol_chip(kcontrol); - /* same bit as spdi_phase */ - spin_lock_irq(&cm->reg_lock); - ucontrol->value.enumerated.item[0] = - (snd_cmipci_read_b(cm, CM_REG_MISC) & CM_SPDIF_INVERSE) ? 1 : 0; - spin_unlock_irq(&cm->reg_lock); - return 0; -} - -static int snd_cmipci_mic_in_mode_put(snd_kcontrol_t *kcontrol, - snd_ctl_elem_value_t *ucontrol) -{ - cmipci_t *cm = snd_kcontrol_chip(kcontrol); - int change; - - spin_lock_irq(&cm->reg_lock); - if (ucontrol->value.enumerated.item[0]) - change = snd_cmipci_set_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE); - else - change = snd_cmipci_clear_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE); - spin_unlock_irq(&cm->reg_lock); - return change; -} - /* both for CM8338/8738 */ static snd_kcontrol_new_t snd_cmipci_mixer_switches[] __devinitdata = { DEFINE_MIXER_SWITCH("Four Channel Mode", fourch), - { - .name = "Line-In Mode", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_cmipci_line_in_mode_info, - .get = snd_cmipci_line_in_mode_get, - .put = snd_cmipci_line_in_mode_put, - }, + DEFINE_MIXER_SWITCH("Line-In As Rear", line_rear), }; /* for non-multichannel chips */ @@ -2455,15 +2341,10 @@ static snd_kcontrol_new_t snd_cmipci_old_mixer_switches[] __devinitdata = { /* only for model 039 or later */ static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = { + DEFINE_MIXER_SWITCH("Line-In As Bass", line_bass), DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2), DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2), - { - .name = "Mic-In Mode", - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .info = snd_cmipci_mic_in_mode_info, - .get = snd_cmipci_mic_in_mode_get, - .put = snd_cmipci_mic_in_mode_put, - } + DEFINE_MIXER_SWITCH("Mic As Center/LFE", spdi_phase), /* same bit as spdi_phase */ }; /* card control switches */ @@ -3063,7 +2944,7 @@ static struct pci_driver driver = { static int __init alsa_card_cmipci_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_cmipci_exit(void) diff --git a/trunk/sound/pci/cs4281.c b/trunk/sound/pci/cs4281.c index b6e1854e9389..d7e06b3caf97 100644 --- a/trunk/sound/pci/cs4281.c +++ b/trunk/sound/pci/cs4281.c @@ -206,10 +206,7 @@ MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled)."); #define BA0_PMCS 0x0344 /* Power Management Control/Status */ #define BA0_CWPR 0x03e0 /* Configuration Write Protect */ - #define BA0_EPPMC 0x03e4 /* Extended PCI Power Management Control */ -#define BA0_EPPMC_FPDN (1<<14) /* Full Power DowN */ - #define BA0_GPIOR 0x03e8 /* GPIO Pin Interface Register */ #define BA0_SPMC 0x03ec /* Serial Port Power Management Control (& ASDIN2 enable) */ @@ -1464,11 +1461,6 @@ static int snd_cs4281_chip_init(cs4281_t *chip) int timeout; int retry_count = 2; - /* Having EPPMC.FPDN=1 prevent proper chip initialisation */ - tmp = snd_cs4281_peekBA0(chip, BA0_EPPMC); - if (tmp & BA0_EPPMC_FPDN) - snd_cs4281_pokeBA0(chip, BA0_EPPMC, tmp & ~BA0_EPPMC_FPDN); - __retry: tmp = snd_cs4281_peekBA0(chip, BA0_CFLR); if (tmp != BA0_CFLR_DEFAULT) { @@ -2132,7 +2124,7 @@ static struct pci_driver driver = { static int __init alsa_card_cs4281_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_cs4281_exit(void) diff --git a/trunk/sound/pci/cs46xx/cs46xx.c b/trunk/sound/pci/cs46xx/cs46xx.c index db212ecd792a..25d6466a867c 100644 --- a/trunk/sound/pci/cs46xx/cs46xx.c +++ b/trunk/sound/pci/cs46xx/cs46xx.c @@ -171,7 +171,7 @@ static struct pci_driver driver = { static int __init alsa_card_cs46xx_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_cs46xx_exit(void) diff --git a/trunk/sound/pci/emu10k1/emu10k1.c b/trunk/sound/pci/emu10k1/emu10k1.c index 2085a998eaeb..6446afe19d80 100644 --- a/trunk/sound/pci/emu10k1/emu10k1.c +++ b/trunk/sound/pci/emu10k1/emu10k1.c @@ -228,7 +228,7 @@ static struct pci_driver driver = { static int __init alsa_card_emu10k1_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_emu10k1_exit(void) diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 77be07283bb0..c3c96f9f2c7f 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -170,7 +170,7 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); - if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ + if (emu->audigy && emu->revision == 4) { /* audigy2 */ /* Hacks for Alice3 to work independent of haP16V driver */ u32 tmp; @@ -189,7 +189,7 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) /* Enabled Phased (8-channel) P16V playback */ outl(0x0201, emu->port + HCFG2); /* Set playback routing. */ - snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4); + snd_emu10k1_ptr_write(emu, CAPTURE_P16V_SOURCE, 0, 78e4); } if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */ /* Hacks for Alice3 to work independent of haP16V driver */ @@ -600,7 +600,7 @@ static int snd_emu10k1_free(emu10k1_t *emu) if (emu->port) pci_release_regions(emu->pci); pci_disable_device(emu->pci); - if (emu->card_capabilities->ca0151_chip) /* P16V */ + if (emu->audigy && emu->revision == 4) /* P16V */ snd_p16v_free(emu); kfree(emu); return 0; @@ -612,24 +612,21 @@ static int snd_emu10k1_dev_free(snd_device_t *device) return snd_emu10k1_free(emu); } +/* vendor, device, subsystem, emu10k1_chip, emu10k2_chip, ca0102_chip, ca0108_chip, ca0151_chip, spk71, spdif_bug, ac97_chip, ecard, driver, name */ + static emu_chip_details_t emu_chip_details[] = { /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0108_chip = 1, - .spk71 = 1, - .ac97_chip = 1} , + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", - .id = "Audigy2", .emu10k2_chip = 1, - .ca0108_chip = 1, - .ac97_chip = 1} , + .ca0108_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, .ca0151_chip = 1, @@ -638,7 +635,6 @@ static emu_chip_details_t emu_chip_details[] = { .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, .ca0151_chip = 1, @@ -647,7 +643,6 @@ static emu_chip_details_t emu_chip_details[] = { .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, .ca0151_chip = 1, @@ -656,7 +651,6 @@ static emu_chip_details_t emu_chip_details[] = { .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, .driver = "Audigy2", .name = "Audigy 2 [SB0240]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, .ca0151_chip = 1, @@ -665,87 +659,35 @@ static emu_chip_details_t emu_chip_details[] = { .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, .driver = "Audigy2", .name = "Audigy 2 EX [1005]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, .ca0151_chip = 1, .spdif_bug = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", - .id = "Audigy2", .emu10k2_chip = 1, .ca0102_chip = 1, .ca0151_chip = 1, .spk71 = 1, .spdif_bug = 1, .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, - .driver = "Audigy2", .name = "Audigy 2 [Unknown]", - .id = "Audigy2", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .ca0151_chip = 1, - .spdif_bug = 1, - .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10020052, - .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", - .id = "Audigy", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .spdif_bug = 1, - .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, - .driver = "Audigy", .name = "Audigy 1 [SB0090]", - .id = "Audigy", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, - .driver = "Audigy", .name = "Audigy 1 [SB0090]", - .id = "Audigy", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, - .driver = "Audigy", .name = "Audigy 1 [Unknown]", - .id = "Audigy", + .driver = "Audigy", .name = "Audigy 1 or 2 [Unknown]", .emu10k2_chip = 1, .ca0102_chip = 1, - .ac97_chip = 1} , + .spdif_bug = 1} , {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, .driver = "EMU10K1", .name = "E-mu APS [4001]", - .id = "APS", .emu10k1_chip = 1, .ecard = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, - .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", - .id = "Live", - .emu10k1_chip = 1, - .ac97_chip = 1, - .sblive51 = 1} , {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, .driver = "EMU10K1", .name = "SB Live 5.1", - .id = "Live", - .emu10k1_chip = 1, - .ac97_chip = 1, - .sblive51 = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, - .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", - .id = "Live", .emu10k1_chip = 1, .ac97_chip = 1} , - {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, - .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", - .id = "Live", - .emu10k1_chip = 1, - .ac97_chip = 1, - .sblive51 = 1} , {.vendor = 0x1102, .device = 0x0002, .driver = "EMU10K1", .name = "SB Live [Unknown]", - .id = "Live", .emu10k1_chip = 1, - .ac97_chip = 1, - .sblive51 = 1} , + .ac97_chip = 1} , { } /* terminator */ }; @@ -796,15 +738,13 @@ int __devinit snd_emu10k1_create(snd_card_t * card, emu->revision = revision; pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); + emu->card_type = EMU10K1_CARD_CREATIVE; snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model); for (c = emu_chip_details; c->vendor; c++) { if (c->vendor == pci->vendor && c->device == pci->device) { - if (c->subsystem && c->subsystem != emu->serial) - continue; - if (c->revision && c->revision != emu->revision) - continue; - break; + if (c->subsystem == emu->serial) break; + if (c->subsystem == 0) break; } } if (c->vendor == 0) { @@ -819,23 +759,6 @@ int __devinit snd_emu10k1_create(snd_card_t * card, else snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial); - if (!*card->id && c->id) { - int i, n = 0; - strlcpy(card->id, c->id, sizeof(card->id)); - for (;;) { - for (i = 0; i < snd_ecards_limit; i++) { - if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id)) - break; - } - if (i >= snd_ecards_limit) - break; - n++; - if (n >= SNDRV_CARDS) - break; - snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n); - } - } - is_audigy = emu->audigy = c->emu10k2_chip; /* set the DMA transfer mask */ @@ -893,6 +816,15 @@ int __devinit snd_emu10k1_create(snd_card_t * card, pci_set_master(pci); + if (c->ecard) { + emu->card_type = EMU10K1_CARD_EMUAPS; + emu->APS = 1; + } + if (! c->ac97_chip) + emu->no_ac97 = 1; + + emu->spk71 = c->spk71; + emu->fx8010.fxbus_mask = 0x303f; if (extin_mask == 0) extin_mask = 0x3fcf; @@ -901,7 +833,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card, emu->fx8010.extin_mask = extin_mask; emu->fx8010.extout_mask = extout_mask; - if (emu->card_capabilities->ecard) { + if (emu->APS) { if ((err = snd_emu10k1_ecard_init(emu)) < 0) { snd_emu10k1_free(emu); return err; diff --git a/trunk/sound/pci/emu10k1/emu10k1x.c b/trunk/sound/pci/emu10k1/emu10k1x.c index f8d92335a353..27dfd8ddddf4 100644 --- a/trunk/sound/pci/emu10k1/emu10k1x.c +++ b/trunk/sound/pci/emu10k1/emu10k1x.c @@ -1075,7 +1075,6 @@ static int __devinit snd_emu10k1x_proc_init(emu10k1x_t * emu) snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read); entry->c.text.write_size = 64; entry->c.text.write = snd_emu10k1x_proc_reg_write; - entry->mode |= S_IWUSR; entry->private_data = emu; } @@ -1628,7 +1627,7 @@ static int __init alsa_card_emu10k1x_init(void) { int err; - if ((err = pci_register_driver(&driver)) > 0) + if ((err = pci_module_init(&driver)) > 0) return err; return 0; diff --git a/trunk/sound/pci/emu10k1/emufx.c b/trunk/sound/pci/emu10k1/emufx.c index 0529fb281125..b9fa2e887fee 100644 --- a/trunk/sound/pci/emu10k1/emufx.c +++ b/trunk/sound/pci/emu10k1/emufx.c @@ -1077,7 +1077,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu) gpr += 2; /* PCM Side Playback (independent from stereo mix) */ - if (emu->card_capabilities->spk71) { + if (emu->spk71) { A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE)); A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE)); snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100); @@ -1145,14 +1145,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L); A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R); snd_emu10k1_init_stereo_control(&controls[nctl++], - emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume", + emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume", gpr, 0); gpr += 2; /* Audigy CD Capture Volume */ A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L); A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R); snd_emu10k1_init_stereo_control(&controls[nctl++], - emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume", + emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume", gpr, 0); gpr += 2; @@ -1171,14 +1171,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L); A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R); snd_emu10k1_init_stereo_control(&controls[nctl++], - emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume", + emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume", gpr, 0); gpr += 2; /* Line2 Capture Volume */ A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L); A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R); snd_emu10k1_init_stereo_control(&controls[nctl++], - emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume", + emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume", gpr, 0); gpr += 2; @@ -1197,14 +1197,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L); A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R); snd_emu10k1_init_stereo_control(&controls[nctl++], - emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume", + emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume", gpr, 0); gpr += 2; /* Aux2 Capture Volume */ A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L); A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R); snd_emu10k1_init_stereo_control(&controls[nctl++], - emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume", + emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume", gpr, 0); gpr += 2; @@ -1232,7 +1232,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0); gpr++; - if (emu->card_capabilities->spk71) { + if (emu->spk71) { /* Stereo Mix Side Playback */ A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix)); A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1)); @@ -1266,7 +1266,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */ A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */ A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */ - if (emu->card_capabilities->spk71) { + if (emu->spk71) { A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */ A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */ } @@ -1359,7 +1359,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS); A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS); - if (emu->card_capabilities->spk71) + if (emu->spk71) A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS); /* headphone */ @@ -1982,27 +1982,22 @@ static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu) OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000); /* EFX capture - capture the 16 EXTINS */ - if (emu->card_capabilities->sblive51) { - /* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER - * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording. - * - * Since only 14 of the 16 EXTINs are used, this is not a big problem. - * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture - * 0 and 3, then the rest of the EXTINs to the corresponding FX capture - * channel. Multitrack recorders will still see the center/lfe output signal - * on the second and third channels. - */ - OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0)); - OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1)); - OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2)); - OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3)); - for (z = 4; z < 14; z++) - OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); - } else { - for (z = 0; z < 16; z++) - OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); + OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0)); + OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1)); + OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2)); + OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3)); + /* Dont connect anything to FXBUS2 1 and 2. These are shared with + * Center/LFE on the SBLive 5.1. The kX driver only changes the + * routing when it detects an SBLive 5.1. + * + * Since only 14 of the 16 EXTINs are used, this is not a big problem. + * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture + * 0 and 3, then the rest of the EXTINs to the corresponding FX capture + * channel. + */ + for (z = 4; z < 14; z++) { + OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z)); } - if (gpr > tmp) { snd_BUG(); @@ -2133,6 +2128,7 @@ static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info) int res; memset(info, 0, sizeof(info)); + info->card = emu->card_type; info->internal_tram_size = emu->fx8010.itram_size; info->external_tram_size = emu->fx8010.etram_pages.bytes / 2; fxbus = fxbuses; diff --git a/trunk/sound/pci/emu10k1/emumixer.c b/trunk/sound/pci/emu10k1/emumixer.c index 6be82c5fe138..044663d31aa7 100644 --- a/trunk/sound/pci/emu10k1/emumixer.c +++ b/trunk/sound/pci/emu10k1/emumixer.c @@ -68,7 +68,6 @@ static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol, return 0; } -#if 0 static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { static char *texts[] = {"44100", "48000", "96000"}; @@ -153,7 +152,6 @@ static snd_kcontrol_new_t snd_audigy_spdif_output_rate = .get = snd_audigy_spdif_output_rate_get, .put = snd_audigy_spdif_output_rate_put }; -#endif static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) @@ -793,7 +791,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) NULL }; - if (emu->card_capabilities->ac97_chip) { + if (!emu->no_ac97) { ac97_bus_t *pbus; ac97_template_t ac97; static ac97_bus_ops_t ops = { @@ -835,7 +833,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) for (; *c; c++) remove_ctl(card, *c); } else { - if (emu->card_capabilities->ecard) + if (emu->APS) strcpy(emu->card->mixername, "EMU APS"); else if (emu->audigy) strcpy(emu->card->mixername, "SB Audigy"); @@ -920,7 +918,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) mix->attn[0] = 0xffff; } - if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */ + if (! emu->APS) { /* FIXME: APS has these controls? */ /* sb live! and audigy */ if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL) return -ENOMEM; @@ -937,20 +935,18 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; -#if 0 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; -#endif - } else if (! emu->card_capabilities->ecard) { + } else if (! emu->APS) { /* sb live! */ if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; } - if (emu->card_capabilities->ca0151_chip) { /* P16V */ + if (emu->audigy && emu->revision == 4) { /* P16V */ if ((err = snd_p16v_mixer(emu))) return err; } diff --git a/trunk/sound/pci/emu10k1/emupcm.c b/trunk/sound/pci/emu10k1/emupcm.c index fd7cc389f82a..d1c2a02c486b 100644 --- a/trunk/sound/pci/emu10k1/emupcm.c +++ b/trunk/sound/pci/emu10k1/emupcm.c @@ -262,7 +262,7 @@ static unsigned int emu10k1_select_interprom(unsigned int pitch_target) * * returns: cache invalidate size in samples */ -static inline int emu10k1_ccis(int stereo, int w_16) +static int inline emu10k1_ccis(int stereo, int w_16) { if (w_16) { return stereo ? 24 : 26; diff --git a/trunk/sound/pci/emu10k1/emuproc.c b/trunk/sound/pci/emu10k1/emuproc.c index cc22707c91fa..d990d5eb45a8 100644 --- a/trunk/sound/pci/emu10k1/emuproc.c +++ b/trunk/sound/pci/emu10k1/emuproc.c @@ -30,7 +30,6 @@ #include #include #include -#include "p16v.h" static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, snd_info_buffer_t * buffer, @@ -45,34 +44,28 @@ static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, unsigned int status, rate = 0; status = snd_emu10k1_ptr_read(emu, status_reg, 0); + if (rate_reg > 0) + rate = snd_emu10k1_ptr_read(emu, rate_reg, 0); snd_iprintf(buffer, "\n%s\n", title); - if (status != 0xffffffff) { - snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no"); - snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no"); - snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no"); - snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]); - snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6); - snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8); - snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy"); - snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16); - snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]); - snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]); - snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]); - - if (rate_reg > 0) { - rate = snd_emu10k1_ptr_read(emu, rate_reg, 0); - snd_iprintf(buffer, "S/PDIF Valid : %s\n", rate & SRCS_SPDIFVALID ? "on" : "off"); - snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off"); - snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off"); - /* From ((Rate * 48000 ) / 262144); */ - snd_iprintf(buffer, "Estimated Sample Rate : %d\n", ((rate & 0xFFFFF ) * 375) >> 11); - } - } else { - snd_iprintf(buffer, "No signal detected.\n"); + snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no"); + snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no"); + snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no"); + snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]); + snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6); + snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8); + snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy"); + snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16); + snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]); + snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]); + snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]); + + if (rate_reg > 0) { + snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off"); + snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off"); + snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", rate & SRCS_ESTSAMPLERATE); } - } static void snd_emu10k1_proc_read(snd_info_entry_t *entry, @@ -189,7 +182,7 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry, snd_iprintf(buffer, "EMU10K1\n\n"); snd_iprintf(buffer, "Card : %s\n", - emu->audigy ? "Audigy" : (emu->card_capabilities->ecard ? "EMU APS" : "Creative")); + emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative")); snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size); snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2); snd_iprintf(buffer, "\n"); @@ -230,35 +223,15 @@ static void snd_emu10k1_proc_read(snd_info_entry_t *entry, snd_iprintf(buffer, "\nAll FX Outputs :\n"); for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++) snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]); -} - -static void snd_emu10k1_proc_spdif_read(snd_info_entry_t *entry, - snd_info_buffer_t * buffer) -{ - emu10k1_t *emu = entry->private_data; - snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS); - snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS); -#if 0 + snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 0", SPCS0, -1); + snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 1", SPCS1, -1); + snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 2/3", SPCS2, -1); + snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF", CDCS, CDSRCS); + snd_emu10k1_proc_spdif_status(emu, buffer, "General purpose S/PDIF", GPSCS, GPSRCS); val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0); snd_iprintf(buffer, "\nZoomed Video\n"); snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off"); snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE); -#endif -} - -static void snd_emu10k1_proc_rates_read(snd_info_entry_t *entry, - snd_info_buffer_t * buffer) -{ - static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 }; - emu10k1_t *emu = entry->private_data; - unsigned int val, tmp, n; - val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); - tmp = (val >> 16) & 0x8; - for (n=0;n<4;n++) { - tmp = val >> (16 + (n*4)); - if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); - else snd_iprintf(buffer, "Channel %d: No input\n", n); - } } static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, @@ -527,46 +500,32 @@ int __devinit snd_emu10k1_proc_init(emu10k1_t * emu) snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read); entry->c.text.write_size = 64; entry->c.text.write = snd_emu_proc_io_reg_write; - entry->mode |= S_IWUSR; } if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a); entry->c.text.write_size = 64; entry->c.text.write = snd_emu_proc_ptr_reg_write00; - entry->mode |= S_IWUSR; } if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b); entry->c.text.write_size = 64; entry->c.text.write = snd_emu_proc_ptr_reg_write00; - entry->mode |= S_IWUSR; } if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a); entry->c.text.write_size = 64; entry->c.text.write = snd_emu_proc_ptr_reg_write20; - entry->mode |= S_IWUSR; } if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b); entry->c.text.write_size = 64; entry->c.text.write = snd_emu_proc_ptr_reg_write20; - entry->mode |= S_IWUSR; } #endif if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read); - if (emu->card_capabilities->emu10k2_chip) { - if (! snd_card_proc_new(emu->card, "spdif-in", &entry)) - snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read); - } - if (emu->card_capabilities->ca0151_chip) { - if (! snd_card_proc_new(emu->card, "capture-rates", &entry)) - snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_rates_read); - } - if (! snd_card_proc_new(emu->card, "voices", &entry)) snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read); diff --git a/trunk/sound/pci/emu10k1/irq.c b/trunk/sound/pci/emu10k1/irq.c index cd8460d56752..b81a7cafff39 100644 --- a/trunk/sound/pci/emu10k1/irq.c +++ b/trunk/sound/pci/emu10k1/irq.c @@ -37,7 +37,7 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) int handled = 0; while ((status = inl(emu->port + IPR)) != 0) { - //printk("emu10k1 irq - status = 0x%x\n", status); + // printk("irq - status = 0x%x\n", status); orig_status = status; handled = 1; if (status & IPR_PCIERROR) { @@ -147,36 +147,9 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE); status &= ~IPR_FXDSP; } - if (status & IPR_P16V) { - while ((status2 = inl(emu->port + IPR2)) != 0) { - u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ - emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]); - emu10k1_voice_t *cvoice = &(emu->p16v_capture_voice); - - //printk(KERN_INFO "status2=0x%x\n", status2); - orig_status2 = status2; - if(status2 & mask) { - if(pvoice->use) { - snd_pcm_period_elapsed(pvoice->epcm->substream); - } else { - snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use); - } - } - if(status2 & 0x110000) { - //printk(KERN_INFO "capture int found\n"); - if(cvoice->use) { - //printk(KERN_INFO "capture period_elapsed\n"); - snd_pcm_period_elapsed(cvoice->epcm->substream); - } - } - outl(orig_status2, emu->port + IPR2); /* ack all */ - } - status &= ~IPR_P16V; - } - if (status) { unsigned int bits; - snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status); + //snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status); //make sure any interrupts we don't handle are disabled: bits = INTE_FXDSPENABLE | INTE_PCIERRORENABLE | @@ -197,5 +170,20 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) } outl(orig_status, emu->port + IPR); /* ack all */ } + if (emu->audigy && emu->revision == 4) { /* P16V */ + while ((status2 = inl(emu->port + IPR2)) != 0) { + u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */ + emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]); + orig_status2 = status2; + if(status2 & mask) { + if(pvoice->use) { + snd_pcm_period_elapsed(pvoice->epcm->substream); + } else { + snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use); + } + } + outl(orig_status2, emu->port + IPR2); /* ack all */ + } + } return IRQ_RETVAL(handled); } diff --git a/trunk/sound/pci/emu10k1/p16v.c b/trunk/sound/pci/emu10k1/p16v.c index 98f980189892..d03cb2fefc9e 100644 --- a/trunk/sound/pci/emu10k1/p16v.c +++ b/trunk/sound/pci/emu10k1/p16v.c @@ -1,7 +1,7 @@ /* * Copyright (c) by James Courtier-Dutton * Driver p16v chips - * Version: 0.25 + * Version: 0.22 * * FEATURES currently supported: * Output fixed at S32_LE, 2 channel to hw:0,0 @@ -41,15 +41,7 @@ * Integrated with snd-emu10k1 driver. * 0.22 * Removed #if 0 ... #endif - * 0.23 - * Implement different capture rates. - * 0.24 - * Implement different capture source channels. - * e.g. When HD Capture source is set to SPDIF, - * setting HD Capture channel to 0 captures from CDROM digital input. - * setting HD Capture channel to 1 captures from SPDIF in. - * 0.25 - * Include capture buffer sizes. + * * * BUGS: * Some stability problems when unloading the snd-p16v kernel module. @@ -127,41 +119,22 @@ static snd_pcm_hardware_t snd_p16v_playback_hw = { SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */ - .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, - .rate_min = 44100, + .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 , + .rate_min = 48000, .rate_max = 192000, .channels_min = 8, .channels_max = 8, - .buffer_bytes_max = ((65536 - 64) * 8), + .buffer_bytes_max = (32*1024), .period_bytes_min = 64, - .period_bytes_max = (65536 - 64), + .period_bytes_max = (16*1024), .periods_min = 2, .periods_max = 8, .fifo_size = 0, }; -static snd_pcm_hardware_t snd_p16v_capture_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S32_LE, - .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, - .rate_min = 44100, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = (65536 - 64), - .period_bytes_min = 64, - .period_bytes_max = (65536 - 128) >> 1, /* size has to be N*64 bytes */ - .periods_min = 2, - .periods_max = 2, - .fifo_size = 0, -}; - static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime) { - emu10k1_pcm_t *epcm = runtime->private_data; + snd_pcm_t *epcm = runtime->private_data; if (epcm) { //snd_printk("epcm free: %p\n", epcm); @@ -205,63 +178,15 @@ static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, in return 0; } -/* open_capture callback */ -static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - emu10k1_voice_t *channel = &(emu->p16v_capture_voice); - emu10k1_pcm_t *epcm; - snd_pcm_runtime_t *runtime = substream->runtime; - int err; - - epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL); - //snd_printk("epcm kcalloc: %p\n", epcm); - - if (epcm == NULL) - return -ENOMEM; - epcm->emu = emu; - epcm->substream = substream; - //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id); - - runtime->private_data = epcm; - runtime->private_free = snd_p16v_pcm_free_substream; - - runtime->hw = snd_p16v_capture_hw; - - channel->emu = emu; - channel->number = channel_id; - - channel->use=1; - //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use); - //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); - //channel->interrupt = snd_p16v_pcm_channel_interrupt; - channel->epcm=epcm; - if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) - return err; - - return 0; -} - /* close callback */ static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream) { emu10k1_t *emu = snd_pcm_substream_chip(substream); //snd_pcm_runtime_t *runtime = substream->runtime; - //emu10k1_pcm_t *epcm = runtime->private_data; - emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; - /* FIXME: maybe zero others */ - return 0; -} - -/* close callback */ -static int snd_p16v_pcm_close_capture(snd_pcm_substream_t *substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - //snd_pcm_runtime_t *runtime = substream->runtime; - //emu10k1_pcm_t *epcm = runtime->private_data; - emu->p16v_capture_voice.use=0; - /* FIXME: maybe zero others */ + //emu10k1_pcm_t *epcm = runtime->private_data; + emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; +/* FIXME: maybe zero others */ return 0; } @@ -270,55 +195,36 @@ static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream) return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL); } -static int snd_p16v_pcm_open_capture(snd_pcm_substream_t *substream) -{ - // Only using channel 0 for now, but the card has 2 channels. - return snd_p16v_pcm_open_capture_channel(substream, 0); -} - /* hw_params callback */ static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream, snd_pcm_hw_params_t * hw_params) { int result; + //snd_printk("hw_params alloc: substream=%p\n", substream); result = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + //snd_printk("hw_params alloc: result=%d\n", result); + //dump_stack(); return result; } -/* hw_params callback */ -static int snd_p16v_pcm_hw_params_capture(snd_pcm_substream_t *substream, - snd_pcm_hw_params_t * hw_params) -{ - int result; - result = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - return result; -} - - /* hw_free callback */ static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream) { int result; + //snd_printk("hw_params free: substream=%p\n", substream); result = snd_pcm_lib_free_pages(substream); + //snd_printk("hw_params free: result=%d\n", result); + //dump_stack(); return result; } -/* hw_free callback */ -static int snd_p16v_pcm_hw_free_capture(snd_pcm_substream_t *substream) -{ - int result; - result = snd_pcm_lib_free_pages(substream); - return result; -} - - /* prepare playback callback */ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) { emu10k1_t *emu = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; + //emu10k1_pcm_t *epcm = runtime->private_data; int channel = substream->pcm->device - emu->p16v_device_offset; u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel)); u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); @@ -331,21 +237,23 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); switch (runtime->rate) { case 44100: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080); + snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */ + break; + case 48000: + snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */ break; case 96000: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040); + snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */ break; case 192000: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020); + snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */ break; - case 48000: default: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000); + snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */ break; } /* FIXME: Check emu->buffer.size before actually writing to it. */ - for(i=0; i < runtime->periods; i++) { + for(i=0; i < runtime->periods; i++) { table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); table_base[(i*2)+1]=period_size_bytes<<16; } @@ -354,8 +262,7 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19); snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0); snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr); - //snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes - snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes + snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0); snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0); snd_emu10k1_ptr20_write(emu, 0x08, channel, 0); @@ -363,41 +270,6 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) return 0; } -/* prepare capture callback */ -static int snd_p16v_pcm_prepare_capture(snd_pcm_substream_t *substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - int channel = substream->pcm->device - emu->p16v_device_offset; - u32 tmp; - //printk("prepare capture:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1)); - tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); - switch (runtime->rate) { - case 44100: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800); - break; - case 96000: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400); - break; - case 192000: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200); - break; - case 48000: - default: - snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000); - break; - } - /* FIXME: Check emu->buffer.size before actually writing to it. */ - snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); - snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); - snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes - snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); - //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ - //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<runtime; - emu10k1_pcm_t *epcm = runtime->private_data; - int channel = 0; - int result = 0; - u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - snd_p16v_intr_enable(emu, inte); - snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<running = 1; - break; - case SNDRV_PCM_TRIGGER_STOP: - snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<running = 0; - break; - default: - result = -EINVAL; - break; - } - return result; -} - /* pointer_playback callback */ static snd_pcm_uframes_t snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) @@ -528,31 +370,6 @@ snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) return ptr; } -/* pointer_capture callback */ -static snd_pcm_uframes_t -snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream) -{ - emu10k1_t *emu = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - emu10k1_pcm_t *epcm = runtime->private_data; - snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; - int channel = 0; - - if (!epcm->running) - return 0; - - ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel); - ptr2 = bytes_to_frames(runtime, ptr1); - ptr=ptr2; - if (ptr >= runtime->buffer_size) { - ptr -= runtime->buffer_size; - printk("buffer capture limited!\n"); - } - //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate); - - return ptr; -} - /* operators */ static snd_pcm_ops_t snd_p16v_playback_front_ops = { .open = snd_p16v_pcm_open_playback_front, @@ -565,18 +382,6 @@ static snd_pcm_ops_t snd_p16v_playback_front_ops = { .pointer = snd_p16v_pcm_pointer_playback, }; -static snd_pcm_ops_t snd_p16v_capture_ops = { - .open = snd_p16v_pcm_open_capture, - .close = snd_p16v_pcm_close_capture, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_p16v_pcm_hw_params_capture, - .hw_free = snd_p16v_pcm_hw_free_capture, - .prepare = snd_p16v_pcm_prepare_capture, - .trigger = snd_p16v_pcm_trigger_capture, - .pointer = snd_p16v_pcm_pointer_capture, -}; - - int snd_p16v_free(emu10k1_t *chip) { // release the data @@ -600,22 +405,20 @@ int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) snd_pcm_t *pcm; snd_pcm_substream_t *substream; int err; - int capture=1; + int capture=0; //snd_printk("snd_p16v_pcm called. device=%d\n", device); emu->p16v_device_offset = device; if (rpcm) *rpcm = NULL; - + //if (device == 0) capture=1; if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) return err; pcm->private_data = emu; pcm->private_free = snd_p16v_pcm_free; - // Single playback 8 channel device. - // Single capture 2 channel device. + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops); pcm->info_flags = 0; pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; @@ -628,7 +431,7 @@ int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), - ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) + 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */ return err; //snd_printk("preallocate playback substream: err=%d\n", err); } @@ -639,7 +442,7 @@ int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), - 65536 - 64, 65536 - 64)) < 0) + 64*1024, 64*1024)) < 0) return err; //snd_printk("preallocate capture substream: err=%d\n", err); } @@ -891,106 +694,6 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear = .put = snd_p16v_volume_put_spdif_rear }; -static int snd_p16v_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) -{ - static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item > 7) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_p16v_capture_source_get(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - emu10k1_t *emu = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = emu->p16v_capture_source; - return 0; -} - -static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - emu10k1_t *emu = snd_kcontrol_chip(kcontrol); - unsigned int val; - int change = 0; - u32 mask; - u32 source; - - val = ucontrol->value.enumerated.item[0] ; - change = (emu->p16v_capture_source != val); - if (change) { - emu->p16v_capture_source = val; - source = (val << 28) | (val << 24) | (val << 20) | (val << 16); - mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff; - snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask); - } - return change; -} - -static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata = -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD Capture source", - .info = snd_p16v_capture_source_info, - .get = snd_p16v_capture_source_get, - .put = snd_p16v_capture_source_put -}; - -static int snd_p16v_capture_channel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) -{ - static char *texts[4] = { "0", "1", "2", "3", }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item > 3) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int snd_p16v_capture_channel_get(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - emu10k1_t *emu = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel; - return 0; -} - -static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol, - snd_ctl_elem_value_t * ucontrol) -{ - emu10k1_t *emu = snd_kcontrol_chip(kcontrol); - unsigned int val; - int change = 0; - u32 tmp; - - val = ucontrol->value.enumerated.item[0] ; - change = (emu->p16v_capture_channel != val); - if (change) { - emu->p16v_capture_channel = val; - tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc; - snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val); - } - return change; -} - -static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata = -{ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "HD Capture channel", - .info = snd_p16v_capture_channel_info, - .get = snd_p16v_capture_channel_get, - .put = snd_p16v_capture_channel_put -}; - int snd_p16v_mixer(emu10k1_t *emu) { int err; @@ -1028,14 +731,6 @@ int snd_p16v_mixer(emu10k1_t *emu) return -ENOMEM; if ((err = snd_ctl_add(card, kctl))) return err; - if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL) - return -ENOMEM; - if ((err = snd_ctl_add(card, kctl))) - return err; - if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL) - return -ENOMEM; - if ((err = snd_ctl_add(card, kctl))) - return err; return 0; } diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 4e63498a58b2..f910399db5c3 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -2401,7 +2401,7 @@ static struct pci_driver driver = { static int __init alsa_card_ens137x_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_ens137x_exit(void) diff --git a/trunk/sound/pci/es1938.c b/trunk/sound/pci/es1938.c index b492777bc30f..b4ca8adf393c 100644 --- a/trunk/sound/pci/es1938.c +++ b/trunk/sound/pci/es1938.c @@ -1761,7 +1761,7 @@ static struct pci_driver driver = { static int __init alsa_card_es1938_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_es1938_exit(void) diff --git a/trunk/sound/pci/es1968.c b/trunk/sound/pci/es1968.c index ea889b311390..faf63ff19c42 100644 --- a/trunk/sound/pci/es1968.c +++ b/trunk/sound/pci/es1968.c @@ -2559,7 +2559,6 @@ static struct ess_device_list pm_whitelist[] __devinitdata = { { TYPE_MAESTRO2E, 0x103c }, { TYPE_MAESTRO2E, 0x1179 }, { TYPE_MAESTRO2E, 0x14c0 }, /* HP omnibook 4150 */ - { TYPE_MAESTRO2E, 0x1558 }, }; static struct ess_device_list mpu_blacklist[] __devinitdata = { @@ -2796,7 +2795,7 @@ static struct pci_driver driver = { static int __init alsa_card_es1968_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_es1968_exit(void) diff --git a/trunk/sound/pci/fm801.c b/trunk/sound/pci/fm801.c index ff10e637a95e..08e7c5a296d5 100644 --- a/trunk/sound/pci/fm801.c +++ b/trunk/sound/pci/fm801.c @@ -195,7 +195,6 @@ struct _snd_fm801 { static struct pci_device_id snd_fm801_ids[] = { { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */ - { 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */ { 0, } }; @@ -1469,7 +1468,7 @@ static struct pci_driver driver = { static int __init alsa_card_fm801_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_fm801_exit(void) diff --git a/trunk/sound/pci/hda/Makefile b/trunk/sound/pci/hda/Makefile index bd8cb33c4fb4..570a59d33b41 100644 --- a/trunk/sound/pci/hda/Makefile +++ b/trunk/sound/pci/hda/Makefile @@ -1,5 +1,5 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o +snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o ifdef CONFIG_PROC_FS snd-hda-codec-objs += hda_proc.o endif diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index e6efaed4b464..9ed117ac0c09 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -49,10 +49,8 @@ struct hda_vendor_id { /* codec vendor labels */ static struct hda_vendor_id hda_vendor_ids[] = { { 0x10ec, "Realtek" }, - { 0x11d4, "Analog Devices" }, { 0x13f6, "C-Media" }, { 0x434d, "C-Media" }, - { 0x8384, "SigmaTel" }, {} /* terminator */ }; @@ -510,7 +508,7 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, /* FIXME: support for multiple AFGs? */ codec->afg = look_for_afg_node(codec); if (! codec->afg) { - snd_printdd("hda_codec: no AFG node found\n"); + snd_printk(KERN_ERR "hda_codec: no AFG node found\n"); snd_hda_codec_free(codec); return -ENODEV; } @@ -550,9 +548,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format) { - if (! nid) - return; - snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", nid, stream_tag, channel_id, format); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, @@ -663,7 +658,7 @@ static void put_vol_mute(struct hda_codec *codec, /* * read/write AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit. */ -static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) +int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) { struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); if (! info) @@ -672,7 +667,7 @@ static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch return info->vol[ch]; } -static int snd_hda_codec_amp_write(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int val) +int snd_hda_codec_amp_write(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int val) { struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); if (! info) @@ -1453,6 +1448,10 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream snd_assert(info->nid, return -EINVAL); info->ops.prepare = hda_pcm_default_prepare; } + if (info->ops.prepare == NULL) { + snd_assert(info->nid, return -EINVAL); + info->ops.prepare = hda_pcm_default_prepare; + } if (info->ops.cleanup == NULL) { snd_assert(info->nid, return -EINVAL); info->ops.cleanup = hda_pcm_default_cleanup; @@ -1531,7 +1530,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config struct hda_board_config *c; if (codec->bus->modelname) { - for (c = tbl; c->modelname || c->pci_subvendor; c++) { + for (c = tbl; c->modelname || c->pci_vendor; c++) { if (c->modelname && ! strcmp(codec->bus->modelname, c->modelname)) { snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname); @@ -1544,9 +1543,9 @@ int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config u16 subsystem_vendor, subsystem_device; pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device); - for (c = tbl; c->modelname || c->pci_subvendor; c++) { - if (c->pci_subvendor == subsystem_vendor && - c->pci_subdevice == subsystem_device) + for (c = tbl; c->modelname || c->pci_vendor; c++) { + if (c->pci_vendor == subsystem_vendor && + c->pci_device == subsystem_device) return c->config; } } diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 1b1203539ea6..c9e9dc9c7c98 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -176,15 +176,16 @@ enum { #define AC_PINCAP_OUT (1<<4) /* output capable */ #define AC_PINCAP_IN (1<<5) /* input capable */ #define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */ -#define AC_PINCAP_VREF (0x37<<8) +#define AC_PINCAP_VREF (7<<8) #define AC_PINCAP_VREF_SHIFT 8 #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ -/* Vref status (used in pin cap) */ -#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ -#define AC_PINCAP_VREF_50 (1<<1) /* 50% */ -#define AC_PINCAP_VREF_GRD (1<<2) /* ground */ -#define AC_PINCAP_VREF_80 (1<<4) /* 80% */ -#define AC_PINCAP_VREF_100 (1<<5) /* 100% */ +/* Vref status (used in pin cap and pin ctl) */ +#define AC_PIN_VREF_HIZ (1<<0) /* Hi-Z */ +#define AC_PIN_VREF_50 (1<<1) /* 50% */ +#define AC_PIN_VREF_GRD (1<<2) /* ground */ +#define AC_PIN_VREF_80 (1<<4) /* 80% */ +#define AC_PIN_VREF_100 (1<<5) /* 100% */ + /* Amplifier capabilities */ #define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */ @@ -247,11 +248,6 @@ enum { /* Pin widget control - 8bit */ #define AC_PINCTL_VREFEN (0x7<<0) -#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ -#define AC_PINCTL_VREF_50 1 /* 50% */ -#define AC_PINCTL_VREF_GRD 2 /* ground */ -#define AC_PINCTL_VREF_80 4 /* 80% */ -#define AC_PINCTL_VREF_100 5 /* 100% */ #define AC_PINCTL_IN_EN (1<<5) #define AC_PINCTL_OUT_EN (1<<6) #define AC_PINCTL_HP_EN (1<<7) @@ -259,9 +255,7 @@ enum { /* configuration default - 32bit */ #define AC_DEFCFG_SEQUENCE (0xf<<0) #define AC_DEFCFG_DEF_ASSOC (0xf<<4) -#define AC_DEFCFG_ASSOC_SHIFT 4 #define AC_DEFCFG_MISC (0xf<<8) -#define AC_DEFCFG_MISC_SHIFT 8 #define AC_DEFCFG_COLOR (0xf<<12) #define AC_DEFCFG_COLOR_SHIFT 12 #define AC_DEFCFG_CONN_TYPE (0xf<<16) @@ -419,7 +413,7 @@ struct hda_bus { /* codec linked list */ struct list_head codec_list; - struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ + struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS]; /* caddr -> codec */ struct semaphore cmd_mutex; diff --git a/trunk/sound/pci/hda/hda_generic.c b/trunk/sound/pci/hda/hda_generic.c index bfbeff2e0d0c..69f7b6c4cf83 100644 --- a/trunk/sound/pci/hda/hda_generic.c +++ b/trunk/sound/pci/hda/hda_generic.c @@ -44,7 +44,7 @@ struct hda_gnode { struct list_head list; }; -/* patch-specific record */ +/* pathc-specific record */ struct hda_gspec { struct hda_gnode *dac_node; /* DAC node */ struct hda_gnode *out_pin_node; /* Output pin (Line-Out) node */ @@ -426,7 +426,7 @@ static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl) return "Line"; case AC_JACK_CD: if (pinctl) - *pinctl |= AC_PINCTL_VREF_GRD; + *pinctl |= AC_PIN_VREF_GRD; return "CD"; case AC_JACK_AUX: if ((location & 0x0f) == AC_JACK_LOC_FRONT) diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index f05a6384b9c0..959953ca320a 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -51,7 +51,6 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; static char *model[SNDRV_CARDS]; -static int position_fix[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); @@ -61,17 +60,12 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); -module_param_array(position_fix, int, NULL, 0444); -MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)."); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ICH6M}," "{Intel, ICH7}," - "{Intel, ESB2}," - "{ATI, SB450}," - "{VIA, VT8251}," - "{VIA, VT8237A}}"); + "{Intel, ESB2}}"); MODULE_DESCRIPTION("Intel HDA driver"); #define SFX "hda-intel: " @@ -156,7 +150,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; /* STATESTS int mask: SD2,SD1,SD0 */ #define STATESTS_INT_MASK 0x07 -#define AZX_MAX_CODECS 4 +#define AZX_MAX_CODECS 3 /* SD_CTL bits */ #define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ @@ -189,18 +183,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define ICH6_MAX_CORB_ENTRIES 256 #define ICH6_MAX_RIRB_ENTRIES 256 -/* position fix mode */ -enum { - POS_FIX_FIFO, - POS_FIX_NONE, - POS_FIX_POSBUF -}; - -/* Defines for ATI HD Audio support in SB450 south bridge */ -#define ATI_SB450_HDAUDIO_PCI_DEVICE_ID 0x437b -#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR 0x42 -#define ATI_SB450_HDAUDIO_ENABLE_SNOOP 0x02 - /* * Use CORB/RIRB for communication from/to codecs. @@ -208,6 +190,12 @@ enum { */ #define USE_CORB_RIRB +/* + * Define this if use the position buffer instead of reading SD_LPIB + * It's not used as default since SD_LPIB seems to give more accurate position + */ +/* #define USE_POSBUF */ + /* */ @@ -283,9 +271,6 @@ struct snd_azx { struct snd_dma_buffer bdl; struct snd_dma_buffer rb; struct snd_dma_buffer posbuf; - - /* flags */ - int position_fix; }; /* @@ -653,7 +638,7 @@ static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev) */ static void azx_init_chip(azx_t *chip) { - unsigned char tcsel_reg, ati_misc_cntl2; + unsigned char tcsel_reg; /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS @@ -672,20 +657,11 @@ static void azx_init_chip(azx_t *chip) /* initialize the codec command I/O */ azx_init_cmd_io(chip); - if (chip->position_fix == POS_FIX_POSBUF) { - /* program the position buffer */ - azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); - azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); - } - - /* For ATI SB450 azalia HD audio, we need to enable snoop */ - if (chip->pci->vendor == PCI_VENDOR_ID_ATI && - chip->pci->device == ATI_SB450_HDAUDIO_PCI_DEVICE_ID) { - pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, - &ati_misc_cntl2); - pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, - (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP); - } +#ifdef USE_POSBUF + /* program the position buffer */ + azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); + azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr)); +#endif } @@ -815,12 +791,11 @@ static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev) /* upper BDL address */ azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr)); - if (chip->position_fix == POS_FIX_POSBUF) { - /* enable the position buffer */ - if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) - azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); - } - +#ifdef USE_POSBUF + /* enable the position buffer */ + if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) + azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); +#endif /* set the interrupt enable bits in the descriptor control register */ azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK); @@ -1061,20 +1036,16 @@ static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream) { - struct azx_pcm *apcm = snd_pcm_substream_chip(substream); - azx_t *chip = apcm->chip; azx_dev_t *azx_dev = get_azx_dev(substream); unsigned int pos; - if (chip->position_fix == POS_FIX_POSBUF) { - /* use the position buffer */ - pos = *azx_dev->posbuf; - } else { - /* read LPIB */ - pos = azx_sd_readl(azx_dev, SD_LPIB); - if (chip->position_fix == POS_FIX_FIFO) - pos += azx_dev->fifo_size; - } +#ifdef USE_POSBUF + /* use the position buffer */ + pos = *azx_dev->posbuf; +#else + /* read LPIB */ + pos = azx_sd_readl(azx_dev, SD_LPIB) + azx_dev->fifo_size; +#endif if (pos >= azx_dev->bufsize) pos = 0; return bytes_to_frames(substream->runtime, pos); @@ -1184,8 +1155,9 @@ static int __devinit azx_init_stream(azx_t *chip) azx_dev_t *azx_dev = &chip->azx_dev[i]; azx_dev->bdl = (u32 *)(chip->bdl.area + off); azx_dev->bdl_addr = chip->bdl.addr + off; - if (chip->position_fix == POS_FIX_POSBUF) - azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); +#ifdef USE_POSBUF + azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8); +#endif /* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */ azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ @@ -1265,8 +1237,10 @@ static int azx_free(azx_t *chip) snd_dma_free_pages(&chip->bdl); if (chip->rb.area) snd_dma_free_pages(&chip->rb); +#ifdef USE_POSBUF if (chip->posbuf.area) snd_dma_free_pages(&chip->posbuf); +#endif pci_release_regions(chip->pci); pci_disable_device(chip->pci); kfree(chip); @@ -1282,8 +1256,7 @@ static int azx_dev_free(snd_device_t *device) /* * constructor */ -static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, - int posfix, azx_t **rchip) +static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, azx_t **rchip) { azx_t *chip; int err = 0; @@ -1310,8 +1283,6 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, chip->pci = pci; chip->irq = -1; - chip->position_fix = posfix; - if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) { kfree(chip); pci_disable_device(pci); @@ -1343,14 +1314,14 @@ static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); goto errout; } - if (chip->position_fix == POS_FIX_POSBUF) { - /* allocate memory for the position buffer */ - if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), - MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) { - snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); - goto errout; - } +#ifdef USE_POSBUF + /* allocate memory for the position buffer */ + if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), + MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) { + snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); + goto errout; } +#endif /* allocate CORB/RIRB */ if ((err = azx_alloc_cmd_io(chip)) < 0) goto errout; @@ -1401,7 +1372,7 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id * return -ENOMEM; } - if ((err = azx_create(card, pci, position_fix[dev], &chip)) < 0) { + if ((err = azx_create(card, pci, &chip)) < 0) { snd_card_free(card); return err; } @@ -1453,8 +1424,6 @@ static struct pci_device_id azx_ids[] = { { 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */ { 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */ { 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */ - { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ATI SB450 */ - { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* VIA VT8251/VT8237A */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); @@ -1470,7 +1439,7 @@ static struct pci_driver driver = { static int __init alsa_card_azx_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_azx_exit(void) diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index b8fbbc4901d9..7c7b849875a0 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -126,8 +126,8 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } struct hda_board_config { const char *modelname; int config; - unsigned short pci_subvendor; - unsigned short pci_subdevice; + unsigned short pci_vendor; + unsigned short pci_device; }; int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl); diff --git a/trunk/sound/pci/hda/hda_patch.h b/trunk/sound/pci/hda/hda_patch.h index a5de684b6944..cf6abce42bc9 100644 --- a/trunk/sound/pci/hda/hda_patch.h +++ b/trunk/sound/pci/hda/hda_patch.h @@ -8,13 +8,10 @@ extern struct hda_codec_preset snd_hda_preset_realtek[]; extern struct hda_codec_preset snd_hda_preset_cmedia[]; /* Analog Devices codecs */ extern struct hda_codec_preset snd_hda_preset_analog[]; -/* SigmaTel codecs */ -extern struct hda_codec_preset snd_hda_preset_sigmatel[]; static const struct hda_codec_preset *hda_preset_tables[] = { snd_hda_preset_realtek, snd_hda_preset_cmedia, snd_hda_preset_analog, - snd_hda_preset_sigmatel, NULL }; diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index 15df7162f17e..4d5db7faad8d 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -157,7 +157,6 @@ static const char *get_jack_color(u32 cfg) static void print_pin_caps(snd_info_buffer_t *buffer, struct hda_codec *codec, hda_nid_t nid) { - static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" }; static char *jack_types[16] = { "Line Out", "Speaker", "HP Out", "CD", "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand", @@ -177,8 +176,7 @@ static void print_pin_caps(snd_info_buffer_t *buffer, snd_iprintf(buffer, " HP"); snd_iprintf(buffer, "\n"); caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); - snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, - jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT], + snd_iprintf(buffer, " Pin Default 0x%08x: %s at %s %s\n", caps, jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT], jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3], get_jack_location(caps)); @@ -268,19 +266,13 @@ static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer) if (wid_caps & AC_WCAP_CONN_LIST) { hda_nid_t conn[HDA_MAX_CONNECTIONS]; - int c, conn_len, curr = -1; + int c, conn_len; conn_len = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); - if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) - curr = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONNECT_SEL, 0); snd_iprintf(buffer, " Connection: %d\n", conn_len); snd_iprintf(buffer, " "); - for (c = 0; c < conn_len; c++) { + for (c = 0; c < conn_len; c++) snd_iprintf(buffer, " 0x%02x", conn[c]); - if (c == curr) - snd_iprintf(buffer, "*"); - } snd_iprintf(buffer, "\n"); } } diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index caa486993446..75d23849f71a 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -1,5 +1,5 @@ /* - * HD audio interface patch for AD1981HD, AD1983, AD1986A + * HD audio interface patch for AD1986A * * Copyright (c) 2005 Takashi Iwai * @@ -27,239 +27,13 @@ #include "hda_codec.h" #include "hda_local.h" -struct ad198x_spec { +struct ad1986a_spec { struct semaphore amp_mutex; /* PCM volume/mute control mutex */ struct hda_multi_out multiout; /* playback */ - hda_nid_t adc_nid; - const struct hda_input_mux *input_mux; unsigned int cur_mux; /* capture source */ - unsigned int spdif_route; - snd_kcontrol_new_t *mixers; - const struct hda_verb *init_verbs; struct hda_pcm pcm_rec[2]; /* PCM information */ }; -/* - * input MUX handling (common part) - */ -static int ad198x_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - - return snd_hda_input_mux_info(spec->input_mux, uinfo); -} - -static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - - ucontrol->value.enumerated.item[0] = spec->cur_mux; - return 0; -} - -static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - spec->adc_nid, &spec->cur_mux); -} - -/* - * initialization (common callbacks) - */ -static int ad198x_init(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - snd_hda_sequence_write(codec, spec->init_verbs); - return 0; -} - -static int ad198x_build_controls(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - int err; - - err = snd_hda_add_new_ctls(codec, spec->mixers); - if (err < 0) - return err; - if (spec->multiout.dig_out_nid) - err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); - if (err < 0) - return err; - return 0; -} - -/* - * Analog playback callbacks - */ -static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); -} - -static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - unsigned int stream_tag, - unsigned int format, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, - format, substream); -} - -static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); -} - -/* - * Digital out - */ -static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - return snd_hda_multi_out_dig_open(codec, &spec->multiout); -} - -static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - return snd_hda_multi_out_dig_close(codec, &spec->multiout); -} - -/* - * Analog capture - */ -static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - unsigned int stream_tag, - unsigned int format, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format); - return 0; -} - -static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct ad198x_spec *spec = codec->spec; - snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0); - return 0; -} - - -/* - */ -static struct hda_pcm_stream ad198x_pcm_analog_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 6, - .nid = 0, /* fill later */ - .ops = { - .open = ad198x_playback_pcm_open, - .prepare = ad198x_playback_pcm_prepare, - .cleanup = ad198x_playback_pcm_cleanup - }, -}; - -static struct hda_pcm_stream ad198x_pcm_analog_capture = { - .substreams = 2, - .channels_min = 2, - .channels_max = 2, - .nid = 0, /* fill later */ - .ops = { - .prepare = ad198x_capture_pcm_prepare, - .cleanup = ad198x_capture_pcm_cleanup - }, -}; - -static struct hda_pcm_stream ad198x_pcm_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = 0, /* fill later */ - .ops = { - .open = ad198x_dig_playback_pcm_open, - .close = ad198x_dig_playback_pcm_close - }, -}; - -static int ad198x_build_pcms(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - struct hda_pcm *info = spec->pcm_rec; - - codec->num_pcms = 1; - codec->pcm_info = info; - - info->name = "AD198x Analog"; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid; - - if (spec->multiout.dig_out_nid) { - info++; - codec->num_pcms++; - info->name = "AD198x Digital"; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; - } - - return 0; -} - -static void ad198x_free(struct hda_codec *codec) -{ - kfree(codec->spec); -} - -#ifdef CONFIG_PM -static int ad198x_resume(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - - ad198x_init(codec); - snd_hda_resume_ctls(codec, spec->mixers); - snd_hda_resume_spdif_out(codec); - return 0; -} -#endif - -static struct hda_codec_ops ad198x_patch_ops = { - .build_controls = ad198x_build_controls, - .build_pcms = ad198x_build_pcms, - .init = ad198x_init, - .free = ad198x_free, -#ifdef CONFIG_PM - .resume = ad198x_resume, -#endif -}; - - -/* - * AD1986A specific - */ - #define AD1986A_SPDIF_OUT 0x02 #define AD1986A_FRONT_DAC 0x03 #define AD1986A_SURR_DAC 0x04 @@ -294,7 +68,7 @@ static struct hda_input_mux ad1986a_capture_source = { static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; + struct ad1986a_spec *ad = codec->spec; down(&ad->amp_mutex); snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); @@ -305,7 +79,7 @@ static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; + struct ad1986a_spec *ad = codec->spec; int i, change = 0; down(&ad->amp_mutex); @@ -323,7 +97,7 @@ static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_ static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; + struct ad1986a_spec *ad = codec->spec; down(&ad->amp_mutex); snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); @@ -334,7 +108,7 @@ static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *ad = codec->spec; + struct ad1986a_spec *ad = codec->spec; int i, change = 0; down(&ad->amp_mutex); @@ -347,6 +121,32 @@ static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t return change; } +/* + * input MUX handling + */ +static int ad1986a_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +{ + return snd_hda_input_mux_info(&ad1986a_capture_source, uinfo); +} + +static int ad1986a_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct ad1986a_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->cur_mux; + return 0; +} + +static int ad1986a_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct ad1986a_spec *spec = codec->spec; + + return snd_hda_input_mux_put(codec, &ad1986a_capture_source, ucontrol, + AD1986A_ADC, &spec->cur_mux); +} + /* * mixers */ @@ -394,9 +194,9 @@ static snd_kcontrol_new_t ad1986a_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, + .info = ad1986a_mux_enum_info, + .get = ad1986a_mux_enum_get, + .put = ad1986a_mux_enum_put, }, HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT), { } /* end */ @@ -441,328 +241,183 @@ static struct hda_verb ad1986a_init_verbs[] = { {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* HP Pin */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - /* Front, Surround, CLFE Pins */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* Mono Pin */ - {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* Mic Pin */ - {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - /* Line, Aux, CD, Beep-In Pin */ - {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, { } /* end */ }; -static int patch_ad1986a(struct hda_codec *codec) +static int ad1986a_init(struct hda_codec *codec) { - struct ad198x_spec *spec; - - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - init_MUTEX(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 6; - spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); - spec->multiout.dac_nids = ad1986a_dac_nids; - spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; - spec->adc_nid = AD1986A_ADC; - spec->input_mux = &ad1986a_capture_source; - spec->mixers = ad1986a_mixers; - spec->init_verbs = ad1986a_init_verbs; + snd_hda_sequence_write(codec, ad1986a_init_verbs); + return 0; +} - codec->patch_ops = ad198x_patch_ops; +static int ad1986a_build_controls(struct hda_codec *codec) +{ + int err; + err = snd_hda_add_new_ctls(codec, ad1986a_mixers); + if (err < 0) + return err; + err = snd_hda_create_spdif_out_ctls(codec, AD1986A_SPDIF_OUT); + if (err < 0) + return err; return 0; } /* - * AD1983 specific + * Analog playback callbacks */ +static int ad1986a_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) +{ + struct ad1986a_spec *spec = codec->spec; + return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); +} -#define AD1983_SPDIF_OUT 0x02 -#define AD1983_DAC 0x03 -#define AD1983_ADC 0x04 - -static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; +static int ad1986a_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + snd_pcm_substream_t *substream) +{ + struct ad1986a_spec *spec = codec->spec; + return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} -static struct hda_input_mux ad1983_capture_source = { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Line", 0x1 }, - { "Mix", 0x2 }, - { "Mix Mono", 0x3 }, - }, -}; +static int ad1986a_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) +{ + struct ad1986a_spec *spec = codec->spec; + return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); +} /* - * SPDIF playback route + * Digital out */ -static int ad1983_spdif_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +static int ad1986a_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) { - static char *texts[] = { "PCM", "ADC" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item > 1) - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + struct ad1986a_spec *spec = codec->spec; + return snd_hda_multi_out_dig_open(codec, &spec->multiout); } -static int ad1983_spdif_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +static int ad1986a_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) { - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; + struct ad1986a_spec *spec = codec->spec; + return snd_hda_multi_out_dig_close(codec, &spec->multiout); +} - ucontrol->value.enumerated.item[0] = spec->spdif_route; +/* + * Analog capture + */ +static int ad1986a_capture_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + snd_pcm_substream_t *substream) +{ + snd_hda_codec_setup_stream(codec, AD1986A_ADC, stream_tag, 0, format); return 0; } -static int ad1983_spdif_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +static int ad1986a_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + snd_pcm_substream_t *substream) { - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct ad198x_spec *spec = codec->spec; - - if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { - spec->spdif_route = ucontrol->value.enumerated.item[0]; - snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0, - AC_VERB_SET_CONNECT_SEL, spec->spdif_route); - return 1; - } + snd_hda_codec_setup_stream(codec, AD1986A_ADC, 0, 0, 0); return 0; } -static snd_kcontrol_new_t ad1983_mixers[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, + +/* + */ +static struct hda_pcm_stream ad1986a_pcm_analog_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 6, + .nid = AD1986A_FRONT_DAC, /* NID to query formats and rates */ + .ops = { + .open = ad1986a_playback_pcm_open, + .prepare = ad1986a_playback_pcm_prepare, + .cleanup = ad1986a_playback_pcm_cleanup }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Playback Route", - .info = ad1983_spdif_route_info, - .get = ad1983_spdif_route_get, - .put = ad1983_spdif_route_put, +}; + +static struct hda_pcm_stream ad1986a_pcm_analog_capture = { + .substreams = 2, + .channels_min = 2, + .channels_max = 2, + .nid = AD1986A_ADC, /* NID to query formats and rates */ + .ops = { + .prepare = ad1986a_capture_pcm_prepare, + .cleanup = ad1986a_capture_pcm_cleanup }, - { } /* end */ }; -static struct hda_verb ad1983_init_verbs[] = { - /* Front, HP, Mono; mute as default */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* Beep, PCM, Mic, Line-In: mute */ - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* Front, HP selectors; from Mix */ - {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* Mono selector; from Mix */ - {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, - /* Mic selector; Mic */ - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* Line-in selector: Line-in */ - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* Mic boost: 0dB */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* Record selector: mic */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* SPDIF route: PCM */ - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* Front Pin */ - {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* HP Pin */ - {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - /* Mono Pin */ - {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* Mic Pin */ - {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - /* Line Pin */ - {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - { } /* end */ +static struct hda_pcm_stream ad1986a_pcm_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = AD1986A_SPDIF_OUT, + .ops = { + .open = ad1986a_dig_playback_pcm_open, + .close = ad1986a_dig_playback_pcm_close + }, }; -static int patch_ad1983(struct hda_codec *codec) +static int ad1986a_build_pcms(struct hda_codec *codec) { - struct ad198x_spec *spec; - - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; + struct ad1986a_spec *spec = codec->spec; + struct hda_pcm *info = spec->pcm_rec; - init_MUTEX(&spec->amp_mutex); - codec->spec = spec; + codec->num_pcms = 2; + codec->pcm_info = info; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); - spec->multiout.dac_nids = ad1983_dac_nids; - spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; - spec->adc_nid = AD1983_ADC; - spec->input_mux = &ad1983_capture_source; - spec->mixers = ad1983_mixers; - spec->init_verbs = ad1983_init_verbs; - spec->spdif_route = 0; + info->name = "AD1986A Analog"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_analog_playback; + info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1986a_pcm_analog_capture; + info++; - codec->patch_ops = ad198x_patch_ops; + info->name = "AD1986A Digital"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_digital_playback; return 0; } +static void ad1986a_free(struct hda_codec *codec) +{ + kfree(codec->spec); +} -/* - * AD1981 HD specific - */ - -#define AD1981_SPDIF_OUT 0x02 -#define AD1981_DAC 0x03 -#define AD1981_ADC 0x04 - -static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; - -/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ -static struct hda_input_mux ad1981_capture_source = { - .num_items = 7, - .items = { - { "Front Mic", 0x0 }, - { "Line", 0x1 }, - { "Mix", 0x2 }, - { "Mix Mono", 0x3 }, - { "CD", 0x4 }, - { "Mic", 0x6 }, - { "Aux", 0x7 }, - }, -}; - -static snd_kcontrol_new_t ad1981_mixers[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - /* identical with AD1983 */ - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Playback Route", - .info = ad1983_spdif_route_info, - .get = ad1983_spdif_route_get, - .put = ad1983_spdif_route_put, - }, - { } /* end */ -}; +#ifdef CONFIG_PM +static int ad1986a_resume(struct hda_codec *codec) +{ + ad1986a_init(codec); + snd_hda_resume_ctls(codec, ad1986a_mixers); + snd_hda_resume_spdif_out(codec); + return 0; +} +#endif -static struct hda_verb ad1981_init_verbs[] = { - /* Front, HP, Mono; mute as default */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */ - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* Front, HP selectors; from Mix */ - {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* Mono selector; from Mix */ - {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, - /* Mic Mixer; select Front Mic */ - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* Mic boost: 0dB */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* Record selector: Front mic */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* SPDIF route: PCM */ - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* Front Pin */ - {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* HP Pin */ - {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - /* Mono Pin */ - {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - /* Front & Rear Mic Pins */ - {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - /* Line Pin */ - {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* Digital Beep */ - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Line-Out as Input: disabled */ - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - { } /* end */ +static struct hda_codec_ops ad1986a_patch_ops = { + .build_controls = ad1986a_build_controls, + .build_pcms = ad1986a_build_pcms, + .init = ad1986a_init, + .free = ad1986a_free, +#ifdef CONFIG_PM + .resume = ad1986a_resume, +#endif }; -static int patch_ad1981(struct hda_codec *codec) +static int patch_ad1986a(struct hda_codec *codec) { - struct ad198x_spec *spec; + struct ad1986a_spec *spec; spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); if (spec == NULL) @@ -771,28 +426,20 @@ static int patch_ad1981(struct hda_codec *codec) init_MUTEX(&spec->amp_mutex); codec->spec = spec; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); - spec->multiout.dac_nids = ad1981_dac_nids; - spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; - spec->adc_nid = AD1981_ADC; - spec->input_mux = &ad1981_capture_source; - spec->mixers = ad1981_mixers; - spec->init_verbs = ad1981_init_verbs; - spec->spdif_route = 0; + spec->multiout.max_channels = 6; + spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); + spec->multiout.dac_nids = ad1986a_dac_nids; + spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; - codec->patch_ops = ad198x_patch_ops; + codec->patch_ops = ad1986a_patch_ops; return 0; } - /* * patch entries */ struct hda_codec_preset snd_hda_preset_analog[] = { - { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, - { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_cmedia.c b/trunk/sound/pci/hda/patch_cmedia.c index 087230ca20a5..b7cc8e4bffb7 100644 --- a/trunk/sound/pci/hda/patch_cmedia.c +++ b/trunk/sound/pci/hda/patch_cmedia.c @@ -29,7 +29,6 @@ #include #include "hda_codec.h" #include "hda_local.h" -#define NUM_PINS 11 /* board config type */ @@ -39,7 +38,6 @@ enum { CMI_FULL, /* back 6-jack + front-panel 2-jack */ CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */ CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */ - CMI_AUTO, /* let driver guess it */ }; struct cmi_spec { @@ -50,7 +48,6 @@ struct cmi_spec { /* playback */ struct hda_multi_out multiout; - hda_nid_t dac_nids[4]; /* NID for each DAC */ /* capture */ hda_nid_t *adc_nids; @@ -66,15 +63,6 @@ struct cmi_spec { const struct cmi_channel_mode *channel_modes; struct hda_pcm pcm_rec[2]; /* PCM information */ - - /* pin deafault configuration */ - hda_nid_t pin_nid[NUM_PINS]; - unsigned int def_conf[NUM_PINS]; - unsigned int pin_def_confs; - - /* multichannel pins */ - hda_nid_t multich_pin[4]; /* max 8-channel */ - struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */ }; /* @@ -290,10 +278,8 @@ static struct hda_verb cmi9880_basic_init[] = { { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* port-G for CLFE (rear panel) */ { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, /* port-H for side (rear panel) */ { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, /* port-C for line-in (rear panel) */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, /* port-B for mic-in (rear panel) with vref */ @@ -319,10 +305,6 @@ static struct hda_verb cmi9880_allout_init[] = { { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* port-G for CLFE (rear panel) */ { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 }, - /* port-H for side (rear panel) */ - { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 }, /* port-C for surround (rear panel) */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* port-B for mic-in (rear panel) with vref */ @@ -365,174 +347,6 @@ static int cmi9880_build_controls(struct hda_codec *codec) return 0; } -#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) -#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) -#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) - -/* get all pin default configuration in def_conf */ -static int cmi9880_get_pin_def_config(struct hda_codec *codec) -{ - struct cmi_spec *spec = codec->spec; - hda_nid_t nid, nid_start; - int i = 0, nodes; - - nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); - for (nid = nid_start; nid < nodes + nid_start; nid++) { - unsigned int wid_caps = snd_hda_param_read(codec, nid, - AC_PAR_AUDIO_WIDGET_CAP); - unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; - /* read all default configuration for pin complex */ - if (wid_type == AC_WID_PIN) { - spec->pin_nid[i] = nid; - spec->def_conf[i] = - snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONFIG_DEFAULT, 0); - i++; - } - } - spec->pin_def_confs = i; - return 0; -} - -/* get a pin default configuration of nid in def_conf */ -static unsigned int cmi9880_get_def_config(struct hda_codec *codec, hda_nid_t nid) -{ - struct cmi_spec *spec = codec->spec; - int i = 0; - - while (spec->pin_nid[i] != nid && i < spec->pin_def_confs) - i++; - if (i == spec->pin_def_confs) - return (unsigned int) -1; - else - return spec->def_conf[i]; -} - -/* decide what pins to use for multichannel playback */ -static int cmi9880_get_multich_pins(struct hda_codec *codec) -{ - struct cmi_spec *spec = codec->spec; - int i, j, pins, seq[4]; - int max_channel = 0; - unsigned int def_conf, sequence; - hda_nid_t nid; - - memset(spec->multich_pin, 0, sizeof(spec->multich_pin)); - for (pins = 0, i = 0; i < spec->pin_def_confs && pins < 4; i++) { - def_conf = spec->def_conf[i]; - /* skip pin not connected */ - if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) - continue; - /* get the sequence if association == 1 */ - /* the other pins have association = 0, incorrect in spec 1.0 */ - if (get_defcfg_association(def_conf) == 1) { - sequence = get_defcfg_sequence(def_conf); - seq[pins] = sequence; - spec->multich_pin[pins] = spec->pin_nid[i]; - pins++; // ready for next slot - max_channel += 2; - } - } - /* sort by sequence, data collected here will be for Windows */ - for (i = 0; i < pins; i++) { - for (j = i + 1; j < pins; j++) { - if (seq[j] < seq[i]) { - sequence = seq[j]; - nid = spec->multich_pin[j]; - seq[j] = seq[i]; - spec->multich_pin[j] = spec->multich_pin[i]; - seq[i] = sequence; - spec->multich_pin[i] = nid; - } - } - } - /* the pin assignment is for front, C/LFE, surround and back */ - if (max_channel >= 6) { - hda_nid_t temp; - /* exchange pin of C/LFE and surround */ - temp = spec->multich_pin[1]; - spec->multich_pin[1] = spec->multich_pin[2]; - spec->multich_pin[2] = temp; - } - return max_channel; -} - -/* fill in the multi_dac_nids table, which will decide - which audio widget to use for each channel */ -static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec) -{ - struct cmi_spec *spec = codec->spec; - hda_nid_t nid; - int assigned[4]; - int i, j; - - /* clear the table, only one c-media dac assumed here */ - memset(spec->dac_nids, 0, sizeof(spec->dac_nids)); - memset(assigned, 0, sizeof(assigned)); - /* check the pins we found */ - for (i = 0; i < spec->multiout.max_channels / 2; i++) { - nid = spec->multich_pin[i]; - /* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */ - if (nid <= 0x0e && nid >= 0x0b) { - spec->dac_nids[i] = nid - 0x08; - assigned[nid - 0x0b] = 1; - } - } - /* left pin can be connect to any audio widget */ - for (i = 0; i < spec->multiout.max_channels / 2; i++) { - if (!assigned[i]) { - /* search for an empty channel */ - /* I should also check the pin type */ - for (j = 0; j < ARRAY_SIZE(spec->dac_nids); j++) - if (! spec->dac_nids[j]) { - spec->dac_nids[j] = i + 3; - assigned[i] = 1; - break; - } - } - } - return 0; -} - -/* create multi_init table, which is used for multichannel initialization */ -static int cmi9880_fill_multi_init(struct hda_codec *codec) -{ - struct cmi_spec *spec = codec->spec; - hda_nid_t nid; - int i, j, k, len; - - /* clear the table, only one c-media dac assumed here */ - memset(spec->multi_init, 0, sizeof(spec->multi_init)); - for (j = 0, i = 0; i < spec->multiout.max_channels / 2; i++) { - hda_nid_t conn[4]; - nid = spec->multich_pin[i]; - /* set as output */ - spec->multi_init[j].nid = nid; - spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL; - spec->multi_init[j].param = 0xc0; - j++; - /* nid 0x0f,0x10,0x1f,0x20 are needed to set connection */ - switch (nid) { - case 0x0f: - case 0x10: - case 0x1f: - case 0x20: - /* set connection */ - spec->multi_init[j].nid = nid; - spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; - /* find the index in connect list */ - len = snd_hda_get_connections(codec, nid, conn, 4); - for (k = 0; k < len; k++) - if (conn[k] == spec->dac_nids[i]) - break; - spec->multi_init[j].param = k < len ? k : 0; - j++; - break; - } - } - return 0; -} - static int cmi9880_init(struct hda_codec *codec) { struct cmi_spec *spec = codec->spec; @@ -540,8 +354,6 @@ static int cmi9880_init(struct hda_codec *codec) snd_hda_sequence_write(codec, cmi9880_allout_init); else snd_hda_sequence_write(codec, cmi9880_basic_init); - if (spec->board_config == CMI_AUTO) - snd_hda_sequence_write(codec, spec->multi_init); return 0; } @@ -728,7 +540,6 @@ static struct hda_board_config cmi9880_cfg_tbl[] = { { .modelname = "full", .config = CMI_FULL }, { .modelname = "full_dig", .config = CMI_FULL_DIG }, { .modelname = "allout", .config = CMI_ALLOUT }, - { .modelname = "auto", .config = CMI_AUTO }, {} /* terminator */ }; @@ -753,13 +564,10 @@ static int patch_cmi9880(struct hda_codec *codec) codec->spec = spec; spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl); if (spec->board_config < 0) { - snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); - spec->board_config = CMI_AUTO; /* try everything */ + snd_printd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); + spec->board_config = CMI_FULL_DIG; /* try everything */ } - /* copy default DAC NIDs */ - memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids)); - switch (spec->board_config) { case CMI_MINIMAL: case CMI_MIN_FP: @@ -791,58 +599,10 @@ static int patch_cmi9880(struct hda_codec *codec) spec->input_mux = &cmi9880_no_line_mux; spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; break; - case CMI_AUTO: - { - unsigned int port_e, port_f, port_g, port_h; - unsigned int port_spdifi, port_spdifo; - int max_channels; - /* collect pin default configuration */ - cmi9880_get_pin_def_config(codec); - port_e = cmi9880_get_def_config(codec, 0x0f); - port_f = cmi9880_get_def_config(codec, 0x10); - port_g = cmi9880_get_def_config(codec, 0x1f); - port_h = cmi9880_get_def_config(codec, 0x20); - port_spdifi = cmi9880_get_def_config(codec, 0x13); - port_spdifo = cmi9880_get_def_config(codec, 0x12); - spec->front_panel = 1; - if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE || - get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) { - spec->surr_switch = 1; - /* no front panel */ - if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE || - get_defcfg_connect(port_h) == AC_JACK_PORT_NONE) { - /* no optional rear panel */ - spec->board_config = CMI_MINIMAL; - spec->front_panel = 0; - spec->num_ch_modes = 2; - } else { - spec->board_config = CMI_MIN_FP; - spec->num_ch_modes = 3; - } - spec->channel_modes = cmi9880_channel_modes; - spec->input_mux = &cmi9880_basic_mux; - spec->multiout.max_channels = cmi9880_channel_modes[0].channels; - } else { - spec->input_mux = &cmi9880_basic_mux; - if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE) - spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; - if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE) - spec->dig_in_nid = CMI_DIG_IN_NID; - spec->multiout.max_channels = 8; - } - max_channels = cmi9880_get_multich_pins(codec); - if (max_channels > 0) { - spec->multiout.max_channels = max_channels; - cmi9880_fill_multi_dac_nids(codec); - cmi9880_fill_multi_init(codec); - } else - snd_printd("patch_cmedia: cannot detect association in defcfg\n"); - break; - } } spec->multiout.num_dacs = 4; - spec->multiout.dac_nids = spec->dac_nids; + spec->multiout.dac_nids = cmi9880_dac_nids; spec->adc_nids = cmi9880_adc_nids; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index ee1c4cd7f00a..17c5062423ae 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -39,8 +39,6 @@ enum { ALC880_5ST, ALC880_5ST_DIG, ALC880_W810, - ALC880_Z71V, - ALC880_TEST, }; struct alc_spec { @@ -92,25 +90,10 @@ static hda_nid_t alc880_w810_dac_nids[3] = { 0x02, 0x03, 0x04 }; -static hda_nid_t alc880_z71v_dac_nids[1] = { - /* front only? */ - 0x02 -}; - -#if 0 -/* The datasheet says the node 0x07 is connected from inputs, - * but it shows zero connection in the real implementation. - */ static hda_nid_t alc880_adc_nids[3] = { /* ADC0-2 */ 0x07, 0x08, 0x09, }; -#else -static hda_nid_t alc880_adc_nids[2] = { - /* ADC1-2 */ - 0x08, 0x09, -}; -#endif #define ALC880_DIGOUT_NID 0x06 #define ALC880_DIGIN_NID 0x0a @@ -301,24 +284,19 @@ static struct alc_channel_mode alc880_w810_modes[1] = { { 6, NULL } }; -static struct alc_channel_mode alc880_z71v_modes[1] = { - { 2, NULL } -}; - /* */ static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; - int items = kcontrol->private_value ? (int)kcontrol->private_value : 2; snd_assert(spec->channel_mode, return -ENXIO); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; - uinfo->value.enumerated.items = items; - if (uinfo->value.enumerated.item >= items) - uinfo->value.enumerated.item = items - 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= 2) + uinfo->value.enumerated.item = 1; sprintf(uinfo->value.enumerated.name, "%dch", spec->channel_mode[uinfo->value.enumerated.item].channels); return 0; @@ -328,16 +306,10 @@ static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; - int items = kcontrol->private_value ? (int)kcontrol->private_value : 2; - int i; snd_assert(spec->channel_mode, return -ENXIO); - for (i = 0; i < items; i++) { - if (spec->multiout.max_channels == spec->channel_mode[i].channels) { - ucontrol->value.enumerated.item[0] = i; - break; - } - } + ucontrol->value.enumerated.item[0] = + (spec->multiout.max_channels == spec->channel_mode[0].channels) ? 0 : 1; return 0; } @@ -390,11 +362,10 @@ static snd_kcontrol_new_t alc880_base_mixer[] = { HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), - /* We don't use NID 0x07 - see above */ - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* The multiple "Capture Source" controls confuse alsamixer @@ -445,11 +416,10 @@ static snd_kcontrol_new_t alc880_five_stack_mixer[] = { HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), - /* We don't use NID 0x07 - see above */ - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* The multiple "Capture Source" controls confuse alsamixer @@ -505,37 +475,6 @@ static snd_kcontrol_new_t alc880_w810_base_mixer[] = { { } /* end */ }; -static snd_kcontrol_new_t alc880_z71v_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 3, - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc_mux_enum_put, - }, - { } /* end */ -}; - /* */ static int alc_build_controls(struct hda_codec *codec) @@ -578,16 +517,8 @@ static struct hda_verb alc880_init_verbs_three_stack[] = { {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, /* unmute amp left and right */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* set connection select to line in (default select for this ADC) */ + {0x07, AC_VERB_SET_CONNECT_SEL, 0x02}, /* unmute front mixer amp left (volume = 0) */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ @@ -661,16 +592,8 @@ static struct hda_verb alc880_init_verbs_five_stack[] = { {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, /* unmute amp left and right */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* set connection select to line in (default select for this ADC) */ + {0x07, AC_VERB_SET_CONNECT_SEL, 0x02}, /* unmute front mixer amp left and right (volume = 0) */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ @@ -796,65 +719,6 @@ static struct hda_verb alc880_w810_init_verbs[] = { { } }; -static struct hda_verb alc880_z71v_init_verbs[] = { - /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180}, - /* front channel selector/amp: output 0: unmuted, max volume */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* front out pin: muted, (no volume selection) */ - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* front out pin: NOT headphone enable, out enable, vref disabled */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - /* headphone channel selector/amp: input 0: DAC: unmuted, (no volume selection) */ - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* headphone channel selector/amp: input 1: capture mix: muted, (no volume selection) */ - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180}, - /* headphone channel selector/amp: output 0: unmuted, max volume */ - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* headphone out pin: muted, (no volume selection) */ - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* headpohne out pin: headphone enable, out enable, vref disabled */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - - /* Line In pin widget for input */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - /* CD pin widget for input */ - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - /* Mic1 (rear panel) pin widget for input and vref at 80% */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - /* Mic2 (front panel) pin widget for input and vref at 80% */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - /* unmute amp left and right */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* unmute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - /* set connection select to mic in */ - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer - * widget(nid=0x0B) to support the input path of analog loopback - */ - /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */ - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/ - /* unmute CD */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, - /* unmute Line In */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - /* unmute Mic 1 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - /* unmute Line In 2 (for PASD boards Mic 2) */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - - { } -}; - static int alc_init(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -978,9 +842,7 @@ static struct hda_pcm_stream alc880_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, - .nid = 0x08, /* NID to query formats and rates - * (0x07 might be broken on some devices) - */ + .nid = 0x07, /* NID to query formats and rates */ .ops = { .prepare = alc880_capture_pcm_prepare, .cleanup = alc880_capture_pcm_cleanup @@ -1059,336 +921,77 @@ static struct hda_codec_ops alc_patch_ops = { #endif }; - -/* - * Test configuration for debugging - * - * Almost all inputs/outputs are enabled. I/O pins can be configured via - * enum controls. - */ -#ifdef CONFIG_SND_DEBUG -static hda_nid_t alc880_test_dac_nids[4] = { - 0x02, 0x03, 0x04, 0x05 -}; - -static struct hda_input_mux alc880_test_capture_source = { - .num_items = 5, - .items = { - { "In-1", 0x0 }, - { "In-2", 0x1 }, - { "In-3", 0x2 }, - { "In-4", 0x3 }, - { "CD", 0x4 }, - }, -}; - -static struct alc_channel_mode alc880_test_modes[4] = { - { 2, NULL }, - { 4, NULL }, - { 6, NULL }, - { 8, NULL }, -}; - -static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - static char *texts[] = { - "N/A", "Line Out", "HP Out", - "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 8; - if (uinfo->value.enumerated.item >= 8) - uinfo->value.enumerated.item = 7; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = (hda_nid_t)kcontrol->private_value; - unsigned int pin_ctl, item = 0; - - pin_ctl = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_WIDGET_CONTROL, 0); - if (pin_ctl & AC_PINCTL_OUT_EN) { - if (pin_ctl & AC_PINCTL_HP_EN) - item = 2; - else - item = 1; - } else if (pin_ctl & AC_PINCTL_IN_EN) { - switch (pin_ctl & AC_PINCTL_VREFEN) { - case AC_PINCTL_VREF_HIZ: item = 3; break; - case AC_PINCTL_VREF_50: item = 4; break; - case AC_PINCTL_VREF_GRD: item = 5; break; - case AC_PINCTL_VREF_80: item = 6; break; - case AC_PINCTL_VREF_100: item = 7; break; - } - } - ucontrol->value.enumerated.item[0] = item; - return 0; -} - -static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = (hda_nid_t)kcontrol->private_value; - static unsigned int ctls[] = { - 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, - AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, - AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, - AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, - AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, - AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, - }; - unsigned int old_ctl, new_ctl; - - old_ctl = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_WIDGET_CONTROL, 0); - new_ctl = ctls[ucontrol->value.enumerated.item[0]]; - if (old_ctl != new_ctl) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000); - return 1; - } - return 0; -} - -static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - static char *texts[] = { - "Front", "Surround", "CLFE", "Side" - }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= 4) - uinfo->value.enumerated.item = 3; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; -} - -static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = (hda_nid_t)kcontrol->private_value; - unsigned int sel; - - sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); - ucontrol->value.enumerated.item[0] = sel & 3; - return 0; -} - -static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = (hda_nid_t)kcontrol->private_value; - unsigned int sel; - - sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; - if (ucontrol->value.enumerated.item[0] != sel) { - sel = ucontrol->value.enumerated.item[0] & 3; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel); - return 1; - } - return 0; -} - -#define PIN_CTL_TEST(xname,nid) { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .info = alc_test_pin_ctl_info, \ - .get = alc_test_pin_ctl_get, \ - .put = alc_test_pin_ctl_put, \ - .private_value = nid \ - } - -#define PIN_SRC_TEST(xname,nid) { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .info = alc_test_pin_src_info, \ - .get = alc_test_pin_src_get, \ - .put = alc_test_pin_src_put, \ - .private_value = nid \ - } - -static snd_kcontrol_new_t alc880_test_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - PIN_CTL_TEST("Front Pin Mode", 0x14), - PIN_CTL_TEST("Surround Pin Mode", 0x15), - PIN_CTL_TEST("CLFE Pin Mode", 0x16), - PIN_CTL_TEST("Side Pin Mode", 0x17), - PIN_CTL_TEST("In-1 Pin Mode", 0x18), - PIN_CTL_TEST("In-2 Pin Mode", 0x19), - PIN_CTL_TEST("In-3 Pin Mode", 0x1a), - PIN_CTL_TEST("In-4 Pin Mode", 0x1b), - PIN_SRC_TEST("In-1 Pin Source", 0x18), - PIN_SRC_TEST("In-2 Pin Source", 0x19), - PIN_SRC_TEST("In-3 Pin Source", 0x1a), - PIN_SRC_TEST("In-4 Pin Source", 0x1b), - HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 2, - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc_mux_enum_put, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = alc880_ch_mode_info, - .get = alc880_ch_mode_get, - .put = alc880_ch_mode_put, - .private_value = ARRAY_SIZE(alc880_test_modes), - }, - { } /* end */ -}; - -static struct hda_verb alc880_test_init_verbs[] = { - /* Unmute inputs of 0x0c - 0x0f */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100}, - /* Vol output for 0x0c-0x0f */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, - /* Set output pins 0x14-0x17 */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - /* Unmute output pins 0x14-0x17 */ - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* Set input pins 0x18-0x1c */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, /* vref 80% */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - /* Mute input pins 0x18-0x1b */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, - /* ADC set up */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, - { } -}; -#endif - /* */ static struct hda_board_config alc880_cfg_tbl[] = { /* Back 3 jack, front 2 jack */ { .modelname = "3stack", .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe200, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe201, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe202, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe203, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe204, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe205, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe206, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe207, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe208, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe209, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe20a, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe20b, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe20c, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe20d, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe20e, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe20f, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe210, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe211, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe214, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe302, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe303, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe304, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe306, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe307, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xe404, .config = ALC880_3ST }, + { .pci_vendor = 0x8086, .pci_device = 0xa101, .config = ALC880_3ST }, + { .pci_vendor = 0x107b, .pci_device = 0x3031, .config = ALC880_3ST }, + { .pci_vendor = 0x107b, .pci_device = 0x4036, .config = ALC880_3ST }, + { .pci_vendor = 0x107b, .pci_device = 0x4037, .config = ALC880_3ST }, + { .pci_vendor = 0x107b, .pci_device = 0x4038, .config = ALC880_3ST }, + { .pci_vendor = 0x107b, .pci_device = 0x4040, .config = ALC880_3ST }, + { .pci_vendor = 0x107b, .pci_device = 0x4041, .config = ALC880_3ST }, /* Back 3 jack, front 2 jack (Internal add Aux-In) */ - { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST }, + { .pci_vendor = 0x1025, .pci_device = 0xe310, .config = ALC880_3ST }, /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */ { .modelname = "3stack-digout", .config = ALC880_3ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xe308, .config = ALC880_3ST_DIG }, /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/ - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG }, - { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xe305, .config = ALC880_3ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xd402, .config = ALC880_3ST_DIG }, + { .pci_vendor = 0x1025, .pci_device = 0xe309, .config = ALC880_3ST_DIG }, /* Back 5 jack, front 2 jack */ { .modelname = "5stack", .config = ALC880_5ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST }, - { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST }, - { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST }, + { .pci_vendor = 0x107b, .pci_device = 0x3033, .config = ALC880_5ST }, + { .pci_vendor = 0x107b, .pci_device = 0x4039, .config = ALC880_5ST }, + { .pci_vendor = 0x107b, .pci_device = 0x3032, .config = ALC880_5ST }, + { .pci_vendor = 0x103c, .pci_device = 0x2a09, .config = ALC880_5ST }, /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */ { .modelname = "5stack-digout", .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, - { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xe224, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xe400, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xe401, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xe402, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xd400, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xd401, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x8086, .pci_device = 0xa100, .config = ALC880_5ST_DIG }, + { .pci_vendor = 0x1565, .pci_device = 0x8202, .config = ALC880_5ST_DIG }, { .modelname = "w810", .config = ALC880_W810 }, - { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, - - { .modelname = "z71v", .config = ALC880_Z71V }, - { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, - -#ifdef CONFIG_SND_DEBUG - { .modelname = "test", .config = ALC880_TEST }, -#endif + { .pci_vendor = 0x161f, .pci_device = 0x203d, .config = ALC880_W810 }, {} }; @@ -1420,16 +1023,6 @@ static int patch_alc880(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc880_five_stack_mixer; spec->num_mixers++; break; - case ALC880_Z71V: - spec->mixers[spec->num_mixers] = alc880_z71v_mixer; - spec->num_mixers++; - break; -#ifdef CONFIG_SND_DEBUG - case ALC880_TEST: - spec->mixers[spec->num_mixers] = alc880_test_mixer; - spec->num_mixers++; - break; -#endif default: spec->mixers[spec->num_mixers] = alc880_base_mixer; spec->num_mixers++; @@ -1440,8 +1033,6 @@ static int patch_alc880(struct hda_codec *codec) case ALC880_3ST_DIG: case ALC880_5ST_DIG: case ALC880_W810: - case ALC880_Z71V: - case ALC880_TEST: spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; break; default: @@ -1472,18 +1063,6 @@ static int patch_alc880(struct hda_codec *codec) spec->channel_mode = alc880_w810_modes; spec->num_channel_mode = ARRAY_SIZE(alc880_w810_modes); break; - case ALC880_Z71V: - spec->init_verbs = alc880_z71v_init_verbs; - spec->channel_mode = alc880_z71v_modes; - spec->num_channel_mode = ARRAY_SIZE(alc880_z71v_modes); - break; -#ifdef CONFIG_SND_DEBUG - case ALC880_TEST: - spec->init_verbs = alc880_test_init_verbs; - spec->channel_mode = alc880_test_modes; - spec->num_channel_mode = ARRAY_SIZE(alc880_test_modes); - break; -#endif default: spec->init_verbs = alc880_init_verbs_three_stack; spec->channel_mode = alc880_threestack_modes; @@ -1507,18 +1086,6 @@ static int patch_alc880(struct hda_codec *codec) spec->multiout.dac_nids = alc880_w810_dac_nids; // No dedicated headphone socket - it's shared with built-in speakers. break; - case ALC880_Z71V: - spec->multiout.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids); - spec->multiout.dac_nids = alc880_z71v_dac_nids; - spec->multiout.hp_nid = 0x03; - break; -#ifdef CONFIG_SND_DEBUG - case ALC880_TEST: - spec->multiout.num_dacs = ARRAY_SIZE(alc880_test_dac_nids); - spec->multiout.dac_nids = alc880_test_dac_nids; - spec->input_mux = &alc880_test_capture_source; - break; -#endif default: spec->multiout.num_dacs = ARRAY_SIZE(alc880_dac_nids); spec->multiout.dac_nids = alc880_dac_nids; @@ -1526,8 +1093,7 @@ static int patch_alc880(struct hda_codec *codec) break; } - if (! spec->input_mux) - spec->input_mux = &alc880_capture_source; + spec->input_mux = &alc880_capture_source; spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); spec->adc_nids = alc880_adc_nids; @@ -1868,13 +1434,11 @@ static struct hda_verb alc882_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, /* ADC1: unmute amp left and right */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, /* ADC2: unmute amp left and right */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* ADC3: unmute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, + /* Unmute front loopback */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /* Unmute rear loopback */ diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c deleted file mode 100644 index 1534e20af63d..000000000000 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Universal Interface for Intel High Definition Audio Codec - * - * HD audio interface patch for SigmaTel STAC92xx - * - * Copyright (c) 2005 Embedded Alley Solutions, Inc. - * - * - * Based on patch_cmedia.c and patch_realtek.c - * Copyright (c) 2004 Takashi Iwai - * - * This driver is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This driver is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include "hda_codec.h" -#include "hda_local.h" - -#undef STAC_TEST - -struct sigmatel_spec { - /* playback */ - struct hda_multi_out multiout; - hda_nid_t playback_nid; - - /* capture */ - hda_nid_t *adc_nids; - hda_nid_t *mux_nids; - unsigned int num_adcs; - hda_nid_t capture_nid; - - /* power management*/ - hda_nid_t *pstate_nids; - unsigned int num_pstates; - - /* pin widgets */ - hda_nid_t *pin_nids; - unsigned int num_pins; -#ifdef STAC_TEST - unsigned int *pin_configs; -#endif - - /* codec specific stuff */ - struct hda_verb *init; - snd_kcontrol_new_t *mixer; - - /* capture source */ - const struct hda_input_mux *input_mux; - unsigned int cur_mux[2]; - - /* channel mode */ - unsigned int num_ch_modes; - unsigned int cur_ch_mode; - const struct sigmatel_channel_mode *channel_modes; - - struct hda_pcm pcm_rec[1]; /* PCM information */ -}; - -static hda_nid_t stac9200_adc_nids[1] = { - 0x03, -}; - -static hda_nid_t stac9200_mux_nids[1] = { - 0x0c, -}; - -static hda_nid_t stac9200_dac_nids[1] = { - 0x02, -}; - -static hda_nid_t stac9200_pstate_nids[3] = { - 0x01, 0x02, 0x03, -}; - -static hda_nid_t stac9200_pin_nids[8] = { - 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, -}; - -static hda_nid_t stac922x_adc_nids[2] = { - 0x06, 0x07, -}; - -static hda_nid_t stac922x_mux_nids[2] = { - 0x12, 0x13, -}; - -static hda_nid_t stac922x_dac_nids[4] = { - 0x02, 0x03, 0x04, 0x05, -}; - -static hda_nid_t stac922x_pstate_nids[7] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, -}; - -static hda_nid_t stac922x_pin_nids[10] = { - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, - 0x0f, 0x10, 0x11, 0x15, 0x1b, -}; - -static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - return snd_hda_input_mux_info(spec->input_mux, uinfo); -} - -static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - - ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; - return 0; -} - -static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct sigmatel_spec *spec = codec->spec; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, - spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); -} - -static struct hda_verb stac9200_ch2_init[] = { - /* set dac0mux for dac converter */ - { 0x07, 0x701, 0x00}, - {} -}; - -static struct hda_verb stac922x_ch2_init[] = { - /* set master volume and direct control */ - { 0x16, 0x70f, 0xff}, - {} -}; - -struct sigmatel_channel_mode { - unsigned int channels; - const struct hda_verb *sequence; -}; - -static snd_kcontrol_new_t stac9200_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, - HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Input Mux Volume", 0x0c, 0, HDA_OUTPUT), - { } /* end */ -}; - -static snd_kcontrol_new_t stac922x_mixer[] = { - HDA_CODEC_VOLUME("PCM Playback Volume", 0x2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("PCM Playback Switch", 0x2, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Input Source", - .count = 1, - .info = stac92xx_mux_enum_info, - .get = stac92xx_mux_enum_get, - .put = stac92xx_mux_enum_put, - }, - HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT), - { } /* end */ -}; - -static struct hda_input_mux stac9200_input_mux = { - .num_items = 5, - .items = { - { "Port B", 0x0 }, - { "Port C", 0x1 }, - { "Port D", 0x2 }, - { "Port A", 0x3 }, - { "CD", 0x4 }, - } -}; - -static struct hda_input_mux stac922x_input_mux = { - .num_items = 7, - .items = { - { "Port E", 0x0 }, - { "CD", 0x1 }, - { "Port F", 0x2 }, - { "Port B", 0x3 }, - { "Port C", 0x4 }, - { "Port D", 0x5 }, - { "Port A", 0x6 }, - } -}; - -static int stac92xx_build_controls(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int err; - - err = snd_hda_add_new_ctls(codec, spec->mixer); - if (err < 0) - return err; - - return 0; -} - -#ifdef STAC_TEST -static unsigned int stac9200_pin_configs[8] = { - 0x40000100, 0x40000100, 0x0221401f, 0x01114010, - 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, -}; - -static unsigned int stac922x_pin_configs[14] = { - 0x40000100, 0x40000100, 0x40000100, 0x01114010, - 0x01813122, 0x40000100, 0x40000100, 0x40000100, - 0x40000100, 0x40000100, -}; - -static void stac92xx_set_config_regs(struct hda_codec *codec) -{ - int i; - struct sigmatel_spec *spec = codec->spec; - unsigned int pin_cfg; - - for (i=0; i < spec->num_pins; i++) { - snd_hda_codec_write(codec, spec->pin_nids[i], 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, - spec->pin_configs[i] & 0x000000ff); - snd_hda_codec_write(codec, spec->pin_nids[i], 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, - (spec->pin_configs[i] & 0x0000ff00) >> 8); - snd_hda_codec_write(codec, spec->pin_nids[i], 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, - (spec->pin_configs[i] & 0x00ff0000) >> 16); - snd_hda_codec_write(codec, spec->pin_nids[i], 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, - spec->pin_configs[i] >> 24); - pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, - AC_VERB_GET_CONFIG_DEFAULT, - 0x00); - printk("pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg); - } -} -#endif - -static int stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, unsigned int value) -{ - unsigned int pin_ctl; - - pin_ctl = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_WIDGET_CONTROL, - 0x00); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - pin_ctl | value); - - return 0; -} - -static int stac92xx_set_vref(struct hda_codec *codec, hda_nid_t nid) -{ - unsigned int vref_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) >> AC_PINCAP_VREF_SHIFT; - unsigned int vref_ctl = AC_PINCTL_VREF_HIZ; - - if (vref_caps & AC_PINCAP_VREF_100) - vref_ctl = AC_PINCTL_VREF_100; - else if (vref_caps & AC_PINCAP_VREF_80) - vref_ctl = AC_PINCTL_VREF_80; - else if (vref_caps & AC_PINCAP_VREF_50) - vref_ctl = AC_PINCTL_VREF_50; - else if (vref_caps & AC_PINCAP_VREF_GRD) - vref_ctl = AC_PINCTL_VREF_GRD; - - stac92xx_set_pinctl(codec, nid, vref_ctl); - - return 0; -} - -static int stac92xx_config_pin(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_cfg) -{ - switch((pin_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) { - case AC_JACK_HP_OUT: - /* Enable HP amp */ - stac92xx_set_pinctl(codec, nid, AC_PINCTL_HP_EN); - /* Fall through */ - case AC_JACK_LINE_OUT: - case AC_JACK_SPEAKER: - /* Enable output */ - stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); - break; - case AC_JACK_MIC_IN: - /* Set vref */ - stac92xx_set_vref(codec, nid); - case AC_JACK_CD: - case AC_JACK_LINE_IN: - case AC_JACK_AUX: - /* Enable input */ - stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); - break; - } - - return 0; -} - -static int stac92xx_config_pins(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int i; - unsigned int pin_cfg; - - for (i=0; i < spec->num_pins; i++) { - /* Default to disabled */ - snd_hda_codec_write(codec, spec->pin_nids[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - 0x00); - - pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, - AC_VERB_GET_CONFIG_DEFAULT, - 0x00); - if (((pin_cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) == AC_JACK_PORT_NONE) - continue; /* Move on */ - - stac92xx_config_pin(codec, spec->pin_nids[i], pin_cfg); - } - - return 0; -} - -static int stac92xx_init(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - int i; - - for (i=0; i < spec->num_pstates; i++) - snd_hda_codec_write(codec, spec->pstate_nids[i], 0, - AC_VERB_SET_POWER_STATE, 0x00); - - mdelay(100); - - snd_hda_sequence_write(codec, spec->init); - -#ifdef STAC_TEST - stac92xx_set_config_regs(codec); -#endif - - stac92xx_config_pins(codec); - - return 0; -} - -/* - * Analog playback callbacks - */ -static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct sigmatel_spec *spec = codec->spec; - return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); -} - -static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - unsigned int stream_tag, - unsigned int format, - snd_pcm_substream_t *substream) -{ - struct sigmatel_spec *spec = codec->spec; - return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, - format, substream); -} - -static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct sigmatel_spec *spec = codec->spec; - return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); -} - -/* - * Analog capture callbacks - */ -static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - unsigned int stream_tag, - unsigned int format, - snd_pcm_substream_t *substream) -{ - struct sigmatel_spec *spec = codec->spec; - - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], - stream_tag, 0, format); - return 0; -} - -static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - snd_pcm_substream_t *substream) -{ - struct sigmatel_spec *spec = codec->spec; - - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0); - return 0; -} - -static struct hda_pcm_stream stac92xx_pcm_analog_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - .nid = 0x02, /* NID to query formats and rates */ - .ops = { - .open = stac92xx_playback_pcm_open, - .prepare = stac92xx_playback_pcm_prepare, - .cleanup = stac92xx_playback_pcm_cleanup - }, -}; - -static struct hda_pcm_stream stac92xx_pcm_analog_capture = { - .substreams = 2, - .channels_min = 2, - .channels_max = 2, - .nid = 0x06, /* NID to query formats and rates */ - .ops = { - .prepare = stac92xx_capture_pcm_prepare, - .cleanup = stac92xx_capture_pcm_cleanup - }, -}; - -static int stac92xx_build_pcms(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - struct hda_pcm *info = spec->pcm_rec; - - codec->num_pcms = 1; - codec->pcm_info = info; - - info->name = "STAC92xx"; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->playback_nid; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->capture_nid; - - return 0; -} - -static void stac92xx_free(struct hda_codec *codec) -{ - kfree(codec->spec); -} - -static struct hda_codec_ops stac92xx_patch_ops = { - .build_controls = stac92xx_build_controls, - .build_pcms = stac92xx_build_pcms, - .init = stac92xx_init, - .free = stac92xx_free, -}; - -static int patch_stac9200(struct hda_codec *codec) -{ - struct sigmatel_spec *spec; - - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - spec->multiout.dac_nids = stac9200_dac_nids; - spec->adc_nids = stac9200_adc_nids; - spec->mux_nids = stac9200_mux_nids; - spec->input_mux = &stac9200_input_mux; - spec->pstate_nids = stac9200_pstate_nids; - spec->num_pstates = 3; - spec->pin_nids = stac9200_pin_nids; -#ifdef STAC_TEST - spec->pin_configs = stac9200_pin_configs; -#endif - spec->num_pins = 8; - spec->init = stac9200_ch2_init; - spec->mixer = stac9200_mixer; - spec->playback_nid = 0x02; - spec->capture_nid = 0x03; - - codec->patch_ops = stac92xx_patch_ops; - - return 0; -} - -static int patch_stac922x(struct hda_codec *codec) -{ - struct sigmatel_spec *spec; - - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 4; - spec->multiout.dac_nids = stac922x_dac_nids; - spec->adc_nids = stac922x_adc_nids; - spec->mux_nids = stac922x_mux_nids; - spec->input_mux = &stac922x_input_mux; - spec->pstate_nids = stac922x_pstate_nids; - spec->num_pstates = 7; - spec->pin_nids = stac922x_pin_nids; -#ifdef STAC_TEST - spec->pin_configs = stac922x_pin_configs; -#endif - spec->num_pins = 10; - spec->init = stac922x_ch2_init; - spec->mixer = stac922x_mixer; - spec->playback_nid = 0x02; - spec->capture_nid = 0x06; - - codec->patch_ops = stac92xx_patch_ops; - - return 0; -} - -/* - * patch entries - */ -struct hda_codec_preset snd_hda_preset_sigmatel[] = { - { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, - { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, - { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, - { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x }, - { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, - { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, - { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, - {} /* terminator */ -}; diff --git a/trunk/sound/pci/ice1712/amp.c b/trunk/sound/pci/ice1712/amp.c index 289b0b5711e4..779951725e1e 100644 --- a/trunk/sound/pci/ice1712/amp.c +++ b/trunk/sound/pci/ice1712/amp.c @@ -30,39 +30,16 @@ #include #include "ice1712.h" -#include "envy24ht.h" #include "amp.h" -static void wm_put(ice1712_t *ice, int reg, unsigned short val) -{ - unsigned short cval; - cval = (reg << 9) | val; - snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff); -} static int __devinit snd_vt1724_amp_init(ice1712_t *ice) { - static unsigned short wm_inits[] = { - WM_ATTEN_L, 0x0000, /* 0 db */ - WM_ATTEN_R, 0x0000, /* 0 db */ - WM_DAC_CTRL, 0x0008, /* 24bit I2S */ - WM_INT_CTRL, 0x0001, /* 24bit I2S */ - }; - - unsigned int i; - /* only use basic functionality for now */ ice->num_total_dacs = 2; /* only PSDOUT0 is connected */ ice->num_total_adcs = 2; - /* Chaintech AV-710 has another codecs, which need initialization */ - /* initialize WM8728 codec */ - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) { - for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) - wm_put(ice, wm_inits[i], wm_inits[i+1]); - } - return 0; } @@ -76,13 +53,6 @@ static int __devinit snd_vt1724_amp_add_controls(ice1712_t *ice) /* entry point */ struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { - { - .subvendor = VT1724_SUBDEVICE_AV710, - .name = "Chaintech AV-710", - .model = "av710", - .chip_init = snd_vt1724_amp_init, - .build_controls = snd_vt1724_amp_add_controls, - }, { .subvendor = VT1724_SUBDEVICE_AUDIO2000, .name = "AMP Ltd AUDIO2000", diff --git a/trunk/sound/pci/ice1712/amp.h b/trunk/sound/pci/ice1712/amp.h index a0fc89b48122..d58d43383e83 100644 --- a/trunk/sound/pci/ice1712/amp.h +++ b/trunk/sound/pci/ice1712/amp.h @@ -24,23 +24,9 @@ * */ -#define AMP_AUDIO2000_DEVICE_DESC "{AMP Ltd,AUDIO2000},"\ - "{Chaintech,AV-710}," +#define AMP_AUDIO2000_DEVICE_DESC "{AMP Ltd,AUDIO2000}," -#if 0 #define VT1724_SUBDEVICE_AUDIO2000 0x12142417 /* Advanced Micro Peripherals Ltd AUDIO2000 */ -#else -#define VT1724_SUBDEVICE_AUDIO2000 0x00030003 /* a dummy ID for AMP Audio2000 */ -#endif -#define VT1724_SUBDEVICE_AV710 0x12142417 /* AV710 - the same ID with Audio2000! */ - -/* WM8728 on I2C for AV710 */ -#define WM_DEV 0x36 - -#define WM_ATTEN_L 0x00 -#define WM_ATTEN_R 0x01 -#define WM_DAC_CTRL 0x02 -#define WM_INT_CTRL 0x03 extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; diff --git a/trunk/sound/pci/ice1712/ice1712.c b/trunk/sound/pci/ice1712/ice1712.c index a2545a5b26c4..79fba6be3503 100644 --- a/trunk/sound/pci/ice1712/ice1712.c +++ b/trunk/sound/pci/ice1712/ice1712.c @@ -2748,7 +2748,7 @@ static struct pci_driver driver = { static int __init alsa_card_ice1712_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_ice1712_exit(void) diff --git a/trunk/sound/pci/ice1712/ice1712.h b/trunk/sound/pci/ice1712/ice1712.h index 5ad4728daa7b..8bb1c58c26a0 100644 --- a/trunk/sound/pci/ice1712/ice1712.h +++ b/trunk/sound/pci/ice1712/ice1712.h @@ -373,11 +373,6 @@ struct _snd_ice1712 { unsigned short master[2]; unsigned short vol[8]; } aureon; - /* AC97 register cache for Phase28 */ - struct phase28_spec { - unsigned short master[2]; - unsigned short vol[8]; - } phase28; /* Hoontech-specific setting */ struct hoontech_spec { unsigned char boxbits[4]; diff --git a/trunk/sound/pci/ice1712/ice1724.c b/trunk/sound/pci/ice1712/ice1724.c index 79b5f12e06fc..95500f06f0c6 100644 --- a/trunk/sound/pci/ice1712/ice1724.c +++ b/trunk/sound/pci/ice1712/ice1724.c @@ -2328,7 +2328,7 @@ static struct pci_driver driver = { static int __init alsa_card_ice1724_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_ice1724_exit(void) diff --git a/trunk/sound/pci/ice1712/phase.c b/trunk/sound/pci/ice1712/phase.c index 5bf734b04fa0..d1f90832443c 100644 --- a/trunk/sound/pci/ice1712/phase.c +++ b/trunk/sound/pci/ice1712/phase.c @@ -45,47 +45,6 @@ #include "envy24ht.h" #include "phase.h" -/* WM8770 registers */ -#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ -#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */ -#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */ -#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */ -#define WM_PHASE_SWAP 0x12 /* DAC phase */ -#define WM_DAC_CTRL1 0x13 /* DAC control bits */ -#define WM_MUTE 0x14 /* mute controls */ -#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */ -#define WM_INT_CTRL 0x16 /* interface control */ -#define WM_MASTER 0x17 /* master clock and mode */ -#define WM_POWERDOWN 0x18 /* power-down controls */ -#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */ -#define WM_ADC_MUX 0x1b /* input MUX */ -#define WM_OUT_MUX1 0x1c /* output MUX */ -#define WM_OUT_MUX2 0x1e /* output MUX */ -#define WM_RESET 0x1f /* software reset */ - - -/* - * Logarithmic volume values for WM8770 - * Computed as 20 * Log10(255 / x) - */ -static unsigned char wm_vol[256] = { - 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, - 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, - 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -#define WM_VOL_MAX (sizeof(wm_vol) - 1) -#define WM_VOL_MUTE 0x8000 - static akm4xxx_t akm_phase22 __devinitdata = { .type = SND_AK4524, .num_dacs = 2, @@ -165,684 +124,6 @@ static unsigned char phase22_eeprom[] __devinitdata = { 0x00, /* GPIO_STATE2 */ }; -static unsigned char phase28_eeprom[] __devinitdata = { - 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ - 0x80, /* ACLINK: I2S */ - 0xfc, /* I2S: vol, 96k, 24bit, 192k */ - 0xc3, /* SPDIF: out-en, out-int, spdif-in */ - 0xff, /* GPIO_DIR */ - 0xff, /* GPIO_DIR1 */ - 0x5f, /* GPIO_DIR2 */ - 0x00, /* GPIO_MASK */ - 0x00, /* GPIO_MASK1 */ - 0x00, /* GPIO_MASK2 */ - 0x00, /* GPIO_STATE */ - 0x00, /* GPIO_STATE1 */ - 0x00, /* GPIO_STATE2 */ -}; - -/* - * write data in the SPI mode - */ -static void phase28_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits) -{ - unsigned int tmp; - int i; - - tmp = snd_ice1712_gpio_read(ice); - - snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|PHASE28_SPI_CLK| - PHASE28_WM_CS)); - tmp |= PHASE28_WM_RW; - tmp &= ~cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - for (i = bits - 1; i >= 0; i--) { - tmp &= ~PHASE28_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - if (data & (1 << i)) - tmp |= PHASE28_SPI_MOSI; - else - tmp &= ~PHASE28_SPI_MOSI; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - } - - tmp &= ~PHASE28_SPI_CLK; - tmp |= cs; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_SPI_CLK; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); -} - -/* - * get the current register value of WM codec - */ -static unsigned short wm_get(ice1712_t *ice, int reg) -{ - reg <<= 1; - return ((unsigned short)ice->akm[0].images[reg] << 8) | - ice->akm[0].images[reg + 1]; -} - -/* - * set the register value of WM codec - */ -static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val) -{ - phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16); -} - -/* - * set the register value of WM codec and remember it - */ -static void wm_put(ice1712_t *ice, int reg, unsigned short val) -{ - wm_put_nocache(ice, reg, val); - reg <<= 1; - ice->akm[0].images[reg] = val >> 8; - ice->akm[0].images[reg + 1] = val; -} - -static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master) -{ - unsigned char nvol; - - if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) - nvol = 0; - else - nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; - - wm_put(ice, index, nvol); - wm_put_nocache(ice, index, 0x180 | nvol); -} - -/* - * DAC mute control - */ -#define wm_pcm_mute_info phase28_mono_bool_info - -static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - - down(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; - up(&ice->gpio_mutex); - return 0; -} - -static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - unsigned short nval, oval; - int change; - - snd_ice1712_save_gpio_status(ice); - oval = wm_get(ice, WM_MUTE); - nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); - if ((change = (nval != oval))) - wm_put(ice, WM_MUTE, nval); - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * Master volume attenuation mixer control - */ -static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = WM_VOL_MAX; - return 0; -} - -static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int i; - for (i=0; i<2; i++) - ucontrol->value.integer.value[i] = ice->spec.phase28.master[i] & ~WM_VOL_MUTE; - return 0; -} - -static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int ch, change = 0; - - snd_ice1712_save_gpio_status(ice); - for (ch = 0; ch < 2; ch++) { - if (ucontrol->value.integer.value[ch] != ice->spec.phase28.master[ch]) { - int dac; - ice->spec.phase28.master[ch] &= WM_VOL_MUTE; - ice->spec.phase28.master[ch] |= ucontrol->value.integer.value[ch]; - for (dac = 0; dac < ice->num_total_dacs; dac += 2) - wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, - ice->spec.phase28.vol[dac + ch], - ice->spec.phase28.master[ch]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -static int __devinit phase28_init(ice1712_t *ice) -{ - static unsigned short wm_inits_phase28[] = { - /* These come first to reduce init pop noise */ - 0x1b, 0x044, /* ADC Mux (AC'97 source) */ - 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ - 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ - - 0x18, 0x000, /* All power-up */ - - 0x16, 0x122, /* I2S, normal polarity, 24bit */ - 0x17, 0x022, /* 256fs, slave mode */ - 0x00, 0, /* DAC1 analog mute */ - 0x01, 0, /* DAC2 analog mute */ - 0x02, 0, /* DAC3 analog mute */ - 0x03, 0, /* DAC4 analog mute */ - 0x04, 0, /* DAC5 analog mute */ - 0x05, 0, /* DAC6 analog mute */ - 0x06, 0, /* DAC7 analog mute */ - 0x07, 0, /* DAC8 analog mute */ - 0x08, 0x100, /* master analog mute */ - 0x09, 0xff, /* DAC1 digital full */ - 0x0a, 0xff, /* DAC2 digital full */ - 0x0b, 0xff, /* DAC3 digital full */ - 0x0c, 0xff, /* DAC4 digital full */ - 0x0d, 0xff, /* DAC5 digital full */ - 0x0e, 0xff, /* DAC6 digital full */ - 0x0f, 0xff, /* DAC7 digital full */ - 0x10, 0xff, /* DAC8 digital full */ - 0x11, 0x1ff, /* master digital full */ - 0x12, 0x000, /* phase normal */ - 0x13, 0x090, /* unmute DAC L/R */ - 0x14, 0x000, /* all unmute */ - 0x15, 0x000, /* no deemphasis, no ZFLG */ - 0x19, 0x000, /* -12dB ADC/L */ - 0x1a, 0x000, /* -12dB ADC/R */ - (unsigned short)-1 - }; - - unsigned int tmp; - akm4xxx_t *ak; - unsigned short *p; - int i; - - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - - // Initialize analog chips - ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL); - if (!ak) - return -ENOMEM; - ice->akm_codecs = 1; - - snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ - - /* reset the wm codec as the SPI mode */ - snd_ice1712_save_gpio_status(ice); - snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL)); - - tmp = snd_ice1712_gpio_read(ice); - tmp &= ~PHASE28_WM_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_WM_CS; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - tmp |= PHASE28_WM_RESET; - snd_ice1712_gpio_write(ice, tmp); - udelay(1); - - p = wm_inits_phase28; - for (; *p != (unsigned short)-1; p += 2) - wm_put(ice, p[0], p[1]); - - snd_ice1712_restore_gpio_status(ice); - - ice->spec.phase28.master[0] = WM_VOL_MUTE; - ice->spec.phase28.master[1] = WM_VOL_MUTE; - for (i = 0; i < ice->num_total_dacs; i++) { - ice->spec.phase28.vol[i] = WM_VOL_MUTE; - wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]); - } - - return 0; -} - -/* - * DAC volume attenuation mixer control - */ -static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - int voices = kcontrol->private_value >> 8; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = voices; - uinfo->value.integer.min = 0; /* mute (-101dB) */ - uinfo->value.integer.max = 0x7F; /* 0dB */ - return 0; -} - -static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int i, ofs, voices; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = ice->spec.phase28.vol[ofs+i] & ~WM_VOL_MUTE; - return 0; -} - -static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int i, idx, ofs, voices; - int change = 0; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xff; - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < voices; i++) { - idx = WM_DAC_ATTEN + ofs + i; - if (ucontrol->value.integer.value[i] != ice->spec.phase28.vol[ofs+i]) { - ice->spec.phase28.vol[ofs+i] &= WM_VOL_MUTE; - ice->spec.phase28.vol[ofs+i] |= ucontrol->value.integer.value[i]; - wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i], - ice->spec.phase28.master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - * WM8770 mute control - */ -static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = kcontrol->private_value >> 8; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int voices, ofs, i; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xFF; - - for (i = 0; i < voices; i++) - ucontrol->value.integer.value[i] = (ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1; - return 0; -} - -static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int change = 0, voices, ofs, i; - - voices = kcontrol->private_value >> 8; - ofs = kcontrol->private_value & 0xFF; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < voices; i++) { - int val = (ice->spec.phase28.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; - if (ucontrol->value.integer.value[i] != val) { - ice->spec.phase28.vol[ofs + i] &= ~WM_VOL_MUTE; - ice->spec.phase28.vol[ofs + i] |= - ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; - wm_set_vol(ice, ofs + i, ice->spec.phase28.vol[ofs + i], - ice->spec.phase28.master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* - * WM8770 master mute control - */ -static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1; - ucontrol->value.integer.value[1] = (ice->spec.phase28.master[1] & WM_VOL_MUTE) ? 0 : 1; - return 0; -} - -static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int change = 0, i; - - snd_ice1712_save_gpio_status(ice); - for (i = 0; i < 2; i++) { - int val = (ice->spec.phase28.master[i] & WM_VOL_MUTE) ? 0 : 1; - if (ucontrol->value.integer.value[i] != val) { - int dac; - ice->spec.phase28.master[i] &= ~WM_VOL_MUTE; - ice->spec.phase28.master[i] |= - ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; - for (dac = 0; dac < ice->num_total_dacs; dac += 2) - wm_set_vol(ice, WM_DAC_ATTEN + dac + i, - ice->spec.phase28.vol[dac + i], - ice->spec.phase28.master[i]); - change = 1; - } - } - snd_ice1712_restore_gpio_status(ice); - - return change; -} - -/* digital master volume */ -#define PCM_0dB 0xff -#define PCM_RES 128 /* -64dB */ -#define PCM_MIN (PCM_0dB - PCM_RES) -static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; /* mute (-64dB) */ - uinfo->value.integer.max = PCM_RES; /* 0dB */ - return 0; -} - -static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - unsigned short val; - - down(&ice->gpio_mutex); - val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; - val = val > PCM_MIN ? (val - PCM_MIN) : 0; - ucontrol->value.integer.value[0] = val; - up(&ice->gpio_mutex); - return 0; -} - -static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - unsigned short ovol, nvol; - int change = 0; - - snd_ice1712_save_gpio_status(ice); - nvol = ucontrol->value.integer.value[0]; - nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; - ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; - if (ovol != nvol) { - wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */ - wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */ - change = 1; - } - snd_ice1712_restore_gpio_status(ice); - return change; -} - -/* - */ -static int phase28_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -/* - * Deemphasis - */ -#define phase28_deemp_info phase28_mono_bool_info - -static int phase28_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; - return 0; -} - -static int phase28_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int temp, temp2; - temp2 = temp = wm_get(ice, WM_DAC_CTRL2); - if (ucontrol->value.integer.value[0]) - temp |= 0xf; - else - temp &= ~0xf; - if (temp != temp2) { - wm_put(ice, WM_DAC_CTRL2, temp); - return 1; - } - return 0; -} - -/* - * ADC Oversampling - */ -static int phase28_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo) -{ - static char *texts[2] = { "128x", "64x" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - - return 0; -} - -static int phase28_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; - return 0; -} - -static int phase28_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - int temp, temp2; - ice1712_t *ice = snd_kcontrol_chip(kcontrol); - - temp2 = temp = wm_get(ice, WM_MASTER); - - if (ucontrol->value.enumerated.item[0]) - temp |= 0x8; - else - temp &= ~0x8; - - if (temp != temp2) { - wm_put(ice, WM_MASTER, temp); - return 1; - } - return 0; -} - -static snd_kcontrol_new_t phase28_dac_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = wm_master_mute_info, - .get = wm_master_mute_get, - .put = wm_master_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = wm_master_vol_info, - .get = wm_master_vol_get, - .put = wm_master_vol_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 0 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 0 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Rear Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 2 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Rear Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 2 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Center Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (1 << 8) | 4 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Center Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (1 << 8) | 4 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "LFE Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (1 << 8) | 5 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "LFE Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (1 << 8) | 5 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Side Playback Switch", - .info = wm_mute_info, - .get = wm_mute_get, - .put = wm_mute_put, - .private_value = (2 << 8) | 6 - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Side Playback Volume", - .info = wm_vol_info, - .get = wm_vol_get, - .put = wm_vol_put, - .private_value = (2 << 8) | 6 - } -}; - -static snd_kcontrol_new_t wm_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .info = wm_pcm_mute_info, - .get = wm_pcm_mute_get, - .put = wm_pcm_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .info = wm_pcm_vol_info, - .get = wm_pcm_vol_get, - .put = wm_pcm_vol_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Deemphasis Switch", - .info = phase28_deemp_info, - .get = phase28_deemp_get, - .put = phase28_deemp_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Oversampling", - .info = phase28_oversampling_info, - .get = phase28_oversampling_get, - .put = phase28_oversampling_put - } -}; - -static int __devinit phase28_add_controls(ice1712_t *ice) -{ - unsigned int i, counts; - int err; - - counts = ARRAY_SIZE(phase28_dac_controls); - for (i = 0; i < counts; i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&phase28_dac_controls[i], ice)); - if (err < 0) - return err; - } - - for (i = 0; i < ARRAY_SIZE(wm_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice)); - if (err < 0) - return err; - } - - return 0; -} - struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PHASE22, @@ -853,14 +134,5 @@ struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { .eeprom_size = sizeof(phase22_eeprom), .eeprom_data = phase22_eeprom, }, - { - .subvendor = VT1724_SUBDEVICE_PHASE28, - .name = "Terratec PHASE 28", - .model = "phase28", - .chip_init = phase28_init, - .build_controls = phase28_add_controls, - .eeprom_size = sizeof(phase28_eeprom), - .eeprom_data = phase28_eeprom, - }, { } /* terminator */ }; diff --git a/trunk/sound/pci/ice1712/phase.h b/trunk/sound/pci/ice1712/phase.h index 13e841b55488..6230cf16989f 100644 --- a/trunk/sound/pci/ice1712/phase.h +++ b/trunk/sound/pci/ice1712/phase.h @@ -24,28 +24,11 @@ * */ -#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\ - "{Terratec,Phase 28}," +#define PHASE_DEVICE_DESC "{Terratec,Phase 22}," #define VT1724_SUBDEVICE_PHASE22 0x3b155011 -#define VT1724_SUBDEVICE_PHASE28 0x3b154911 /* entry point */ extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; -/* PHASE28 GPIO bits */ -#define PHASE28_SPI_MISO (1 << 21) -#define PHASE28_WM_RESET (1 << 20) -#define PHASE28_SPI_CLK (1 << 19) -#define PHASE28_SPI_MOSI (1 << 18) -#define PHASE28_WM_RW (1 << 17) -#define PHASE28_AC97_RESET (1 << 16) -#define PHASE28_DIGITAL_SEL1 (1 << 15) -#define PHASE28_HP_SEL (1 << 14) -#define PHASE28_WM_CS (1 << 12) -#define PHASE28_AC97_COMMIT (1 << 11) -#define PHASE28_AC97_ADDR (1 << 10) -#define PHASE28_AC97_DATA_LOW (1 << 9) -#define PHASE28_AC97_DATA_HIGH (1 << 8) -#define PHASE28_AC97_DATA_MASK 0xFF #endif /* __SOUND_PHASE */ diff --git a/trunk/sound/pci/ice1712/vt1720_mobo.c b/trunk/sound/pci/ice1712/vt1720_mobo.c index ab61e383024f..3bd92627231c 100644 --- a/trunk/sound/pci/ice1712/vt1720_mobo.c +++ b/trunk/sound/pci/ice1712/vt1720_mobo.c @@ -110,15 +110,6 @@ struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { .eeprom_size = sizeof(k8x800_eeprom), .eeprom_data = k8x800_eeprom, }, - { - .subvendor = VT1720_SUBDEVICE_SN25P, - .name = "Shuttle SN25P", - /* identical with k8x800 */ - .chip_init = k8x800_init, - .build_controls = k8x800_add_controls, - .eeprom_size = sizeof(k8x800_eeprom), - .eeprom_data = k8x800_eeprom, - }, { } /* terminator */ }; diff --git a/trunk/sound/pci/ice1712/vt1720_mobo.h b/trunk/sound/pci/ice1712/vt1720_mobo.h index 0b1b0ee1bea7..f949eb804cae 100644 --- a/trunk/sound/pci/ice1712/vt1720_mobo.h +++ b/trunk/sound/pci/ice1712/vt1720_mobo.h @@ -27,14 +27,12 @@ #define VT1720_MOBO_DEVICE_DESC "{Albatron,K8X800 Pro II},"\ "{Chaintech,ZNF3-150},"\ "{Chaintech,ZNF3-250},"\ - "{Chaintech,9CJS},"\ - "{Shuttle,SN25P}," + "{Chaintech,9CJS}," #define VT1720_SUBDEVICE_K8X800 0xf217052c #define VT1720_SUBDEVICE_ZNF3_150 0x0f2741f6 #define VT1720_SUBDEVICE_ZNF3_250 0x0f2745f6 #define VT1720_SUBDEVICE_9CJS 0x0f272327 -#define VT1720_SUBDEVICE_SN25P 0x97123650 extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; diff --git a/trunk/sound/pci/intel8x0.c b/trunk/sound/pci/intel8x0.c index 9c5710daed50..8b33b12fa5dc 100644 --- a/trunk/sound/pci/intel8x0.c +++ b/trunk/sound/pci/intel8x0.c @@ -2849,7 +2849,7 @@ static struct pci_driver driver = { static int __init alsa_card_intel8x0_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_intel8x0_exit(void) diff --git a/trunk/sound/pci/intel8x0m.c b/trunk/sound/pci/intel8x0m.c index f655cf914060..67da096d659b 100644 --- a/trunk/sound/pci/intel8x0m.c +++ b/trunk/sound/pci/intel8x0m.c @@ -500,8 +500,6 @@ static unsigned short snd_intel8x0_codec_read(ac97_t *ac97, res = 0xffff; } } - if (reg == AC97_GPIO_STATUS) - iagetword(chip, 0); /* clear semaphore */ return res; } @@ -1452,7 +1450,7 @@ static struct pci_driver driver = { static int __init alsa_card_intel8x0m_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_intel8x0m_exit(void) diff --git a/trunk/sound/pci/korg1212/korg1212.c b/trunk/sound/pci/korg1212/korg1212.c index 79d8eda54f0d..bb1de2008176 100644 --- a/trunk/sound/pci/korg1212/korg1212.c +++ b/trunk/sound/pci/korg1212/korg1212.c @@ -2541,7 +2541,7 @@ static struct pci_driver driver = { static int __init alsa_card_korg1212_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_korg1212_exit(void) diff --git a/trunk/sound/pci/maestro3.c b/trunk/sound/pci/maestro3.c index 096f15132853..2cf33083d7cc 100644 --- a/trunk/sound/pci/maestro3.c +++ b/trunk/sound/pci/maestro3.c @@ -779,12 +779,6 @@ struct m3_quirk { (e.g. for IrDA on Dell Inspirons) */ }; -struct m3_hv_quirk { - u16 vendor, device, subsystem_vendor, subsystem_device; - u32 config; /* ALLEGRO_CONFIG hardware volume bits */ - int is_omnibook; /* Do HP OmniBook GPIO magic? */ -}; - struct m3_list { int curlen; int mem_addr; @@ -834,7 +828,6 @@ struct snd_m3 { struct pci_dev *pci; struct m3_quirk *quirk; - struct m3_hv_quirk *hv_quirk; int dacs_active; int timer_users; @@ -858,11 +851,6 @@ struct snd_m3 { m3_dma_t *substreams; spinlock_t reg_lock; - spinlock_t ac97_lock; - - snd_kcontrol_t *master_switch; - snd_kcontrol_t *master_volume; - struct tasklet_struct hwvol_tq; #ifdef CONFIG_PM u16 *suspend_mem; @@ -980,71 +968,6 @@ static struct m3_quirk m3_quirk_list[] = { { NULL } }; -/* These values came from the Windows driver. */ -static struct m3_hv_quirk m3_hv_quirk_list[] = { - /* Allegro chips */ - { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x0E11, 0xB112, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x0E11, 0xB114, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x103C, 0x0012, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x103C, 0x0018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x103C, 0x001C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x103C, 0x001D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x103C, 0x001E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x107B, 0x3350, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x10F7, 0x8338, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x10F7, 0x833C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x10F7, 0x833D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x10F7, 0x833E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x10F7, 0x833F, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x13BD, 0x1018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x13BD, 0x1019, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x13BD, 0x101A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x14FF, 0x0F03, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x14FF, 0x0F04, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x14FF, 0x0F05, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x156D, 0xB400, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x156D, 0xB795, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x156D, 0xB797, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x156D, 0xC700, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, - { 0x125D, 0x1988, 0x1033, 0x80F1, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x103C, 0x001A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, /* HP OmniBook 6100 */ - { 0x125D, 0x1988, 0x107B, 0x340A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x107B, 0x3450, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x109F, 0x3134, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x109F, 0x3161, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x144D, 0x3280, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x144D, 0x3281, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x144D, 0xC002, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x144D, 0xC003, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x1509, 0x1740, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x1610, 0x0010, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x1988, 0x1042, 0x1042, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1988, 0x107B, 0x9500, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1988, 0x14FF, 0x0F06, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1988, 0x1558, 0x8586, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1988, 0x161F, 0x2011, HV_CTRL_ENABLE, 0 }, - /* Maestro3 chips */ - { 0x125D, 0x1998, 0x103C, 0x000E, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x103C, 0x0010, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 6000 */ - { 0x125D, 0x1998, 0x103C, 0x0011, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 500 */ - { 0x125D, 0x1998, 0x103C, 0x001B, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x104D, 0x80A6, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x104D, 0x80AA, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x107B, 0x5300, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x110A, 0x1998, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x13BD, 0x1015, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x13BD, 0x101C, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x13BD, 0x1802, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x1599, 0x0715, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x1998, 0x5643, 0x5643, HV_CTRL_ENABLE, 0 }, - { 0x125D, 0x199A, 0x144D, 0x3260, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x199A, 0x144D, 0x3261, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x199A, 0x144D, 0xC000, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, - { 0x125D, 0x199A, 0x144D, 0xC001, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, - { 0 } -}; /* * lowlevel functions @@ -1642,68 +1565,6 @@ static void snd_m3_update_ptr(m3_t *chip, m3_dma_t *s) } } -static void snd_m3_update_hw_volume(unsigned long private_data) -{ - m3_t *chip = (m3_t *) private_data; - int x, val; - unsigned long flags; - - /* Figure out which volume control button was pushed, - based on differences from the default register - values. */ - x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee; - - /* Reset the volume control registers. */ - outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE); - outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE); - outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); - outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER); - - if (!chip->master_switch || !chip->master_volume) - return; - - /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */ - spin_lock_irqsave(&chip->ac97_lock, flags); - - val = chip->ac97->regs[AC97_MASTER_VOL]; - switch (x) { - case 0x88: - /* mute */ - val ^= 0x8000; - chip->ac97->regs[AC97_MASTER_VOL] = val; - outw(val, chip->iobase + CODEC_DATA); - outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND); - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - &chip->master_switch->id); - break; - case 0xaa: - /* volume up */ - if ((val & 0x7f) > 0) - val--; - if ((val & 0x7f00) > 0) - val -= 0x0100; - chip->ac97->regs[AC97_MASTER_VOL] = val; - outw(val, chip->iobase + CODEC_DATA); - outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND); - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - &chip->master_volume->id); - break; - case 0x66: - /* volume down */ - if ((val & 0x7f) < 0x1f) - val++; - if ((val & 0x7f00) < 0x1f00) - val += 0x0100; - chip->ac97->regs[AC97_MASTER_VOL] = val; - outw(val, chip->iobase + CODEC_DATA); - outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND); - snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - &chip->master_volume->id); - break; - } - spin_unlock_irqrestore(&chip->ac97_lock, flags); -} - static irqreturn_t snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -1715,10 +1576,7 @@ snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (status == 0xff) return IRQ_NONE; - - if (status & HV_INT_PENDING) - tasklet_hi_schedule(&chip->hwvol_tq); - + /* * ack an assp int if its running * and has an int pending @@ -1747,7 +1605,7 @@ snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs) #endif /* ack ints */ - outb(status, chip->iobase + HOST_INT_STATUS); + snd_m3_outw(chip, HOST_INT_STATUS, status); return IRQ_HANDLED; } @@ -1984,32 +1842,24 @@ static unsigned short snd_m3_ac97_read(ac97_t *ac97, unsigned short reg) { m3_t *chip = ac97->private_data; - unsigned long flags; - unsigned short data; if (snd_m3_ac97_wait(chip)) return 0xffff; - spin_lock_irqsave(&chip->ac97_lock, flags); snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); if (snd_m3_ac97_wait(chip)) return 0xffff; - data = snd_m3_inw(chip, CODEC_DATA); - spin_unlock_irqrestore(&chip->ac97_lock, flags); - return data; + return snd_m3_inw(chip, CODEC_DATA); } static void snd_m3_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) { m3_t *chip = ac97->private_data; - unsigned long flags; if (snd_m3_ac97_wait(chip)) return; - spin_lock_irqsave(&chip->ac97_lock, flags); snd_m3_outw(chip, val, CODEC_DATA); snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); - spin_unlock_irqrestore(&chip->ac97_lock, flags); } @@ -2118,7 +1968,6 @@ static int __devinit snd_m3_mixer(m3_t *chip) { ac97_bus_t *pbus; ac97_template_t ac97; - snd_ctl_elem_id_t id; int err; static ac97_bus_ops_t ops = { .write = snd_m3_ac97_write, @@ -2139,15 +1988,6 @@ static int __devinit snd_m3_mixer(m3_t *chip) schedule_timeout(HZ / 10); snd_ac97_write(chip->ac97, AC97_PCM, 0); - memset(&id, 0, sizeof(id)); - id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(id.name, "Master Playback Switch"); - chip->master_switch = snd_ctl_find_id(chip->card, &id); - memset(&id, 0, sizeof(id)); - id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(id.name, "Master Playback Volume"); - chip->master_volume = snd_ctl_find_id(chip->card, &id); - return 0; } @@ -2453,7 +2293,6 @@ static int snd_m3_chip_init(m3_t *chip) { struct pci_dev *pcidev = chip->pci; - unsigned long io = chip->iobase; u32 n; u16 w; u8 t; /* makes as much sense as 'n', no? */ @@ -2464,27 +2303,8 @@ snd_m3_chip_init(m3_t *chip) DISABLE_LEGACY); pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w); - if (chip->hv_quirk && chip->hv_quirk->is_omnibook) { - /* - * Volume buttons on some HP OmniBook laptops don't work - * correctly. This makes them work for the most part. - * - * Volume up and down buttons on the laptop side work. - * Fn+cursor_up (volme up) works. - * Fn+cursor_down (volume down) doesn't work. - * Fn+F7 (mute) works acts as volume up. - */ - outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK); - outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION); - outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA); - outw(0xffff, io + GPIO_MASK); - } pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); - n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD); - if (chip->hv_quirk) - n |= chip->hv_quirk->config; - /* For some reason we must always use reduced debounce. */ - n |= REDUCED_DEBOUNCE; + n &= REDUCED_DEBOUNCE; n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING; pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n); @@ -2512,12 +2332,6 @@ snd_m3_chip_init(m3_t *chip) outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B); - outb(0x00, io + HARDWARE_VOL_CTRL); - outb(0x88, io + SHADOW_MIX_REG_VOICE); - outb(0x88, io + HW_VOL_COUNTER_VOICE); - outb(0x88, io + SHADOW_MIX_REG_MASTER); - outb(0x88, io + HW_VOL_COUNTER_MASTER); - return 0; } @@ -2527,7 +2341,7 @@ snd_m3_enable_ints(m3_t *chip) unsigned long io = chip->iobase; /* TODO: MPU401 not supported yet */ - outw(ASSP_INT_ENABLE | HV_INT_ENABLE /*| MPU401_INT_ENABLE*/, io + HOST_INT_CTRL); + outw(ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/, io + HOST_INT_CTRL); outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, io + ASSP_CONTROL_C); } @@ -2553,7 +2367,7 @@ static int snd_m3_free(m3_t *chip) kfree(chip->substreams); } if (chip->iobase) { - outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */ + snd_m3_outw(chip, HOST_INT_CTRL, 0); /* disable ints */ } #ifdef CONFIG_PM @@ -2672,7 +2486,7 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, m3_t *chip; int i, err; struct m3_quirk *quirk; - struct m3_hv_quirk *hv_quirk; + u16 subsystem_vendor, subsystem_device; static snd_device_ops_t ops = { .dev_free = snd_m3_dev_free, }; @@ -2710,25 +2524,18 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, chip->pci = pci; chip->irq = -1; + pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); + pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); + for (quirk = m3_quirk_list; quirk->vendor; quirk++) { - if (pci->subsystem_vendor == quirk->vendor && - pci->subsystem_device == quirk->device) { + if (subsystem_vendor == quirk->vendor && + subsystem_device == quirk->device) { printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name); chip->quirk = quirk; break; } } - for (hv_quirk = m3_hv_quirk_list; hv_quirk->vendor; hv_quirk++) { - if (pci->vendor == hv_quirk->vendor && - pci->device == hv_quirk->device && - pci->subsystem_vendor == hv_quirk->subsystem_vendor && - pci->subsystem_device == hv_quirk->subsystem_device) { - chip->hv_quirk = hv_quirk; - break; - } - } - chip->external_amp = enable_amp; if (amp_gpio >= 0 && amp_gpio <= 0x0f) chip->amp_gpio = amp_gpio; @@ -2786,9 +2593,6 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, return err; } - spin_lock_init(&chip->ac97_lock); - tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); - if ((err = snd_m3_mixer(chip)) < 0) return err; @@ -2898,7 +2702,7 @@ static struct pci_driver driver = { static int __init alsa_card_m3_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_m3_exit(void) diff --git a/trunk/sound/pci/mixart/mixart.c b/trunk/sound/pci/mixart/mixart.c index 082c0d0f73d2..65bb0f47af2c 100644 --- a/trunk/sound/pci/mixart/mixart.c +++ b/trunk/sound/pci/mixart/mixart.c @@ -1431,7 +1431,7 @@ static struct pci_driver driver = { static int __init alsa_card_mixart_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_mixart_exit(void) diff --git a/trunk/sound/pci/nm256/nm256.c b/trunk/sound/pci/nm256/nm256.c index 8a52091f8552..356fbeac6f9e 100644 --- a/trunk/sound/pci/nm256/nm256.c +++ b/trunk/sound/pci/nm256/nm256.c @@ -1645,7 +1645,7 @@ static struct pci_driver driver = { static int __init alsa_card_nm256_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_nm256_exit(void) diff --git a/trunk/sound/pci/rme32.c b/trunk/sound/pci/rme32.c index b7b554df6705..b96acd5a57db 100644 --- a/trunk/sound/pci/rme32.c +++ b/trunk/sound/pci/rme32.c @@ -2031,7 +2031,7 @@ static struct pci_driver driver = { static int __init alsa_card_rme32_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_rme32_exit(void) diff --git a/trunk/sound/pci/rme96.c b/trunk/sound/pci/rme96.c index 10c4f45a913c..8e2666841d21 100644 --- a/trunk/sound/pci/rme96.c +++ b/trunk/sound/pci/rme96.c @@ -2437,7 +2437,7 @@ static struct pci_driver driver = { static int __init alsa_card_rme96_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_rme96_exit(void) diff --git a/trunk/sound/pci/rme9652/hdsp.c b/trunk/sound/pci/rme9652/hdsp.c index b35ed5f0c042..12efbf0fab54 100644 --- a/trunk/sound/pci/rme9652/hdsp.c +++ b/trunk/sound/pci/rme9652/hdsp.c @@ -4912,9 +4912,19 @@ static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp) release_firmware(fw); return -EINVAL; } - +#ifdef SNDRV_BIG_ENDIAN + { + int i; + u32 *src = (u32*)fw->data; + for (i = 0; i < ARRAY_SIZE(hdsp->firmware_cache); i++, src++) + hdsp->firmware_cache[i] = ((*src & 0x000000ff) << 16) | + ((*src & 0x0000ff00) << 8) | + ((*src & 0x00ff0000) >> 8) | + ((*src & 0xff000000) >> 16); + } +#else memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache)); - +#endif release_firmware(fw); hdsp->state |= HDSP_FirmwareCached; @@ -5184,7 +5194,7 @@ static struct pci_driver driver = { static int __init alsa_card_hdsp_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_hdsp_exit(void) diff --git a/trunk/sound/pci/rme9652/rme9652.c b/trunk/sound/pci/rme9652/rme9652.c index 5861f234af21..69cd81eaa111 100644 --- a/trunk/sound/pci/rme9652/rme9652.c +++ b/trunk/sound/pci/rme9652/rme9652.c @@ -2664,7 +2664,7 @@ static struct pci_driver driver = { static int __init alsa_card_hammerfall_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_hammerfall_exit(void) diff --git a/trunk/sound/pci/sonicvibes.c b/trunk/sound/pci/sonicvibes.c index 60ecb2bdb65e..cfd2c5fd6ddf 100644 --- a/trunk/sound/pci/sonicvibes.c +++ b/trunk/sound/pci/sonicvibes.c @@ -1522,7 +1522,7 @@ static struct pci_driver driver = { static int __init alsa_card_sonicvibes_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_sonicvibes_exit(void) diff --git a/trunk/sound/pci/trident/trident.c b/trunk/sound/pci/trident/trident.c index 5d21cb811c8a..ad58e08d66e2 100644 --- a/trunk/sound/pci/trident/trident.c +++ b/trunk/sound/pci/trident/trident.c @@ -184,7 +184,7 @@ static struct pci_driver driver = { static int __init alsa_card_trident_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_trident_exit(void) diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index bb322de4777f..9b4d74d49f98 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -101,7 +101,7 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); module_param_array(ac97_quirk, charp, NULL, 0444); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); module_param_array(dxs_support, int, NULL, 0444); -MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)"); +MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA)"); /* pci ids */ @@ -302,7 +302,6 @@ DEFINE_VIA_REGSET(CAPTURE_8233, 0x60); #define VIA_DXS_DISABLE 2 #define VIA_DXS_48K 3 #define VIA_DXS_NO_VRA 4 -#define VIA_DXS_SRC 5 /* @@ -381,7 +380,6 @@ struct _snd_via82xx { struct via_rate_lock rates[2]; /* playback and capture */ unsigned int dxs_fixed: 1; /* DXS channel accepts only 48kHz */ unsigned int no_vra: 1; /* no need to set VRA on DXS channels */ - unsigned int dxs_src: 1; /* use full SRC capabilities of DXS */ unsigned int spdif_on: 1; /* only spdif rates work to external DACs */ snd_pcm_t *pcms[2]; @@ -926,17 +924,15 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) via82xx_t *chip = snd_pcm_substream_chip(substream); viadev_t *viadev = (viadev_t *)substream->runtime->private_data; snd_pcm_runtime_t *runtime = substream->runtime; - int ac97_rate = chip->dxs_src ? 48000 : runtime->rate; int rate_changed; u32 rbits; - if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0) + if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0) return rate_changed; if (rate_changed) { snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, chip->no_vra ? 48000 : runtime->rate); - snd_ac97_set_rate(chip->ac97, AC97_SPDIF, - chip->no_vra ? 48000 : runtime->rate); + snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); } if (runtime->rate == 48000) rbits = 0xfffff; @@ -1078,12 +1074,6 @@ static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_subst /* fixed DXS playback rate */ runtime->hw.rates = SNDRV_PCM_RATE_48000; runtime->hw.rate_min = runtime->hw.rate_max = 48000; - } else if (chip->dxs_src && viadev->reg_offset < 0x40) { - /* use full SRC capabilities of DXS */ - runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS | - SNDRV_PCM_RATE_8000_48000); - runtime->hw.rate_min = 8000; - runtime->hw.rate_max = 48000; } else if (! ratep->rate) { int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; runtime->hw.rates = chip->ac97->rates[idx]; @@ -2159,17 +2149,14 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/ { .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */ { .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ - { .vendor = 0x1043, .device = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */ { .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */ { .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */ { .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */ { .vendor = 0x1106, .device = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */ { .vendor = 0x1106, .device = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */ - { .vendor = 0x1106, .device = 0xc001, .action = VIA_DXS_SRC }, /* Insight P4-ITX */ { .vendor = 0x1297, .device = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */ { .vendor = 0x1297, .device = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */ { .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */ - { .vendor = 0x1462, .device = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */ { .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */ { .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */ { .vendor = 0x1462, .device = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */ @@ -2179,7 +2166,6 @@ static int __devinit check_dxs_list(struct pci_dev *pci) { .vendor = 0x147b, .device = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ { .vendor = 0x147b, .device = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */ { .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */ - { .vendor = 0x14ff, .device = 0x0408, .action = VIA_DXS_NO_VRA }, /* Twinhead mobo */ { .vendor = 0x1584, .device = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */ { .vendor = 0x1584, .device = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */ { .vendor = 0x161f, .device = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */ @@ -2302,10 +2288,6 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci, chip->dxs_fixed = 1; else if (dxs_support[dev] == VIA_DXS_NO_VRA) chip->no_vra = 1; - else if (dxs_support[dev] == VIA_DXS_SRC) { - chip->no_vra = 1; - chip->dxs_src = 1; - } } if ((err = snd_via8233_init_misc(chip, dev)) < 0) goto __error; @@ -2352,7 +2334,7 @@ static struct pci_driver driver = { static int __init alsa_card_via82xx_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_via82xx_exit(void) diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index 276ce5299684..ea5c6f640159 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -938,7 +938,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) * */ -static int snd_via82xx_chip_init(via82xx_t *chip) +static int __devinit snd_via82xx_chip_init(via82xx_t *chip) { unsigned int val; int max_count; @@ -1233,7 +1233,7 @@ static struct pci_driver driver = { static int __init alsa_card_via82xx_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_via82xx_exit(void) diff --git a/trunk/sound/pci/vx222/vx222.c b/trunk/sound/pci/vx222/vx222.c index dca6bd2c7580..4ffbb25658a5 100644 --- a/trunk/sound/pci/vx222/vx222.c +++ b/trunk/sound/pci/vx222/vx222.c @@ -260,7 +260,7 @@ static struct pci_driver driver = { static int __init alsa_card_vx222_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_vx222_exit(void) diff --git a/trunk/sound/pci/ymfpci/ymfpci.c b/trunk/sound/pci/ymfpci/ymfpci.c index 5b5b624b47d0..9f3ef22df08d 100644 --- a/trunk/sound/pci/ymfpci/ymfpci.c +++ b/trunk/sound/pci/ymfpci/ymfpci.c @@ -360,7 +360,7 @@ static struct pci_driver driver = { static int __init alsa_card_ymfpci_init(void) { - return pci_register_driver(&driver); + return pci_module_init(&driver); } static void __exit alsa_card_ymfpci_exit(void) diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index 997cf37cdddd..05f1629760bc 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -1421,15 +1421,17 @@ static snd_kcontrol_new_t snd_ymfpci_drec_source __devinitdata = { static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { + unsigned int mask = 1; + switch (kcontrol->private_value) { case YDSXGR_SPDIFOUTCTRL: break; case YDSXGR_SPDIFINCTRL: break; default: return -EINVAL; } - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; + uinfo->value.integer.max = mask; return 0; } @@ -1437,7 +1439,7 @@ static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value; - unsigned int shift = 0, mask = 1; + unsigned int shift = 0, mask = 1, invert = 0; switch (kcontrol->private_value) { case YDSXGR_SPDIFOUTCTRL: break; @@ -1445,6 +1447,8 @@ static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t default: return -EINVAL; } ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask; + if (invert) + ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; return 0; } @@ -1452,7 +1456,7 @@ static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value; - unsigned int shift = 0, mask = 1; + unsigned int shift = 0, mask = 1, invert = 0; int change; unsigned int val, oval; @@ -1462,6 +1466,8 @@ static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t default: return -EINVAL; } val = (ucontrol->value.integer.value[0] & mask); + if (invert) + val = mask - val; val <<= shift; spin_lock_irq(&chip->reg_lock); oval = snd_ymfpci_readl(chip, reg); @@ -1481,13 +1487,14 @@ static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t static int snd_ymfpci_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { unsigned int reg = kcontrol->private_value; + unsigned int mask = 16383; if (reg < 0x80 || reg >= 0xc0) return -EINVAL; - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; uinfo->value.integer.min = 0; - uinfo->value.integer.max = 16383; + uinfo->value.integer.max = mask; return 0; } @@ -1495,7 +1502,7 @@ static int snd_ymfpci_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int reg = kcontrol->private_value; - unsigned int shift_left = 0, shift_right = 16, mask = 16383; + unsigned int shift_left = 0, shift_right = 16, mask = 16383, invert = 0; unsigned int val; if (reg < 0x80 || reg >= 0xc0) @@ -1505,6 +1512,10 @@ static int snd_ymfpci_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t spin_unlock_irq(&chip->reg_lock); ucontrol->value.integer.value[0] = (val >> shift_left) & mask; ucontrol->value.integer.value[1] = (val >> shift_right) & mask; + if (invert) { + ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; + ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; + } return 0; } @@ -1512,7 +1523,7 @@ static int snd_ymfpci_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int reg = kcontrol->private_value; - unsigned int shift_left = 0, shift_right = 16, mask = 16383; + unsigned int shift_left = 0, shift_right = 16, mask = 16383, invert = 0; int change; unsigned int val1, val2, oval; @@ -1520,6 +1531,10 @@ static int snd_ymfpci_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t return -EINVAL; val1 = ucontrol->value.integer.value[0] & mask; val2 = ucontrol->value.integer.value[1] & mask; + if (invert) { + val1 = mask - val1; + val2 = mask - val2; + } val1 <<= shift_left; val2 <<= shift_right; spin_lock_irq(&chip->reg_lock); diff --git a/trunk/sound/ppc/pmac.c b/trunk/sound/ppc/pmac.c index 080ef3928465..32d94754acf8 100644 --- a/trunk/sound/ppc/pmac.c +++ b/trunk/sound/ppc/pmac.c @@ -876,7 +876,7 @@ static void __init detect_byte_swap(pmac_t *chip) */ static int __init snd_pmac_detect(pmac_t *chip) { - struct device_node *sound = NULL; + struct device_node *sound; unsigned int *prop, l; struct macio_chip* macio; @@ -906,22 +906,20 @@ static int __init snd_pmac_detect(pmac_t *chip) chip->is_pbook_G3 = 1; chip->node = find_devices("awacs"); if (chip->node) - sound = chip->node; + return 0; /* ok */ /* * powermac G3 models have a node called "davbus" * with a child called "sound". */ - if (!chip->node) - chip->node = find_devices("davbus"); + chip->node = find_devices("davbus"); /* * if we didn't find a davbus device, try 'i2s-a' since * this seems to be what iBooks have */ if (! chip->node) { chip->node = find_devices("i2s-a"); - if (chip->node && chip->node->parent && - chip->node->parent->parent) { + if (chip->node && chip->node->parent && chip->node->parent->parent) { if (device_is_compatible(chip->node->parent->parent, "K2-Keylargo")) chip->is_k2 = 1; @@ -930,11 +928,9 @@ static int __init snd_pmac_detect(pmac_t *chip) if (! chip->node) return -ENODEV; - if (!sound) { - sound = find_devices("sound"); - while (sound && sound->parent != chip->node) - sound = sound->next; - } + sound = find_devices("sound"); + while (sound && sound->parent != chip->node) + sound = sound->next; if (! sound) return -ENODEV; prop = (unsigned int *) get_property(sound, "sub-frame", NULL); @@ -1023,8 +1019,7 @@ static int __init snd_pmac_detect(pmac_t *chip) } } if (chip->pdev == NULL) - printk(KERN_WARNING "snd-powermac: can't locate macio PCI" - " device !\n"); + printk(KERN_WARNING "snd-powermac: can't locate macio PCI device !\n"); detect_byte_swap(chip); @@ -1032,8 +1027,7 @@ static int __init snd_pmac_detect(pmac_t *chip) are available */ prop = (unsigned int *) get_property(sound, "sample-rates", &l); if (! prop) - prop = (unsigned int *) get_property(sound, - "output-frame-rates", &l); + prop = (unsigned int *) get_property(sound, "output-frame-rates", &l); if (prop) { int i; chip->freqs_ok = 0; @@ -1060,8 +1054,7 @@ static int __init snd_pmac_detect(pmac_t *chip) /* * exported - boolean info callbacks for ease of programming */ -int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, - snd_ctl_elem_info_t *uinfo) +int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 2; @@ -1070,8 +1063,7 @@ int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, return 0; } -int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, - snd_ctl_elem_info_t *uinfo) +int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; diff --git a/trunk/sound/usb/Kconfig b/trunk/sound/usb/Kconfig index f05d02f5b69f..9329e992c841 100644 --- a/trunk/sound/usb/Kconfig +++ b/trunk/sound/usb/Kconfig @@ -6,7 +6,6 @@ menu "USB devices" config SND_USB_AUDIO tristate "USB Audio/MIDI driver" depends on SND && USB - select SND_HWDEP select SND_RAWMIDI select SND_PCM help diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index a82412b8790d..84b0bbddbd22 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -98,7 +98,7 @@ MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); #define MAX_PACKS 10 #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ #define MAX_URBS 5 /* max. 20ms long packets */ -#define SYNC_URBS 4 /* always four urbs for sync */ +#define SYNC_URBS 2 /* always two urbs for sync */ #define MIN_PACKS_URB 1 /* minimum 1 packet per urb */ typedef struct snd_usb_substream snd_usb_substream_t; @@ -177,7 +177,7 @@ struct snd_usb_substream { unsigned int nurbs; /* # urbs */ snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ - char syncbuf[SYNC_URBS * 4]; /* sync buffer; it's so small - let's get static */ + char syncbuf[SYNC_URBS * MAX_PACKS * 4]; /* sync buffer; it's so small - let's get static */ char *tmpbuf; /* temporary buffer for playback */ u64 formats; /* format bitmasks (all or'ed) */ @@ -251,13 +251,17 @@ static int prepare_capture_sync_urb(snd_usb_substream_t *subs, { unsigned char *cp = urb->transfer_buffer; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; + int i, offs; + urb->number_of_packets = ctx->packets; urb->dev = ctx->subs->dev; /* we need to set this at each time */ - urb->iso_frame_desc[0].length = 3; - urb->iso_frame_desc[0].offset = 0; - cp[0] = subs->freqn >> 2; - cp[1] = subs->freqn >> 10; - cp[2] = subs->freqn >> 18; + for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) { + urb->iso_frame_desc[i].length = 3; + urb->iso_frame_desc[i].offset = offs; + cp[0] = subs->freqn >> 2; + cp[1] = subs->freqn >> 10; + cp[2] = subs->freqn >> 18; + } return 0; } @@ -273,14 +277,18 @@ static int prepare_capture_sync_urb_hs(snd_usb_substream_t *subs, { unsigned char *cp = urb->transfer_buffer; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; + int i, offs; + urb->number_of_packets = ctx->packets; urb->dev = ctx->subs->dev; /* we need to set this at each time */ - urb->iso_frame_desc[0].length = 4; - urb->iso_frame_desc[0].offset = 0; - cp[0] = subs->freqn; - cp[1] = subs->freqn >> 8; - cp[2] = subs->freqn >> 16; - cp[3] = subs->freqn >> 24; + for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) { + urb->iso_frame_desc[i].length = 4; + urb->iso_frame_desc[i].offset = offs; + cp[0] = subs->freqn; + cp[1] = subs->freqn >> 8; + cp[2] = subs->freqn >> 16; + cp[3] = subs->freqn >> 24; + } return 0; } @@ -410,11 +418,15 @@ static int prepare_playback_sync_urb(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *urb) { + int i, offs; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; + urb->number_of_packets = ctx->packets; urb->dev = ctx->subs->dev; /* we need to set this at each time */ - urb->iso_frame_desc[0].length = 3; - urb->iso_frame_desc[0].offset = 0; + for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) { + urb->iso_frame_desc[i].length = 3; + urb->iso_frame_desc[i].offset = offs; + } return 0; } @@ -428,11 +440,15 @@ static int prepare_playback_sync_urb_hs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *urb) { + int i, offs; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; + urb->number_of_packets = ctx->packets; urb->dev = ctx->subs->dev; /* we need to set this at each time */ - urb->iso_frame_desc[0].length = 4; - urb->iso_frame_desc[0].offset = 0; + for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) { + urb->iso_frame_desc[i].length = 4; + urb->iso_frame_desc[i].offset = offs; + } return 0; } @@ -446,17 +462,31 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *urb) { - unsigned int f; + int i; + unsigned int f, found; + unsigned char *cp = urb->transfer_buffer; unsigned long flags; - if (urb->iso_frame_desc[0].status == 0 && - urb->iso_frame_desc[0].actual_length == 3) { - f = combine_triple((u8*)urb->transfer_buffer) << 2; - if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) { - spin_lock_irqsave(&subs->lock, flags); - subs->freqm = f; - spin_unlock_irqrestore(&subs->lock, flags); + found = 0; + for (i = 0; i < urb->number_of_packets; i++, cp += 4) { + if (urb->iso_frame_desc[i].status || + urb->iso_frame_desc[i].actual_length < 3) + continue; + f = combine_triple(cp) << 2; +#if 0 + if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) { + snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n", + f, f >> 14, (f & ((1 << 14) - 1) * 1000) / ((1 << 14) - 1), + subs->freqn, subs->freqn >> 14, (subs->freqn & ((1 << 14) - 1) * 1000) / ((1 << 14) - 1)); + continue; } +#endif + found = f; + } + if (found) { + spin_lock_irqsave(&subs->lock, flags); + subs->freqm = found; + spin_unlock_irqrestore(&subs->lock, flags); } return 0; @@ -472,17 +502,22 @@ static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *urb) { - unsigned int f; + int i; + unsigned int found; + unsigned char *cp = urb->transfer_buffer; unsigned long flags; - if (urb->iso_frame_desc[0].status == 0 && - urb->iso_frame_desc[0].actual_length == 4) { - f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; - if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) { - spin_lock_irqsave(&subs->lock, flags); - subs->freqm = f; - spin_unlock_irqrestore(&subs->lock, flags); - } + found = 0; + for (i = 0; i < urb->number_of_packets; i++, cp += 4) { + if (urb->iso_frame_desc[i].status || + urb->iso_frame_desc[i].actual_length < 4) + continue; + found = combine_quad(cp) & 0x0fffffff; + } + if (found) { + spin_lock_irqsave(&subs->lock, flags); + subs->freqm = found; + spin_unlock_irqrestore(&subs->lock, flags); } return 0; @@ -565,8 +600,6 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, /* set the buffer pointer */ urb->transfer_buffer = runtime->dma_area + subs->hwptr * stride; subs->hwptr += offs; - if (subs->hwptr == runtime->buffer_size) - subs->hwptr = 0; } spin_unlock_irqrestore(&subs->lock, flags); urb->transfer_buffer_length = offs * stride; @@ -1006,19 +1039,22 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by snd_urb_ctx_t *u = &subs->syncurb[i]; u->index = i; u->subs = subs; - u->packets = 1; - u->urb = usb_alloc_urb(1, GFP_KERNEL); + u->packets = nrpacks; + u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); if (! u->urb) { release_substream_urbs(subs, 0); return -ENOMEM; } - u->urb->transfer_buffer = subs->syncbuf + i * 4; - u->urb->transfer_buffer_length = 4; + u->urb->transfer_buffer = subs->syncbuf + i * nrpacks * 4; + u->urb->transfer_buffer_length = nrpacks * 4; u->urb->dev = subs->dev; u->urb->pipe = subs->syncpipe; u->urb->transfer_flags = URB_ISO_ASAP; - u->urb->number_of_packets = 1; - u->urb->interval = 1 << subs->syncinterval; + u->urb->number_of_packets = u->packets; + if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) + u->urb->interval = 8; + else + u->urb->interval = 1; u->urb->context = u; u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb); } @@ -1236,17 +1272,7 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt) subs->syncpipe = usb_rcvisocpipe(dev, ep); else subs->syncpipe = usb_sndisocpipe(dev, ep); - if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && - get_endpoint(alts, 1)->bRefresh >= 1 && - get_endpoint(alts, 1)->bRefresh <= 9) - subs->syncinterval = get_endpoint(alts, 1)->bRefresh; - else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) - subs->syncinterval = 1; - else if (get_endpoint(alts, 1)->bInterval >= 1 && - get_endpoint(alts, 1)->bInterval <= 16) - subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1; - else - subs->syncinterval = 3; + subs->syncinterval = get_endpoint(alts, 1)->bRefresh; } /* always fill max packet size */ @@ -1964,11 +1990,10 @@ static void proc_dump_substream_status(snd_usb_substream_t *subs, snd_info_buffe snd_iprintf(buffer, "%d ", subs->dataurb[i].packets); snd_iprintf(buffer, "]\n"); snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize); - snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", + snd_iprintf(buffer, " Momentary freq = %u Hz\n", snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ? get_full_speed_hz(subs->freqm) - : get_high_speed_hz(subs->freqm), - subs->freqm >> 16, subs->freqm & 0xffff); + : get_high_speed_hz(subs->freqm)); } else { snd_iprintf(buffer, " Status: Stop\n"); } @@ -2158,15 +2183,17 @@ static int add_audio_endpoint(snd_usb_audio_t *chip, int stream, struct audiofor /* * check if the device uses big-endian samples */ -static int is_big_endian_format(snd_usb_audio_t *chip, struct audioformat *fp) +static int is_big_endian_format(struct usb_device *dev, struct audioformat *fp) { - switch (chip->usb_id) { - case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ - if (fp->endpoint & USB_DIR_IN) + /* M-Audio */ + if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763) { + /* Quattro: captured data only */ + if (le16_to_cpu(dev->descriptor.idProduct) == 0x2001 && + fp->endpoint & USB_DIR_IN) + return 1; + /* Audiophile USB */ + if (le16_to_cpu(dev->descriptor.idProduct) == 0x2003) return 1; - break; - case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ - return 1; } return 0; } @@ -2180,7 +2207,7 @@ static int is_big_endian_format(snd_usb_audio_t *chip, struct audioformat *fp) * @format: the format tag (wFormatTag) * @fmt: the format type descriptor */ -static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat *fp, +static int parse_audio_format_i_type(struct usb_device *dev, struct audioformat *fp, int format, unsigned char *fmt) { int pcm_format; @@ -2193,12 +2220,12 @@ static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat * switch (format) { case 0: /* some devices don't define this correctly... */ snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", - chip->dev->devnum, fp->iface, fp->altsetting); + dev->devnum, fp->iface, fp->altsetting); /* fall-through */ case USB_AUDIO_FORMAT_PCM: if (sample_width > sample_bytes * 8) { snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", - chip->dev->devnum, fp->iface, fp->altsetting, + dev->devnum, fp->iface, fp->altsetting, sample_width, sample_bytes); } /* check the format byte size */ @@ -2207,13 +2234,13 @@ static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat * pcm_format = SNDRV_PCM_FORMAT_S8; break; case 2: - if (is_big_endian_format(chip, fp)) + if (is_big_endian_format(dev, fp)) pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */ else pcm_format = SNDRV_PCM_FORMAT_S16_LE; break; case 3: - if (is_big_endian_format(chip, fp)) + if (is_big_endian_format(dev, fp)) pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */ else pcm_format = SNDRV_PCM_FORMAT_S24_3LE; @@ -2223,14 +2250,14 @@ static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat * break; default: snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n", - chip->dev->devnum, fp->iface, - fp->altsetting, sample_width, sample_bytes); + dev->devnum, fp->iface, fp->altsetting, sample_width, sample_bytes); break; } break; case USB_AUDIO_FORMAT_PCM8: /* Dallas DS4201 workaround */ - if (chip->usb_id == USB_ID(0x04fa, 0x4201)) + if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa && + le16_to_cpu(dev->descriptor.idProduct) == 0x4201) pcm_format = SNDRV_PCM_FORMAT_S8; else pcm_format = SNDRV_PCM_FORMAT_U8; @@ -2246,7 +2273,7 @@ static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat * break; default: snd_printk(KERN_INFO "%d:%u:%d : unsupported format type %d\n", - chip->dev->devnum, fp->iface, fp->altsetting, format); + dev->devnum, fp->iface, fp->altsetting, format); break; } return pcm_format; @@ -2263,13 +2290,13 @@ static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat * * @offset: the start offset of descriptor pointing the rate type * (7 for type I and II, 8 for type II) */ -static int parse_audio_format_rates(snd_usb_audio_t *chip, struct audioformat *fp, +static int parse_audio_format_rates(struct usb_device *dev, struct audioformat *fp, unsigned char *fmt, int offset) { int nr_rates = fmt[offset]; if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", - chip->dev->devnum, fp->iface, fp->altsetting); + dev->devnum, fp->iface, fp->altsetting); return -1; } @@ -2316,7 +2343,7 @@ static int parse_audio_format_rates(snd_usb_audio_t *chip, struct audioformat *f /* * parse the format type I and III descriptors */ -static int parse_audio_format_i(snd_usb_audio_t *chip, struct audioformat *fp, +static int parse_audio_format_i(struct usb_device *dev, struct audioformat *fp, int format, unsigned char *fmt) { int pcm_format; @@ -2328,7 +2355,7 @@ static int parse_audio_format_i(snd_usb_audio_t *chip, struct audioformat *fp, */ pcm_format = SNDRV_PCM_FORMAT_S16_LE; } else { - pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); + pcm_format = parse_audio_format_i_type(dev, fp, format, fmt); if (pcm_format < 0) return -1; } @@ -2336,16 +2363,16 @@ static int parse_audio_format_i(snd_usb_audio_t *chip, struct audioformat *fp, fp->channels = fmt[4]; if (fp->channels < 1) { snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", - chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); + dev->devnum, fp->iface, fp->altsetting, fp->channels); return -1; } - return parse_audio_format_rates(chip, fp, fmt, 7); + return parse_audio_format_rates(dev, fp, fmt, 7); } /* * prase the format type II descriptor */ -static int parse_audio_format_ii(snd_usb_audio_t *chip, struct audioformat *fp, +static int parse_audio_format_ii(struct usb_device *dev, struct audioformat *fp, int format, unsigned char *fmt) { int brate, framesize; @@ -2360,7 +2387,7 @@ static int parse_audio_format_ii(snd_usb_audio_t *chip, struct audioformat *fp, break; default: snd_printd(KERN_INFO "%d:%u:%d : unknown format tag 0x%x is detected. processed as MPEG.\n", - chip->dev->devnum, fp->iface, fp->altsetting, format); + dev->devnum, fp->iface, fp->altsetting, format); fp->format = SNDRV_PCM_FORMAT_MPEG; break; } @@ -2369,10 +2396,10 @@ static int parse_audio_format_ii(snd_usb_audio_t *chip, struct audioformat *fp, framesize = combine_word(&fmt[6]); /* fmt[6,7]: wSamplesPerFrame */ snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize); fp->frame_size = framesize; - return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */ + return parse_audio_format_rates(dev, fp, fmt, 8); /* fmt[8..] sample rates */ } -static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp, +static int parse_audio_format(struct usb_device *dev, struct audioformat *fp, int format, unsigned char *fmt, int stream) { int err; @@ -2380,30 +2407,29 @@ static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp, switch (fmt[3]) { case USB_FORMAT_TYPE_I: case USB_FORMAT_TYPE_III: - err = parse_audio_format_i(chip, fp, format, fmt); + err = parse_audio_format_i(dev, fp, format, fmt); break; case USB_FORMAT_TYPE_II: - err = parse_audio_format_ii(chip, fp, format, fmt); + err = parse_audio_format_ii(dev, fp, format, fmt); break; default: snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", - chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); + dev->devnum, fp->iface, fp->altsetting, fmt[3]); return -1; } fp->fmt_type = fmt[3]; if (err < 0) return err; #if 1 - /* FIXME: temporary hack for extigy/audigy 2 nx */ + /* FIXME: temporary hack for extigy */ /* extigy apparently supports sample rates other than 48k * but not in ordinary way. so we enable only 48k atm. */ - if (chip->usb_id == USB_ID(0x041e, 0x3000) || - chip->usb_id == USB_ID(0x041e, 0x3020)) { + if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e && + le16_to_cpu(dev->descriptor.idProduct) == 0x3000) { if (fmt[3] == USB_FORMAT_TYPE_I && stream == SNDRV_PCM_STREAM_PLAYBACK && - fp->rates != SNDRV_PCM_RATE_48000 && - fp->rates != SNDRV_PCM_RATE_96000) + fp->rates != SNDRV_PCM_RATE_48000) return -1; /* use 48k only */ } #endif @@ -2502,35 +2528,40 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no) /* some quirks for attributes here */ - switch (chip->usb_id) { - case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ + /* workaround for AudioTrak Optoplay */ + if (le16_to_cpu(dev->descriptor.idVendor) == 0x0a92 && + le16_to_cpu(dev->descriptor.idProduct) == 0x0053) { /* Optoplay sets the sample rate attribute although * it seems not supporting it in fact. */ fp->attributes &= ~EP_CS_ATTR_SAMPLE_RATE; - break; - case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ - case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ + } + + /* workaround for M-Audio Audiophile USB */ + if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763 && + le16_to_cpu(dev->descriptor.idProduct) == 0x2003) { /* doesn't set the sample rate attribute, but supports it */ fp->attributes |= EP_CS_ATTR_SAMPLE_RATE; - break; - case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ - case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is - an older model 77d:223) */ + } + /* * plantronics headset and Griffin iMic have set adaptive-in * although it's really not... */ + if ((le16_to_cpu(dev->descriptor.idVendor) == 0x047f && + le16_to_cpu(dev->descriptor.idProduct) == 0x0ca1) || + /* Griffin iMic (note that there is an older model 77d:223) */ + (le16_to_cpu(dev->descriptor.idVendor) == 0x077d && + le16_to_cpu(dev->descriptor.idProduct) == 0x07af)) { fp->ep_attr &= ~EP_ATTR_MASK; if (stream == SNDRV_PCM_STREAM_PLAYBACK) fp->ep_attr |= EP_ATTR_ADAPTIVE; else fp->ep_attr |= EP_ATTR_SYNC; - break; } /* ok, let's parse further... */ - if (parse_audio_format(chip, fp, format, fmt, stream) < 0) { + if (parse_audio_format(dev, fp, format, fmt, stream) < 0) { kfree(fp->rate_table); kfree(fp); continue; @@ -2556,7 +2587,7 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no) * disconnect streams * called from snd_usb_audio_disconnect() */ -static void snd_usb_stream_disconnect(struct list_head *head) +static void snd_usb_stream_disconnect(struct list_head *head, struct usb_driver *driver) { int idx; snd_usb_stream_t *as; @@ -2765,7 +2796,7 @@ static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = &ua25_ep }; - if (chip->usb_id == USB_ID(0x0582, 0x002b)) + if (le16_to_cpu(chip->dev->descriptor.idProduct) == 0x002b) return snd_usb_create_midi_interface(chip, iface, &ua700_quirk); else @@ -2928,25 +2959,6 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac return 0; } -static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) -{ -#if 0 - /* TODO: enable this when high speed synchronization actually works */ - u8 buf = 1; - - snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, - 0, 0, &buf, 1, 1000); - if (buf == 0) { - snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, - 1, 2000, NULL, 0, 1000); - return -ENODEV; - } -#endif - return 0; -} - /* * audio-interface quirks @@ -3003,8 +3015,8 @@ static void proc_audio_usbid_read(snd_info_entry_t *entry, snd_info_buffer_t *bu snd_usb_audio_t *chip = entry->private_data; if (! chip->shutdown) snd_iprintf(buffer, "%04x:%04x\n", - USB_ID_VENDOR(chip->usb_id), - USB_ID_PRODUCT(chip->usb_id)); + le16_to_cpu(chip->dev->descriptor.idVendor), + le16_to_cpu(chip->dev->descriptor.idProduct)); } static void snd_usb_audio_create_proc(snd_usb_audio_t *chip) @@ -3074,11 +3086,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, chip->index = idx; chip->dev = dev; chip->card = card; - chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); INIT_LIST_HEAD(&chip->pcm_list); INIT_LIST_HEAD(&chip->midi_list); - INIT_LIST_HEAD(&chip->mixer_list); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_usb_audio_free(chip); @@ -3088,7 +3097,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, strcpy(card->driver, "USB-Audio"); sprintf(component, "USB%04x:%04x", - USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); snd_component_add(card, component); /* retrieve the device string as shortname */ @@ -3100,8 +3110,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, card->shortname, sizeof(card->shortname)) <= 0) { /* no name available from anywhere, so use ID */ sprintf(card->shortname, "USB Device %#04x:%#04x", - USB_ID_VENDOR(chip->usb_id), - USB_ID_PRODUCT(chip->usb_id)); + le16_to_cpu(dev->descriptor.idVendor), + le16_to_cpu(dev->descriptor.idProduct)); } } @@ -3132,6 +3142,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, snd_usb_audio_create_proc(chip); + snd_card_set_dev(card, &dev->dev); + *rchip = chip; return 0; } @@ -3157,28 +3169,21 @@ static void *snd_usb_audio_probe(struct usb_device *dev, snd_usb_audio_t *chip; struct usb_host_interface *alts; int ifnum; - u32 id; alts = &intf->altsetting[0]; ifnum = get_iface_desc(alts)->bInterfaceNumber; - id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), - le16_to_cpu(dev->descriptor.idProduct)); if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum) goto __err_val; /* SB Extigy needs special boot-up sequence */ /* if more models come, this will go to the quirk list. */ - if (id == USB_ID(0x041e, 0x3000)) { + if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e && + le16_to_cpu(dev->descriptor.idProduct) == 0x3000) { if (snd_usb_extigy_boot_quirk(dev, intf) < 0) goto __err_val; config = dev->actconfig; } - /* SB Audigy 2 NX needs its own boot-up magic, too */ - if (id == USB_ID(0x041e, 0x3020)) { - if (snd_usb_audigy2nx_boot_quirk(dev) < 0) - goto __err_val; - } /* * found a config. now register to ALSA @@ -3208,12 +3213,11 @@ static void *snd_usb_audio_probe(struct usb_device *dev, } for (i = 0; i < SNDRV_CARDS; i++) if (enable[i] && ! usb_chip[i] && - (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && - (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { + (vid[i] == -1 || vid[i] == le16_to_cpu(dev->descriptor.idVendor)) && + (pid[i] == -1 || pid[i] == le16_to_cpu(dev->descriptor.idProduct))) { if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) { goto __error; } - snd_card_set_dev(chip->card, &intf->dev); break; } if (! chip) { @@ -3277,19 +3281,15 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) snd_card_disconnect(card); /* release the pcm resources */ list_for_each(p, &chip->pcm_list) { - snd_usb_stream_disconnect(p); + snd_usb_stream_disconnect(p, &usb_audio_driver); } /* release the midi resources */ list_for_each(p, &chip->midi_list) { - snd_usbmidi_disconnect(p); - } - /* release mixer resources */ - list_for_each(p, &chip->mixer_list) { - snd_usb_mixer_disconnect(p); + snd_usbmidi_disconnect(p, &usb_audio_driver); } usb_chip[chip->index] = NULL; up(®ister_mutex); - snd_card_free(card); + snd_card_free_in_thread(card); } else { up(®ister_mutex); } diff --git a/trunk/sound/usb/usbaudio.h b/trunk/sound/usb/usbaudio.h index aedb42aaa749..eecbf19fcb6f 100644 --- a/trunk/sound/usb/usbaudio.h +++ b/trunk/sound/usb/usbaudio.h @@ -118,11 +118,6 @@ /* maximum number of endpoints per interface */ #define MIDI_MAX_ENDPOINTS 2 -/* handling of USB vendor/product ID pairs as 32-bit numbers */ -#define USB_ID(vendor, product) (((vendor) << 16) | (product)) -#define USB_ID_VENDOR(id) ((id) >> 16) -#define USB_ID_PRODUCT(id) ((u16)(id)) - /* */ @@ -132,7 +127,6 @@ struct snd_usb_audio { int index; struct usb_device *dev; snd_card_t *card; - u32 usb_id; int shutdown; int num_interfaces; @@ -142,7 +136,7 @@ struct snd_usb_audio { struct list_head midi_list; /* list of midi interfaces */ int next_midi_device; - struct list_head mixer_list; /* list of mixer interfaces */ + unsigned int ignore_ctl_error; /* for mixer */ }; /* @@ -225,12 +219,11 @@ void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsub int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout); int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif); -void snd_usb_mixer_disconnect(struct list_head *p); int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk); void snd_usbmidi_input_stop(struct list_head* p); void snd_usbmidi_input_start(struct list_head* p); -void snd_usbmidi_disconnect(struct list_head *p); +void snd_usbmidi_disconnect(struct list_head *p, struct usb_driver *driver); /* * retrieve usb_interface descriptor from the host interface diff --git a/trunk/sound/usb/usbmidi.c b/trunk/sound/usb/usbmidi.c index bee70068dce0..5d32857ff955 100644 --- a/trunk/sound/usb/usbmidi.c +++ b/trunk/sound/usb/usbmidi.c @@ -912,7 +912,7 @@ static void snd_usbmidi_free(snd_usb_midi_t* umidi) /* * Unlinks all URBs (must be done before the usb_device is deleted). */ -void snd_usbmidi_disconnect(struct list_head* p) +void snd_usbmidi_disconnect(struct list_head* p, struct usb_driver *driver) { snd_usb_midi_t* umidi; int i; @@ -955,87 +955,88 @@ static snd_rawmidi_substream_t* snd_usbmidi_find_substream(snd_usb_midi_t* umidi * such as internal control or synthesizer ports. */ static struct { - u32 id; + __u16 vendor; + __u16 product; int port; const char *name_format; } snd_usbmidi_port_names[] = { /* Roland UA-100 */ - { USB_ID(0x0582, 0x0000), 2, "%s Control" }, + {0x0582, 0x0000, 2, "%s Control"}, /* Roland SC-8850 */ - { USB_ID(0x0582, 0x0003), 0, "%s Part A" }, - { USB_ID(0x0582, 0x0003), 1, "%s Part B" }, - { USB_ID(0x0582, 0x0003), 2, "%s Part C" }, - { USB_ID(0x0582, 0x0003), 3, "%s Part D" }, - { USB_ID(0x0582, 0x0003), 4, "%s MIDI 1" }, - { USB_ID(0x0582, 0x0003), 5, "%s MIDI 2" }, + {0x0582, 0x0003, 0, "%s Part A"}, + {0x0582, 0x0003, 1, "%s Part B"}, + {0x0582, 0x0003, 2, "%s Part C"}, + {0x0582, 0x0003, 3, "%s Part D"}, + {0x0582, 0x0003, 4, "%s MIDI 1"}, + {0x0582, 0x0003, 5, "%s MIDI 2"}, /* Roland U-8 */ - { USB_ID(0x0582, 0x0004), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x0004), 1, "%s Control" }, + {0x0582, 0x0004, 0, "%s MIDI"}, + {0x0582, 0x0004, 1, "%s Control"}, /* Roland SC-8820 */ - { USB_ID(0x0582, 0x0007), 0, "%s Part A" }, - { USB_ID(0x0582, 0x0007), 1, "%s Part B" }, - { USB_ID(0x0582, 0x0007), 2, "%s MIDI" }, + {0x0582, 0x0007, 0, "%s Part A"}, + {0x0582, 0x0007, 1, "%s Part B"}, + {0x0582, 0x0007, 2, "%s MIDI"}, /* Roland SK-500 */ - { USB_ID(0x0582, 0x000b), 0, "%s Part A" }, - { USB_ID(0x0582, 0x000b), 1, "%s Part B" }, - { USB_ID(0x0582, 0x000b), 2, "%s MIDI" }, + {0x0582, 0x000b, 0, "%s Part A"}, + {0x0582, 0x000b, 1, "%s Part B"}, + {0x0582, 0x000b, 2, "%s MIDI"}, /* Roland SC-D70 */ - { USB_ID(0x0582, 0x000c), 0, "%s Part A" }, - { USB_ID(0x0582, 0x000c), 1, "%s Part B" }, - { USB_ID(0x0582, 0x000c), 2, "%s MIDI" }, + {0x0582, 0x000c, 0, "%s Part A"}, + {0x0582, 0x000c, 1, "%s Part B"}, + {0x0582, 0x000c, 2, "%s MIDI"}, /* Edirol UM-880 */ - { USB_ID(0x0582, 0x0014), 8, "%s Control" }, + {0x0582, 0x0014, 8, "%s Control"}, /* Edirol SD-90 */ - { USB_ID(0x0582, 0x0016), 0, "%s Part A" }, - { USB_ID(0x0582, 0x0016), 1, "%s Part B" }, - { USB_ID(0x0582, 0x0016), 2, "%s MIDI 1" }, - { USB_ID(0x0582, 0x0016), 3, "%s MIDI 2" }, + {0x0582, 0x0016, 0, "%s Part A"}, + {0x0582, 0x0016, 1, "%s Part B"}, + {0x0582, 0x0016, 2, "%s MIDI 1"}, + {0x0582, 0x0016, 3, "%s MIDI 2"}, /* Edirol UM-550 */ - { USB_ID(0x0582, 0x0023), 5, "%s Control" }, + {0x0582, 0x0023, 5, "%s Control"}, /* Edirol SD-20 */ - { USB_ID(0x0582, 0x0027), 0, "%s Part A" }, - { USB_ID(0x0582, 0x0027), 1, "%s Part B" }, - { USB_ID(0x0582, 0x0027), 2, "%s MIDI" }, + {0x0582, 0x0027, 0, "%s Part A"}, + {0x0582, 0x0027, 1, "%s Part B"}, + {0x0582, 0x0027, 2, "%s MIDI"}, /* Edirol SD-80 */ - { USB_ID(0x0582, 0x0029), 0, "%s Part A" }, - { USB_ID(0x0582, 0x0029), 1, "%s Part B" }, - { USB_ID(0x0582, 0x0029), 2, "%s MIDI 1" }, - { USB_ID(0x0582, 0x0029), 3, "%s MIDI 2" }, + {0x0582, 0x0029, 0, "%s Part A"}, + {0x0582, 0x0029, 1, "%s Part B"}, + {0x0582, 0x0029, 2, "%s MIDI 1"}, + {0x0582, 0x0029, 3, "%s MIDI 2"}, /* Edirol UA-700 */ - { USB_ID(0x0582, 0x002b), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x002b), 1, "%s Control" }, + {0x0582, 0x002b, 0, "%s MIDI"}, + {0x0582, 0x002b, 1, "%s Control"}, /* Roland VariOS */ - { USB_ID(0x0582, 0x002f), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x002f), 1, "%s External MIDI" }, - { USB_ID(0x0582, 0x002f), 2, "%s Sync" }, + {0x0582, 0x002f, 0, "%s MIDI"}, + {0x0582, 0x002f, 1, "%s External MIDI"}, + {0x0582, 0x002f, 2, "%s Sync"}, /* Edirol PCR */ - { USB_ID(0x0582, 0x0033), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x0033), 1, "%s 1" }, - { USB_ID(0x0582, 0x0033), 2, "%s 2" }, + {0x0582, 0x0033, 0, "%s MIDI"}, + {0x0582, 0x0033, 1, "%s 1"}, + {0x0582, 0x0033, 2, "%s 2"}, /* BOSS GS-10 */ - { USB_ID(0x0582, 0x003b), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x003b), 1, "%s Control" }, + {0x0582, 0x003b, 0, "%s MIDI"}, + {0x0582, 0x003b, 1, "%s Control"}, /* Edirol UA-1000 */ - { USB_ID(0x0582, 0x0044), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x0044), 1, "%s Control" }, + {0x0582, 0x0044, 0, "%s MIDI"}, + {0x0582, 0x0044, 1, "%s Control"}, /* Edirol UR-80 */ - { USB_ID(0x0582, 0x0048), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x0048), 1, "%s 1" }, - { USB_ID(0x0582, 0x0048), 2, "%s 2" }, + {0x0582, 0x0048, 0, "%s MIDI"}, + {0x0582, 0x0048, 1, "%s 1"}, + {0x0582, 0x0048, 2, "%s 2"}, /* Edirol PCR-A */ - { USB_ID(0x0582, 0x004d), 0, "%s MIDI" }, - { USB_ID(0x0582, 0x004d), 1, "%s 1" }, - { USB_ID(0x0582, 0x004d), 2, "%s 2" }, + {0x0582, 0x004d, 0, "%s MIDI"}, + {0x0582, 0x004d, 1, "%s 1"}, + {0x0582, 0x004d, 2, "%s 2"}, /* M-Audio MidiSport 8x8 */ - { USB_ID(0x0763, 0x1031), 8, "%s Control" }, - { USB_ID(0x0763, 0x1033), 8, "%s Control" }, + {0x0763, 0x1031, 8, "%s Control"}, + {0x0763, 0x1033, 8, "%s Control"}, /* MOTU Fastlane */ - { USB_ID(0x07fd, 0x0001), 0, "%s MIDI A" }, - { USB_ID(0x07fd, 0x0001), 1, "%s MIDI B" }, + {0x07fd, 0x0001, 0, "%s MIDI A"}, + {0x07fd, 0x0001, 1, "%s MIDI B"}, /* Emagic Unitor8/AMT8/MT4 */ - { USB_ID(0x086a, 0x0001), 8, "%s Broadcast" }, - { USB_ID(0x086a, 0x0002), 8, "%s Broadcast" }, - { USB_ID(0x086a, 0x0003), 4, "%s Broadcast" }, + {0x086a, 0x0001, 8, "%s Broadcast"}, + {0x086a, 0x0002, 8, "%s Broadcast"}, + {0x086a, 0x0003, 4, "%s Broadcast"}, }; static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi, @@ -1043,6 +1044,7 @@ static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi, snd_rawmidi_substream_t** rsubstream) { int i; + __u16 vendor, product; const char *name_format; snd_rawmidi_substream_t* substream = snd_usbmidi_find_substream(umidi, stream, number); @@ -1053,8 +1055,11 @@ static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi, /* TODO: read port name from jack descriptor */ name_format = "%s MIDI %d"; + vendor = le16_to_cpu(umidi->chip->dev->descriptor.idVendor); + product = le16_to_cpu(umidi->chip->dev->descriptor.idProduct); for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) { - if (snd_usbmidi_port_names[i].id == umidi->chip->usb_id && + if (snd_usbmidi_port_names[i].vendor == vendor && + snd_usbmidi_port_names[i].product == product && snd_usbmidi_port_names[i].port == number) { name_format = snd_usbmidi_port_names[i].name_format; break; @@ -1221,12 +1226,9 @@ static int snd_usbmidi_detect_endpoints(snd_usb_midi_t* umidi, struct usb_endpoint_descriptor* epd; int i, out_eps = 0, in_eps = 0; - if (USB_ID_VENDOR(umidi->chip->usb_id) == 0x0582) + if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) == 0x0582) snd_usbmidi_switch_roland_altsetting(umidi); - if (endpoint[0].out_ep || endpoint[0].in_ep) - return 0; - intf = umidi->iface; if (!intf || intf->num_altsetting < 1) return -ENOENT; diff --git a/trunk/sound/usb/usbmixer.c b/trunk/sound/usb/usbmixer.c index 83ba665e5c6e..5f1906915aa6 100644 --- a/trunk/sound/usb/usbmixer.c +++ b/trunk/sound/usb/usbmixer.c @@ -35,11 +35,10 @@ #include #include #include -#include -#include #include "usbaudio.h" + /* */ @@ -51,31 +50,6 @@ typedef struct usb_audio_term usb_audio_term_t; typedef struct usb_mixer_elem_info usb_mixer_elem_info_t; -struct usb_mixer_interface { - snd_usb_audio_t *chip; - unsigned int ctrlif; - struct list_head list; - unsigned int ignore_ctl_error; - struct urb *urb; - usb_mixer_elem_info_t **id_elems; /* array[256], indexed by unit id */ - - /* Sound Blaster remote control stuff */ - enum { - RC_NONE, - RC_EXTIGY, - RC_AUDIGY2NX, - } rc_type; - unsigned long rc_hwdep_open; - u32 rc_code; - wait_queue_head_t rc_waitq; - struct urb *rc_urb; - struct usb_ctrlrequest *rc_setup_packet; - u8 rc_buffer[6]; - - u8 audigy2nx_leds[3]; -}; - - struct usb_audio_term { int id; int type; @@ -88,26 +62,26 @@ struct usbmix_name_map; struct usb_mixer_build { snd_usb_audio_t *chip; - struct usb_mixer_interface *mixer; unsigned char *buffer; unsigned int buflen; - DECLARE_BITMAP(unitbitmap, 256); + unsigned int ctrlif; + unsigned short vendor; + unsigned short product; + DECLARE_BITMAP(unitbitmap, 32*32); usb_audio_term_t oterm; const struct usbmix_name_map *map; - const struct usbmix_selector_map *selector_map; }; struct usb_mixer_elem_info { - struct usb_mixer_interface *mixer; - usb_mixer_elem_info_t *next_id_elem; /* list of controls with same id */ - snd_ctl_elem_id_t *elem_id; + snd_usb_audio_t *chip; + unsigned int ctrlif; unsigned int id; unsigned int control; /* CS or ICN (high byte) */ unsigned int cmask; /* channel mask bitmap: 0 = master */ int channels; int val_type; int min, max, res; - u8 initialized; + unsigned int initialized: 1; }; @@ -213,21 +187,6 @@ static int check_ignored_ctl(mixer_build_t *state, int unitid, int control) return 0; } -/* get the mapped selector source name */ -static int check_mapped_selector_name(mixer_build_t *state, int unitid, - int index, char *buf, int buflen) -{ - const struct usbmix_selector_map *p; - - if (! state->selector_map) - return 0; - for (p = state->selector_map; p->id; p++) { - if (p->id == unitid && index < p->count) - return strlcpy(buf, p->names[index], buflen); - } - return 0; -} - /* * find an audio control unit with the given unit id */ @@ -342,18 +301,16 @@ static int get_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, i int timeout = 10; while (timeout-- > 0) { - if (snd_usb_ctl_msg(cval->mixer->chip->dev, - usb_rcvctrlpipe(cval->mixer->chip->dev, 0), + if (snd_usb_ctl_msg(cval->chip->dev, usb_rcvctrlpipe(cval->chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, cval->mixer->ctrlif | (cval->id << 8), + validx, cval->ctrlif | (cval->id << 8), buf, val_len, 100) >= 0) { *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); return 0; } } - snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", - request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type); + snd_printdd(KERN_ERR "cannot get ctl value: req = 0x%x, wValue = 0x%x, wIndex = 0x%x, type = %d\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type); return -EINVAL; } @@ -382,15 +339,13 @@ static int set_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, i buf[0] = value_set & 0xff; buf[1] = (value_set >> 8) & 0xff; while (timeout -- > 0) - if (snd_usb_ctl_msg(cval->mixer->chip->dev, - usb_sndctrlpipe(cval->mixer->chip->dev, 0), + if (snd_usb_ctl_msg(cval->chip->dev, usb_sndctrlpipe(cval->chip->dev, 0), request, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - validx, cval->mixer->ctrlif | (cval->id << 8), + validx, cval->ctrlif | (cval->id << 8), buf, val_len, 100) >= 0) return 0; - snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", - request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]); + snd_printdd(KERN_ERR "cannot set ctl value: req = 0x%x, wValue = 0x%x, wIndex = 0x%x, type = %d, data = 0x%x/0x%x\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]); return -EINVAL; } @@ -430,22 +385,16 @@ static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_ou * if failed, give up and free the control instance. */ -static int add_control_to_empty(mixer_build_t *state, snd_kcontrol_t *kctl) +static int add_control_to_empty(snd_card_t *card, snd_kcontrol_t *kctl) { - usb_mixer_elem_info_t *cval = kctl->private_data; int err; - - while (snd_ctl_find_id(state->chip->card, &kctl->id)) + while (snd_ctl_find_id(card, &kctl->id)) kctl->id.index++; - if ((err = snd_ctl_add(state->chip->card, kctl)) < 0) { + if ((err = snd_ctl_add(card, kctl)) < 0) { snd_printd(KERN_ERR "cannot add control (err = %d)\n", err); snd_ctl_free_one(kctl); - return err; } - cval->elem_id = &kctl->id; - cval->next_id_elem = state->mixer->id_elems[cval->id]; - state->mixer->id_elems[cval->id] = cval; - return 0; + return err; } @@ -659,8 +608,7 @@ static int get_min_max(usb_mixer_elem_info_t *cval, int default_min) } if (get_ctl_value(cval, GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || get_ctl_value(cval, GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { - snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", - cval->id, cval->mixer->ctrlif, cval->control, cval->id); + snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", cval->id, cval->ctrlif, cval->control, cval->id); return -EINVAL; } if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { @@ -720,7 +668,7 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t if (cval->cmask & (1 << c)) { err = get_cur_mix_value(cval, c + 1, &val); if (err < 0) { - if (cval->mixer->ignore_ctl_error) { + if (cval->chip->ignore_ctl_error) { ucontrol->value.integer.value[0] = cval->min; return 0; } @@ -736,7 +684,7 @@ static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t /* master channel */ err = get_cur_mix_value(cval, 0, &val); if (err < 0) { - if (cval->mixer->ignore_ctl_error) { + if (cval->chip->ignore_ctl_error) { ucontrol->value.integer.value[0] = cval->min; return 0; } @@ -762,7 +710,7 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t if (cval->cmask & (1 << c)) { err = get_cur_mix_value(cval, c + 1, &oval); if (err < 0) { - if (cval->mixer->ignore_ctl_error) + if (cval->chip->ignore_ctl_error) return 0; return err; } @@ -779,7 +727,7 @@ static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t } else { /* master channel */ err = get_cur_mix_value(cval, 0, &oval); - if (err < 0 && cval->mixer->ignore_ctl_error) + if (err < 0 && cval->chip->ignore_ctl_error) return 0; if (err < 0) return err; @@ -831,7 +779,8 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc, snd_printk(KERN_ERR "cannot malloc kcontrol\n"); return; } - cval->mixer = state->mixer; + cval->chip = state->chip; + cval->ctrlif = state->ctrlif; cval->id = unitid; cval->control = control; cval->cmask = ctl_mask; @@ -906,21 +855,16 @@ static void build_feature_ctl(mixer_build_t *state, unsigned char *desc, /* note that detection between firmware 2.1.1.7 (N101) and later 2.1.1.21 */ /* is not very clear from datasheets */ /* I hope that the min value is -15360 for newer firmware --jk */ - switch (state->chip->usb_id) { - case USB_ID(0x0471, 0x0101): - case USB_ID(0x0471, 0x0104): - case USB_ID(0x0471, 0x0105): - case USB_ID(0x0672, 0x1041): - if (!strcmp(kctl->id.name, "PCM Playback Volume") && - cval->min == -15616) { - snd_printk("using volume control quirk for the UDA1321/N101 chip\n"); - cval->max = -256; - } + if (((state->vendor == 0x471 && (state->product == 0x104 || state->product == 0x105 || state->product == 0x101)) || + (state->vendor == 0x672 && state->product == 0x1041)) && !strcmp(kctl->id.name, "PCM Playback Volume") && + cval->min == -15616) { + snd_printk("USB Audio: using volume control quirk for the UDA1321/N101 chip\n"); + cval->max = -256; } snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); - add_control_to_empty(state, kctl); + add_control_to_empty(state->chip->card, kctl); } @@ -1003,7 +947,8 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc, if (! cval) return; - cval->mixer = state->mixer; + cval->chip = state->chip; + cval->ctrlif = state->ctrlif; cval->id = unitid; cval->control = in_ch + 1; /* based on 1 */ cval->val_type = USB_MIXER_S16; @@ -1034,7 +979,7 @@ static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc, snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", cval->id, kctl->id.name, cval->channels, cval->min, cval->max); - add_control_to_empty(state, kctl); + add_control_to_empty(state->chip->card, kctl); } @@ -1097,7 +1042,7 @@ static int mixer_ctl_procunit_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t int err, val; err = get_cur_ctl_value(cval, cval->control << 8, &val); - if (err < 0 && cval->mixer->ignore_ctl_error) { + if (err < 0 && cval->chip->ignore_ctl_error) { ucontrol->value.integer.value[0] = cval->min; return 0; } @@ -1116,7 +1061,7 @@ static int mixer_ctl_procunit_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t err = get_cur_ctl_value(cval, cval->control << 8, &oval); if (err < 0) { - if (cval->mixer->ignore_ctl_error) + if (cval->chip->ignore_ctl_error) return 0; return err; } @@ -1234,6 +1179,9 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char } type = combine_word(&dsc[4]); + if (! type) + return 0; /* undefined? */ + for (info = list; info && info->type; info++) if (info->type == type) break; @@ -1251,7 +1199,8 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char snd_printk(KERN_ERR "cannot malloc kcontrol\n"); return -ENOMEM; } - cval->mixer = state->mixer; + cval->chip = state->chip; + cval->ctrlif = state->ctrlif; cval->id = unitid; cval->control = valinfo->control; cval->val_type = valinfo->val_type; @@ -1292,7 +1241,7 @@ static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n", cval->id, kctl->id.name, cval->channels, cval->min, cval->max); - if ((err = add_control_to_empty(state, kctl)) < 0) + if ((err = add_control_to_empty(state->chip->card, kctl)) < 0) return err; } return 0; @@ -1340,7 +1289,7 @@ static int mixer_ctl_selector_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t err = get_cur_ctl_value(cval, 0, &val); if (err < 0) { - if (cval->mixer->ignore_ctl_error) { + if (cval->chip->ignore_ctl_error) { ucontrol->value.enumerated.item[0] = 0; return 0; } @@ -1359,7 +1308,7 @@ static int mixer_ctl_selector_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t err = get_cur_ctl_value(cval, 0, &oval); if (err < 0) { - if (cval->mixer->ignore_ctl_error) + if (cval->chip->ignore_ctl_error) return 0; return err; } @@ -1437,7 +1386,8 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned snd_printk(KERN_ERR "cannot malloc kcontrol\n"); return -ENOMEM; } - cval->mixer = state->mixer; + cval->chip = state->chip; + cval->ctrlif = state->ctrlif; cval->id = unitid; cval->val_type = USB_MIXER_U8; cval->channels = 1; @@ -1465,9 +1415,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned kfree(cval); return -ENOMEM; } - len = check_mapped_selector_name(state, unitid, i, namelist[i], - MAX_ITEM_NAME_LEN); - if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0) + if (check_input_term(state, desc[5 + i], &iterm) >= 0) len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); if (! len) sprintf(namelist[i], "Input %d", i); @@ -1502,7 +1450,7 @@ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", cval->id, kctl->id.name, num_ins); - if ((err = add_control_to_empty(state, kctl)) < 0) + if ((err = add_control_to_empty(state->chip->card, kctl)) < 0) return err; return 0; @@ -1545,55 +1493,41 @@ static int parse_audio_unit(mixer_build_t *state, int unitid) } } -static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) -{ - kfree(mixer->id_elems); - if (mixer->urb) { - kfree(mixer->urb->transfer_buffer); - usb_free_urb(mixer->urb); - } - if (mixer->rc_urb) - usb_free_urb(mixer->rc_urb); - kfree(mixer->rc_setup_packet); - kfree(mixer); -} - -static int snd_usb_mixer_dev_free(snd_device_t *device) -{ - struct usb_mixer_interface *mixer = device->device_data; - snd_usb_mixer_free(mixer); - return 0; -} - /* * create mixer controls * * walk through all OUTPUT_TERMINAL descriptors to search for mixers */ -static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) +int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) { unsigned char *desc; mixer_build_t state; int err; const struct usbmix_ctl_map *map; - struct usb_host_interface *hostif; + struct usb_device_descriptor *dev = &chip->dev->descriptor; + struct usb_host_interface *hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; + + strcpy(chip->card->mixername, "USB Mixer"); - hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; memset(&state, 0, sizeof(state)); - state.chip = mixer->chip; - state.mixer = mixer; + state.chip = chip; state.buffer = hostif->extra; state.buflen = hostif->extralen; + state.ctrlif = ctrlif; + state.vendor = le16_to_cpu(dev->idVendor); + state.product = le16_to_cpu(dev->idProduct); /* check the mapping table */ - for (map = usbmix_ctl_maps; map->id; map++) { - if (map->id == state.chip->usb_id) { + for (map = usbmix_ctl_maps; map->vendor; map++) { + if (map->vendor == state.vendor && map->product == state.product) { state.map = map->map; - state.selector_map = map->selector_map; - mixer->ignore_ctl_error = map->ignore_ctl_error; + chip->ignore_ctl_error = map->ignore_ctl_error; break; } } +#ifdef IGNORE_CTL_ERROR + chip->ignore_ctl_error = 1; +#endif desc = NULL; while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) { @@ -1609,393 +1543,3 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) } return 0; } - -static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, - int unitid) -{ - usb_mixer_elem_info_t *info; - - for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) - snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, - info->elem_id); -} - -static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, - int unitid) -{ - if (mixer->rc_type == RC_NONE) - return; - /* unit ids specific to Extigy/Audigy 2 NX: */ - switch (unitid) { - case 0: /* remote control */ - mixer->rc_urb->dev = mixer->chip->dev; - usb_submit_urb(mixer->rc_urb, GFP_ATOMIC); - break; - case 4: /* digital in jack */ - case 7: /* line in jacks */ - case 19: /* speaker out jacks */ - case 20: /* headphones out jack */ - break; - default: - snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid); - break; - } -} - -static void snd_usb_mixer_status_complete(struct urb *urb, struct pt_regs *regs) -{ - struct usb_mixer_interface *mixer = urb->context; - - if (urb->status == 0) { - u8 *buf = urb->transfer_buffer; - int i; - - for (i = urb->actual_length; i >= 2; buf += 2, i -= 2) { - snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n", - buf[0], buf[1]); - /* ignore any notifications not from the control interface */ - if ((buf[0] & 0x0f) != 0) - continue; - if (!(buf[0] & 0x40)) - snd_usb_mixer_notify_id(mixer, buf[1]); - else - snd_usb_mixer_memory_change(mixer, buf[1]); - } - } - if (urb->status != -ENOENT && urb->status != -ECONNRESET) { - urb->dev = mixer->chip->dev; - usb_submit_urb(urb, GFP_ATOMIC); - } -} - -/* create the handler for the optional status interrupt endpoint */ -static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) -{ - struct usb_host_interface *hostif; - struct usb_endpoint_descriptor *ep; - void *transfer_buffer; - int buffer_length; - unsigned int epnum; - - hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; - /* we need one interrupt input endpoint */ - if (get_iface_desc(hostif)->bNumEndpoints < 1) - return 0; - ep = get_endpoint(hostif, 0); - if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN || - (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) - return 0; - - epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - buffer_length = le16_to_cpu(ep->wMaxPacketSize); - transfer_buffer = kmalloc(buffer_length, GFP_KERNEL); - if (!transfer_buffer) - return -ENOMEM; - mixer->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!mixer->urb) { - kfree(transfer_buffer); - return -ENOMEM; - } - usb_fill_int_urb(mixer->urb, mixer->chip->dev, - usb_rcvintpipe(mixer->chip->dev, epnum), - transfer_buffer, buffer_length, - snd_usb_mixer_status_complete, mixer, ep->bInterval); - usb_submit_urb(mixer->urb, GFP_KERNEL); - return 0; -} - -static void snd_usb_soundblaster_remote_complete(struct urb *urb, - struct pt_regs *regs) -{ - struct usb_mixer_interface *mixer = urb->context; - /* - * format of remote control data: - * Extigy: xx 00 - * Audigy 2 NX: 06 80 xx 00 00 00 - */ - int offset = mixer->rc_type == RC_EXTIGY ? 0 : 2; - u32 code; - - if (urb->status < 0 || urb->actual_length <= offset) - return; - code = mixer->rc_buffer[offset]; - /* the Mute button actually changes the mixer control */ - if (code == 13) - snd_usb_mixer_notify_id(mixer, 18); - mixer->rc_code = code; - wmb(); - wake_up(&mixer->rc_waitq); -} - -static int snd_usb_sbrc_hwdep_open(snd_hwdep_t *hw, struct file *file) -{ - struct usb_mixer_interface *mixer = hw->private_data; - - if (test_and_set_bit(0, &mixer->rc_hwdep_open)) - return -EBUSY; - return 0; -} - -static int snd_usb_sbrc_hwdep_release(snd_hwdep_t *hw, struct file *file) -{ - struct usb_mixer_interface *mixer = hw->private_data; - - clear_bit(0, &mixer->rc_hwdep_open); - smp_mb__after_clear_bit(); - return 0; -} - -static long snd_usb_sbrc_hwdep_read(snd_hwdep_t *hw, char __user *buf, - long count, loff_t *offset) -{ - struct usb_mixer_interface *mixer = hw->private_data; - int err; - u32 rc_code; - - if (count != 1 && count != 4) - return -EINVAL; - err = wait_event_interruptible(mixer->rc_waitq, - (rc_code = xchg(&mixer->rc_code, 0)) != 0); - if (err == 0) { - if (count == 1) - err = put_user(rc_code, buf); - else - err = put_user(rc_code, (u32 __user *)buf); - } - return err < 0 ? err : count; -} - -static unsigned int snd_usb_sbrc_hwdep_poll(snd_hwdep_t *hw, struct file *file, - poll_table *wait) -{ - struct usb_mixer_interface *mixer = hw->private_data; - - poll_wait(file, &mixer->rc_waitq, wait); - return mixer->rc_code ? POLLIN | POLLRDNORM : 0; -} - -static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) -{ - snd_hwdep_t *hwdep; - int err, len; - - switch (mixer->chip->usb_id) { - case USB_ID(0x041e, 0x3000): - mixer->rc_type = RC_EXTIGY; - len = 2; - break; - case USB_ID(0x041e, 0x3020): - mixer->rc_type = RC_AUDIGY2NX; - len = 6; - break; - default: - return 0; - } - - init_waitqueue_head(&mixer->rc_waitq); - err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep); - if (err < 0) - return err; - snprintf(hwdep->name, sizeof(hwdep->name), - "%s remote control", mixer->chip->card->shortname); - hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC; - hwdep->private_data = mixer; - hwdep->ops.read = snd_usb_sbrc_hwdep_read; - hwdep->ops.open = snd_usb_sbrc_hwdep_open; - hwdep->ops.release = snd_usb_sbrc_hwdep_release; - hwdep->ops.poll = snd_usb_sbrc_hwdep_poll; - - mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!mixer->rc_urb) - return -ENOMEM; - mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL); - if (!mixer->rc_setup_packet) { - usb_free_urb(mixer->rc_urb); - mixer->rc_urb = NULL; - return -ENOMEM; - } - mixer->rc_setup_packet->bRequestType = - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; - mixer->rc_setup_packet->bRequest = GET_MEM; - mixer->rc_setup_packet->wValue = cpu_to_le16(0); - mixer->rc_setup_packet->wIndex = cpu_to_le16(0); - mixer->rc_setup_packet->wLength = cpu_to_le16(len); - usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev, - usb_rcvctrlpipe(mixer->chip->dev, 0), - (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len, - snd_usb_soundblaster_remote_complete, mixer); - return 0; -} - -static int snd_audigy2nx_led_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int snd_audigy2nx_led_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - int index = kcontrol->private_value; - - ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index]; - return 0; -} - -static int snd_audigy2nx_led_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) -{ - struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); - int index = kcontrol->private_value; - int value = ucontrol->value.integer.value[0]; - int err, changed; - - if (value > 1) - return -EINVAL; - changed = value != mixer->audigy2nx_leds[index]; - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, - value, index + 2, NULL, 0, 100); - if (err < 0) - return err; - mixer->audigy2nx_leds[index] = value; - return changed; -} - -static snd_kcontrol_new_t snd_audigy2nx_controls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CMSS LED Switch", - .info = snd_audigy2nx_led_info, - .get = snd_audigy2nx_led_get, - .put = snd_audigy2nx_led_put, - .private_value = 0, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Power LED Switch", - .info = snd_audigy2nx_led_info, - .get = snd_audigy2nx_led_get, - .put = snd_audigy2nx_led_put, - .private_value = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Dolby Digital LED Switch", - .info = snd_audigy2nx_led_info, - .get = snd_audigy2nx_led_get, - .put = snd_audigy2nx_led_put, - .private_value = 2, - }, -}; - -static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) -{ - int i, err; - - for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { - err = snd_ctl_add(mixer->chip->card, - snd_ctl_new1(&snd_audigy2nx_controls[i], mixer)); - if (err < 0) - return err; - } - mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */ - return 0; -} - -static void snd_audigy2nx_proc_read(snd_info_entry_t *entry, - snd_info_buffer_t *buffer) -{ - static const struct { - int unitid; - const char *name; - } jacks[] = { - {4, "dig in "}, - {7, "line in"}, - {19, "spk out"}, - {20, "hph out"}, - }; - struct usb_mixer_interface *mixer = entry->private_data; - int i, err; - u8 buf[3]; - - snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname); - for (i = 0; i < ARRAY_SIZE(jacks); ++i) { - snd_iprintf(buffer, "%s: ", jacks[i].name); - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_rcvctrlpipe(mixer->chip->dev, 0), - GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, 0, - jacks[i].unitid << 8, buf, 3, 100); - if (err == 3 && buf[0] == 3) - snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); - else - snd_iprintf(buffer, "?\n"); - } -} - -int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif) -{ - static snd_device_ops_t dev_ops = { - .dev_free = snd_usb_mixer_dev_free - }; - struct usb_mixer_interface *mixer; - int err; - - strcpy(chip->card->mixername, "USB Mixer"); - - mixer = kcalloc(1, sizeof(*mixer), GFP_KERNEL); - if (!mixer) - return -ENOMEM; - mixer->chip = chip; - mixer->ctrlif = ctrlif; -#ifdef IGNORE_CTL_ERROR - mixer->ignore_ctl_error = 1; -#endif - mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL); - if (!mixer->id_elems) { - kfree(mixer); - return -ENOMEM; - } - - if ((err = snd_usb_mixer_controls(mixer)) < 0 || - (err = snd_usb_mixer_status_create(mixer)) < 0) - goto _error; - - if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) - goto _error; - - if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) { - snd_info_entry_t *entry; - - if ((err = snd_audigy2nx_controls_create(mixer)) < 0) - goto _error; - if (!snd_card_proc_new(chip->card, "audigy2nx", &entry)) - snd_info_set_text_ops(entry, mixer, 1024, - snd_audigy2nx_proc_read); - } - - err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); - if (err < 0) - goto _error; - list_add(&mixer->list, &chip->mixer_list); - return 0; - -_error: - snd_usb_mixer_free(mixer); - return err; -} - -void snd_usb_mixer_disconnect(struct list_head *p) -{ - struct usb_mixer_interface *mixer; - - mixer = list_entry(p, struct usb_mixer_interface, list); - if (mixer->urb) - usb_kill_urb(mixer->urb); - if (mixer->rc_urb) - usb_kill_urb(mixer->rc_urb); -} diff --git a/trunk/sound/usb/usbmixer_maps.c b/trunk/sound/usb/usbmixer_maps.c index f05500b05ec0..c69b4b0875f8 100644 --- a/trunk/sound/usb/usbmixer_maps.c +++ b/trunk/sound/usb/usbmixer_maps.c @@ -26,16 +26,10 @@ struct usbmix_name_map { int control; }; -struct usbmix_selector_map { - int id; - int count; - const char **names; -}; - struct usbmix_ctl_map { - u32 id; + int vendor; + int product; const struct usbmix_name_map *map; - const struct usbmix_selector_map *selector_map; int ignore_ctl_error; }; @@ -97,96 +91,6 @@ static struct usbmix_name_map extigy_map[] = { { 0 } /* terminator */ }; -/* Sound Blaster MP3+ controls mapping - * The default mixer channels have totally misleading names, - * e.g. no Master and fake PCM volume - * Pavel Mihaylov - */ -static struct usbmix_name_map mp3plus_map[] = { - /* 1: IT pcm */ - /* 2: IT mic */ - /* 3: IT line */ - /* 4: IT digital in */ - /* 5: OT digital out */ - /* 6: OT speaker */ - /* 7: OT pcm capture */ - { 8, "Capture Input Source" }, /* FU, default PCM Capture Source */ - /* (Mic, Input 1 = Line input, Input 2 = Optical input) */ - { 9, "Master Playback" }, /* FU, default Speaker 1 */ - /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */ - /* { 10, "Mic Capture", 2 }, */ /* FU, Mic Capture */ - { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */ - { 11, "Line Capture" }, /* FU, default PCM Capture */ - { 12, "Digital In Playback" }, /* FU, default PCM 1 */ - /* { 13, "Mic Playback" }, */ /* FU, default Mic Playback */ - { 14, "Line Playback" }, /* FU, default Speaker */ - /* 15: MU */ - { 0 } /* terminator */ -}; - -/* Topology of SB Audigy 2 NX - - +----------------------------->EU[27]--+ - | v - | +----------------------------------->SU[29]---->FU[22]-->Dig_OUT[24] - | | ^ -USB_IN[1]-+------------+ +->EU[17]->+->FU[11]-+ - | v | v | -Dig_IN[4]---+->FU[6]-->MU[16]->FU[18]-+->EU[21]->SU[31]----->FU[30]->Hph_OUT[20] - | ^ | | -Lin_IN[7]-+--->FU[8]---+ +->EU[23]->FU[28]------------->Spk_OUT[19] - | | v - +--->FU[12]------------------------------------->SU[14]--->USB_OUT[15] - | ^ - +->FU[13]--------------------------------------+ -*/ -static struct usbmix_name_map audigy2nx_map[] = { - /* 1: IT pcm playback */ - /* 4: IT digital in */ - { 6, "Digital In Playback" }, /* FU */ - /* 7: IT line in */ - { 8, "Line Playback" }, /* FU */ - { 11, "What-U-Hear Capture" }, /* FU */ - { 12, "Line Capture" }, /* FU */ - { 13, "Digital In Capture" }, /* FU */ - { 14, "Capture Source" }, /* SU */ - /* 15: OT pcm capture */ - /* 16: MU w/o controls */ - { 17, NULL }, /* DISABLED: EU (for what?) */ - { 18, "Master Playback" }, /* FU */ - /* 19: OT speaker */ - /* 20: OT headphone */ - { 21, NULL }, /* DISABLED: EU (for what?) */ - { 22, "Digital Out Playback" }, /* FU */ - { 23, NULL }, /* DISABLED: EU (for what?) */ - /* 24: OT digital out */ - { 27, NULL }, /* DISABLED: EU (for what?) */ - { 28, "Speaker Playback" }, /* FU */ - { 29, "Digital Out Source" }, /* SU */ - { 30, "Headphone Playback" }, /* FU */ - { 31, "Headphone Source" }, /* SU */ - { 0 } /* terminator */ -}; - -static struct usbmix_selector_map audigy2nx_selectors[] = { - { - .id = 14, /* Capture Source */ - .count = 3, - .names = (const char*[]) {"Line", "Digital In", "What-U-Hear"} - }, - { - .id = 29, /* Digital Out Source */ - .count = 3, - .names = (const char*[]) {"Front", "PCM", "Digital In"} - }, - { - .id = 31, /* Headphone Source */ - .count = 2, - .names = (const char*[]) {"Front", "Side"} - }, - { 0 } /* terminator */ -}; - /* LineX FM Transmitter entry - needed to bypass controls bug */ static struct usbmix_name_map linex_map[] = { /* 1: IT pcm */ @@ -223,29 +127,9 @@ static struct usbmix_name_map justlink_map[] = { */ static struct usbmix_ctl_map usbmix_ctl_maps[] = { - { - .id = USB_ID(0x041e, 0x3000), - .map = extigy_map, - .ignore_ctl_error = 1, - }, - { - .id = USB_ID(0x041e, 0x3010), - .map = mp3plus_map, - }, - { - .id = USB_ID(0x041e, 0x3020), - .map = audigy2nx_map, - .selector_map = audigy2nx_selectors, - }, - { - .id = USB_ID(0x08bb, 0x2702), - .map = linex_map, - .ignore_ctl_error = 1, - }, - { - .id = USB_ID(0x0c45, 0x1158), - .map = justlink_map, - }, + { 0x41e, 0x3000, extigy_map, 1 }, + { 0x8bb, 0x2702, linex_map, 1 }, + { 0xc45, 0x1158, justlink_map, 0 }, { 0 } /* terminator */ }; diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index f5135641b3e2..88bbd944d4be 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -203,28 +203,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "EDIROL", .product_name = "UM-4", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x000f, - .in_cables = 0x000f - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x000f, + .in_cables = 0x000f } } }, @@ -233,28 +216,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "SC-8850", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x003f, - .in_cables = 0x003f - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x003f, + .in_cables = 0x003f } } }, @@ -263,28 +229,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "U-8", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0005, - .in_cables = 0x0005 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0005, + .in_cables = 0x0005 } } }, @@ -293,28 +242,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "EDIROL", .product_name = "UM-2", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0003, - .in_cables = 0x0003 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0003, + .in_cables = 0x0003 } } }, @@ -323,28 +255,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "SC-8820", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0013, - .in_cables = 0x0013 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0013, + .in_cables = 0x0013 } } }, @@ -353,28 +268,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "PC-300", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0001, + .in_cables = 0x0001 } } }, @@ -383,28 +281,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "EDIROL", .product_name = "UM-1", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0001, + .in_cables = 0x0001 } } }, @@ -413,28 +294,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "SK-500", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0013, - .in_cables = 0x0013 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0013, + .in_cables = 0x0013 } } }, @@ -557,28 +421,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "EDIROL", .product_name = "SD-90", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x000f, - .in_cables = 0x000f - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x000f, + .in_cables = 0x000f } } }, @@ -587,28 +434,11 @@ YAMAHA_DEVICE(0x7010, "UB99"), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "MMP-2", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - }, - { - .ifnum = -1 - } + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0001, + .in_cables = 0x0001 } } }, @@ -779,33 +609,15 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { - /* - * This quirk is for the "Advanced Driver" mode. If off, the GS-10 - * has ID 0x003c and is standard compliant, but has only 16-bit PCM - * and no MIDI. - */ USB_DEVICE_VENDOR_SPEC(0x0582, 0x003b), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "BOSS", .product_name = "GS-10", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = & (const snd_usb_audio_quirk_t[]) { - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 3, - .type = QUIRK_MIDI_STANDARD_INTERFACE - }, - { - .ifnum = -1 - } + .ifnum = 3, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0003, + .in_cables = 0x0003 } } }, diff --git a/trunk/sound/usb/usx2y/usbusx2y.c b/trunk/sound/usb/usx2y/usbusx2y.c index e6e6da159671..b06a267e5dac 100644 --- a/trunk/sound/usb/usx2y/usbusx2y.c +++ b/trunk/sound/usb/usx2y/usbusx2y.c @@ -1,11 +1,6 @@ /* * usbusy2y.c - ALSA USB US-428 Driver * -2005-04-14 Karsten Wiese - Version 0.8.7.2: - Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. - Tested ok with kernel 2.6.12-rc2. - 2004-12-14 Karsten Wiese Version 0.8.7.1: snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open. @@ -148,7 +143,7 @@ MODULE_AUTHOR("Karsten Wiese "); -MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); +MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.1"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}"); @@ -435,6 +430,8 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr) if (ptr) { usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr); struct list_head* p; + if (usX2Y->chip_status == USX2Y_STAT_CHIP_HUP) // on 2.6.1 kernel snd_usbmidi_disconnect() + return; // calls us back. better leave :-) . usX2Y->chip.shutdown = 1; usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; usX2Y_unlinkSeq(&usX2Y->AS04); @@ -442,11 +439,11 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr) snd_card_disconnect((snd_card_t*)ptr); /* release the midi resources */ list_for_each(p, &usX2Y->chip.midi_list) { - snd_usbmidi_disconnect(p); + snd_usbmidi_disconnect(p, &snd_usX2Y_usb_driver); } if (usX2Y->us428ctls_sharedmem) wake_up(&usX2Y->us428ctls_wait_queue_head); - snd_card_free((snd_card_t*)ptr); + snd_card_free_in_thread((snd_card_t*)ptr); } }