From 223f18e4482fd90b7cdabb222fad5ca502dc0028 Mon Sep 17 00:00:00 2001 From: Raymond Yau Date: Mon, 4 Jun 2012 14:59:55 +0800 Subject: ALSA: au88x0 - Remove unused "Master Mono" Playback Volume and Playback Switch of ac97 codec Remove "Master Mono Playback Volume" and "Master Mono Playback Switch" of ac97 mixer since au88x0 does no use "Master Mono Pin" of AC97 codec even au88x0 support mono playback Signed-off-by: Raymond Yau Signed-off-by: Takashi Iwai diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c index 557c782..fa13efb 100644 --- a/sound/pci/au88x0/au88x0_mixer.c +++ b/sound/pci/au88x0/au88x0_mixer.c @@ -10,6 +10,15 @@ #include #include "au88x0.h" +static int remove_ctl(struct snd_card *card, const char *name) +{ + struct snd_ctl_elem_id id; + memset(&id, 0, sizeof(id)); + strcpy(id.name, name); + id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + return snd_ctl_remove_id(card, &id); +} + static int __devinit snd_vortex_mixer(vortex_t * vortex) { struct snd_ac97_bus *pbus; @@ -28,5 +37,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex) ac97.scaps = AC97_SCAP_NO_SPDIF; err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); + remove_ctl(vortex->card, "Master Mono Playback Volume"); + remove_ctl(vortex->card, "Master Mono Playback Switch"); return err; } -- cgit v0.10.2 From b71dad181a55d2ad90bd03cd3216a5a8a31d9468 Mon Sep 17 00:00:00 2001 From: Mark Hills Date: Sat, 9 Jun 2012 13:16:38 +0100 Subject: ALSA: usb-audio: Use a table of mixer controls Allow mixer controls to be provided clearly in a table, to avoid quantity of error checking at each use. Signed-off-by: Mark Hills Signed-off-by: Takashi Iwai diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 41f4b69..ce7d96f 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -42,6 +42,13 @@ extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; +struct std_mono_table { + unsigned int unitid, control, cmask; + int val_type; + const char *name; + snd_kcontrol_tlv_rw_t *tlv_callback; +}; + /* private_free callback */ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) { @@ -114,6 +121,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, } /* + * Create a set of standard UAC controls from a table + */ +static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, + struct std_mono_table *t) +{ + int err; + + while (t->name != NULL) { + err = snd_create_std_mono_ctl(mixer, t->unitid, t->control, + t->cmask, t->val_type, t->name, t->tlv_callback); + if (err < 0) + return err; + t++; + } + + return 0; +} + +/* * Sound Blaster remote control configuration * * format of remote control data: @@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer) return 0; } - -/* - * Create mixer for Electrix Ebox-44 - * - * The mixer units from this device are corrupt, and even where they - * are valid they presents mono controls as L and R channels of - * stereo. So we create a good mixer in code. - */ - -static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer) -{ - int err; - - err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, - "Headphone Playback Switch", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16, - "Headphone A Mix Playback Volume", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16, - "Headphone B Mix Playback Volume", NULL); - if (err < 0) - return err; - - err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, - "Output Playback Switch", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16, - "Output A Playback Volume", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16, - "Output B Playback Volume", NULL); - if (err < 0) - return err; - - err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, - "Input Capture Switch", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16, - "Input A Capture Volume", NULL); - if (err < 0) - return err; - err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16, - "Input B Capture Volume", NULL); - if (err < 0) - return err; - - return 0; -} - void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, unsigned char samplerate_id) { @@ -990,6 +961,27 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, } } +/* + * The mixer units for Ebox-44 are corrupt, and even where they + * are valid they presents mono controls as L and R channels of + * stereo. So we provide a good mixer here. + */ +struct std_mono_table ebox44_table[] = { + { 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL }, + { 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL }, + { 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL }, + + { 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL }, + { 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL }, + { 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL }, + + { 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL }, + { 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL }, + { 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL }, + + { } +}; + int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) { int err = 0; @@ -1035,7 +1027,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) break; case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ - err = snd_ebox44_create_mixer(mixer); + /* detection is disabled in mixer_maps.c */ + err = snd_create_std_mono_table(mixer, ebox44_table); break; } -- cgit v0.10.2 From 989b01385fa3cc4eaa488068a0868ae4de5198a9 Mon Sep 17 00:00:00 2001 From: Mark Hills Date: Sat, 9 Jun 2012 13:16:39 +0100 Subject: ALSA: usb-audio: Convert table to preferred C99 format Signed-off-by: Mark Hills Signed-off-by: Takashi Iwai diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ce7d96f..690000d 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -967,19 +967,73 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, * stereo. So we provide a good mixer here. */ struct std_mono_table ebox44_table[] = { - { 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL }, - { 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL }, - { 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL }, + { + .unitid = 4, + .control = 1, + .cmask = 0x0, + .val_type = USB_MIXER_INV_BOOLEAN, + .name = "Headphone Playback Switch" + }, + { + .unitid = 4, + .control = 2, + .cmask = 0x1, + .val_type = USB_MIXER_S16, + .name = "Headphone A Mix Playback Volume" + }, + { + .unitid = 4, + .control = 2, + .cmask = 0x2, + .val_type = USB_MIXER_S16, + .name = "Headphone B Mix Playback Volume" + }, - { 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL }, - { 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL }, - { 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL }, + { + .unitid = 7, + .control = 1, + .cmask = 0x0, + .val_type = USB_MIXER_INV_BOOLEAN, + .name = "Output Playback Switch" + }, + { + .unitid = 7, + .control = 2, + .cmask = 0x1, + .val_type = USB_MIXER_S16, + .name = "Output A Playback Volume" + }, + { + .unitid = 7, + .control = 2, + .cmask = 0x2, + .val_type = USB_MIXER_S16, + .name = "Output B Playback Volume" + }, - { 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL }, - { 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL }, - { 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL }, + { + .unitid = 10, + .control = 1, + .cmask = 0x0, + .val_type = USB_MIXER_INV_BOOLEAN, + .name = "Input Capture Switch" + }, + { + .unitid = 10, + .control = 2, + .cmask = 0x1, + .val_type = USB_MIXER_S16, + .name = "Input A Capture Volume" + }, + { + .unitid = 10, + .control = 2, + .cmask = 0x2, + .val_type = USB_MIXER_S16, + .name = "Input B Capture Volume" + }, - { } + {} }; int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) -- cgit v0.10.2 From 4be77a530be1ea62574f31c20dd9848e7e2ab0f6 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 15 Jun 2012 16:35:28 +0100 Subject: ALSA: pcm: Add snd_pcm_rate_bit_to_rate() This is essentially the reverse of snd_pcm_rate_to_rate_bit(). This is generally useful as the Compress API uses the rate bit directly and it helps to be able to map back to the actual sample rate. Signed-off-by: Dimitris Papastamos Signed-off-by: Takashi Iwai diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 0d11128..68372bc 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -893,6 +893,7 @@ extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates; int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime); unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); +unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, struct snd_dma_buffer *bufp) diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 9c9eff9..d4fc1bf 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -488,3 +488,21 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) return SNDRV_PCM_RATE_KNOT; } EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); + +/** + * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate + * @rate_bit: the rate bit to convert + * + * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag + * or 0 for an unknown rate bit + */ +unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) +{ + unsigned int i; + + for (i = 0; i < snd_pcm_known_rates.count; i++) + if ((1u << i) == rate_bit) + return snd_pcm_known_rates.list[i]; + return 0; +} +EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); -- cgit v0.10.2 From 10a3061accd897c9e4e3821cbd501660ac482497 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Fri, 15 Jun 2012 20:55:54 +0200 Subject: ALSA: snd-opti9xx: fixes for MED3931 card (opti931) MED3931 card did not work (failed with "OPTI chip not found") because snd-opti9xx gets mc_indir_index from pnp by adding 2 to the pnp-reported port. It probably works for some cards but not for this one. Datasheet says that the port is always at 0xe?e so just force the lowest nibble to be 0xe. Also this card powers up with (ugly) 3D sound enabled. As there's no mixer control for this, just disable it. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index d7ccf28..ecc68df 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -135,7 +135,6 @@ struct snd_opti9xx { unsigned long mc_base_size; #ifdef OPTi93X unsigned long mc_indir_index; - unsigned long mc_indir_size; struct resource *res_mc_indir; struct snd_wss *codec; #endif /* OPTi93X */ @@ -245,10 +244,8 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, case OPTi9XX_HW_82C931: case OPTi9XX_HW_82C933: chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; - if (!chip->mc_indir_index) { + if (!chip->mc_indir_index) chip->mc_indir_index = 0xe0e; - chip->mc_indir_size = 2; - } chip->password = 0xe4; chip->pwd_reg = 0; break; @@ -403,7 +400,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, #else /* OPTi93X */ case OPTi9XX_HW_82C931: - case OPTi9XX_HW_82C933: + /* disable 3D sound (set GPIO1 as output, low) */ + snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c); + case OPTi9XX_HW_82C933: /* FALL THROUGH */ /* * The BTC 1817DW has QS1000 wavetable which is connected * to the serial digital input of the OPTI931. @@ -696,8 +695,7 @@ static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip) if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) return 0; #else /* OPTi93X */ - chip->res_mc_indir = request_region(chip->mc_indir_index, - chip->mc_indir_size, + chip->res_mc_indir = request_region(chip->mc_indir_index, 2, "OPTi93x MC"); if (chip->res_mc_indir == NULL) return -EBUSY; @@ -770,8 +768,9 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, #ifdef OPTi93X port = pnp_port_start(pdev, 0) - 4; fm_port = pnp_port_start(pdev, 1) + 8; - chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; - chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; + /* adjust mc_indir_index - some cards report it at 0xe?d, + other at 0xe?c but it really is always at 0xe?e */ + chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe; #else devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); if (devmc == NULL) -- cgit v0.10.2 From e0815f35ccd276a903298ad4c3d8d10b65933b86 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Jun 2012 16:58:49 -0300 Subject: ALSA: maestro3: Remove unused AC97 register definitions Signed-off-by: Ezequiel Garcia Signed-off-by: Takashi Iwai diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index deef213..adb3b4c 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -361,74 +361,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)"); #define DSP2HOST_REQ_I2SRATE 0x02 #define DSP2HOST_REQ_TIMER 0x04 -/* AC97 registers */ -/* XXX fix this crap up */ -/*#define AC97_RESET 0x00*/ - -#define AC97_VOL_MUTE_B 0x8000 -#define AC97_VOL_M 0x1F -#define AC97_LEFT_VOL_S 8 - -#define AC97_MASTER_VOL 0x02 -#define AC97_LINE_LEVEL_VOL 0x04 -#define AC97_MASTER_MONO_VOL 0x06 -#define AC97_PC_BEEP_VOL 0x0A -#define AC97_PC_BEEP_VOL_M 0x0F -#define AC97_SROUND_MASTER_VOL 0x38 -#define AC97_PC_BEEP_VOL_S 1 - -/*#define AC97_PHONE_VOL 0x0C -#define AC97_MIC_VOL 0x0E*/ -#define AC97_MIC_20DB_ENABLE 0x40 - -/*#define AC97_LINEIN_VOL 0x10 -#define AC97_CD_VOL 0x12 -#define AC97_VIDEO_VOL 0x14 -#define AC97_AUX_VOL 0x16*/ -#define AC97_PCM_OUT_VOL 0x18 -/*#define AC97_RECORD_SELECT 0x1A*/ -#define AC97_RECORD_MIC 0x00 -#define AC97_RECORD_CD 0x01 -#define AC97_RECORD_VIDEO 0x02 -#define AC97_RECORD_AUX 0x03 -#define AC97_RECORD_MONO_MUX 0x02 -#define AC97_RECORD_DIGITAL 0x03 -#define AC97_RECORD_LINE 0x04 -#define AC97_RECORD_STEREO 0x05 -#define AC97_RECORD_MONO 0x06 -#define AC97_RECORD_PHONE 0x07 - -/*#define AC97_RECORD_GAIN 0x1C*/ -#define AC97_RECORD_VOL_M 0x0F - -/*#define AC97_GENERAL_PURPOSE 0x20*/ -#define AC97_POWER_DOWN_CTRL 0x26 -#define AC97_ADC_READY 0x0001 -#define AC97_DAC_READY 0x0002 -#define AC97_ANALOG_READY 0x0004 -#define AC97_VREF_ON 0x0008 -#define AC97_PR0 0x0100 -#define AC97_PR1 0x0200 -#define AC97_PR2 0x0400 -#define AC97_PR3 0x0800 -#define AC97_PR4 0x1000 - -#define AC97_RESERVED1 0x28 - -#define AC97_VENDOR_TEST 0x5A - -#define AC97_CLOCK_DELAY 0x5C -#define AC97_LINEOUT_MUX_SEL 0x0001 -#define AC97_MONO_MUX_SEL 0x0002 -#define AC97_CLOCK_DELAY_SEL 0x1F -#define AC97_DAC_CDS_SHIFT 6 -#define AC97_ADC_CDS_SHIFT 11 - -#define AC97_MULTI_CHANNEL_SEL 0x74 - -/*#define AC97_VENDOR_ID1 0x7C -#define AC97_VENDOR_ID2 0x7E*/ - /* * ASSP control regs */ -- cgit v0.10.2 From d7dc9e32ae64b5db777017344da61a285c2347f8 Mon Sep 17 00:00:00 2001 From: Markus Bollinger Date: Wed, 20 Jun 2012 08:32:48 +0200 Subject: ALSA: pcxhr: Fix a counter wrap fix a counter wrap to avoid resynchronization of stream positions every several minutes. The resynchronization may create stream position jitter Signed-off-by: Markus Bollinger Signed-off-by: Takashi Iwai diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 304411c..841703b 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -1133,13 +1133,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr, hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; hw_sample_count += (u_int64_t)rmh.stat[1]; - snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", + snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n", stream->pipe->is_capture ? 'C' : 'P', stream->substream->number, - (long unsigned int)hw_sample_count, - (long unsigned int)(stream->timer_abs_periods + - stream->timer_period_frag + - mgr->granularity)); + hw_sample_count, + stream->timer_abs_periods + stream->timer_period_frag + + mgr->granularity); return hw_sample_count; } @@ -1243,10 +1242,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) if ((dsp_time_diff < 0) && (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { - snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " - "resynchronize all streams\n", + /* handle dsp counter wraparound without resync */ + int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1; + snd_printdd("WARNING DSP timestamp old(%d) new(%d)", mgr->dsp_time_last, dsp_time_new); - mgr->dsp_time_err++; + if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) { + snd_printdd("-> timestamp wraparound OK: " + "diff=%d\n", tmp_diff); + dsp_time_diff = tmp_diff; + } else { + snd_printdd("-> resynchronize all streams\n"); + mgr->dsp_time_err++; + } } #ifdef CONFIG_SND_DEBUG_VERBOSE if (dsp_time_diff == 0) -- cgit v0.10.2 From fdfbaf69e0b9d6843c0da6501caf4ecacec0f775 Mon Sep 17 00:00:00 2001 From: Markus Bollinger Date: Wed, 20 Jun 2012 08:34:40 +0200 Subject: ALSA: pcxhr: Add LTC support add LTC (linear timecode) read function via proc interface to the pcxhr driver Signed-off-by: Markus Bollinger Signed-off-by: Takashi Iwai diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 0435f45..e3ac1f7 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -1368,6 +1368,67 @@ static void pcxhr_proc_gpo_write(struct snd_info_entry *entry, } } +/* Access to the results of the CMD_GET_TIME_CODE RMH */ +#define TIME_CODE_VALID_MASK 0x00800000 +#define TIME_CODE_NEW_MASK 0x00400000 +#define TIME_CODE_BACK_MASK 0x00200000 +#define TIME_CODE_WAIT_MASK 0x00100000 + +/* Values for the CMD_MANAGE_SIGNAL RMH */ +#define MANAGE_SIGNAL_TIME_CODE 0x01 +#define MANAGE_SIGNAL_MIDI 0x02 + +/* linear time code read proc*/ +static void pcxhr_proc_ltc(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct snd_pcxhr *chip = entry->private_data; + struct pcxhr_mgr *mgr = chip->mgr; + struct pcxhr_rmh rmh; + unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm; + int err; + /* commands available when embedded DSP is running */ + if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) { + snd_iprintf(buffer, "no firmware loaded\n"); + return; + } + if (!mgr->capture_ltc) { + pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL); + rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE; + err = pcxhr_send_msg(mgr, &rmh); + if (err) { + snd_iprintf(buffer, "ltc not activated (%d)\n", err); + return; + } + if (mgr->is_hr_stereo) + hr222_manage_timecode(mgr, 1); + else + pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE, + REG_CONT_VALSMPTE, NULL); + mgr->capture_ltc = 1; + } + pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE); + err = pcxhr_send_msg(mgr, &rmh); + if (err) { + snd_iprintf(buffer, "ltc read error (err=%d)\n", err); + return ; + } + ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf); + ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf); + ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf); + ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf); + + snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n", + ltcHrs, ltcMin, ltcSec, ltcFrm); + snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff, + rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff); + /*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n", + rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/ + if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) { + snd_iprintf(buffer, "warning: linear timecode not valid\n"); + } +} + static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) { struct snd_info_entry *entry; @@ -1383,6 +1444,8 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) entry->c.text.write = pcxhr_proc_gpo_write; entry->mode |= S_IWUSR; } + if (!snd_card_proc_new(chip->card, "ltc", &entry)) + snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc); } /* end of proc interface */ diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index bda776c..a4c602c 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h @@ -103,6 +103,7 @@ struct pcxhr_mgr { unsigned int board_has_mic:1; /* if 1 the board has microphone input */ unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ unsigned int mono_capture:1; /* if 1 the board does mono capture */ + unsigned int capture_ltc:1; /* if 1 the board captures LTC input */ struct snd_dma_buffer hostport; diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 841703b..b33db1e 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = { [CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, [CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, [CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, +[CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED }, +[CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED }, }; #ifdef CONFIG_SND_DEBUG_VERBOSE @@ -533,6 +535,8 @@ static char* cmd_names[] = { [CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", [CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", [CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", +[CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE", +[CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL", }; #endif diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h index be01737..a81ab6b 100644 --- a/sound/pci/pcxhr/pcxhr_core.h +++ b/sound/pci/pcxhr/pcxhr_core.h @@ -79,6 +79,8 @@ enum { CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */ CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */ CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */ + CMD_GET_TIME_CODE, /* cmd_len = 1 stat_len = 5 */ + CMD_MANAGE_SIGNAL, /* cmd_len = 1 stat_len = 0 */ CMD_LAST_INDEX }; @@ -116,7 +118,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh); #define IO_NUM_REG_OUT_ANA_LEVEL 20 #define IO_NUM_REG_IN_ANA_LEVEL 21 - +#define REG_CONT_VALSMPTE 0x000800 #define REG_CONT_UNMUTE_INPUTS 0x020000 /* parameters used with register IO_NUM_REG_STATUS */ diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c index 1cb82c0..84fe576 100644 --- a/sound/pci/pcxhr/pcxhr_mix22.c +++ b/sound/pci/pcxhr/pcxhr_mix22.c @@ -53,6 +53,7 @@ #define PCXHR_DSP_RESET_DSP 0x01 #define PCXHR_DSP_RESET_MUTE 0x02 #define PCXHR_DSP_RESET_CODEC 0x08 +#define PCXHR_DSP_RESET_SMPTE 0x10 #define PCXHR_DSP_RESET_GPO_OFFSET 5 #define PCXHR_DSP_RESET_GPO_MASK 0x60 @@ -527,6 +528,16 @@ int hr222_write_gpo(struct pcxhr_mgr *mgr, int value) return 0; } +int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable) +{ + if (enable) + mgr->dsp_reset |= PCXHR_DSP_RESET_SMPTE; + else + mgr->dsp_reset &= ~PCXHR_DSP_RESET_SMPTE; + + PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset); + return 0; +} int hr222_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h index 5a37a00..5971b99 100644 --- a/sound/pci/pcxhr/pcxhr_mix22.h +++ b/sound/pci/pcxhr/pcxhr_mix22.h @@ -34,6 +34,7 @@ int hr222_get_external_clock(struct pcxhr_mgr *mgr, int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value); int hr222_write_gpo(struct pcxhr_mgr *mgr, int value); +int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable); #define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */ #define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */ -- cgit v0.10.2 From 24fe5ddc5f189606bde68136ac808da37e4dfe04 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 19 Jun 2012 16:20:23 -0300 Subject: sound: swarm_cs4297: Provide definitions for AC97 registers This patch removes the last usage of linux/ac97_codec.h by re-defining used AC97 registers. We can't use sound/ac97_codec.h here, since it is an OSS driver. Cc: Ralf Baechle Cc: Jaroslav Kysela Cc: Clemens Ladisch Signed-off-by: Ezequiel Garcia Signed-off-by: Takashi Iwai diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 09d4648..7d8803a 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include #include @@ -199,6 +198,22 @@ static const char invalid_magic[] = } \ }) +/* AC97 registers */ +#define AC97_MASTER_VOL_STEREO 0x0002 /* Line Out */ +#define AC97_PCBEEP_VOL 0x000a /* none */ +#define AC97_PHONE_VOL 0x000c /* TAD Input (mono) */ +#define AC97_MIC_VOL 0x000e /* MIC Input (mono) */ +#define AC97_LINEIN_VOL 0x0010 /* Line Input (stereo) */ +#define AC97_CD_VOL 0x0012 /* CD Input (stereo) */ +#define AC97_AUX_VOL 0x0016 /* Aux Input (stereo) */ +#define AC97_PCMOUT_VOL 0x0018 /* Wave Output (stereo) */ +#define AC97_RECORD_SELECT 0x001a /* */ +#define AC97_RECORD_GAIN 0x001c +#define AC97_GENERAL_PURPOSE 0x0020 +#define AC97_3D_CONTROL 0x0022 +#define AC97_POWER_CONTROL 0x0026 +#define AC97_VENDOR_ID1 0x007c + struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs }; typedef struct serdma_descr_s { -- cgit v0.10.2 From 33eb3311f3ad4a14f2e55d36fdb0d3ec54712231 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 19 Jun 2012 16:20:24 -0300 Subject: sound: Remove unused include/linux/ac97_codec.h header This file has been superseded by include/sound/ac97_codec.h, and has currently no users. Cc: Ralf Baechle Cc: Jaroslav Kysela Cc: Clemens Ladisch Signed-off-by: Ezequiel Garcia Signed-off-by: Takashi Iwai diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h deleted file mode 100644 index 0260c3e..0000000 --- a/include/linux/ac97_codec.h +++ /dev/null @@ -1,362 +0,0 @@ -#ifndef _AC97_CODEC_H_ -#define _AC97_CODEC_H_ - -#include -#include - -/* AC97 1.0 */ -#define AC97_RESET 0x0000 // -#define AC97_MASTER_VOL_STEREO 0x0002 // Line Out -#define AC97_HEADPHONE_VOL 0x0004 // -#define AC97_MASTER_VOL_MONO 0x0006 // TAD Output -#define AC97_MASTER_TONE 0x0008 // -#define AC97_PCBEEP_VOL 0x000a // none -#define AC97_PHONE_VOL 0x000c // TAD Input (mono) -#define AC97_MIC_VOL 0x000e // MIC Input (mono) -#define AC97_LINEIN_VOL 0x0010 // Line Input (stereo) -#define AC97_CD_VOL 0x0012 // CD Input (stereo) -#define AC97_VIDEO_VOL 0x0014 // none -#define AC97_AUX_VOL 0x0016 // Aux Input (stereo) -#define AC97_PCMOUT_VOL 0x0018 // Wave Output (stereo) -#define AC97_RECORD_SELECT 0x001a // -#define AC97_RECORD_GAIN 0x001c -#define AC97_RECORD_GAIN_MIC 0x001e -#define AC97_GENERAL_PURPOSE 0x0020 -#define AC97_3D_CONTROL 0x0022 -#define AC97_MODEM_RATE 0x0024 -#define AC97_POWER_CONTROL 0x0026 - -/* AC'97 2.0 */ -#define AC97_EXTENDED_ID 0x0028 /* Extended Audio ID */ -#define AC97_EXTENDED_STATUS 0x002A /* Extended Audio Status */ -#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */ -#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */ -#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */ -#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */ -#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */ -#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */ -#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */ -#define AC97_RESERVED_3A 0x003A /* Reserved in AC '97 < 2.2 */ - -/* AC'97 2.2 */ -#define AC97_SPDIF_CONTROL 0x003A /* S/PDIF Control */ - -/* range 0x3c-0x58 - MODEM */ -#define AC97_EXTENDED_MODEM_ID 0x003C -#define AC97_EXTEND_MODEM_STAT 0x003E -#define AC97_LINE1_RATE 0x0040 -#define AC97_LINE2_RATE 0x0042 -#define AC97_HANDSET_RATE 0x0044 -#define AC97_LINE1_LEVEL 0x0046 -#define AC97_LINE2_LEVEL 0x0048 -#define AC97_HANDSET_LEVEL 0x004A -#define AC97_GPIO_CONFIG 0x004C -#define AC97_GPIO_POLARITY 0x004E -#define AC97_GPIO_STICKY 0x0050 -#define AC97_GPIO_WAKE_UP 0x0052 -#define AC97_GPIO_STATUS 0x0054 -#define AC97_MISC_MODEM_STAT 0x0056 -#define AC97_RESERVED_58 0x0058 - -/* registers 0x005a - 0x007a are vendor reserved */ - -#define AC97_VENDOR_ID1 0x007c -#define AC97_VENDOR_ID2 0x007e - -/* volume control bit defines */ -#define AC97_MUTE 0x8000 -#define AC97_MICBOOST 0x0040 -#define AC97_LEFTVOL 0x3f00 -#define AC97_RIGHTVOL 0x003f - -/* record mux defines */ -#define AC97_RECMUX_MIC 0x0000 -#define AC97_RECMUX_CD 0x0101 -#define AC97_RECMUX_VIDEO 0x0202 -#define AC97_RECMUX_AUX 0x0303 -#define AC97_RECMUX_LINE 0x0404 -#define AC97_RECMUX_STEREO_MIX 0x0505 -#define AC97_RECMUX_MONO_MIX 0x0606 -#define AC97_RECMUX_PHONE 0x0707 - -/* general purpose register bit defines */ -#define AC97_GP_LPBK 0x0080 /* Loopback mode */ -#define AC97_GP_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 */ -#define AC97_GP_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic */ -#define AC97_GP_RLBK 0x0400 /* Remote Loopback - Modem line codec */ -#define AC97_GP_LLBK 0x0800 /* Local Loopback - Modem Line codec */ -#define AC97_GP_LD 0x1000 /* Loudness 1=on */ -#define AC97_GP_3D 0x2000 /* 3D Enhancement 1=on */ -#define AC97_GP_ST 0x4000 /* Stereo Enhancement 1=on */ -#define AC97_GP_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */ - -/* extended audio status and control bit defines */ -#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */ -#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */ -#define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */ -#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */ -#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */ -#define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */ -#define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */ -#define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */ -#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */ -#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */ -#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */ -#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */ -#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */ -#define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */ -#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */ -#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */ -#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */ -#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */ - -/* S/PDIF control bit defines */ -#define AC97_SC_PRO 0x0001 /* Professional status */ -#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */ -#define AC97_SC_COPY 0x0004 /* Copyright status */ -#define AC97_SC_PRE 0x0008 /* Preemphasis status */ -#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */ -#define AC97_SC_L 0x0800 /* Generation Level status */ -#define AC97_SC_SPSR_MASK 0xcfff /* S/PDIF Sample Rate bits */ -#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */ -#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */ -#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */ -#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */ -#define AC97_SC_V 0x8000 /* Validity status */ - -/* powerdown control and status bit defines */ - -/* status */ -#define AC97_PWR_MDM 0x0010 /* Modem section ready */ -#define AC97_PWR_REF 0x0008 /* Vref nominal */ -#define AC97_PWR_ANL 0x0004 /* Analog section ready */ -#define AC97_PWR_DAC 0x0002 /* DAC section ready */ -#define AC97_PWR_ADC 0x0001 /* ADC section ready */ - -/* control */ -#define AC97_PWR_PR0 0x0100 /* ADC and Mux powerdown */ -#define AC97_PWR_PR1 0x0200 /* DAC powerdown */ -#define AC97_PWR_PR2 0x0400 /* Output mixer powerdown (Vref on) */ -#define AC97_PWR_PR3 0x0800 /* Output mixer powerdown (Vref off) */ -#define AC97_PWR_PR4 0x1000 /* AC-link powerdown */ -#define AC97_PWR_PR5 0x2000 /* Internal Clk disable */ -#define AC97_PWR_PR6 0x4000 /* HP amp powerdown */ -#define AC97_PWR_PR7 0x8000 /* Modem off - if supported */ - -/* extended audio ID register bit defines */ -#define AC97_EXTID_VRA 0x0001 -#define AC97_EXTID_DRA 0x0002 -#define AC97_EXTID_SPDIF 0x0004 -#define AC97_EXTID_VRM 0x0008 -#define AC97_EXTID_DSA0 0x0010 -#define AC97_EXTID_DSA1 0x0020 -#define AC97_EXTID_CDAC 0x0040 -#define AC97_EXTID_SDAC 0x0080 -#define AC97_EXTID_LDAC 0x0100 -#define AC97_EXTID_AMAP 0x0200 -#define AC97_EXTID_REV0 0x0400 -#define AC97_EXTID_REV1 0x0800 -#define AC97_EXTID_ID0 0x4000 -#define AC97_EXTID_ID1 0x8000 - -/* extended status register bit defines */ -#define AC97_EXTSTAT_VRA 0x0001 -#define AC97_EXTSTAT_DRA 0x0002 -#define AC97_EXTSTAT_SPDIF 0x0004 -#define AC97_EXTSTAT_VRM 0x0008 -#define AC97_EXTSTAT_SPSA0 0x0010 -#define AC97_EXTSTAT_SPSA1 0x0020 -#define AC97_EXTSTAT_CDAC 0x0040 -#define AC97_EXTSTAT_SDAC 0x0080 -#define AC97_EXTSTAT_LDAC 0x0100 -#define AC97_EXTSTAT_MADC 0x0200 -#define AC97_EXTSTAT_SPCV 0x0400 -#define AC97_EXTSTAT_PRI 0x0800 -#define AC97_EXTSTAT_PRJ 0x1000 -#define AC97_EXTSTAT_PRK 0x2000 -#define AC97_EXTSTAT_PRL 0x4000 - -/* extended audio ID register bit defines */ -#define AC97_EXTID_VRA 0x0001 -#define AC97_EXTID_DRA 0x0002 -#define AC97_EXTID_SPDIF 0x0004 -#define AC97_EXTID_VRM 0x0008 -#define AC97_EXTID_DSA0 0x0010 -#define AC97_EXTID_DSA1 0x0020 -#define AC97_EXTID_CDAC 0x0040 -#define AC97_EXTID_SDAC 0x0080 -#define AC97_EXTID_LDAC 0x0100 -#define AC97_EXTID_AMAP 0x0200 -#define AC97_EXTID_REV0 0x0400 -#define AC97_EXTID_REV1 0x0800 -#define AC97_EXTID_ID0 0x4000 -#define AC97_EXTID_ID1 0x8000 - -/* extended status register bit defines */ -#define AC97_EXTSTAT_VRA 0x0001 -#define AC97_EXTSTAT_DRA 0x0002 -#define AC97_EXTSTAT_SPDIF 0x0004 -#define AC97_EXTSTAT_VRM 0x0008 -#define AC97_EXTSTAT_SPSA0 0x0010 -#define AC97_EXTSTAT_SPSA1 0x0020 -#define AC97_EXTSTAT_CDAC 0x0040 -#define AC97_EXTSTAT_SDAC 0x0080 -#define AC97_EXTSTAT_LDAC 0x0100 -#define AC97_EXTSTAT_MADC 0x0200 -#define AC97_EXTSTAT_SPCV 0x0400 -#define AC97_EXTSTAT_PRI 0x0800 -#define AC97_EXTSTAT_PRJ 0x1000 -#define AC97_EXTSTAT_PRK 0x2000 -#define AC97_EXTSTAT_PRL 0x4000 - -/* useful power states */ -#define AC97_PWR_D0 0x0000 /* everything on */ -#define AC97_PWR_D1 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4 -#define AC97_PWR_D2 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 -#define AC97_PWR_D3 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR2|AC97_PWR_PR3|AC97_PWR_PR4 -#define AC97_PWR_ANLOFF AC97_PWR_PR2|AC97_PWR_PR3 /* analog section off */ - -/* Total number of defined registers. */ -#define AC97_REG_CNT 64 - - -/* OSS interface to the ac97s.. */ -#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|SOUND_MASK_PCM|\ - SOUND_MASK_LINE|SOUND_MASK_CD|\ - SOUND_MASK_ALTPCM|SOUND_MASK_IGAIN|\ - SOUND_MASK_LINE1|SOUND_MASK_VIDEO) - -#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \ - SOUND_MASK_BASS|SOUND_MASK_TREBLE|\ - SOUND_MASK_SPEAKER|SOUND_MASK_MIC|\ - SOUND_MASK_PHONEIN|SOUND_MASK_PHONEOUT) - -#define AC97_RECORD_MASK (SOUND_MASK_MIC|\ - SOUND_MASK_CD|SOUND_MASK_IGAIN|SOUND_MASK_VIDEO|\ - SOUND_MASK_LINE1| SOUND_MASK_LINE|\ - SOUND_MASK_PHONEIN) - -/* original check is not good enough in case FOO is greater than - * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly - * SOUND_MIXER_NRDEVICES elements. - * before matching the given mixer against the bitmask in supported_mixers we - * check if mixer number exceeds maximum allowed size which is as mentioned - * above SOUND_MIXER_NRDEVICES */ -#define supported_mixer(CODEC,FOO) ((FOO >= 0) && \ - (FOO < SOUND_MIXER_NRDEVICES) && \ - (CODEC)->supported_mixers & (1< Date: Tue, 19 Jun 2012 19:31:48 +0100 Subject: ALSA: Add missing include of pcm.h to pcm_params.h There's a dependency but no #include. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h index f494f1e..37ae12e 100644 --- a/include/sound/pcm_params.h +++ b/include/sound/pcm_params.h @@ -22,6 +22,8 @@ * */ +#include + int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var, int *dir); -- cgit v0.10.2 From da185443c12f5ef7416af50293833a5654854186 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 18 Jun 2012 21:16:31 +0200 Subject: ALSA: snd-usb-caiaq: initialize card pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following warning: CC [M] sound/usb/caiaq/device.o sound/usb/caiaq/device.c: In function ‘snd_probe’: sound/usb/caiaq/device.c:500:16: warning: ‘card’ may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 64aed43..7da0d0a 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -485,7 +485,7 @@ static int __devinit snd_probe(struct usb_interface *intf, const struct usb_device_id *id) { int ret; - struct snd_card *card; + struct snd_card *card = NULL; struct usb_device *device = interface_to_usbdev(intf); ret = create_card(device, intf, &card); -- cgit v0.10.2 From 1464189f8c2a5341722437ef916786afaf241c44 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 5 Jul 2012 12:15:01 +0100 Subject: ALSA: pcm: Make constraints lists const They aren't modified by the core so the drivers can declare them const. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 68372bc..e91e604 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -810,7 +810,7 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, unsigned int cond, snd_pcm_hw_param_t var, - struct snd_pcm_hw_constraint_list *l); + const struct snd_pcm_hw_constraint_list *l); int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, unsigned int cond, snd_pcm_hw_param_t var, diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 8f312fa..7ae6719 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1250,10 +1250,10 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, unsigned int cond, snd_pcm_hw_param_t var, - struct snd_pcm_hw_constraint_list *l) + const struct snd_pcm_hw_constraint_list *l) { return snd_pcm_hw_rule_add(runtime, cond, var, - snd_pcm_hw_rule_list, l, + snd_pcm_hw_rule_list, (void *)l, var, -1); } -- cgit v0.10.2 From b5b9eb546762c4015c67c31364a6ec6f83fd2ada Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 20 Nov 2011 16:22:24 +0100 Subject: ALSA: tlv: compute TLV_*_ITEM lengths automatically Add helper macros with a little bit of preprocessor magic to automatically compute the length of a TLV item. This lets us avoid having to compute this by hand, and will allow to use items that do not use a fixed length. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai diff --git a/include/sound/tlv.h b/include/sound/tlv.h index 7067e2d..137d165 100644 --- a/include/sound/tlv.h +++ b/include/sound/tlv.h @@ -38,21 +38,26 @@ #define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */ #define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */ +#define TLV_ITEM(type, ...) \ + (type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__ +#define TLV_LENGTH(...) \ + ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) + #define TLV_DB_SCALE_MASK 0xffff #define TLV_DB_SCALE_MUTE 0x10000 #define TLV_DB_SCALE_ITEM(min, step, mute) \ - SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \ - (min), ((step) & TLV_DB_SCALE_MASK) | ((mute) ? TLV_DB_SCALE_MUTE : 0) + TLV_ITEM(SNDRV_CTL_TLVT_DB_SCALE, \ + (min), \ + ((step) & TLV_DB_SCALE_MASK) | \ + ((mute) ? TLV_DB_SCALE_MUTE : 0)) #define DECLARE_TLV_DB_SCALE(name, min, step, mute) \ unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) } /* dB scale specified with min/max values instead of step */ #define TLV_DB_MINMAX_ITEM(min_dB, max_dB) \ - SNDRV_CTL_TLVT_DB_MINMAX, 2 * sizeof(unsigned int), \ - (min_dB), (max_dB) + TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB)) #define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ - SNDRV_CTL_TLVT_DB_MINMAX_MUTE, 2 * sizeof(unsigned int), \ - (min_dB), (max_dB) + TLV_ITEM(SNDRV_CTL_TLVT_DB_MINMAX_MUTE, (min_dB), (max_dB)) #define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \ unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) } #define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \ @@ -60,8 +65,7 @@ /* linear volume between min_dB and max_dB (.01dB unit) */ #define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \ - SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \ - (min_dB), (max_dB) + TLV_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB)) #define DECLARE_TLV_DB_LINEAR(name, min_dB, max_dB) \ unsigned int name[] = { TLV_DB_LINEAR_ITEM(min_dB, max_dB) } -- cgit v0.10.2 From 570aef5de13df21e42eeb90db67e2436bee91bd4 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 2 Dec 2011 23:20:00 +0100 Subject: ALSA: tlv: add DECLARE_TLV_CONTAINER() Add the DECLARE_TLV_CONTAINER() macro to allow having static TLVs containing more than one item. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai diff --git a/include/sound/tlv.h b/include/sound/tlv.h index 137d165..a9ff3db 100644 --- a/include/sound/tlv.h +++ b/include/sound/tlv.h @@ -43,6 +43,11 @@ #define TLV_LENGTH(...) \ ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) +#define TLV_CONTAINER_ITEM(...) \ + TLV_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) +#define DECLARE_TLV_CONTAINER(name, ...) \ + unsigned int name[] = { TLV_CONTAINER_ITEM(__VA_ARGS__) } + #define TLV_DB_SCALE_MASK 0xffff #define TLV_DB_SCALE_MUTE 0x10000 #define TLV_DB_SCALE_ITEM(min, step, mute) \ -- cgit v0.10.2 From bf1d1c9b6179faa3bc32cee882462bc8eebde25d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 20 Nov 2011 17:17:35 +0100 Subject: ALSA: tlv: add DECLARE_TLV_DB_RANGE() Add a DECLARE_TLV_DB_RANGE() macro so that dB range information can be specified without having to count the items manually for TLV_DB_RANGE_HEAD(). Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai diff --git a/include/sound/tlv.h b/include/sound/tlv.h index a9ff3db..a64d8fe 100644 --- a/include/sound/tlv.h +++ b/include/sound/tlv.h @@ -76,6 +76,10 @@ /* dB range container */ /* Each item is: */ +#define TLV_DB_RANGE_ITEM(...) \ + TLV_ITEM(SNDRV_CTL_TLVT_DB_RANGE, __VA_ARGS__) +#define DECLARE_TLV_DB_RANGE(name, ...) \ + unsigned int name[] = { TLV_DB_RANGE_ITEM(__VA_ARGS__) } /* The below assumes that each item TLV is 4 words like DB_SCALE or LINEAR */ #define TLV_DB_RANGE_HEAD(num) \ SNDRV_CTL_TLVT_DB_RANGE, 6 * (num) * sizeof(unsigned int) -- cgit v0.10.2 From 093eef416642c84265cced12335ff125f0db7313 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Sun, 20 Nov 2011 17:21:34 +0100 Subject: ALSA: es1938: replace TLV_DB_RANGE_HEAD with DECLARE_TLV_DB_RANGE Instead of the hard-to-mantain TLV_DB_RANGE_HEAD macro, use DECLARE_TLV_DB_RANGE, which computes its size automatically. (Also make this data const on the way.) Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 82c8d8c..a41106d 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -1321,35 +1321,30 @@ static int snd_es1938_put_double(struct snd_kcontrol *kcontrol, return change; } -static unsigned int db_scale_master[] = { - TLV_DB_RANGE_HEAD(2), +static const DECLARE_TLV_DB_RANGE(db_scale_master, 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1), 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0), -}; +); -static unsigned int db_scale_audio1[] = { - TLV_DB_RANGE_HEAD(2), +static const DECLARE_TLV_DB_RANGE(db_scale_audio1, 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1), 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0), -}; +); -static unsigned int db_scale_audio2[] = { - TLV_DB_RANGE_HEAD(2), +static const DECLARE_TLV_DB_RANGE(db_scale_audio2, 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1), 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0), -}; +); -static unsigned int db_scale_mic[] = { - TLV_DB_RANGE_HEAD(2), +static const DECLARE_TLV_DB_RANGE(db_scale_mic, 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1), 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0), -}; +); -static unsigned int db_scale_line[] = { - TLV_DB_RANGE_HEAD(2), +static const DECLARE_TLV_DB_RANGE(db_scale_line, 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1), 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), -}; +); static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); -- cgit v0.10.2 From ca3273fb594ae4e953042c956eb40141ba46ad2c Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Thu, 12 Jul 2012 23:30:31 +0200 Subject: ALSA: wss_lib: fix suspend/resume By setting SNDRV_PCM_INFO_RESUME, wss_lib claims that it can restore the card state fully on resume. But in fact, it can't as DMA is not restored so any playback/capture running during suspend will fail to continue after resume. Remove SNDRV_PCM_INFO_RESUME flag from pcm info field to fix the problem. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 49c8a0c..00ca9fc 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1456,7 +1456,6 @@ static struct snd_pcm_hardware snd_wss_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_SYNC_START), .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), -- cgit v0.10.2 From b4e2a16f992288f1c5cddda1948c53ba3dde9cb3 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 16 Jul 2012 08:30:18 +0200 Subject: ALSA: wss_lib: Fix resume on Yamaha OPL3-SAx Yamaha OPL3-SAx chips don't resume properly when playback is running - garbage is played after resume. Restoring the CS4231_PLAYBK_FORMAT register last fixes the problem. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 00ca9fc..360b08b 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1656,6 +1656,10 @@ static void snd_wss_resume(struct snd_wss *chip) break; } } + /* Yamaha needs this to resume properly */ + if (chip->hardware == WSS_HW_OPL3SA2) + snd_wss_out(chip, CS4231_PLAYBK_FORMAT, + chip->image[CS4231_PLAYBK_FORMAT]); spin_unlock_irqrestore(&chip->reg_lock, flags); #if 1 snd_wss_mce_down(chip); -- cgit v0.10.2 From 5dd250728aa4cad49cfa18eb8ed11ba470ce382a Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Tue, 17 Jul 2012 09:16:44 +0200 Subject: ALSA: snd-opti9xx: Implement suspend/resume Implement suspend/resume support for Opti 92x and 93x chips. Tested with Opti 929A+AD1848 and Opti 931. Signed-off-by: Ondrej Zary Signed-off-by: Takashi Iwai diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index ecc68df..d7ce012 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -136,8 +136,8 @@ struct snd_opti9xx { #ifdef OPTi93X unsigned long mc_indir_index; struct resource *res_mc_indir; - struct snd_wss *codec; #endif /* OPTi93X */ + struct snd_wss *codec; unsigned long pwd_reg; spinlock_t lock; @@ -870,9 +870,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) &codec); if (error < 0) return error; -#ifdef OPTi93X chip->codec = codec; -#endif error = snd_wss_pcm(codec, 0, &pcm); if (error < 0) return error; @@ -1053,11 +1051,55 @@ static int __devexit snd_opti9xx_isa_remove(struct device *devptr, return 0; } +#ifdef CONFIG_PM +static int snd_opti9xx_suspend(struct snd_card *card) +{ + struct snd_opti9xx *chip = card->private_data; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + chip->codec->suspend(chip->codec); + return 0; +} + +static int snd_opti9xx_resume(struct snd_card *card) +{ + struct snd_opti9xx *chip = card->private_data; + int error, xdma2; +#if defined(CS4231) || defined(OPTi93X) + xdma2 = dma2; +#else + xdma2 = -1; +#endif + + error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2, + mpu_port, mpu_irq); + if (error) + return error; + chip->codec->resume(chip->codec); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} + +static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) +{ + return snd_opti9xx_suspend(dev_get_drvdata(dev)); +} + +static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n) +{ + return snd_opti9xx_resume(dev_get_drvdata(dev)); +} +#endif + static struct isa_driver snd_opti9xx_driver = { .match = snd_opti9xx_isa_match, .probe = snd_opti9xx_isa_probe, .remove = __devexit_p(snd_opti9xx_isa_remove), - /* FIXME: suspend/resume */ +#ifdef CONFIG_PM + .suspend = snd_opti9xx_isa_suspend, + .resume = snd_opti9xx_isa_resume, +#endif .driver = { .name = DEV_NAME }, @@ -1123,12 +1165,29 @@ static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard) snd_opti9xx_pnp_is_probed = 0; } +#ifdef CONFIG_PM +static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard, + pm_message_t state) +{ + return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard)); +} + +static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard) +{ + return snd_opti9xx_resume(pnp_get_card_drvdata(pcard)); +} +#endif + static struct pnp_card_driver opti9xx_pnpc_driver = { .flags = PNP_DRIVER_RES_DISABLE, .name = "opti9xx", .id_table = snd_opti9xx_pnpids, .probe = snd_opti9xx_pnp_probe, .remove = __devexit_p(snd_opti9xx_pnp_remove), +#ifdef CONFIG_PM + .suspend = snd_opti9xx_pnp_suspend, + .resume = snd_opti9xx_pnp_resume, +#endif }; #endif -- cgit v0.10.2 From 59b1f084abd8690ffe68c67758ad08bbcb7d1af0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 17 Jul 2012 12:14:17 +0200 Subject: ALSA: opti9xx: Fix section mismatch by PM support In the previous commit, snd_opti9xx_configure() is called from the resume handler but it's still marked as __devinit. Fix it. Reported-by: Fengguang Wu Signed-off-by: Takashi Iwai diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index d7ce012..f8fbe22 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -348,7 +348,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) -static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, +static int snd_opti9xx_configure(struct snd_opti9xx *chip, long port, int irq, int dma1, int dma2, long mpu_port, int mpu_irq) -- cgit v0.10.2