Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-next' into for-linus

4.18-rc1 merge material.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

+8718 -1444
+7
Documentation/sound/alsa-configuration.rst
··· 2224 2224 Quirk alias list, pass strings like ``0123abcd:5678beef``, which 2225 2225 applies the existing quirk for the device 5678:beef to a new 2226 2226 device 0123:abcd. 2227 + use_vmalloc 2228 + Use vmalloc() for allocations of the PCM buffers (default: yes). 2229 + For architectures with non-coherent memory like ARM or MIPS, the 2230 + mmap access may give inconsistent results with vmalloc'ed 2231 + buffers. If mmap is used on such architectures, turn off this 2232 + option, so that the DMA-coherent buffers are allocated and used 2233 + instead. 2227 2234 2228 2235 This module supports multiple devices, autoprobe and hotplugging. 2229 2236
+2
Documentation/sound/hd-audio/models.rst
··· 263 263 HP dock support 264 264 mute-led-gpio 265 265 Mute LED control via GPIO 266 + hp-mic-fix 267 + Fix for headset mic pin on HP boxes 266 268 267 269 STAC9200 268 270 ========
+7
MAINTAINERS
··· 15494 15494 F: arch/x86/xen/*swiotlb* 15495 15495 F: drivers/xen/*swiotlb* 15496 15496 15497 + XEN SOUND FRONTEND DRIVER 15498 + M: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 15499 + L: xen-devel@lists.xenproject.org (moderated for non-subscribers) 15500 + L: alsa-devel@alsa-project.org (moderated for non-subscribers) 15501 + S: Supported 15502 + F: sound/xen/* 15503 + 15497 15504 XFS FILESYSTEM 15498 15505 M: Darrick J. Wong <darrick.wong@oracle.com> 15499 15506 M: linux-xfs@vger.kernel.org
+7
include/linux/usb/audio-v2.h
··· 189 189 #define UAC2_CONTROL_DATA_OVERRUN (3 << 2) 190 190 #define UAC2_CONTROL_DATA_UNDERRUN (3 << 4) 191 191 192 + /* 5.2.5.4.2 Connector Control Parameter Block */ 193 + struct uac2_connectors_ctl_blk { 194 + __u8 bNrChannels; 195 + __le32 bmChannelConfig; 196 + __u8 iChannelNames; 197 + } __attribute__((packed)); 198 + 192 199 /* 6.1 Interrupt Data Message */ 193 200 194 201 #define UAC2_INTERRUPT_DATA_MSG_VENDOR (1 << 0)
+40
include/linux/usb/audio-v3.h
··· 221 221 __le16 wLockDelay; 222 222 } __attribute__((packed)); 223 223 224 + /* 5.2.1.6.1 INSERTION CONTROL PARAMETER BLOCK */ 225 + struct uac3_insertion_ctl_blk { 226 + __u8 bSize; 227 + __u8 bmConInserted; 228 + } __attribute__ ((packed)); 229 + 224 230 /* 6.1 INTERRUPT DATA MESSAGE */ 225 231 struct uac3_interrupt_data_msg { 226 232 __u8 bInfo; ··· 397 391 #define UAC3_AC_CONTROL_UNDEFINED 0x00 398 392 #define UAC3_AC_ACTIVE_INTERFACE_CONTROL 0x01 399 393 #define UAC3_AC_POWER_DOMAIN_CONTROL 0x02 394 + 395 + /* A.23.5 TERMINAL CONTROL SELECTORS */ 396 + #define UAC3_TE_UNDEFINED 0x00 397 + #define UAC3_TE_INSERTION 0x01 398 + #define UAC3_TE_OVERLOAD 0x02 399 + #define UAC3_TE_UNDERFLOW 0x03 400 + #define UAC3_TE_OVERFLOW 0x04 401 + #define UAC3_TE_LATENCY 0x05 402 + 403 + /* BADD predefined Unit/Terminal values */ 404 + #define UAC3_BADD_IT_ID1 1 /* Input Terminal ID1: bTerminalID = 1 */ 405 + #define UAC3_BADD_FU_ID2 2 /* Feature Unit ID2: bUnitID = 2 */ 406 + #define UAC3_BADD_OT_ID3 3 /* Output Terminal ID3: bTerminalID = 3 */ 407 + #define UAC3_BADD_IT_ID4 4 /* Input Terminal ID4: bTerminalID = 4 */ 408 + #define UAC3_BADD_FU_ID5 5 /* Feature Unit ID5: bUnitID = 5 */ 409 + #define UAC3_BADD_OT_ID6 6 /* Output Terminal ID6: bTerminalID = 6 */ 410 + #define UAC3_BADD_FU_ID7 7 /* Feature Unit ID7: bUnitID = 7 */ 411 + #define UAC3_BADD_MU_ID8 8 /* Mixer Unit ID8: bUnitID = 8 */ 412 + #define UAC3_BADD_CS_ID9 9 /* Clock Source Entity ID9: bClockID = 9 */ 413 + #define UAC3_BADD_PD_ID10 10 /* Power Domain ID10: bPowerDomainID = 10 */ 414 + #define UAC3_BADD_PD_ID11 11 /* Power Domain ID11: bPowerDomainID = 11 */ 415 + 416 + /* BADD wMaxPacketSize of AS endpoints */ 417 + #define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16 0x0060 418 + #define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16 0x0062 419 + #define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24 0x0090 420 + #define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24 0x0093 421 + #define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16 0x00C0 422 + #define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16 0x00C4 423 + #define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24 0x0120 424 + #define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24 0x0126 425 + 426 + /* BADD sample rate is always fixed to 48kHz */ 427 + #define UAC3_BADD_SAMPLING_RATE 48000 400 428 401 429 #endif /* __LINUX_USB_AUDIO_V3_H */
+1 -1
include/sound/core.h
··· 51 51 */ 52 52 enum snd_device_type { 53 53 SNDRV_DEV_LOWLEVEL, 54 - SNDRV_DEV_CONTROL, 55 54 SNDRV_DEV_INFO, 56 55 SNDRV_DEV_BUS, 57 56 SNDRV_DEV_CODEC, ··· 61 62 SNDRV_DEV_SEQUENCER, 62 63 SNDRV_DEV_HWDEP, 63 64 SNDRV_DEV_JACK, 65 + SNDRV_DEV_CONTROL, /* NOTE: this must be the last one */ 64 66 }; 65 67 66 68 enum snd_device_state {
+2 -2
include/sound/emu10k1.h
··· 1610 1610 struct snd_pcm_indirect pcm_rec; 1611 1611 unsigned int tram_pos; 1612 1612 unsigned int tram_shift; 1613 - struct snd_emu10k1_fx8010_irq *irq; 1613 + struct snd_emu10k1_fx8010_irq irq; 1614 1614 }; 1615 1615 1616 1616 struct snd_emu10k1_fx8010 { ··· 1902 1902 snd_fx8010_irq_handler_t *handler, 1903 1903 unsigned char gpr_running, 1904 1904 void *private_data, 1905 - struct snd_emu10k1_fx8010_irq **r_irq); 1905 + struct snd_emu10k1_fx8010_irq *irq); 1906 1906 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu, 1907 1907 struct snd_emu10k1_fx8010_irq *irq); 1908 1908
+5
include/sound/hdaudio.h
··· 571 571 return (unsigned long)(ptr - array->list) / array->elem_size; 572 572 } 573 573 574 + /* a helper macro to iterate for each snd_array element */ 575 + #define snd_array_for_each(array, idx, ptr) \ 576 + for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \ 577 + (ptr) = snd_array_elem(array, ++(idx))) 578 + 574 579 #endif /* __SOUND_HDAUDIO_H */
-2
include/sound/memalloc.h
··· 34 34 struct device *dev; /* generic device */ 35 35 }; 36 36 37 - #ifndef snd_dma_pci_data 38 37 #define snd_dma_pci_data(pci) (&(pci)->dev) 39 38 #define snd_dma_isa_data() NULL 40 39 #define snd_dma_continuous_data(x) ((struct device *)(__force unsigned long)(x)) 41 - #endif 42 40 43 41 44 42 /*
+16 -3
include/uapi/linux/usb/audio.h
··· 285 285 static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc, 286 286 int protocol) 287 287 { 288 - return (protocol == UAC_VERSION_1) ? 289 - &desc->baSourceID[desc->bNrInPins + 4] : 290 - &desc->baSourceID[desc->bNrInPins + 6]; 288 + switch (protocol) { 289 + case UAC_VERSION_1: 290 + return &desc->baSourceID[desc->bNrInPins + 4]; 291 + case UAC_VERSION_2: 292 + return &desc->baSourceID[desc->bNrInPins + 6]; 293 + case UAC_VERSION_3: 294 + return &desc->baSourceID[desc->bNrInPins + 2]; 295 + default: 296 + return NULL; 297 + } 298 + } 299 + 300 + static inline __u16 uac3_mixer_unit_wClusterDescrID(struct uac_mixer_unit_descriptor *desc) 301 + { 302 + return (desc->baSourceID[desc->bNrInPins + 1] << 8) | 303 + desc->baSourceID[desc->bNrInPins]; 291 304 } 292 305 293 306 static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
+16
include/uapi/sound/tlv.h
··· 42 42 #define SNDRV_CTL_TLVD_LENGTH(...) \ 43 43 ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) 44 44 45 + /* Accessor offsets for TLV data items */ 46 + #define SNDRV_CTL_TLVO_TYPE 0 47 + #define SNDRV_CTL_TLVO_LEN 1 48 + 45 49 #define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \ 46 50 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) 47 51 #define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \ ··· 65 61 SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \ 66 62 } 67 63 64 + /* Accessor offsets for min, mute and step items in dB scale type TLV */ 65 + #define SNDRV_CTL_TLVO_DB_SCALE_MIN 2 66 + #define SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP 3 67 + 68 68 /* dB scale specified with min/max values instead of step */ 69 69 #define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \ 70 70 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB)) ··· 83 75 SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ 84 76 } 85 77 78 + /* Accessor offsets for min, max items in db-minmax types of TLV. */ 79 + #define SNDRV_CTL_TLVO_DB_MINMAX_MIN 2 80 + #define SNDRV_CTL_TLVO_DB_MINMAX_MAX 3 81 + 86 82 /* linear volume between min_dB and max_dB (.01dB unit) */ 87 83 #define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ 88 84 SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB)) ··· 94 82 unsigned int name[] = { \ 95 83 SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ 96 84 } 85 + 86 + /* Accessor offsets for min, max items in db-linear type of TLV. */ 87 + #define SNDRV_CTL_TLVO_DB_LINEAR_MIN 2 88 + #define SNDRV_CTL_TLVO_DB_LINEAR_MAX 3 97 89 98 90 /* dB range container: 99 91 * Items in dB range container must be ordered by their values and by their
+2
sound/Kconfig
··· 96 96 97 97 source "sound/synth/Kconfig" 98 98 99 + source "sound/xen/Kconfig" 100 + 99 101 endif # SND 100 102 101 103 endif # !UML
+1 -1
sound/Makefile
··· 5 5 obj-$(CONFIG_SOUND) += soundcore.o 6 6 obj-$(CONFIG_DMASOUND) += oss/dmasound/ 7 7 obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ 8 - firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ 8 + firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/ 9 9 obj-$(CONFIG_SND_AOA) += aoa/ 10 10 11 11 # This one must be compilable even if sound is configured out
+1 -1
sound/core/compress_offload.c
··· 1001 1001 compr->card->proc_root); 1002 1002 if (!entry) 1003 1003 return -ENOMEM; 1004 - entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 1004 + entry->mode = S_IFDIR | 0555; 1005 1005 if (snd_info_register(entry) < 0) { 1006 1006 snd_info_free_entry(entry); 1007 1007 return -ENOMEM;
+9
sound/core/device.c
··· 240 240 241 241 if (snd_BUG_ON(!card)) 242 242 return; 243 + list_for_each_entry_safe_reverse(dev, next, &card->devices, list) { 244 + /* exception: free ctl and lowlevel stuff later */ 245 + if (dev->type == SNDRV_DEV_CONTROL || 246 + dev->type == SNDRV_DEV_LOWLEVEL) 247 + continue; 248 + __snd_device_free(dev); 249 + } 250 + 251 + /* free all */ 243 252 list_for_each_entry_safe_reverse(dev, next, &card->devices, list) 244 253 __snd_device_free(dev); 245 254 }
+3 -3
sound/core/info.c
··· 454 454 entry = snd_info_create_module_entry(mod, name, NULL); 455 455 if (!entry) 456 456 return NULL; 457 - entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 457 + entry->mode = S_IFDIR | 0555; 458 458 if (snd_info_register(entry) < 0) { 459 459 snd_info_free_entry(entry); 460 460 return NULL; ··· 470 470 snd_proc_root = snd_info_create_entry("asound", NULL); 471 471 if (!snd_proc_root) 472 472 return -ENOMEM; 473 - snd_proc_root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 473 + snd_proc_root->mode = S_IFDIR | 0555; 474 474 snd_proc_root->p = proc_mkdir("asound", NULL); 475 475 if (!snd_proc_root->p) 476 476 goto error; ··· 716 716 kfree(entry); 717 717 return NULL; 718 718 } 719 - entry->mode = S_IFREG | S_IRUGO; 719 + entry->mode = S_IFREG | 0444; 720 720 entry->content = SNDRV_INFO_CONTENT_TEXT; 721 721 mutex_init(&entry->access); 722 722 INIT_LIST_HEAD(&entry->children);
+2 -2
sound/core/init.c
··· 703 703 return count; 704 704 } 705 705 706 - static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr); 706 + static DEVICE_ATTR(id, 0644, card_id_show_attr, card_id_store_attr); 707 707 708 708 static ssize_t 709 709 card_number_show_attr(struct device *dev, ··· 713 713 return scnprintf(buf, PAGE_SIZE, "%i\n", card->number); 714 714 } 715 715 716 - static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL); 716 + static DEVICE_ATTR(number, 0444, card_number_show_attr, NULL); 717 717 718 718 static struct attribute *card_dev_attrs[] = { 719 719 &dev_attr_id.attr,
+1 -1
sound/core/oss/mixer_oss.c
··· 1247 1247 if (! entry) 1248 1248 return; 1249 1249 entry->content = SNDRV_INFO_CONTENT_TEXT; 1250 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 1250 + entry->mode = S_IFREG | 0644; 1251 1251 entry->c.text.read = snd_mixer_oss_proc_read; 1252 1252 entry->c.text.write = snd_mixer_oss_proc_write; 1253 1253 entry->private_data = mixer;
+1 -1
sound/core/oss/pcm_oss.c
··· 3045 3045 continue; 3046 3046 if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) { 3047 3047 entry->content = SNDRV_INFO_CONTENT_TEXT; 3048 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 3048 + entry->mode = S_IFREG | 0644; 3049 3049 entry->c.text.read = snd_pcm_oss_proc_read; 3050 3050 entry->c.text.write = snd_pcm_oss_proc_write; 3051 3051 entry->private_data = pstr;
+5 -5
sound/core/pcm.c
··· 530 530 pcm->card->proc_root); 531 531 if (!entry) 532 532 return -ENOMEM; 533 - entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 533 + entry->mode = S_IFDIR | 0555; 534 534 if (snd_info_register(entry) < 0) { 535 535 snd_info_free_entry(entry); 536 536 return -ENOMEM; ··· 552 552 if (entry) { 553 553 entry->c.text.read = snd_pcm_xrun_debug_read; 554 554 entry->c.text.write = snd_pcm_xrun_debug_write; 555 - entry->mode |= S_IWUSR; 555 + entry->mode |= 0200; 556 556 entry->private_data = pstr; 557 557 if (snd_info_register(entry) < 0) { 558 558 snd_info_free_entry(entry); ··· 590 590 substream->pstr->proc_root); 591 591 if (!entry) 592 592 return -ENOMEM; 593 - entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 593 + entry->mode = S_IFDIR | 0555; 594 594 if (snd_info_register(entry) < 0) { 595 595 snd_info_free_entry(entry); 596 596 return -ENOMEM; ··· 647 647 entry->private_data = substream; 648 648 entry->c.text.read = NULL; 649 649 entry->c.text.write = snd_pcm_xrun_injection_write; 650 - entry->mode = S_IFREG | S_IWUSR; 650 + entry->mode = S_IFREG | 0200; 651 651 if (snd_info_register(entry) < 0) { 652 652 snd_info_free_entry(entry); 653 653 entry = NULL; ··· 1087 1087 return snprintf(buf, PAGE_SIZE, "%s\n", str); 1088 1088 } 1089 1089 1090 - static DEVICE_ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); 1090 + static DEVICE_ATTR(pcm_class, 0444, show_pcm_class, NULL); 1091 1091 static struct attribute *pcm_dev_attrs[] = { 1092 1092 &dev_attr_pcm_class.attr, 1093 1093 NULL
+2 -8
sound/core/pcm_compat.c
··· 45 45 46 46 if (get_user(frames, src)) 47 47 return -EFAULT; 48 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 49 - err = snd_pcm_playback_rewind(substream, frames); 50 - else 51 - err = snd_pcm_capture_rewind(substream, frames); 48 + err = snd_pcm_rewind(substream, frames); 52 49 if (put_user(err, src)) 53 50 return -EFAULT; 54 51 return err < 0 ? err : 0; ··· 59 62 60 63 if (get_user(frames, src)) 61 64 return -EFAULT; 62 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 63 - err = snd_pcm_playback_forward(substream, frames); 64 - else 65 - err = snd_pcm_capture_forward(substream, frames); 65 + err = snd_pcm_forward(substream, frames); 66 66 if (put_user(err, src)) 67 67 return -EFAULT; 68 68 return err < 0 ? err : 0;
+3 -12
sound/core/pcm_lib.c
··· 191 191 { 192 192 snd_pcm_uframes_t avail; 193 193 194 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 195 - avail = snd_pcm_playback_avail(runtime); 196 - else 197 - avail = snd_pcm_capture_avail(runtime); 194 + avail = snd_pcm_avail(substream); 198 195 if (avail > runtime->avail_max) 199 196 runtime->avail_max = avail; 200 197 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { ··· 1853 1856 * This check must happen after been added to the waitqueue 1854 1857 * and having current state be INTERRUPTIBLE. 1855 1858 */ 1856 - if (is_playback) 1857 - avail = snd_pcm_playback_avail(runtime); 1858 - else 1859 - avail = snd_pcm_capture_avail(runtime); 1859 + avail = snd_pcm_avail(substream); 1860 1860 if (avail >= runtime->twake) 1861 1861 break; 1862 1862 snd_pcm_stream_unlock_irq(substream); ··· 2169 2175 runtime->twake = runtime->control->avail_min ? : 1; 2170 2176 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) 2171 2177 snd_pcm_update_hw_ptr(substream); 2172 - if (is_playback) 2173 - avail = snd_pcm_playback_avail(runtime); 2174 - else 2175 - avail = snd_pcm_capture_avail(runtime); 2178 + avail = snd_pcm_avail(substream); 2176 2179 while (size > 0) { 2177 2180 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2178 2181 snd_pcm_uframes_t cont;
+18
sound/core/pcm_local.h
··· 36 36 void snd_pcm_playback_silence(struct snd_pcm_substream *substream, 37 37 snd_pcm_uframes_t new_hw_ptr); 38 38 39 + static inline snd_pcm_uframes_t 40 + snd_pcm_avail(struct snd_pcm_substream *substream) 41 + { 42 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 43 + return snd_pcm_playback_avail(substream->runtime); 44 + else 45 + return snd_pcm_capture_avail(substream->runtime); 46 + } 47 + 48 + static inline snd_pcm_uframes_t 49 + snd_pcm_hw_avail(struct snd_pcm_substream *substream) 50 + { 51 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 52 + return snd_pcm_playback_hw_avail(substream->runtime); 53 + else 54 + return snd_pcm_capture_hw_avail(substream->runtime); 55 + } 56 + 39 57 #ifdef CONFIG_SND_PCM_TIMER 40 58 void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); 41 59 void snd_pcm_timer_init(struct snd_pcm_substream *substream);
+1 -1
sound/core/pcm_memory.c
··· 201 201 if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) { 202 202 entry->c.text.read = snd_pcm_lib_preallocate_proc_read; 203 203 entry->c.text.write = snd_pcm_lib_preallocate_proc_write; 204 - entry->mode |= S_IWUSR; 204 + entry->mode |= 0200; 205 205 entry->private_data = substream; 206 206 if (snd_info_register(entry) < 0) { 207 207 snd_info_free_entry(entry);
+103 -160
sound/core/pcm_native.c
··· 99 99 cond_resched(); 100 100 } 101 101 102 + #define PCM_LOCK_DEFAULT 0 103 + #define PCM_LOCK_IRQ 1 104 + #define PCM_LOCK_IRQSAVE 2 105 + 106 + static unsigned long __snd_pcm_stream_lock_mode(struct snd_pcm_substream *substream, 107 + unsigned int mode) 108 + { 109 + unsigned long flags = 0; 110 + if (substream->pcm->nonatomic) { 111 + down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING); 112 + mutex_lock(&substream->self_group.mutex); 113 + } else { 114 + switch (mode) { 115 + case PCM_LOCK_DEFAULT: 116 + read_lock(&snd_pcm_link_rwlock); 117 + break; 118 + case PCM_LOCK_IRQ: 119 + read_lock_irq(&snd_pcm_link_rwlock); 120 + break; 121 + case PCM_LOCK_IRQSAVE: 122 + read_lock_irqsave(&snd_pcm_link_rwlock, flags); 123 + break; 124 + } 125 + spin_lock(&substream->self_group.lock); 126 + } 127 + return flags; 128 + } 129 + 130 + static void __snd_pcm_stream_unlock_mode(struct snd_pcm_substream *substream, 131 + unsigned int mode, unsigned long flags) 132 + { 133 + if (substream->pcm->nonatomic) { 134 + mutex_unlock(&substream->self_group.mutex); 135 + up_read(&snd_pcm_link_rwsem); 136 + } else { 137 + spin_unlock(&substream->self_group.lock); 138 + 139 + switch (mode) { 140 + case PCM_LOCK_DEFAULT: 141 + read_unlock(&snd_pcm_link_rwlock); 142 + break; 143 + case PCM_LOCK_IRQ: 144 + read_unlock_irq(&snd_pcm_link_rwlock); 145 + break; 146 + case PCM_LOCK_IRQSAVE: 147 + read_unlock_irqrestore(&snd_pcm_link_rwlock, flags); 148 + break; 149 + } 150 + } 151 + } 152 + 102 153 /** 103 154 * snd_pcm_stream_lock - Lock the PCM stream 104 155 * @substream: PCM substream ··· 160 109 */ 161 110 void snd_pcm_stream_lock(struct snd_pcm_substream *substream) 162 111 { 163 - if (substream->pcm->nonatomic) { 164 - down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING); 165 - mutex_lock(&substream->self_group.mutex); 166 - } else { 167 - read_lock(&snd_pcm_link_rwlock); 168 - spin_lock(&substream->self_group.lock); 169 - } 112 + __snd_pcm_stream_lock_mode(substream, PCM_LOCK_DEFAULT); 170 113 } 171 114 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock); 172 115 ··· 172 127 */ 173 128 void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) 174 129 { 175 - if (substream->pcm->nonatomic) { 176 - mutex_unlock(&substream->self_group.mutex); 177 - up_read(&snd_pcm_link_rwsem); 178 - } else { 179 - spin_unlock(&substream->self_group.lock); 180 - read_unlock(&snd_pcm_link_rwlock); 181 - } 130 + __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_DEFAULT, 0); 182 131 } 183 132 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); 184 133 ··· 186 147 */ 187 148 void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) 188 149 { 189 - if (!substream->pcm->nonatomic) 190 - local_irq_disable(); 191 - snd_pcm_stream_lock(substream); 150 + __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQ); 192 151 } 193 152 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); 194 153 ··· 198 161 */ 199 162 void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) 200 163 { 201 - snd_pcm_stream_unlock(substream); 202 - if (!substream->pcm->nonatomic) 203 - local_irq_enable(); 164 + __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQ, 0); 204 165 } 205 166 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq); 206 167 207 168 unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream) 208 169 { 209 - unsigned long flags = 0; 210 - if (!substream->pcm->nonatomic) 211 - local_irq_save(flags); 212 - snd_pcm_stream_lock(substream); 213 - return flags; 170 + return __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQSAVE); 214 171 } 215 172 EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave); 216 173 ··· 218 187 void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, 219 188 unsigned long flags) 220 189 { 221 - snd_pcm_stream_unlock(substream); 222 - if (!substream->pcm->nonatomic) 223 - local_irq_restore(flags); 190 + __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQSAVE, flags); 224 191 } 225 192 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore); 226 193 ··· 886 857 return err; 887 858 } 888 859 860 + static inline snd_pcm_uframes_t 861 + snd_pcm_calc_delay(struct snd_pcm_substream *substream) 862 + { 863 + snd_pcm_uframes_t delay; 864 + 865 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 866 + delay = snd_pcm_playback_hw_avail(substream->runtime); 867 + else 868 + delay = snd_pcm_capture_avail(substream->runtime); 869 + return delay + substream->runtime->delay; 870 + } 871 + 889 872 int snd_pcm_status(struct snd_pcm_substream *substream, 890 873 struct snd_pcm_status *status) 891 874 { ··· 949 908 _tstamp_end: 950 909 status->appl_ptr = runtime->control->appl_ptr; 951 910 status->hw_ptr = runtime->status->hw_ptr; 952 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 953 - status->avail = snd_pcm_playback_avail(runtime); 954 - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING || 955 - runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 956 - status->delay = runtime->buffer_size - status->avail; 957 - status->delay += runtime->delay; 958 - } else 959 - status->delay = 0; 960 - } else { 961 - status->avail = snd_pcm_capture_avail(runtime); 962 - if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) 963 - status->delay = status->avail + runtime->delay; 964 - else 965 - status->delay = 0; 966 - } 911 + status->avail = snd_pcm_avail(substream); 912 + status->delay = snd_pcm_running(substream) ? 913 + snd_pcm_calc_delay(substream) : 0; 967 914 status->avail_max = runtime->avail_max; 968 915 status->overrange = runtime->overrange; 969 916 runtime->avail_max = 0; ··· 2639 2610 return ret < 0 ? 0 : frames; 2640 2611 } 2641 2612 2642 - static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream, 2643 - snd_pcm_uframes_t frames) 2613 + static snd_pcm_sframes_t snd_pcm_rewind(struct snd_pcm_substream *substream, 2614 + snd_pcm_uframes_t frames) 2644 2615 { 2645 - struct snd_pcm_runtime *runtime = substream->runtime; 2646 2616 snd_pcm_sframes_t ret; 2647 2617 2648 2618 if (frames == 0) ··· 2651 2623 ret = do_pcm_hwsync(substream); 2652 2624 if (!ret) 2653 2625 ret = rewind_appl_ptr(substream, frames, 2654 - snd_pcm_playback_hw_avail(runtime)); 2626 + snd_pcm_hw_avail(substream)); 2655 2627 snd_pcm_stream_unlock_irq(substream); 2656 2628 return ret; 2657 2629 } 2658 2630 2659 - static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream, 2660 - snd_pcm_uframes_t frames) 2631 + static snd_pcm_sframes_t snd_pcm_forward(struct snd_pcm_substream *substream, 2632 + snd_pcm_uframes_t frames) 2661 2633 { 2662 - struct snd_pcm_runtime *runtime = substream->runtime; 2663 - snd_pcm_sframes_t ret; 2664 - 2665 - if (frames == 0) 2666 - return 0; 2667 - 2668 - snd_pcm_stream_lock_irq(substream); 2669 - ret = do_pcm_hwsync(substream); 2670 - if (!ret) 2671 - ret = rewind_appl_ptr(substream, frames, 2672 - snd_pcm_capture_hw_avail(runtime)); 2673 - snd_pcm_stream_unlock_irq(substream); 2674 - return ret; 2675 - } 2676 - 2677 - static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream, 2678 - snd_pcm_uframes_t frames) 2679 - { 2680 - struct snd_pcm_runtime *runtime = substream->runtime; 2681 2634 snd_pcm_sframes_t ret; 2682 2635 2683 2636 if (frames == 0) ··· 2668 2659 ret = do_pcm_hwsync(substream); 2669 2660 if (!ret) 2670 2661 ret = forward_appl_ptr(substream, frames, 2671 - snd_pcm_playback_avail(runtime)); 2672 - snd_pcm_stream_unlock_irq(substream); 2673 - return ret; 2674 - } 2675 - 2676 - static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream, 2677 - snd_pcm_uframes_t frames) 2678 - { 2679 - struct snd_pcm_runtime *runtime = substream->runtime; 2680 - snd_pcm_sframes_t ret; 2681 - 2682 - if (frames == 0) 2683 - return 0; 2684 - 2685 - snd_pcm_stream_lock_irq(substream); 2686 - ret = do_pcm_hwsync(substream); 2687 - if (!ret) 2688 - ret = forward_appl_ptr(substream, frames, 2689 - snd_pcm_capture_avail(runtime)); 2662 + snd_pcm_avail(substream)); 2690 2663 snd_pcm_stream_unlock_irq(substream); 2691 2664 return ret; 2692 2665 } ··· 2686 2695 static int snd_pcm_delay(struct snd_pcm_substream *substream, 2687 2696 snd_pcm_sframes_t *delay) 2688 2697 { 2689 - struct snd_pcm_runtime *runtime = substream->runtime; 2690 2698 int err; 2691 2699 snd_pcm_sframes_t n = 0; 2692 2700 2693 2701 snd_pcm_stream_lock_irq(substream); 2694 2702 err = do_pcm_hwsync(substream); 2695 - if (!err) { 2696 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2697 - n = snd_pcm_playback_hw_avail(runtime); 2698 - else 2699 - n = snd_pcm_capture_avail(runtime); 2700 - n += runtime->delay; 2701 - } 2703 + if (!err) 2704 + n = snd_pcm_calc_delay(substream); 2702 2705 snd_pcm_stream_unlock_irq(substream); 2703 2706 if (!err) 2704 2707 *delay = n; ··· 2819 2834 return -EFAULT; 2820 2835 if (put_user(0, _frames)) 2821 2836 return -EFAULT; 2822 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2823 - result = snd_pcm_playback_rewind(substream, frames); 2824 - else 2825 - result = snd_pcm_capture_rewind(substream, frames); 2837 + result = snd_pcm_rewind(substream, frames); 2826 2838 __put_user(result, _frames); 2827 2839 return result < 0 ? result : 0; 2828 2840 } ··· 2834 2852 return -EFAULT; 2835 2853 if (put_user(0, _frames)) 2836 2854 return -EFAULT; 2837 - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2838 - result = snd_pcm_playback_forward(substream, frames); 2839 - else 2840 - result = snd_pcm_capture_forward(substream, frames); 2855 + result = snd_pcm_forward(substream, frames); 2841 2856 __put_user(result, _frames); 2842 2857 return result < 0 ? result : 0; 2843 2858 } ··· 2977 2998 /* provided only for OSS; capture-only and no value returned */ 2978 2999 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) 2979 3000 return -EINVAL; 2980 - result = snd_pcm_capture_forward(substream, *frames); 3001 + result = snd_pcm_forward(substream, *frames); 2981 3002 return result < 0 ? result : 0; 2982 3003 } 2983 3004 case SNDRV_PCM_IOCTL_HW_PARAMS: ··· 3119 3140 return result; 3120 3141 } 3121 3142 3122 - static __poll_t snd_pcm_playback_poll(struct file *file, poll_table * wait) 3143 + static __poll_t snd_pcm_poll(struct file *file, poll_table *wait) 3123 3144 { 3124 3145 struct snd_pcm_file *pcm_file; 3125 3146 struct snd_pcm_substream *substream; 3126 3147 struct snd_pcm_runtime *runtime; 3127 - __poll_t mask; 3148 + __poll_t mask, ok; 3128 3149 snd_pcm_uframes_t avail; 3129 3150 3130 3151 pcm_file = file->private_data; 3131 3152 3132 3153 substream = pcm_file->substream; 3154 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 3155 + ok = EPOLLOUT | EPOLLWRNORM; 3156 + else 3157 + ok = EPOLLIN | EPOLLRDNORM; 3133 3158 if (PCM_RUNTIME_CHECK(substream)) 3134 - return EPOLLOUT | EPOLLWRNORM | EPOLLERR; 3135 - runtime = substream->runtime; 3159 + return ok | EPOLLERR; 3136 3160 3161 + runtime = substream->runtime; 3137 3162 poll_wait(file, &runtime->sleep, wait); 3138 3163 3164 + mask = 0; 3139 3165 snd_pcm_stream_lock_irq(substream); 3140 - avail = snd_pcm_playback_avail(runtime); 3166 + avail = snd_pcm_avail(substream); 3141 3167 switch (runtime->status->state) { 3142 3168 case SNDRV_PCM_STATE_RUNNING: 3143 3169 case SNDRV_PCM_STATE_PREPARED: 3144 3170 case SNDRV_PCM_STATE_PAUSED: 3145 - if (avail >= runtime->control->avail_min) { 3146 - mask = EPOLLOUT | EPOLLWRNORM; 3147 - break; 3148 - } 3149 - /* Fall through */ 3150 - case SNDRV_PCM_STATE_DRAINING: 3151 - mask = 0; 3152 - break; 3153 - default: 3154 - mask = EPOLLOUT | EPOLLWRNORM | EPOLLERR; 3155 - break; 3156 - } 3157 - snd_pcm_stream_unlock_irq(substream); 3158 - return mask; 3159 - } 3160 - 3161 - static __poll_t snd_pcm_capture_poll(struct file *file, poll_table * wait) 3162 - { 3163 - struct snd_pcm_file *pcm_file; 3164 - struct snd_pcm_substream *substream; 3165 - struct snd_pcm_runtime *runtime; 3166 - __poll_t mask; 3167 - snd_pcm_uframes_t avail; 3168 - 3169 - pcm_file = file->private_data; 3170 - 3171 - substream = pcm_file->substream; 3172 - if (PCM_RUNTIME_CHECK(substream)) 3173 - return EPOLLIN | EPOLLRDNORM | EPOLLERR; 3174 - runtime = substream->runtime; 3175 - 3176 - poll_wait(file, &runtime->sleep, wait); 3177 - 3178 - snd_pcm_stream_lock_irq(substream); 3179 - avail = snd_pcm_capture_avail(runtime); 3180 - switch (runtime->status->state) { 3181 - case SNDRV_PCM_STATE_RUNNING: 3182 - case SNDRV_PCM_STATE_PREPARED: 3183 - case SNDRV_PCM_STATE_PAUSED: 3184 - if (avail >= runtime->control->avail_min) { 3185 - mask = EPOLLIN | EPOLLRDNORM; 3186 - break; 3187 - } 3188 - mask = 0; 3171 + if (avail >= runtime->control->avail_min) 3172 + mask = ok; 3189 3173 break; 3190 3174 case SNDRV_PCM_STATE_DRAINING: 3191 - if (avail > 0) { 3192 - mask = EPOLLIN | EPOLLRDNORM; 3193 - break; 3175 + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 3176 + mask = ok; 3177 + if (!avail) 3178 + mask |= EPOLLERR; 3194 3179 } 3195 - /* Fall through */ 3180 + break; 3196 3181 default: 3197 - mask = EPOLLIN | EPOLLRDNORM | EPOLLERR; 3182 + mask = ok | EPOLLERR; 3198 3183 break; 3199 3184 } 3200 3185 snd_pcm_stream_unlock_irq(substream); ··· 3650 3707 .open = snd_pcm_playback_open, 3651 3708 .release = snd_pcm_release, 3652 3709 .llseek = no_llseek, 3653 - .poll = snd_pcm_playback_poll, 3710 + .poll = snd_pcm_poll, 3654 3711 .unlocked_ioctl = snd_pcm_ioctl, 3655 3712 .compat_ioctl = snd_pcm_ioctl_compat, 3656 3713 .mmap = snd_pcm_mmap, ··· 3664 3721 .open = snd_pcm_capture_open, 3665 3722 .release = snd_pcm_release, 3666 3723 .llseek = no_llseek, 3667 - .poll = snd_pcm_capture_poll, 3724 + .poll = snd_pcm_poll, 3668 3725 .unlocked_ioctl = snd_pcm_ioctl, 3669 3726 .compat_ioctl = snd_pcm_ioctl_compat, 3670 3727 .mmap = snd_pcm_mmap,
+1 -1
sound/core/seq/seq_ports.c
··· 669 669 /* Set up the port */ 670 670 memset(&portinfo, 0, sizeof(portinfo)); 671 671 portinfo.addr.client = client; 672 - strlcpy(portinfo.name, portname ? portname : "Unamed port", 672 + strlcpy(portinfo.name, portname ? portname : "Unnamed port", 673 673 sizeof(portinfo.name)); 674 674 675 675 portinfo.capability = cap;
+1 -3
sound/core/seq/seq_timer.c
··· 371 371 372 372 tmr->ticks = 1; 373 373 if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { 374 - unsigned long r = t->hw.resolution; 375 - if (! r && t->hw.c_resolution) 376 - r = t->hw.c_resolution(t); 374 + unsigned long r = snd_timer_resolution(tmr->timeri); 377 375 if (r) { 378 376 tmr->ticks = (unsigned int)(1000000000uL / (r * freq)); 379 377 if (! tmr->ticks)
+25 -23
sound/core/timer.c
··· 427 427 } 428 428 EXPORT_SYMBOL(snd_timer_close); 429 429 430 + static unsigned long snd_timer_hw_resolution(struct snd_timer *timer) 431 + { 432 + if (timer->hw.c_resolution) 433 + return timer->hw.c_resolution(timer); 434 + else 435 + return timer->hw.resolution; 436 + } 437 + 430 438 unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) 431 439 { 432 440 struct snd_timer * timer; 441 + unsigned long ret = 0; 442 + unsigned long flags; 433 443 434 444 if (timeri == NULL) 435 445 return 0; 436 446 timer = timeri->timer; 437 447 if (timer) { 438 - if (timer->hw.c_resolution) 439 - return timer->hw.c_resolution(timer); 440 - return timer->hw.resolution; 448 + spin_lock_irqsave(&timer->lock, flags); 449 + ret = snd_timer_hw_resolution(timer); 450 + spin_unlock_irqrestore(&timer->lock, flags); 441 451 } 442 - return 0; 452 + return ret; 443 453 } 444 454 EXPORT_SYMBOL(snd_timer_resolution); 445 455 446 456 static void snd_timer_notify1(struct snd_timer_instance *ti, int event) 447 457 { 448 - struct snd_timer *timer; 458 + struct snd_timer *timer = ti->timer; 449 459 unsigned long resolution = 0; 450 460 struct snd_timer_instance *ts; 451 461 struct timespec tstamp; ··· 467 457 if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START || 468 458 event > SNDRV_TIMER_EVENT_PAUSE)) 469 459 return; 470 - if (event == SNDRV_TIMER_EVENT_START || 471 - event == SNDRV_TIMER_EVENT_CONTINUE) 472 - resolution = snd_timer_resolution(ti); 460 + if (timer && 461 + (event == SNDRV_TIMER_EVENT_START || 462 + event == SNDRV_TIMER_EVENT_CONTINUE)) 463 + resolution = snd_timer_hw_resolution(timer); 473 464 if (ti->ccallback) 474 465 ti->ccallback(ti, event, &tstamp, resolution); 475 466 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) 476 467 return; 477 - timer = ti->timer; 478 468 if (timer == NULL) 479 469 return; 480 470 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) ··· 781 771 spin_lock_irqsave(&timer->lock, flags); 782 772 783 773 /* remember the current resolution */ 784 - if (timer->hw.c_resolution) 785 - resolution = timer->hw.c_resolution(timer); 786 - else 787 - resolution = timer->hw.resolution; 774 + resolution = snd_timer_hw_resolution(timer); 788 775 789 776 /* loop for all active instances 790 777 * Here we cannot use list_for_each_entry because the active_list of a ··· 1021 1014 spin_lock_irqsave(&timer->lock, flags); 1022 1015 if (event == SNDRV_TIMER_EVENT_MSTART || 1023 1016 event == SNDRV_TIMER_EVENT_MCONTINUE || 1024 - event == SNDRV_TIMER_EVENT_MRESUME) { 1025 - if (timer->hw.c_resolution) 1026 - resolution = timer->hw.c_resolution(timer); 1027 - else 1028 - resolution = timer->hw.resolution; 1029 - } 1017 + event == SNDRV_TIMER_EVENT_MRESUME) 1018 + resolution = snd_timer_hw_resolution(timer); 1030 1019 list_for_each_entry(ti, &timer->active_list_head, active_list) { 1031 1020 if (ti->ccallback) 1032 1021 ti->ccallback(ti, event, tstamp, resolution); ··· 1659 1656 mutex_lock(&register_mutex); 1660 1657 t = snd_timer_find(&tid); 1661 1658 if (t != NULL) { 1662 - if (t->hw.c_resolution) 1663 - gstatus.resolution = t->hw.c_resolution(t); 1664 - else 1665 - gstatus.resolution = t->hw.resolution; 1659 + spin_lock_irq(&t->lock); 1660 + gstatus.resolution = snd_timer_hw_resolution(t); 1666 1661 if (t->hw.precise_resolution) { 1667 1662 t->hw.precise_resolution(t, &gstatus.resolution_num, 1668 1663 &gstatus.resolution_den); ··· 1668 1667 gstatus.resolution_num = gstatus.resolution; 1669 1668 gstatus.resolution_den = 1000000000uL; 1670 1669 } 1670 + spin_unlock_irq(&t->lock); 1671 1671 } else { 1672 1672 err = -ENODEV; 1673 1673 }
+9 -7
sound/core/vmaster.c
··· 421 421 kctl->private_free = master_free; 422 422 423 423 /* additional (constant) TLV read */ 424 - if (tlv && 425 - (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE || 426 - tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX || 427 - tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) { 428 - kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 429 - memcpy(master->tlv, tlv, sizeof(master->tlv)); 430 - kctl->tlv.p = master->tlv; 424 + if (tlv) { 425 + unsigned int type = tlv[SNDRV_CTL_TLVO_TYPE]; 426 + if (type == SNDRV_CTL_TLVT_DB_SCALE || 427 + type == SNDRV_CTL_TLVT_DB_MINMAX || 428 + type == SNDRV_CTL_TLVT_DB_MINMAX_MUTE) { 429 + kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 430 + memcpy(master->tlv, tlv, sizeof(master->tlv)); 431 + kctl->tlv.p = master->tlv; 432 + } 431 433 } 432 434 433 435 return kctl;
+3 -16
sound/drivers/aloop.c
··· 768 768 return 0; 769 769 } 770 770 771 - static const struct snd_pcm_ops loopback_playback_ops = { 772 - .open = loopback_open, 773 - .close = loopback_close, 774 - .ioctl = snd_pcm_lib_ioctl, 775 - .hw_params = loopback_hw_params, 776 - .hw_free = loopback_hw_free, 777 - .prepare = loopback_prepare, 778 - .trigger = loopback_trigger, 779 - .pointer = loopback_pointer, 780 - .page = snd_pcm_lib_get_vmalloc_page, 781 - .mmap = snd_pcm_lib_mmap_vmalloc, 782 - }; 783 - 784 - static const struct snd_pcm_ops loopback_capture_ops = { 771 + static const struct snd_pcm_ops loopback_pcm_ops = { 785 772 .open = loopback_open, 786 773 .close = loopback_close, 787 774 .ioctl = snd_pcm_lib_ioctl, ··· 791 804 substreams, substreams, &pcm); 792 805 if (err < 0) 793 806 return err; 794 - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops); 795 - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops); 807 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_pcm_ops); 808 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_pcm_ops); 796 809 797 810 pcm->private_data = loopback; 798 811 pcm->info_flags = 0;
+1 -1
sound/drivers/dummy.c
··· 1042 1042 if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) { 1043 1043 snd_info_set_text_ops(entry, chip, dummy_proc_read); 1044 1044 entry->c.text.write = dummy_proc_write; 1045 - entry->mode |= S_IWUSR; 1045 + entry->mode |= 0200; 1046 1046 entry->private_data = chip; 1047 1047 } 1048 1048 }
+3 -3
sound/drivers/mts64.c
··· 41 41 static struct platform_device *platform_devices[SNDRV_CARDS]; 42 42 static int device_count; 43 43 44 - module_param_array(index, int, NULL, S_IRUGO); 44 + module_param_array(index, int, NULL, 0444); 45 45 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 46 - module_param_array(id, charp, NULL, S_IRUGO); 46 + module_param_array(id, charp, NULL, 0444); 47 47 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); 48 - module_param_array(enable, bool, NULL, S_IRUGO); 48 + module_param_array(enable, bool, NULL, 0444); 49 49 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); 50 50 51 51 MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");
+1 -1
sound/drivers/opl4/opl4_proc.c
··· 104 104 if (entry) { 105 105 if (opl4->hardware < OPL3_HW_OPL4_ML) { 106 106 /* OPL4 can access 4 MB external ROM/SRAM */ 107 - entry->mode |= S_IWUSR; 107 + entry->mode |= 0200; 108 108 entry->size = 4 * 1024 * 1024; 109 109 } else { 110 110 /* OPL4-ML has 1 MB internal ROM */
+3 -3
sound/drivers/portman2x4.c
··· 60 60 static struct platform_device *platform_devices[SNDRV_CARDS]; 61 61 static int device_count; 62 62 63 - module_param_array(index, int, NULL, S_IRUGO); 63 + module_param_array(index, int, NULL, 0444); 64 64 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); 65 - module_param_array(id, charp, NULL, S_IRUGO); 65 + module_param_array(id, charp, NULL, 0444); 66 66 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); 67 - module_param_array(enable, bool, NULL, S_IRUGO); 67 + module_param_array(enable, bool, NULL, 0444); 68 68 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); 69 69 70 70 MODULE_AUTHOR("Levent Guendogdu, Tobias Gehrig, Matthias Koenig");
+1 -1
sound/firewire/bebob/bebob_proc.c
··· 183 183 bebob->card->proc_root); 184 184 if (root == NULL) 185 185 return; 186 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 186 + root->mode = S_IFDIR | 0555; 187 187 if (snd_info_register(root) < 0) { 188 188 snd_info_free_entry(root); 189 189 return;
+2 -1
sound/firewire/dice/Makefile
··· 1 1 snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \ 2 - dice-pcm.o dice-hwdep.o dice.o 2 + dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \ 3 + dice-alesis.o dice-extension.o dice-mytek.o 3 4 obj-$(CONFIG_SND_DICE) += snd-dice.o
+52
sound/firewire/dice/dice-alesis.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * dice-alesis.c - a part of driver for DICE based devices 4 + * 5 + * Copyright (c) 2018 Takashi Sakamoto 6 + */ 7 + 8 + #include "dice.h" 9 + 10 + static const unsigned int 11 + alesis_io14_tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT] = { 12 + {6, 6, 4}, /* Tx0 = Analog + S/PDIF. */ 13 + {8, 4, 0}, /* Tx1 = ADAT1. */ 14 + }; 15 + 16 + static const unsigned int 17 + alesis_io26_tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT] = { 18 + {10, 10, 8}, /* Tx0 = Analog + S/PDIF. */ 19 + {16, 8, 0}, /* Tx1 = ADAT1 + ADAT2. */ 20 + }; 21 + 22 + int snd_dice_detect_alesis_formats(struct snd_dice *dice) 23 + { 24 + __be32 reg; 25 + u32 data; 26 + int i; 27 + int err; 28 + 29 + err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO, &reg, 30 + sizeof(reg)); 31 + if (err < 0) 32 + return err; 33 + data = be32_to_cpu(reg); 34 + 35 + if (data == 4 || data == 6) { 36 + memcpy(dice->tx_pcm_chs, alesis_io14_tx_pcm_chs, 37 + MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * 38 + sizeof(unsigned int)); 39 + } else { 40 + memcpy(dice->rx_pcm_chs, alesis_io26_tx_pcm_chs, 41 + MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * 42 + sizeof(unsigned int)); 43 + } 44 + 45 + for (i = 0; i < SND_DICE_RATE_MODE_COUNT; ++i) 46 + dice->rx_pcm_chs[0][i] = 8; 47 + 48 + dice->tx_midi_ports[0] = 1; 49 + dice->rx_midi_ports[0] = 1; 50 + 51 + return 0; 52 + }
+172
sound/firewire/dice/dice-extension.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * dice-extension.c - a part of driver for DICE based devices 4 + * 5 + * Copyright (c) 2018 Takashi Sakamoto 6 + */ 7 + 8 + #include "dice.h" 9 + 10 + /* For TCD2210/2220, TCAT defines extension of application protocol. */ 11 + 12 + #define DICE_EXT_APP_SPACE 0xffffe0200000uLL 13 + 14 + #define DICE_EXT_APP_CAPS_OFFSET 0x00 15 + #define DICE_EXT_APP_CAPS_SIZE 0x04 16 + #define DICE_EXT_APP_CMD_OFFSET 0x08 17 + #define DICE_EXT_APP_CMD_SIZE 0x0c 18 + #define DICE_EXT_APP_MIXER_OFFSET 0x10 19 + #define DICE_EXT_APP_MIXER_SIZE 0x14 20 + #define DICE_EXT_APP_PEAK_OFFSET 0x18 21 + #define DICE_EXT_APP_PEAK_SIZE 0x1c 22 + #define DICE_EXT_APP_ROUTER_OFFSET 0x20 23 + #define DICE_EXT_APP_ROUTER_SIZE 0x24 24 + #define DICE_EXT_APP_STREAM_OFFSET 0x28 25 + #define DICE_EXT_APP_STREAM_SIZE 0x2c 26 + #define DICE_EXT_APP_CURRENT_OFFSET 0x30 27 + #define DICE_EXT_APP_CURRENT_SIZE 0x34 28 + #define DICE_EXT_APP_STANDALONE_OFFSET 0x38 29 + #define DICE_EXT_APP_STANDALONE_SIZE 0x3c 30 + #define DICE_EXT_APP_APPLICATION_OFFSET 0x40 31 + #define DICE_EXT_APP_APPLICATION_SIZE 0x44 32 + 33 + #define EXT_APP_STREAM_TX_NUMBER 0x0000 34 + #define EXT_APP_STREAM_RX_NUMBER 0x0004 35 + #define EXT_APP_STREAM_ENTRIES 0x0008 36 + #define EXT_APP_STREAM_ENTRY_SIZE 0x010c 37 + #define EXT_APP_NUMBER_AUDIO 0x0000 38 + #define EXT_APP_NUMBER_MIDI 0x0004 39 + #define EXT_APP_NAMES 0x0008 40 + #define EXT_APP_NAMES_SIZE 256 41 + #define EXT_APP_AC3 0x0108 42 + 43 + #define EXT_APP_CONFIG_LOW_ROUTER 0x0000 44 + #define EXT_APP_CONFIG_LOW_STREAM 0x1000 45 + #define EXT_APP_CONFIG_MIDDLE_ROUTER 0x2000 46 + #define EXT_APP_CONFIG_MIDDLE_STREAM 0x3000 47 + #define EXT_APP_CONFIG_HIGH_ROUTER 0x4000 48 + #define EXT_APP_CONFIG_HIGH_STREAM 0x5000 49 + 50 + static inline int read_transaction(struct snd_dice *dice, u64 section_addr, 51 + u32 offset, void *buf, size_t len) 52 + { 53 + return snd_fw_transaction(dice->unit, 54 + len == 4 ? TCODE_READ_QUADLET_REQUEST : 55 + TCODE_READ_BLOCK_REQUEST, 56 + section_addr + offset, buf, len, 0); 57 + } 58 + 59 + static int read_stream_entries(struct snd_dice *dice, u64 section_addr, 60 + u32 base_offset, unsigned int stream_count, 61 + unsigned int mode, 62 + unsigned int pcm_channels[MAX_STREAMS][3], 63 + unsigned int midi_ports[MAX_STREAMS]) 64 + { 65 + u32 entry_offset; 66 + __be32 reg[2]; 67 + int err; 68 + int i; 69 + 70 + for (i = 0; i < stream_count; ++i) { 71 + entry_offset = base_offset + i * EXT_APP_STREAM_ENTRY_SIZE; 72 + err = read_transaction(dice, section_addr, 73 + entry_offset + EXT_APP_NUMBER_AUDIO, 74 + reg, sizeof(reg)); 75 + if (err < 0) 76 + return err; 77 + pcm_channels[i][mode] = be32_to_cpu(reg[0]); 78 + midi_ports[i] = max(midi_ports[i], be32_to_cpu(reg[1])); 79 + } 80 + 81 + return 0; 82 + } 83 + 84 + static int detect_stream_formats(struct snd_dice *dice, u64 section_addr) 85 + { 86 + u32 base_offset; 87 + __be32 reg[2]; 88 + unsigned int stream_count; 89 + int mode; 90 + int err = 0; 91 + 92 + for (mode = 0; mode < SND_DICE_RATE_MODE_COUNT; ++mode) { 93 + unsigned int cap; 94 + 95 + /* 96 + * Some models report stream formats at highest mode, however 97 + * they don't support the mode. Check clock capabilities. 98 + */ 99 + if (mode == 2) { 100 + cap = CLOCK_CAP_RATE_176400 | CLOCK_CAP_RATE_192000; 101 + } else if (mode == 1) { 102 + cap = CLOCK_CAP_RATE_88200 | CLOCK_CAP_RATE_96000; 103 + } else { 104 + cap = CLOCK_CAP_RATE_32000 | CLOCK_CAP_RATE_44100 | 105 + CLOCK_CAP_RATE_48000; 106 + } 107 + if (!(cap & dice->clock_caps)) 108 + continue; 109 + 110 + base_offset = 0x2000 * mode + 0x1000; 111 + 112 + err = read_transaction(dice, section_addr, 113 + base_offset + EXT_APP_STREAM_TX_NUMBER, 114 + &reg, sizeof(reg)); 115 + if (err < 0) 116 + break; 117 + 118 + base_offset += EXT_APP_STREAM_ENTRIES; 119 + stream_count = be32_to_cpu(reg[0]); 120 + err = read_stream_entries(dice, section_addr, base_offset, 121 + stream_count, mode, 122 + dice->tx_pcm_chs, 123 + dice->tx_midi_ports); 124 + if (err < 0) 125 + break; 126 + 127 + base_offset += stream_count * EXT_APP_STREAM_ENTRY_SIZE; 128 + stream_count = be32_to_cpu(reg[1]); 129 + err = read_stream_entries(dice, section_addr, base_offset, 130 + stream_count, 131 + mode, dice->rx_pcm_chs, 132 + dice->rx_midi_ports); 133 + if (err < 0) 134 + break; 135 + } 136 + 137 + return err; 138 + } 139 + 140 + int snd_dice_detect_extension_formats(struct snd_dice *dice) 141 + { 142 + __be32 *pointers; 143 + unsigned int i; 144 + u64 section_addr; 145 + int err; 146 + 147 + pointers = kmalloc_array(9, sizeof(__be32) * 2, GFP_KERNEL); 148 + if (pointers == NULL) 149 + return -ENOMEM; 150 + 151 + err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST, 152 + DICE_EXT_APP_SPACE, pointers, 153 + 9 * sizeof(__be32) * 2, 0); 154 + if (err < 0) 155 + goto end; 156 + 157 + /* Check two of them for offset have the same value or not. */ 158 + for (i = 0; i < 9; ++i) { 159 + int j; 160 + 161 + for (j = i + 1; j < 9; ++j) { 162 + if (pointers[i * 2] == pointers[j * 2]) 163 + goto end; 164 + } 165 + } 166 + 167 + section_addr = DICE_EXT_APP_SPACE + be32_to_cpu(pointers[12]) * 4; 168 + err = detect_stream_formats(dice, section_addr); 169 + end: 170 + kfree(pointers); 171 + return err; 172 + }
+7 -2
sound/firewire/dice/dice-interface.h
··· 175 175 #define GLOBAL_SAMPLE_RATE 0x05c 176 176 177 177 /* 178 + * Some old firmware versions do not have the following global registers. 179 + * Windows drivers produced by TCAT lost backward compatibility in its 180 + * early release because they can handle firmware only which supports the 181 + * following registers. 182 + */ 183 + 184 + /* 178 185 * The version of the DICE driver specification that this device conforms to; 179 186 * read-only. 180 187 */ 181 188 #define GLOBAL_VERSION 0x060 182 - 183 - /* Some old firmware versions do not have the following global registers: */ 184 189 185 190 /* 186 191 * Supported sample rates and clock sources; read-only.
+7 -16
sound/firewire/dice/dice-midi.c
··· 101 101 .close = midi_close, 102 102 .trigger = midi_playback_trigger, 103 103 }; 104 - __be32 reg; 105 104 struct snd_rawmidi *rmidi; 106 105 struct snd_rawmidi_str *str; 107 106 unsigned int midi_in_ports, midi_out_ports; 107 + int i; 108 108 int err; 109 109 110 - /* 111 - * Use the number of MIDI conformant data channel at current sampling 112 - * transfer frequency. 113 - */ 114 - err = snd_dice_transaction_read_tx(dice, TX_NUMBER_MIDI, 115 - &reg, sizeof(reg)); 116 - if (err < 0) 117 - return err; 118 - midi_in_ports = be32_to_cpu(reg); 119 - 120 - err = snd_dice_transaction_read_rx(dice, RX_NUMBER_MIDI, 121 - &reg, sizeof(reg)); 122 - if (err < 0) 123 - return err; 124 - midi_out_ports = be32_to_cpu(reg); 110 + midi_in_ports = 0; 111 + midi_out_ports = 0; 112 + for (i = 0; i < MAX_STREAMS; ++i) { 113 + midi_in_ports = max(midi_in_ports, dice->tx_midi_ports[i]); 114 + midi_out_ports = max(midi_out_ports, dice->rx_midi_ports[i]); 115 + } 125 116 126 117 if (midi_in_ports + midi_out_ports == 0) 127 118 return 0;
+46
sound/firewire/dice/dice-mytek.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * dice-mytek.c - a part of driver for DICE based devices 4 + * 5 + * Copyright (c) 2018 Melvin Vermeeren 6 + */ 7 + 8 + #include "dice.h" 9 + 10 + struct dice_mytek_spec { 11 + unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; 12 + unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; 13 + }; 14 + 15 + static const struct dice_mytek_spec stereo_192_dsd_dac = { 16 + /* AES, TOSLINK, SPDIF, ADAT inputs on device */ 17 + .tx_pcm_chs = {{8, 8, 8}, {0, 0, 0} }, 18 + /* PCM 44.1-192, native DSD64/DSD128 to device */ 19 + .rx_pcm_chs = {{4, 4, 4}, {0, 0, 0} } 20 + }; 21 + 22 + /* 23 + * Mytek has a few other firewire-capable devices, though newer models appear 24 + * to lack the port more often than not. As I don't have access to any of them 25 + * they are missing here. An example is the Mytek 8x192 ADDA, which is DICE. 26 + */ 27 + 28 + int snd_dice_detect_mytek_formats(struct snd_dice *dice) 29 + { 30 + int i; 31 + const struct dice_mytek_spec *dev; 32 + 33 + dev = &stereo_192_dsd_dac; 34 + 35 + memcpy(dice->tx_pcm_chs, dev->tx_pcm_chs, 36 + MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int)); 37 + memcpy(dice->rx_pcm_chs, dev->rx_pcm_chs, 38 + MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int)); 39 + 40 + for (i = 0; i < MAX_STREAMS; ++i) { 41 + dice->tx_midi_ports[i] = 0; 42 + dice->rx_midi_ports[i] = 0; 43 + } 44 + 45 + return 0; 46 + }
+161 -70
sound/firewire/dice/dice-pcm.c
··· 9 9 10 10 #include "dice.h" 11 11 12 + static int dice_rate_constraint(struct snd_pcm_hw_params *params, 13 + struct snd_pcm_hw_rule *rule) 14 + { 15 + struct snd_pcm_substream *substream = rule->private; 16 + struct snd_dice *dice = substream->private_data; 17 + unsigned int index = substream->pcm->device; 18 + 19 + const struct snd_interval *c = 20 + hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 21 + struct snd_interval *r = 22 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 23 + struct snd_interval rates = { 24 + .min = UINT_MAX, .max = 0, .integer = 1 25 + }; 26 + unsigned int *pcm_channels; 27 + enum snd_dice_rate_mode mode; 28 + unsigned int i, rate; 29 + 30 + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 31 + pcm_channels = dice->tx_pcm_chs[index]; 32 + else 33 + pcm_channels = dice->rx_pcm_chs[index]; 34 + 35 + for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { 36 + rate = snd_dice_rates[i]; 37 + if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) 38 + continue; 39 + 40 + if (!snd_interval_test(c, pcm_channels[mode])) 41 + continue; 42 + 43 + rates.min = min(rates.min, rate); 44 + rates.max = max(rates.max, rate); 45 + } 46 + 47 + return snd_interval_refine(r, &rates); 48 + } 49 + 50 + static int dice_channels_constraint(struct snd_pcm_hw_params *params, 51 + struct snd_pcm_hw_rule *rule) 52 + { 53 + struct snd_pcm_substream *substream = rule->private; 54 + struct snd_dice *dice = substream->private_data; 55 + unsigned int index = substream->pcm->device; 56 + 57 + const struct snd_interval *r = 58 + hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 59 + struct snd_interval *c = 60 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 61 + struct snd_interval channels = { 62 + .min = UINT_MAX, .max = 0, .integer = 1 63 + }; 64 + unsigned int *pcm_channels; 65 + enum snd_dice_rate_mode mode; 66 + unsigned int i, rate; 67 + 68 + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 69 + pcm_channels = dice->tx_pcm_chs[index]; 70 + else 71 + pcm_channels = dice->rx_pcm_chs[index]; 72 + 73 + for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { 74 + rate = snd_dice_rates[i]; 75 + if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) 76 + continue; 77 + 78 + if (!snd_interval_test(r, rate)) 79 + continue; 80 + 81 + channels.min = min(channels.min, pcm_channels[mode]); 82 + channels.max = max(channels.max, pcm_channels[mode]); 83 + } 84 + 85 + return snd_interval_refine(c, &channels); 86 + } 87 + 12 88 static int limit_channels_and_rates(struct snd_dice *dice, 13 89 struct snd_pcm_runtime *runtime, 14 90 enum amdtp_stream_direction dir, 15 - unsigned int index, unsigned int size) 91 + unsigned int index) 16 92 { 17 93 struct snd_pcm_hardware *hw = &runtime->hw; 18 - struct amdtp_stream *stream; 19 - unsigned int rate; 20 - __be32 reg; 21 - int err; 94 + unsigned int *pcm_channels; 95 + unsigned int i; 22 96 23 - /* 24 - * Retrieve current Multi Bit Linear Audio data channel and limit to 25 - * it. 26 - */ 27 - if (dir == AMDTP_IN_STREAM) { 28 - stream = &dice->tx_stream[index]; 29 - err = snd_dice_transaction_read_tx(dice, 30 - size * index + TX_NUMBER_AUDIO, 31 - &reg, sizeof(reg)); 32 - } else { 33 - stream = &dice->rx_stream[index]; 34 - err = snd_dice_transaction_read_rx(dice, 35 - size * index + RX_NUMBER_AUDIO, 36 - &reg, sizeof(reg)); 97 + if (dir == AMDTP_IN_STREAM) 98 + pcm_channels = dice->tx_pcm_chs[index]; 99 + else 100 + pcm_channels = dice->rx_pcm_chs[index]; 101 + 102 + hw->channels_min = UINT_MAX; 103 + hw->channels_max = 0; 104 + 105 + for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { 106 + enum snd_dice_rate_mode mode; 107 + unsigned int rate, channels; 108 + 109 + rate = snd_dice_rates[i]; 110 + if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0) 111 + continue; 112 + hw->rates |= snd_pcm_rate_to_rate_bit(rate); 113 + 114 + channels = pcm_channels[mode]; 115 + if (channels == 0) 116 + continue; 117 + hw->channels_min = min(hw->channels_min, channels); 118 + hw->channels_max = max(hw->channels_max, channels); 37 119 } 38 - if (err < 0) 39 - return err; 40 120 41 - hw->channels_min = hw->channels_max = be32_to_cpu(reg); 42 - 43 - /* Retrieve current sampling transfer frequency and limit to it. */ 44 - err = snd_dice_transaction_get_rate(dice, &rate); 45 - if (err < 0) 46 - return err; 47 - 48 - hw->rates = snd_pcm_rate_to_rate_bit(rate); 49 121 snd_pcm_limit_hw_rates(runtime); 50 122 51 123 return 0; ··· 128 56 { 129 57 struct snd_pcm_runtime *runtime = substream->runtime; 130 58 struct snd_pcm_hardware *hw = &runtime->hw; 59 + unsigned int index = substream->pcm->device; 131 60 enum amdtp_stream_direction dir; 132 61 struct amdtp_stream *stream; 133 - __be32 reg[2]; 134 - unsigned int count, size; 135 62 int err; 136 63 137 64 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 138 65 hw->formats = AM824_IN_PCM_FORMAT_BITS; 139 66 dir = AMDTP_IN_STREAM; 140 - stream = &dice->tx_stream[substream->pcm->device]; 141 - err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, 142 - sizeof(reg)); 67 + stream = &dice->tx_stream[index]; 143 68 } else { 144 69 hw->formats = AM824_OUT_PCM_FORMAT_BITS; 145 70 dir = AMDTP_OUT_STREAM; 146 - stream = &dice->rx_stream[substream->pcm->device]; 147 - err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, 148 - sizeof(reg)); 71 + stream = &dice->rx_stream[index]; 149 72 } 150 73 74 + err = limit_channels_and_rates(dice, substream->runtime, dir, 75 + index); 151 76 if (err < 0) 152 77 return err; 153 78 154 - count = min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS); 155 - if (substream->pcm->device >= count) 156 - return -ENXIO; 157 - 158 - size = be32_to_cpu(reg[1]) * 4; 159 - err = limit_channels_and_rates(dice, substream->runtime, dir, 160 - substream->pcm->device, size); 79 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 80 + dice_rate_constraint, substream, 81 + SNDRV_PCM_HW_PARAM_CHANNELS, -1); 82 + if (err < 0) 83 + return err; 84 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 85 + dice_channels_constraint, substream, 86 + SNDRV_PCM_HW_PARAM_RATE, -1); 161 87 if (err < 0) 162 88 return err; 163 89 ··· 165 95 static int pcm_open(struct snd_pcm_substream *substream) 166 96 { 167 97 struct snd_dice *dice = substream->private_data; 98 + unsigned int source; 99 + bool internal; 168 100 int err; 169 101 170 102 err = snd_dice_stream_lock_try(dice); ··· 176 104 err = init_hw_info(dice, substream); 177 105 if (err < 0) 178 106 goto err_locked; 107 + 108 + err = snd_dice_transaction_get_clock_source(dice, &source); 109 + if (err < 0) 110 + goto err_locked; 111 + switch (source) { 112 + case CLOCK_SOURCE_AES1: 113 + case CLOCK_SOURCE_AES2: 114 + case CLOCK_SOURCE_AES3: 115 + case CLOCK_SOURCE_AES4: 116 + case CLOCK_SOURCE_AES_ANY: 117 + case CLOCK_SOURCE_ADAT: 118 + case CLOCK_SOURCE_TDIF: 119 + case CLOCK_SOURCE_WC: 120 + internal = false; 121 + break; 122 + default: 123 + internal = true; 124 + break; 125 + } 126 + 127 + /* 128 + * When source of clock is not internal or any PCM streams are running, 129 + * available sampling rate is limited at current sampling rate. 130 + */ 131 + if (!internal || 132 + amdtp_stream_pcm_running(&dice->tx_stream[0]) || 133 + amdtp_stream_pcm_running(&dice->tx_stream[1]) || 134 + amdtp_stream_pcm_running(&dice->rx_stream[0]) || 135 + amdtp_stream_pcm_running(&dice->rx_stream[1])) { 136 + unsigned int rate; 137 + 138 + err = snd_dice_transaction_get_rate(dice, &rate); 139 + if (err < 0) 140 + goto err_locked; 141 + substream->runtime->hw.rate_min = rate; 142 + substream->runtime->hw.rate_max = rate; 143 + } 179 144 180 145 snd_pcm_set_sync(substream); 181 146 end: ··· 427 318 .page = snd_pcm_lib_get_vmalloc_page, 428 319 .mmap = snd_pcm_lib_mmap_vmalloc, 429 320 }; 430 - __be32 reg; 431 321 struct snd_pcm *pcm; 432 - unsigned int i, max_capture, max_playback, capture, playback; 322 + unsigned int capture, playback; 323 + int i, j; 433 324 int err; 434 - 435 - /* Check whether PCM substreams are required. */ 436 - if (dice->force_two_pcms) { 437 - max_capture = max_playback = 2; 438 - } else { 439 - max_capture = max_playback = 0; 440 - err = snd_dice_transaction_read_tx(dice, TX_NUMBER, &reg, 441 - sizeof(reg)); 442 - if (err < 0) 443 - return err; 444 - max_capture = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS); 445 - 446 - err = snd_dice_transaction_read_rx(dice, RX_NUMBER, &reg, 447 - sizeof(reg)); 448 - if (err < 0) 449 - return err; 450 - max_playback = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS); 451 - } 452 325 453 326 for (i = 0; i < MAX_STREAMS; i++) { 454 327 capture = playback = 0; 455 - if (i < max_capture) 456 - capture = 1; 457 - if (i < max_playback) 458 - playback = 1; 459 - if (capture == 0 && playback == 0) 460 - break; 328 + for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) { 329 + if (dice->tx_pcm_chs[i][j] > 0) 330 + capture = 1; 331 + if (dice->rx_pcm_chs[i][j] > 0) 332 + playback = 1; 333 + } 461 334 462 335 err = snd_pcm_new(dice->card, "DICE", i, playback, capture, 463 336 &pcm);
+72 -8
sound/firewire/dice/dice-proc.c
··· 148 148 >> CLOCK_RATE_SHIFT)); 149 149 snd_iprintf(buffer, " ext status: %08x\n", buf.global.extended_status); 150 150 snd_iprintf(buffer, " sample rate: %u\n", buf.global.sample_rate); 151 - snd_iprintf(buffer, " version: %u.%u.%u.%u\n", 152 - (buf.global.version >> 24) & 0xff, 153 - (buf.global.version >> 16) & 0xff, 154 - (buf.global.version >> 8) & 0xff, 155 - (buf.global.version >> 0) & 0xff); 156 151 if (quadlets >= 90) { 152 + snd_iprintf(buffer, " version: %u.%u.%u.%u\n", 153 + (buf.global.version >> 24) & 0xff, 154 + (buf.global.version >> 16) & 0xff, 155 + (buf.global.version >> 8) & 0xff, 156 + (buf.global.version >> 0) & 0xff); 157 157 snd_iprintf(buffer, " clock caps:"); 158 158 for (i = 0; i <= 6; ++i) 159 159 if (buf.global.clock_caps & (1 << i)) ··· 243 243 } 244 244 } 245 245 246 - void snd_dice_create_proc(struct snd_dice *dice) 246 + static void dice_proc_read_formation(struct snd_info_entry *entry, 247 + struct snd_info_buffer *buffer) 248 + { 249 + static const char *const rate_labels[] = { 250 + [SND_DICE_RATE_MODE_LOW] = "low", 251 + [SND_DICE_RATE_MODE_MIDDLE] = "middle", 252 + [SND_DICE_RATE_MODE_HIGH] = "high", 253 + }; 254 + struct snd_dice *dice = entry->private_data; 255 + int i, j; 256 + 257 + snd_iprintf(buffer, "Output stream from unit:\n"); 258 + for (i = 0; i < SND_DICE_RATE_MODE_COUNT; ++i) 259 + snd_iprintf(buffer, "\t%s", rate_labels[i]); 260 + snd_iprintf(buffer, "\tMIDI\n"); 261 + for (i = 0; i < MAX_STREAMS; ++i) { 262 + snd_iprintf(buffer, "Tx %u:", i); 263 + for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) 264 + snd_iprintf(buffer, "\t%u", dice->tx_pcm_chs[i][j]); 265 + snd_iprintf(buffer, "\t%u\n", dice->tx_midi_ports[i]); 266 + } 267 + 268 + snd_iprintf(buffer, "Input stream to unit:\n"); 269 + for (i = 0; i < SND_DICE_RATE_MODE_COUNT; ++i) 270 + snd_iprintf(buffer, "\t%s", rate_labels[i]); 271 + snd_iprintf(buffer, "\n"); 272 + for (i = 0; i < MAX_STREAMS; ++i) { 273 + snd_iprintf(buffer, "Rx %u:", i); 274 + for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) 275 + snd_iprintf(buffer, "\t%u", dice->rx_pcm_chs[i][j]); 276 + snd_iprintf(buffer, "\t%u\n", dice->rx_midi_ports[i]); 277 + } 278 + } 279 + 280 + static void add_node(struct snd_dice *dice, struct snd_info_entry *root, 281 + const char *name, 282 + void (*op)(struct snd_info_entry *entry, 283 + struct snd_info_buffer *buffer)) 247 284 { 248 285 struct snd_info_entry *entry; 249 286 250 - if (!snd_card_proc_new(dice->card, "dice", &entry)) 251 - snd_info_set_text_ops(entry, dice, dice_proc_read); 287 + entry = snd_info_create_card_entry(dice->card, name, root); 288 + if (!entry) 289 + return; 290 + 291 + snd_info_set_text_ops(entry, dice, op); 292 + if (snd_info_register(entry) < 0) 293 + snd_info_free_entry(entry); 294 + } 295 + 296 + void snd_dice_create_proc(struct snd_dice *dice) 297 + { 298 + struct snd_info_entry *root; 299 + 300 + /* 301 + * All nodes are automatically removed at snd_card_disconnect(), 302 + * by following to link list. 303 + */ 304 + root = snd_info_create_card_entry(dice->card, "firewire", 305 + dice->card->proc_root); 306 + if (!root) 307 + return; 308 + root->mode = S_IFDIR | 0555; 309 + if (snd_info_register(root) < 0) { 310 + snd_info_free_entry(root); 311 + return; 312 + } 313 + 314 + add_node(dice, root, "dice", dice_proc_read); 315 + add_node(dice, root, "formation", dice_proc_read_formation); 252 316 }
+215 -68
sound/firewire/dice/dice-stream.c
··· 30 30 [6] = 192000, 31 31 }; 32 32 33 + int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate, 34 + enum snd_dice_rate_mode *mode) 35 + { 36 + /* Corresponding to each entry in snd_dice_rates. */ 37 + static const enum snd_dice_rate_mode modes[] = { 38 + [0] = SND_DICE_RATE_MODE_LOW, 39 + [1] = SND_DICE_RATE_MODE_LOW, 40 + [2] = SND_DICE_RATE_MODE_LOW, 41 + [3] = SND_DICE_RATE_MODE_MIDDLE, 42 + [4] = SND_DICE_RATE_MODE_MIDDLE, 43 + [5] = SND_DICE_RATE_MODE_HIGH, 44 + [6] = SND_DICE_RATE_MODE_HIGH, 45 + }; 46 + int i; 47 + 48 + for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) { 49 + if (!(dice->clock_caps & BIT(i))) 50 + continue; 51 + if (snd_dice_rates[i] != rate) 52 + continue; 53 + 54 + *mode = modes[i]; 55 + return 0; 56 + } 57 + 58 + return -EINVAL; 59 + } 60 + 33 61 /* 34 62 * This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE 35 63 * to GLOBAL_STATUS. Especially, just after powering on, these are different. 36 64 */ 37 - static int ensure_phase_lock(struct snd_dice *dice) 65 + static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate) 38 66 { 39 67 __be32 reg, nominal; 68 + u32 data; 69 + int i; 40 70 int err; 41 71 42 72 err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT, ··· 74 44 if (err < 0) 75 45 return err; 76 46 47 + data = be32_to_cpu(reg); 48 + 49 + data &= ~CLOCK_RATE_MASK; 50 + for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) { 51 + if (snd_dice_rates[i] == rate) 52 + break; 53 + } 54 + if (i == ARRAY_SIZE(snd_dice_rates)) 55 + return -EINVAL; 56 + data |= i << CLOCK_RATE_SHIFT; 57 + 77 58 if (completion_done(&dice->clock_accepted)) 78 59 reinit_completion(&dice->clock_accepted); 79 60 61 + reg = cpu_to_be32(data); 80 62 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, 81 63 &reg, sizeof(reg)); 82 64 if (err < 0) ··· 234 192 unsigned int rate, struct reg_params *params) 235 193 { 236 194 __be32 reg[2]; 195 + enum snd_dice_rate_mode mode; 237 196 unsigned int i, pcm_chs, midi_ports; 238 197 struct amdtp_stream *streams; 239 198 struct fw_iso_resources *resources; ··· 249 206 resources = dice->rx_resources; 250 207 } 251 208 209 + err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 210 + if (err < 0) 211 + return err; 212 + 252 213 for (i = 0; i < params->count; i++) { 214 + unsigned int pcm_cache; 215 + unsigned int midi_cache; 216 + 253 217 if (dir == AMDTP_IN_STREAM) { 218 + pcm_cache = dice->tx_pcm_chs[i][mode]; 219 + midi_cache = dice->tx_midi_ports[i]; 254 220 err = snd_dice_transaction_read_tx(dice, 255 221 params->size * i + TX_NUMBER_AUDIO, 256 222 reg, sizeof(reg)); 257 223 } else { 224 + pcm_cache = dice->rx_pcm_chs[i][mode]; 225 + midi_cache = dice->rx_midi_ports[i]; 258 226 err = snd_dice_transaction_read_rx(dice, 259 227 params->size * i + RX_NUMBER_AUDIO, 260 228 reg, sizeof(reg)); ··· 274 220 return err; 275 221 pcm_chs = be32_to_cpu(reg[0]); 276 222 midi_ports = be32_to_cpu(reg[1]); 223 + 224 + /* These are important for developer of this driver. */ 225 + if (pcm_chs != pcm_cache || midi_ports != midi_cache) { 226 + dev_info(&dice->unit->device, 227 + "cache mismatch: pcm: %u:%u, midi: %u:%u\n", 228 + pcm_chs, pcm_cache, midi_ports, midi_cache); 229 + return -EPROTO; 230 + } 277 231 278 232 err = keep_resources(dice, dir, i, rate, pcm_chs, midi_ports); 279 233 if (err < 0) ··· 318 256 return err; 319 257 } 320 258 259 + static int start_duplex_streams(struct snd_dice *dice, unsigned int rate) 260 + { 261 + struct reg_params tx_params, rx_params; 262 + int i; 263 + int err; 264 + 265 + err = get_register_params(dice, &tx_params, &rx_params); 266 + if (err < 0) 267 + return err; 268 + 269 + /* Stop transmission. */ 270 + stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 271 + stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 272 + snd_dice_transaction_clear_enable(dice); 273 + release_resources(dice); 274 + 275 + err = ensure_phase_lock(dice, rate); 276 + if (err < 0) { 277 + dev_err(&dice->unit->device, "fail to ensure phase lock\n"); 278 + return err; 279 + } 280 + 281 + /* Likely to have changed stream formats. */ 282 + err = get_register_params(dice, &tx_params, &rx_params); 283 + if (err < 0) 284 + return err; 285 + 286 + /* Start both streams. */ 287 + err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params); 288 + if (err < 0) 289 + goto error; 290 + err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params); 291 + if (err < 0) 292 + goto error; 293 + 294 + err = snd_dice_transaction_set_enable(dice); 295 + if (err < 0) { 296 + dev_err(&dice->unit->device, "fail to enable interface\n"); 297 + goto error; 298 + } 299 + 300 + for (i = 0; i < MAX_STREAMS; i++) { 301 + if ((i < tx_params.count && 302 + !amdtp_stream_wait_callback(&dice->tx_stream[i], 303 + CALLBACK_TIMEOUT)) || 304 + (i < rx_params.count && 305 + !amdtp_stream_wait_callback(&dice->rx_stream[i], 306 + CALLBACK_TIMEOUT))) { 307 + err = -ETIMEDOUT; 308 + goto error; 309 + } 310 + } 311 + 312 + return 0; 313 + error: 314 + stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 315 + stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 316 + snd_dice_transaction_clear_enable(dice); 317 + release_resources(dice); 318 + return err; 319 + } 320 + 321 321 /* 322 322 * MEMO: After this function, there're two states of streams: 323 323 * - None streams are running. ··· 389 265 { 390 266 unsigned int curr_rate; 391 267 unsigned int i; 392 - struct reg_params tx_params, rx_params; 393 - bool need_to_start; 268 + enum snd_dice_rate_mode mode; 394 269 int err; 395 270 396 271 if (dice->substreams_counter == 0) 397 272 return -EIO; 398 273 399 - err = get_register_params(dice, &tx_params, &rx_params); 400 - if (err < 0) 401 - return err; 402 - 274 + /* Check sampling transmission frequency. */ 403 275 err = snd_dice_transaction_get_rate(dice, &curr_rate); 404 276 if (err < 0) { 405 277 dev_err(&dice->unit->device, ··· 405 285 if (rate == 0) 406 286 rate = curr_rate; 407 287 if (rate != curr_rate) 408 - return -EINVAL; 288 + goto restart; 409 289 410 - /* Judge to need to restart streams. */ 411 - for (i = 0; i < MAX_STREAMS; i++) { 412 - if (i < tx_params.count) { 413 - if (amdtp_streaming_error(&dice->tx_stream[i]) || 414 - !amdtp_stream_running(&dice->tx_stream[i])) 415 - break; 416 - } 417 - if (i < rx_params.count) { 418 - if (amdtp_streaming_error(&dice->rx_stream[i]) || 419 - !amdtp_stream_running(&dice->rx_stream[i])) 420 - break; 421 - } 290 + /* Check error of packet streaming. */ 291 + for (i = 0; i < MAX_STREAMS; ++i) { 292 + if (amdtp_streaming_error(&dice->tx_stream[i])) 293 + break; 294 + if (amdtp_streaming_error(&dice->rx_stream[i])) 295 + break; 422 296 } 423 - need_to_start = (i < MAX_STREAMS); 297 + if (i < MAX_STREAMS) 298 + goto restart; 424 299 425 - if (need_to_start) { 426 - /* Stop transmission. */ 427 - snd_dice_transaction_clear_enable(dice); 428 - stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 429 - stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 430 - release_resources(dice); 431 - 432 - err = ensure_phase_lock(dice); 433 - if (err < 0) { 434 - dev_err(&dice->unit->device, 435 - "fail to ensure phase lock\n"); 436 - return err; 437 - } 438 - 439 - /* Start both streams. */ 440 - err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params); 441 - if (err < 0) 442 - goto error; 443 - err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params); 444 - if (err < 0) 445 - goto error; 446 - 447 - err = snd_dice_transaction_set_enable(dice); 448 - if (err < 0) { 449 - dev_err(&dice->unit->device, 450 - "fail to enable interface\n"); 451 - goto error; 452 - } 453 - 454 - for (i = 0; i < MAX_STREAMS; i++) { 455 - if ((i < tx_params.count && 456 - !amdtp_stream_wait_callback(&dice->tx_stream[i], 457 - CALLBACK_TIMEOUT)) || 458 - (i < rx_params.count && 459 - !amdtp_stream_wait_callback(&dice->rx_stream[i], 460 - CALLBACK_TIMEOUT))) { 461 - err = -ETIMEDOUT; 462 - goto error; 463 - } 464 - } 300 + /* Check required streams are running or not. */ 301 + err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 302 + if (err < 0) 303 + return err; 304 + for (i = 0; i < MAX_STREAMS; ++i) { 305 + if (dice->tx_pcm_chs[i][mode] > 0 && 306 + !amdtp_stream_running(&dice->tx_stream[i])) 307 + break; 308 + if (dice->rx_pcm_chs[i][mode] > 0 && 309 + !amdtp_stream_running(&dice->rx_stream[i])) 310 + break; 465 311 } 312 + if (i < MAX_STREAMS) 313 + goto restart; 466 314 467 - return err; 468 - error: 469 - snd_dice_transaction_clear_enable(dice); 470 - stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 471 - stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 472 - release_resources(dice); 473 - return err; 315 + return 0; 316 + restart: 317 + return start_duplex_streams(dice, rate); 474 318 } 475 319 476 320 /* ··· 566 482 stop_streams(dice, AMDTP_IN_STREAM, &tx_params); 567 483 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); 568 484 } 485 + } 486 + 487 + int snd_dice_stream_detect_current_formats(struct snd_dice *dice) 488 + { 489 + unsigned int rate; 490 + enum snd_dice_rate_mode mode; 491 + __be32 reg[2]; 492 + struct reg_params tx_params, rx_params; 493 + int i; 494 + int err; 495 + 496 + /* If extended protocol is available, detect detail spec. */ 497 + err = snd_dice_detect_extension_formats(dice); 498 + if (err >= 0) 499 + return err; 500 + 501 + /* 502 + * Available stream format is restricted at current mode of sampling 503 + * clock. 504 + */ 505 + err = snd_dice_transaction_get_rate(dice, &rate); 506 + if (err < 0) 507 + return err; 508 + 509 + err = snd_dice_stream_get_rate_mode(dice, rate, &mode); 510 + if (err < 0) 511 + return err; 512 + 513 + /* 514 + * Just after owning the unit (GLOBAL_OWNER), the unit can return 515 + * invalid stream formats. Selecting clock parameters have an effect 516 + * for the unit to refine it. 517 + */ 518 + err = ensure_phase_lock(dice, rate); 519 + if (err < 0) 520 + return err; 521 + 522 + err = get_register_params(dice, &tx_params, &rx_params); 523 + if (err < 0) 524 + return err; 525 + 526 + for (i = 0; i < tx_params.count; ++i) { 527 + err = snd_dice_transaction_read_tx(dice, 528 + tx_params.size * i + TX_NUMBER_AUDIO, 529 + reg, sizeof(reg)); 530 + if (err < 0) 531 + return err; 532 + dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); 533 + dice->tx_midi_ports[i] = max_t(unsigned int, 534 + be32_to_cpu(reg[1]), dice->tx_midi_ports[i]); 535 + } 536 + for (i = 0; i < rx_params.count; ++i) { 537 + err = snd_dice_transaction_read_rx(dice, 538 + rx_params.size * i + RX_NUMBER_AUDIO, 539 + reg, sizeof(reg)); 540 + if (err < 0) 541 + return err; 542 + dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); 543 + dice->rx_midi_ports[i] = max_t(unsigned int, 544 + be32_to_cpu(reg[1]), dice->rx_midi_ports[i]); 545 + } 546 + 547 + return 0; 569 548 } 570 549 571 550 static void dice_lock_changed(struct snd_dice *dice)
+104
sound/firewire/dice/dice-tcelectronic.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * dice-tc_electronic.c - a part of driver for DICE based devices 4 + * 5 + * Copyright (c) 2018 Takashi Sakamoto 6 + */ 7 + 8 + #include "dice.h" 9 + 10 + struct dice_tc_spec { 11 + unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; 12 + unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; 13 + bool has_midi; 14 + }; 15 + 16 + static const struct dice_tc_spec desktop_konnekt6 = { 17 + .tx_pcm_chs = {{6, 6, 2}, {0, 0, 0} }, 18 + .rx_pcm_chs = {{6, 6, 4}, {0, 0, 0} }, 19 + .has_midi = false, 20 + }; 21 + 22 + static const struct dice_tc_spec impact_twin = { 23 + .tx_pcm_chs = {{14, 10, 6}, {0, 0, 0} }, 24 + .rx_pcm_chs = {{14, 10, 6}, {0, 0, 0} }, 25 + .has_midi = true, 26 + }; 27 + 28 + static const struct dice_tc_spec konnekt_8 = { 29 + .tx_pcm_chs = {{4, 4, 3}, {0, 0, 0} }, 30 + .rx_pcm_chs = {{4, 4, 3}, {0, 0, 0} }, 31 + .has_midi = true, 32 + }; 33 + 34 + static const struct dice_tc_spec konnekt_24d = { 35 + .tx_pcm_chs = {{16, 16, 6}, {0, 0, 0} }, 36 + .rx_pcm_chs = {{16, 16, 6}, {0, 0, 0} }, 37 + .has_midi = true, 38 + }; 39 + 40 + static const struct dice_tc_spec konnekt_live = { 41 + .tx_pcm_chs = {{16, 16, 16}, {0, 0, 0} }, 42 + .rx_pcm_chs = {{16, 16, 16}, {0, 0, 0} }, 43 + .has_midi = true, 44 + }; 45 + 46 + static const struct dice_tc_spec studio_konnekt_48 = { 47 + .tx_pcm_chs = {{16, 16, 8}, {16, 16, 7} }, 48 + .rx_pcm_chs = {{16, 16, 8}, {14, 14, 7} }, 49 + .has_midi = true, 50 + }; 51 + 52 + static const struct dice_tc_spec digital_konnekt_x32 = { 53 + .tx_pcm_chs = {{16, 16, 4}, {0, 0, 0} }, 54 + .rx_pcm_chs = {{16, 16, 4}, {0, 0, 0} }, 55 + .has_midi = false, 56 + }; 57 + 58 + int snd_dice_detect_tcelectronic_formats(struct snd_dice *dice) 59 + { 60 + static const struct { 61 + u32 model_id; 62 + const struct dice_tc_spec *spec; 63 + } *entry, entries[] = { 64 + {0x00000020, &konnekt_24d}, 65 + {0x00000021, &konnekt_8}, 66 + {0x00000022, &studio_konnekt_48}, 67 + {0x00000023, &konnekt_live}, 68 + {0x00000024, &desktop_konnekt6}, 69 + {0x00000027, &impact_twin}, 70 + {0x00000030, &digital_konnekt_x32}, 71 + }; 72 + struct fw_csr_iterator it; 73 + int key, val, model_id; 74 + int i; 75 + 76 + model_id = 0; 77 + fw_csr_iterator_init(&it, dice->unit->directory); 78 + while (fw_csr_iterator_next(&it, &key, &val)) { 79 + if (key == CSR_MODEL) { 80 + model_id = val; 81 + break; 82 + } 83 + } 84 + 85 + for (i = 0; i < ARRAY_SIZE(entries); ++i) { 86 + entry = entries + i; 87 + if (entry->model_id == model_id) 88 + break; 89 + } 90 + if (i == ARRAY_SIZE(entries)) 91 + return -ENODEV; 92 + 93 + memcpy(dice->tx_pcm_chs, entry->spec->tx_pcm_chs, 94 + MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int)); 95 + memcpy(dice->rx_pcm_chs, entry->spec->rx_pcm_chs, 96 + MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int)); 97 + 98 + if (entry->spec->has_midi) { 99 + dice->tx_midi_ports[0] = 1; 100 + dice->rx_midi_ports[0] = 1; 101 + } 102 + 103 + return 0; 104 + }
+28 -21
sound/firewire/dice/dice-transaction.c
··· 265 265 static int get_subaddrs(struct snd_dice *dice) 266 266 { 267 267 static const int min_values[10] = { 268 - 10, 0x64 / 4, 268 + 10, 0x60 / 4, 269 269 10, 0x18 / 4, 270 270 10, 0x18 / 4, 271 271 0, 0, ··· 301 301 } 302 302 } 303 303 304 - /* 305 - * Check that the implemented DICE driver specification major version 306 - * number matches. 307 - */ 308 - err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST, 309 - DICE_PRIVATE_SPACE + 310 - be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION, 311 - &version, sizeof(version), 0); 312 - if (err < 0) 313 - goto end; 304 + if (be32_to_cpu(pointers[1]) > 0x18) { 305 + /* 306 + * Check that the implemented DICE driver specification major 307 + * version number matches. 308 + */ 309 + err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST, 310 + DICE_PRIVATE_SPACE + 311 + be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION, 312 + &version, sizeof(version), 0); 313 + if (err < 0) 314 + goto end; 314 315 315 - if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) { 316 - dev_err(&dice->unit->device, 317 - "unknown DICE version: 0x%08x\n", be32_to_cpu(version)); 318 - err = -ENODEV; 319 - goto end; 316 + if ((version & cpu_to_be32(0xff000000)) != 317 + cpu_to_be32(0x01000000)) { 318 + dev_err(&dice->unit->device, 319 + "unknown DICE version: 0x%08x\n", 320 + be32_to_cpu(version)); 321 + err = -ENODEV; 322 + goto end; 323 + } 324 + 325 + /* Set up later. */ 326 + dice->clock_caps = 1; 320 327 } 321 328 322 329 dice->global_offset = be32_to_cpu(pointers[0]) * 4; 323 330 dice->tx_offset = be32_to_cpu(pointers[2]) * 4; 324 331 dice->rx_offset = be32_to_cpu(pointers[4]) * 4; 325 - dice->sync_offset = be32_to_cpu(pointers[6]) * 4; 326 - dice->rsrv_offset = be32_to_cpu(pointers[8]) * 4; 327 332 328 - /* Set up later. */ 329 - if (be32_to_cpu(pointers[1]) * 4 >= GLOBAL_CLOCK_CAPABILITIES + 4) 330 - dice->clock_caps = 1; 333 + /* Old firmware doesn't support these fields. */ 334 + if (pointers[7]) 335 + dice->sync_offset = be32_to_cpu(pointers[6]) * 4; 336 + if (pointers[9]) 337 + dice->rsrv_offset = be32_to_cpu(pointers[8]) * 4; 331 338 end: 332 339 kfree(pointers); 333 340 return err;
+110 -48
sound/firewire/dice/dice.c
··· 15 15 #define OUI_LOUD 0x000ff2 16 16 #define OUI_FOCUSRITE 0x00130e 17 17 #define OUI_TCELECTRONIC 0x000166 18 + #define OUI_ALESIS 0x000595 19 + #define OUI_MAUDIO 0x000d6c 20 + #define OUI_MYTEK 0x001ee8 18 21 19 22 #define DICE_CATEGORY_ID 0x04 20 23 #define WEISS_CATEGORY_ID 0x00 21 24 #define LOUD_CATEGORY_ID 0x10 22 25 23 - /* 24 - * Some models support several isochronous channels, while these streams are not 25 - * always available. In this case, add the model name to this list. 26 - */ 27 - static bool force_two_pcm_support(struct fw_unit *unit) 28 - { 29 - static const char *const models[] = { 30 - /* TC Electronic models. */ 31 - "StudioKonnekt48", 32 - /* Focusrite models. */ 33 - "SAFFIRE_PRO_40", 34 - "LIQUID_SAFFIRE_56", 35 - "SAFFIRE_PRO_40_1", 36 - }; 37 - char model[32]; 38 - unsigned int i; 39 - int err; 40 - 41 - err = fw_csr_string(unit->directory, CSR_MODEL, model, sizeof(model)); 42 - if (err < 0) 43 - return false; 44 - 45 - for (i = 0; i < ARRAY_SIZE(models); i++) { 46 - if (strcmp(models[i], model) == 0) 47 - break; 48 - } 49 - 50 - return i < ARRAY_SIZE(models); 51 - } 26 + #define MODEL_ALESIS_IO_BOTH 0x000001 52 27 53 28 static int check_dice_category(struct fw_unit *unit) 54 29 { ··· 48 73 model = val; 49 74 break; 50 75 } 51 - } 52 - 53 - if (vendor == OUI_FOCUSRITE || vendor == OUI_TCELECTRONIC) { 54 - if (force_two_pcm_support(unit)) 55 - return 0; 56 76 } 57 77 58 78 if (vendor == OUI_WEISS) ··· 156 186 if (err < 0) 157 187 return; 158 188 159 - if (force_two_pcm_support(dice->unit)) 160 - dice->force_two_pcms = true; 161 - 162 189 err = snd_dice_transaction_init(dice); 163 190 if (err < 0) 164 191 goto error; ··· 165 198 goto error; 166 199 167 200 dice_card_strings(dice); 201 + 202 + err = dice->detect_formats(dice); 203 + if (err < 0) 204 + goto error; 168 205 169 206 err = snd_dice_stream_init_duplex(dice); 170 207 if (err < 0) ··· 210 239 "Sound card registration failed: %d\n", err); 211 240 } 212 241 213 - static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) 242 + static int dice_probe(struct fw_unit *unit, 243 + const struct ieee1394_device_id *entry) 214 244 { 215 245 struct snd_dice *dice; 216 246 int err; 217 247 218 - err = check_dice_category(unit); 219 - if (err < 0) 220 - return -ENODEV; 248 + if (!entry->driver_data) { 249 + err = check_dice_category(unit); 250 + if (err < 0) 251 + return -ENODEV; 252 + } 221 253 222 254 /* Allocate this independent of sound card instance. */ 223 255 dice = kzalloc(sizeof(struct snd_dice), GFP_KERNEL); ··· 229 255 230 256 dice->unit = fw_unit_get(unit); 231 257 dev_set_drvdata(&unit->device, dice); 258 + 259 + if (!entry->driver_data) { 260 + dice->detect_formats = snd_dice_stream_detect_current_formats; 261 + } else { 262 + dice->detect_formats = 263 + (snd_dice_detect_formats_t)entry->driver_data; 264 + } 232 265 233 266 spin_lock_init(&dice->lock); 234 267 mutex_init(&dice->mutex); ··· 294 313 #define DICE_INTERFACE 0x000001 295 314 296 315 static const struct ieee1394_device_id dice_id_table[] = { 316 + /* M-Audio Profire 2626 has a different value in version field. */ 317 + { 318 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 319 + IEEE1394_MATCH_MODEL_ID, 320 + .vendor_id = OUI_MAUDIO, 321 + .model_id = 0x000010, 322 + .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats, 323 + }, 324 + /* M-Audio Profire 610 has a different value in version field. */ 325 + { 326 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 327 + IEEE1394_MATCH_MODEL_ID, 328 + .vendor_id = OUI_MAUDIO, 329 + .model_id = 0x000011, 330 + .driver_data = (kernel_ulong_t)snd_dice_detect_extension_formats, 331 + }, 332 + /* TC Electronic Konnekt 24D. */ 333 + { 334 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 335 + IEEE1394_MATCH_MODEL_ID, 336 + .vendor_id = OUI_TCELECTRONIC, 337 + .model_id = 0x000020, 338 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 339 + }, 340 + /* TC Electronic Konnekt 8. */ 341 + { 342 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 343 + IEEE1394_MATCH_MODEL_ID, 344 + .vendor_id = OUI_TCELECTRONIC, 345 + .model_id = 0x000021, 346 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 347 + }, 348 + /* TC Electronic Studio Konnekt 48. */ 349 + { 350 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 351 + IEEE1394_MATCH_MODEL_ID, 352 + .vendor_id = OUI_TCELECTRONIC, 353 + .model_id = 0x000022, 354 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 355 + }, 356 + /* TC Electronic Konnekt Live. */ 357 + { 358 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 359 + IEEE1394_MATCH_MODEL_ID, 360 + .vendor_id = OUI_TCELECTRONIC, 361 + .model_id = 0x000023, 362 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 363 + }, 364 + /* TC Electronic Desktop Konnekt 6. */ 365 + { 366 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 367 + IEEE1394_MATCH_MODEL_ID, 368 + .vendor_id = OUI_TCELECTRONIC, 369 + .model_id = 0x000024, 370 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 371 + }, 372 + /* TC Electronic Impact Twin. */ 373 + { 374 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 375 + IEEE1394_MATCH_MODEL_ID, 376 + .vendor_id = OUI_TCELECTRONIC, 377 + .model_id = 0x000027, 378 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 379 + }, 380 + /* TC Electronic Digital Konnekt x32. */ 381 + { 382 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 383 + IEEE1394_MATCH_MODEL_ID, 384 + .vendor_id = OUI_TCELECTRONIC, 385 + .model_id = 0x000030, 386 + .driver_data = (kernel_ulong_t)snd_dice_detect_tcelectronic_formats, 387 + }, 388 + /* Alesis iO14/iO26. */ 389 + { 390 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 391 + IEEE1394_MATCH_MODEL_ID, 392 + .vendor_id = OUI_ALESIS, 393 + .model_id = MODEL_ALESIS_IO_BOTH, 394 + .driver_data = (kernel_ulong_t)snd_dice_detect_alesis_formats, 395 + }, 396 + /* Mytek Stereo 192 DSD-DAC. */ 397 + { 398 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 399 + IEEE1394_MATCH_MODEL_ID, 400 + .vendor_id = OUI_MYTEK, 401 + .model_id = 0x000002, 402 + .driver_data = (kernel_ulong_t)snd_dice_detect_mytek_formats, 403 + }, 297 404 { 298 405 .match_flags = IEEE1394_MATCH_VERSION, 299 406 .version = DICE_INTERFACE, 300 - }, 301 - /* M-Audio Profire 610/2626 has a different value in version field. */ 302 - { 303 - .match_flags = IEEE1394_MATCH_VENDOR_ID | 304 - IEEE1394_MATCH_SPECIFIER_ID, 305 - .vendor_id = 0x000d6c, 306 - .specifier_id = 0x000d6c, 307 407 }, 308 408 { } 309 409 };
+23 -2
sound/firewire/dice/dice.h
··· 63 63 */ 64 64 #define MAX_STREAMS 2 65 65 66 + enum snd_dice_rate_mode { 67 + SND_DICE_RATE_MODE_LOW = 0, 68 + SND_DICE_RATE_MODE_MIDDLE, 69 + SND_DICE_RATE_MODE_HIGH, 70 + SND_DICE_RATE_MODE_COUNT, 71 + }; 72 + 73 + struct snd_dice; 74 + typedef int (*snd_dice_detect_formats_t)(struct snd_dice *dice); 75 + 66 76 struct snd_dice { 67 77 struct snd_card *card; 68 78 struct fw_unit *unit; ··· 90 80 unsigned int rsrv_offset; 91 81 92 82 unsigned int clock_caps; 83 + unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; 84 + unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; 85 + unsigned int tx_midi_ports[MAX_STREAMS]; 86 + unsigned int rx_midi_ports[MAX_STREAMS]; 87 + snd_dice_detect_formats_t detect_formats; 93 88 94 89 struct fw_address_handler notification_handler; 95 90 int owner_generation; ··· 113 98 bool global_enabled; 114 99 struct completion clock_accepted; 115 100 unsigned int substreams_counter; 116 - 117 - bool force_two_pcms; 118 101 }; 119 102 120 103 enum snd_dice_addr_type { ··· 203 190 #define SND_DICE_RATES_COUNT 7 204 191 extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT]; 205 192 193 + int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate, 194 + enum snd_dice_rate_mode *mode); 206 195 int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate); 207 196 void snd_dice_stream_stop_duplex(struct snd_dice *dice); 208 197 int snd_dice_stream_init_duplex(struct snd_dice *dice); 209 198 void snd_dice_stream_destroy_duplex(struct snd_dice *dice); 210 199 void snd_dice_stream_update_duplex(struct snd_dice *dice); 200 + int snd_dice_stream_detect_current_formats(struct snd_dice *dice); 211 201 212 202 int snd_dice_stream_lock_try(struct snd_dice *dice); 213 203 void snd_dice_stream_lock_release(struct snd_dice *dice); ··· 222 206 void snd_dice_create_proc(struct snd_dice *dice); 223 207 224 208 int snd_dice_create_midi(struct snd_dice *dice); 209 + 210 + int snd_dice_detect_tcelectronic_formats(struct snd_dice *dice); 211 + int snd_dice_detect_alesis_formats(struct snd_dice *dice); 212 + int snd_dice_detect_extension_formats(struct snd_dice *dice); 213 + int snd_dice_detect_mytek_formats(struct snd_dice *dice); 225 214 226 215 #endif
+1 -1
sound/firewire/digi00x/digi00x-proc.c
··· 79 79 if (root == NULL) 80 80 return; 81 81 82 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 82 + root->mode = S_IFDIR | 0555; 83 83 if (snd_info_register(root) < 0) { 84 84 snd_info_free_entry(root); 85 85 return;
+1 -1
sound/firewire/fireface/ff-proc.c
··· 52 52 ff->card->proc_root); 53 53 if (root == NULL) 54 54 return; 55 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 55 + root->mode = S_IFDIR | 0555; 56 56 if (snd_info_register(root) < 0) { 57 57 snd_info_free_entry(root); 58 58 return;
+1 -1
sound/firewire/fireworks/fireworks_proc.c
··· 219 219 efw->card->proc_root); 220 220 if (root == NULL) 221 221 return; 222 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 222 + root->mode = S_IFDIR | 0555; 223 223 if (snd_info_register(root) < 0) { 224 224 snd_info_free_entry(root); 225 225 return;
+6 -4
sound/firewire/isight.c
··· 569 569 return err; 570 570 isight->gain_max = be32_to_cpu(value); 571 571 572 - isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX; 573 - isight->gain_tlv[1] = 2 * sizeof(unsigned int); 572 + isight->gain_tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_MINMAX; 573 + isight->gain_tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int); 574 574 575 575 err = reg_read(isight, REG_GAIN_DB_START, &value); 576 576 if (err < 0) 577 577 return err; 578 - isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100; 578 + isight->gain_tlv[SNDRV_CTL_TLVO_DB_MINMAX_MIN] = 579 + (s32)be32_to_cpu(value) * 100; 579 580 580 581 err = reg_read(isight, REG_GAIN_DB_END, &value); 581 582 if (err < 0) 582 583 return err; 583 - isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100; 584 + isight->gain_tlv[SNDRV_CTL_TLVO_DB_MINMAX_MAX] = 585 + (s32)be32_to_cpu(value) * 100; 584 586 585 587 ctl = snd_ctl_new1(&gain_control, isight); 586 588 if (ctl)
+1 -1
sound/firewire/motu/motu-proc.c
··· 107 107 motu->card->proc_root); 108 108 if (root == NULL) 109 109 return; 110 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 110 + root->mode = S_IFDIR | 0555; 111 111 if (snd_info_register(root) < 0) { 112 112 snd_info_free_entry(root); 113 113 return;
+1 -1
sound/firewire/oxfw/oxfw-proc.c
··· 103 103 oxfw->card->proc_root); 104 104 if (root == NULL) 105 105 return; 106 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 106 + root->mode = S_IFDIR | 0555; 107 107 if (snd_info_register(root) < 0) { 108 108 snd_info_free_entry(root); 109 109 return;
+1 -7
sound/firewire/oxfw/oxfw.c
··· 49 49 "Tapco LINK.firewire 4x6", 50 50 "U.420"}; 51 51 char model[32]; 52 - unsigned int i; 53 52 int err; 54 53 55 54 err = fw_csr_string(unit->directory, CSR_MODEL, ··· 56 57 if (err < 0) 57 58 return false; 58 59 59 - for (i = 0; i < ARRAY_SIZE(models); i++) { 60 - if (strcmp(models[i], model) == 0) 61 - break; 62 - } 63 - 64 - return (i < ARRAY_SIZE(models)); 60 + return match_string(models, ARRAY_SIZE(models), model) >= 0; 65 61 } 66 62 67 63 static int name_card(struct snd_oxfw *oxfw)
+1 -1
sound/firewire/tascam/tascam-proc.c
··· 78 78 tscm->card->proc_root); 79 79 if (root == NULL) 80 80 return; 81 - root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 81 + root->mode = S_IFDIR | 0555; 82 82 if (snd_info_register(root) < 0) { 83 83 snd_info_free_entry(root); 84 84 return;
+2 -2
sound/hda/hdac_regmap.c
··· 65 65 { 66 66 struct hdac_device *codec = dev_to_hdac_dev(dev); 67 67 unsigned int verb = get_verb(reg); 68 + const unsigned int *v; 68 69 int i; 69 70 70 - for (i = 0; i < codec->vendor_verbs.used; i++) { 71 - unsigned int *v = snd_array_elem(&codec->vendor_verbs, i); 71 + snd_array_for_each(&codec->vendor_verbs, i, v) { 72 72 if (verb == *v) 73 73 return true; 74 74 }
+2 -2
sound/isa/cmi8328.c
··· 192 192 } 193 193 194 194 /* find index of an item in "-1"-ended array */ 195 - int array_find(int array[], int item) 195 + static int array_find(int array[], int item) 196 196 { 197 197 int i; 198 198 ··· 203 203 return -1; 204 204 } 205 205 /* the same for long */ 206 - int array_find_l(long array[], long item) 206 + static int array_find_l(long array[], long item) 207 207 { 208 208 int i; 209 209
+16 -16
sound/isa/msnd/msnd_pinnacle.c
··· 757 757 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 758 758 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 759 759 760 - module_param_array(index, int, NULL, S_IRUGO); 760 + module_param_array(index, int, NULL, 0444); 761 761 MODULE_PARM_DESC(index, "Index value for msnd_pinnacle soundcard."); 762 - module_param_array(id, charp, NULL, S_IRUGO); 762 + module_param_array(id, charp, NULL, 0444); 763 763 MODULE_PARM_DESC(id, "ID string for msnd_pinnacle soundcard."); 764 764 765 765 static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; ··· 801 801 MODULE_FIRMWARE(INITCODEFILE); 802 802 MODULE_FIRMWARE(PERMCODEFILE); 803 803 804 - module_param_hw_array(io, long, ioport, NULL, S_IRUGO); 804 + module_param_hw_array(io, long, ioport, NULL, 0444); 805 805 MODULE_PARM_DESC(io, "IO port #"); 806 - module_param_hw_array(irq, int, irq, NULL, S_IRUGO); 807 - module_param_hw_array(mem, long, iomem, NULL, S_IRUGO); 808 - module_param_array(write_ndelay, int, NULL, S_IRUGO); 809 - module_param(calibrate_signal, int, S_IRUGO); 806 + module_param_hw_array(irq, int, irq, NULL, 0444); 807 + module_param_hw_array(mem, long, iomem, NULL, 0444); 808 + module_param_array(write_ndelay, int, NULL, 0444); 809 + module_param(calibrate_signal, int, 0444); 810 810 #ifndef MSND_CLASSIC 811 - module_param_array(digital, int, NULL, S_IRUGO); 812 - module_param_hw_array(cfg, long, ioport, NULL, S_IRUGO); 813 - module_param_array(reset, int, 0, S_IRUGO); 814 - module_param_hw_array(mpu_io, long, ioport, NULL, S_IRUGO); 815 - module_param_hw_array(mpu_irq, int, irq, NULL, S_IRUGO); 816 - module_param_hw_array(ide_io0, long, ioport, NULL, S_IRUGO); 817 - module_param_hw_array(ide_io1, long, ioport, NULL, S_IRUGO); 818 - module_param_hw_array(ide_irq, int, irq, NULL, S_IRUGO); 819 - module_param_hw_array(joystick_io, long, ioport, NULL, S_IRUGO); 811 + module_param_array(digital, int, NULL, 0444); 812 + module_param_hw_array(cfg, long, ioport, NULL, 0444); 813 + module_param_array(reset, int, 0, 0444); 814 + module_param_hw_array(mpu_io, long, ioport, NULL, 0444); 815 + module_param_hw_array(mpu_irq, int, irq, NULL, 0444); 816 + module_param_hw_array(ide_io0, long, ioport, NULL, 0444); 817 + module_param_hw_array(ide_io1, long, ioport, NULL, 0444); 818 + module_param_hw_array(ide_irq, int, irq, NULL, 0444); 819 + module_param_hw_array(joystick_io, long, ioport, NULL, 0444); 820 820 #endif 821 821 822 822
+2 -2
sound/isa/sc6000.c
··· 592 592 *vport = devm_ioport_map(devptr, port[dev], 0x10); 593 593 if (*vport == NULL) { 594 594 snd_printk(KERN_ERR PFX 595 - "I/O port cannot be iomaped.\n"); 595 + "I/O port cannot be iomapped.\n"); 596 596 err = -EBUSY; 597 597 goto err_unmap1; 598 598 } ··· 607 607 vmss_port = devm_ioport_map(devptr, mss_port[dev], 4); 608 608 if (!vmss_port) { 609 609 snd_printk(KERN_ERR PFX 610 - "MSS port I/O cannot be iomaped.\n"); 610 + "MSS port I/O cannot be iomapped.\n"); 611 611 err = -EBUSY; 612 612 goto err_unmap2; 613 613 }
+2 -2
sound/pci/ac97/ac97_proc.c
··· 448 448 if ((entry = snd_info_create_card_entry(ac97->bus->card, name, ac97->bus->proc)) != NULL) { 449 449 snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read); 450 450 #ifdef CONFIG_SND_DEBUG 451 - entry->mode |= S_IWUSR; 451 + entry->mode |= 0200; 452 452 entry->c.text.write = snd_ac97_proc_regs_write; 453 453 #endif 454 454 if (snd_info_register(entry) < 0) { ··· 474 474 475 475 sprintf(name, "codec97#%d", bus->num); 476 476 if ((entry = snd_info_create_card_entry(bus->card, name, bus->card->proc_root)) != NULL) { 477 - entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 477 + entry->mode = S_IFDIR | 0555; 478 478 if (snd_info_register(entry) < 0) { 479 479 snd_info_free_entry(entry); 480 480 entry = NULL;
+2 -2
sound/pci/ad1889.c
··· 258 258 259 259 while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY) 260 260 && --retry) 261 - mdelay(1); 261 + usleep_range(1000, 2000); 262 262 if (!retry) { 263 263 dev_err(chip->card->dev, "[%s] Link is not ready.\n", 264 264 __func__); ··· 872 872 ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */ 873 873 ad1889_readw(chip, AD_DS_CCS); /* flush posted write */ 874 874 875 - mdelay(10); 875 + usleep_range(10000, 11000); 876 876 877 877 /* enable Master and Target abort interrupts */ 878 878 ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);
+6 -6
sound/pci/asihpi/asihpi.c
··· 69 69 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 70 70 static bool enable_hpi_hwdep = 1; 71 71 72 - module_param_array(index, int, NULL, S_IRUGO); 72 + module_param_array(index, int, NULL, 0444); 73 73 MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard."); 74 74 75 - module_param_array(id, charp, NULL, S_IRUGO); 75 + module_param_array(id, charp, NULL, 0444); 76 76 MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard."); 77 77 78 - module_param_array(enable, bool, NULL, S_IRUGO); 78 + module_param_array(enable, bool, NULL, 0444); 79 79 MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard."); 80 80 81 - module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR); 81 + module_param(enable_hpi_hwdep, bool, 0644); 82 82 MODULE_PARM_DESC(enable_hpi_hwdep, 83 83 "ALSA enable HPI hwdep for AudioScience soundcard "); 84 84 85 85 /* identify driver */ 86 86 #ifdef KERNEL_ALSA_BUILD 87 87 static char *build_info = "Built using headers from kernel source"; 88 - module_param(build_info, charp, S_IRUGO); 88 + module_param(build_info, charp, 0444); 89 89 MODULE_PARM_DESC(build_info, "Built using headers from kernel source"); 90 90 #else 91 91 static char *build_info = "Built within ALSA source"; 92 - module_param(build_info, charp, S_IRUGO); 92 + module_param(build_info, charp, 0444); 93 93 MODULE_PARM_DESC(build_info, "Built within ALSA source"); 94 94 #endif 95 95
+2 -2
sound/pci/asihpi/hpioctl.c
··· 46 46 #endif 47 47 48 48 static int prealloc_stream_buf; 49 - module_param(prealloc_stream_buf, int, S_IRUGO); 49 + module_param(prealloc_stream_buf, int, 0444); 50 50 MODULE_PARM_DESC(prealloc_stream_buf, 51 51 "Preallocate size for per-adapter stream buffer"); 52 52 53 53 /* Allow the debug level to be changed after module load. 54 54 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel 55 55 */ 56 - module_param(hpi_debug_level, int, S_IRUGO | S_IWUSR); 56 + module_param(hpi_debug_level, int, 0644); 57 57 MODULE_PARM_DESC(hpi_debug_level, "debug verbosity 0..5"); 58 58 59 59 /* List of adapters found */
+3 -3
sound/pci/ca0106/ca0106_proc.c
··· 431 431 if(! snd_card_proc_new(emu->card, "ca0106_reg32", &entry)) { 432 432 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read32); 433 433 entry->c.text.write = snd_ca0106_proc_reg_write32; 434 - entry->mode |= S_IWUSR; 434 + entry->mode |= 0200; 435 435 } 436 436 if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry)) 437 437 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read16); ··· 440 440 if(! snd_card_proc_new(emu->card, "ca0106_regs1", &entry)) { 441 441 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read1); 442 442 entry->c.text.write = snd_ca0106_proc_reg_write; 443 - entry->mode |= S_IWUSR; 443 + entry->mode |= 0200; 444 444 } 445 445 if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) { 446 446 entry->c.text.write = snd_ca0106_proc_i2c_write; 447 447 entry->private_data = emu; 448 - entry->mode |= S_IWUSR; 448 + entry->mode |= 0200; 449 449 } 450 450 if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) 451 451 snd_info_set_text_ops(entry, emu, snd_ca0106_proc_reg_read2);
+1 -1
sound/pci/cmipci.c
··· 1139 1139 struct snd_ctl_elem_value *val; 1140 1140 unsigned int i; 1141 1141 1142 - val = kmalloc(sizeof(*val), GFP_ATOMIC); 1142 + val = kmalloc(sizeof(*val), GFP_KERNEL); 1143 1143 if (!val) 1144 1144 return -ENOMEM; 1145 1145 for (i = 0; i < CM_SAVED_MIXERS; i++) {
+1 -1
sound/pci/cs46xx/cs46xx.c
··· 58 58 module_param_array(enable, bool, NULL, 0444); 59 59 MODULE_PARM_DESC(enable, "Enable CS46xx soundcard."); 60 60 module_param_array(external_amp, bool, NULL, 0444); 61 - MODULE_PARM_DESC(external_amp, "Force to enable external amplifer."); 61 + MODULE_PARM_DESC(external_amp, "Force to enable external amplifier."); 62 62 module_param_array(thinkpad, bool, NULL, 0444); 63 63 MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control."); 64 64 module_param_array(mmap_valid, bool, NULL, 0444);
+1 -1
sound/pci/cs46xx/cs46xx_lib.c
··· 2849 2849 entry->private_data = chip; 2850 2850 entry->c.ops = &snd_cs46xx_proc_io_ops; 2851 2851 entry->size = region->size; 2852 - entry->mode = S_IFREG | S_IRUSR; 2852 + entry->mode = S_IFREG | 0400; 2853 2853 } 2854 2854 } 2855 2855 #ifdef CONFIG_SND_CS46XX_NEW_DSP
+7 -7
sound/pci/cs46xx/dsp_spos.c
··· 798 798 799 799 if ((entry = snd_info_create_card_entry(card, "dsp", card->proc_root)) != NULL) { 800 800 entry->content = SNDRV_INFO_CONTENT_TEXT; 801 - entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; 801 + entry->mode = S_IFDIR | 0555; 802 802 803 803 if (snd_info_register(entry) < 0) { 804 804 snd_info_free_entry(entry); ··· 814 814 if ((entry = snd_info_create_card_entry(card, "spos_symbols", ins->proc_dsp_dir)) != NULL) { 815 815 entry->content = SNDRV_INFO_CONTENT_TEXT; 816 816 entry->private_data = chip; 817 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 817 + entry->mode = S_IFREG | 0644; 818 818 entry->c.text.read = cs46xx_dsp_proc_symbol_table_read; 819 819 if (snd_info_register(entry) < 0) { 820 820 snd_info_free_entry(entry); ··· 826 826 if ((entry = snd_info_create_card_entry(card, "spos_modules", ins->proc_dsp_dir)) != NULL) { 827 827 entry->content = SNDRV_INFO_CONTENT_TEXT; 828 828 entry->private_data = chip; 829 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 829 + entry->mode = S_IFREG | 0644; 830 830 entry->c.text.read = cs46xx_dsp_proc_modules_read; 831 831 if (snd_info_register(entry) < 0) { 832 832 snd_info_free_entry(entry); ··· 838 838 if ((entry = snd_info_create_card_entry(card, "parameter", ins->proc_dsp_dir)) != NULL) { 839 839 entry->content = SNDRV_INFO_CONTENT_TEXT; 840 840 entry->private_data = chip; 841 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 841 + entry->mode = S_IFREG | 0644; 842 842 entry->c.text.read = cs46xx_dsp_proc_parameter_dump_read; 843 843 if (snd_info_register(entry) < 0) { 844 844 snd_info_free_entry(entry); ··· 850 850 if ((entry = snd_info_create_card_entry(card, "sample", ins->proc_dsp_dir)) != NULL) { 851 851 entry->content = SNDRV_INFO_CONTENT_TEXT; 852 852 entry->private_data = chip; 853 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 853 + entry->mode = S_IFREG | 0644; 854 854 entry->c.text.read = cs46xx_dsp_proc_sample_dump_read; 855 855 if (snd_info_register(entry) < 0) { 856 856 snd_info_free_entry(entry); ··· 862 862 if ((entry = snd_info_create_card_entry(card, "task_tree", ins->proc_dsp_dir)) != NULL) { 863 863 entry->content = SNDRV_INFO_CONTENT_TEXT; 864 864 entry->private_data = chip; 865 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 865 + entry->mode = S_IFREG | 0644; 866 866 entry->c.text.read = cs46xx_dsp_proc_task_tree_read; 867 867 if (snd_info_register(entry) < 0) { 868 868 snd_info_free_entry(entry); ··· 874 874 if ((entry = snd_info_create_card_entry(card, "scb_info", ins->proc_dsp_dir)) != NULL) { 875 875 entry->content = SNDRV_INFO_CONTENT_TEXT; 876 876 entry->private_data = chip; 877 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 877 + entry->mode = S_IFREG | 0644; 878 878 entry->c.text.read = cs46xx_dsp_proc_scb_read; 879 879 if (snd_info_register(entry) < 0) { 880 880 snd_info_free_entry(entry);
+1 -1
sound/pci/cs46xx/dsp_spos_scb_lib.c
··· 271 271 272 272 entry->content = SNDRV_INFO_CONTENT_TEXT; 273 273 entry->private_data = scb_info; 274 - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 274 + entry->mode = S_IFREG | 0644; 275 275 276 276 entry->c.text.read = cs46xx_dsp_proc_scb_info_read; 277 277
+1 -1
sound/pci/ctxfi/cttimer.c
··· 17 17 18 18 static bool use_system_timer; 19 19 MODULE_PARM_DESC(use_system_timer, "Force to use system-timer"); 20 - module_param(use_system_timer, bool, S_IRUGO); 20 + module_param(use_system_timer, bool, 0444); 21 21 22 22 struct ct_timer_ops { 23 23 void (*init)(struct ct_timer_instance *);
+2 -2
sound/pci/ctxfi/xfi.c
··· 26 26 static unsigned int reference_rate = 48000; 27 27 static unsigned int multiple = 2; 28 28 MODULE_PARM_DESC(reference_rate, "Reference rate (default=48000)"); 29 - module_param(reference_rate, uint, S_IRUGO); 29 + module_param(reference_rate, uint, 0444); 30 30 MODULE_PARM_DESC(multiple, "Rate multiplier (default=2)"); 31 - module_param(multiple, uint, S_IRUGO); 31 + module_param(multiple, uint, 0444); 32 32 33 33 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 34 34 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+1 -1
sound/pci/echoaudio/echoaudio.c
··· 59 59 dev_dbg(chip->card->dev, 60 60 "firmware requested: %s\n", card_fw[fw_index].data); 61 61 snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); 62 - err = request_firmware(fw_entry, name, pci_device(chip)); 62 + err = request_firmware(fw_entry, name, &chip->pci->dev); 63 63 if (err < 0) 64 64 dev_err(chip->card->dev, 65 65 "get_firmware(): Firmware not available (%d)\n", err);
-6
sound/pci/echoaudio/echoaudio.h
··· 559 559 return out * num_busses_in(chip) + in; 560 560 } 561 561 562 - 563 - #ifndef pci_device 564 - #define pci_device(chip) (&chip->pci->dev) 565 - #endif 566 - 567 - 568 562 #endif /* _ECHOAUDIO_H_ */
+1 -1
sound/pci/emu10k1/emu10k1x.c
··· 1070 1070 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) { 1071 1071 snd_info_set_text_ops(entry, emu, snd_emu10k1x_proc_reg_read); 1072 1072 entry->c.text.write = snd_emu10k1x_proc_reg_write; 1073 - entry->mode |= S_IWUSR; 1073 + entry->mode |= 0200; 1074 1074 entry->private_data = emu; 1075 1075 } 1076 1076
+2 -9
sound/pci/emu10k1/emufx.c
··· 170 170 /* 0x0f */ "Rear Right", 171 171 /* 0x10 */ "AC97 Front Left", 172 172 /* 0x11 */ "AC97 Front Right", 173 - /* 0x12 */ "ADC Caputre Left", 173 + /* 0x12 */ "ADC Capture Left", 174 174 /* 0x13 */ "ADC Capture Right", 175 175 /* 0x14 */ NULL, 176 176 /* 0x15 */ NULL, ··· 421 421 snd_fx8010_irq_handler_t *handler, 422 422 unsigned char gpr_running, 423 423 void *private_data, 424 - struct snd_emu10k1_fx8010_irq **r_irq) 424 + struct snd_emu10k1_fx8010_irq *irq) 425 425 { 426 - struct snd_emu10k1_fx8010_irq *irq; 427 426 unsigned long flags; 428 427 429 - irq = kmalloc(sizeof(*irq), GFP_ATOMIC); 430 - if (irq == NULL) 431 - return -ENOMEM; 432 428 irq->handler = handler; 433 429 irq->gpr_running = gpr_running; 434 430 irq->private_data = private_data; ··· 439 443 emu->fx8010.irq_handlers = irq; 440 444 } 441 445 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags); 442 - if (r_irq) 443 - *r_irq = irq; 444 446 return 0; 445 447 } 446 448 ··· 462 468 tmp->next = tmp->next->next; 463 469 } 464 470 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags); 465 - kfree(irq); 466 471 return 0; 467 472 } 468 473
+1 -1
sound/pci/emu10k1/emupcm.c
··· 1724 1724 case SNDRV_PCM_TRIGGER_STOP: 1725 1725 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1726 1726 case SNDRV_PCM_TRIGGER_SUSPEND: 1727 - snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL; 1727 + snd_emu10k1_fx8010_unregister_irq_handler(emu, &pcm->irq); 1728 1728 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); 1729 1729 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size); 1730 1730 pcm->tram_shift = 0;
+12 -12
sound/pci/emu10k1/emuproc.c
··· 135 135 /* 15 */ "Rear Right", 136 136 /* 16 */ "AC97 Front Left", 137 137 /* 17 */ "AC97 Front Right", 138 - /* 18 */ "ADC Caputre Left", 138 + /* 18 */ "ADC Capture Left", 139 139 /* 19 */ "ADC Capture Right", 140 140 /* 20 */ "???", 141 141 /* 21 */ "???", ··· 574 574 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { 575 575 snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); 576 576 entry->c.text.write = snd_emu_proc_io_reg_write; 577 - entry->mode |= S_IWUSR; 577 + entry->mode |= 0200; 578 578 } 579 579 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) { 580 580 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00a); 581 581 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 582 - entry->mode |= S_IWUSR; 582 + entry->mode |= 0200; 583 583 } 584 584 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) { 585 585 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read00b); 586 586 entry->c.text.write = snd_emu_proc_ptr_reg_write00; 587 - entry->mode |= S_IWUSR; 587 + entry->mode |= 0200; 588 588 } 589 589 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) { 590 590 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20a); 591 591 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 592 - entry->mode |= S_IWUSR; 592 + entry->mode |= 0200; 593 593 } 594 594 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) { 595 595 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20b); 596 596 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 597 - entry->mode |= S_IWUSR; 597 + entry->mode |= 0200; 598 598 } 599 599 if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) { 600 600 snd_info_set_text_ops(entry, emu, snd_emu_proc_ptr_reg_read20c); 601 601 entry->c.text.write = snd_emu_proc_ptr_reg_write20; 602 - entry->mode |= S_IWUSR; 602 + entry->mode |= 0200; 603 603 } 604 604 #endif 605 605 ··· 621 621 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) { 622 622 entry->content = SNDRV_INFO_CONTENT_DATA; 623 623 entry->private_data = emu; 624 - entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 624 + entry->mode = S_IFREG | 0444 /*| S_IWUSR*/; 625 625 entry->size = emu->audigy ? A_TOTAL_SIZE_GPR : TOTAL_SIZE_GPR; 626 626 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 627 627 } 628 628 if (! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) { 629 629 entry->content = SNDRV_INFO_CONTENT_DATA; 630 630 entry->private_data = emu; 631 - entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 631 + entry->mode = S_IFREG | 0444 /*| S_IWUSR*/; 632 632 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_DATA : TOTAL_SIZE_TANKMEM_DATA ; 633 633 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 634 634 } 635 635 if (! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) { 636 636 entry->content = SNDRV_INFO_CONTENT_DATA; 637 637 entry->private_data = emu; 638 - entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 638 + entry->mode = S_IFREG | 0444 /*| S_IWUSR*/; 639 639 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_ADDR : TOTAL_SIZE_TANKMEM_ADDR ; 640 640 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 641 641 } 642 642 if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) { 643 643 entry->content = SNDRV_INFO_CONTENT_DATA; 644 644 entry->private_data = emu; 645 - entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 645 + entry->mode = S_IFREG | 0444 /*| S_IWUSR*/; 646 646 entry->size = emu->audigy ? A_TOTAL_SIZE_CODE : TOTAL_SIZE_CODE; 647 647 entry->c.ops = &snd_emu10k1_proc_ops_fx8010; 648 648 } 649 649 if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) { 650 650 entry->content = SNDRV_INFO_CONTENT_TEXT; 651 651 entry->private_data = emu; 652 - entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; 652 + entry->mode = S_IFREG | 0444 /*| S_IWUSR*/; 653 653 entry->c.text.read = snd_emu10k1_proc_acode_read; 654 654 } 655 655 return 0;
+3 -3
sound/pci/emu10k1/memory.c
··· 248 248 static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr) 249 249 { 250 250 if (addr & ~emu->dma_mask) { 251 - dev_err(emu->card->dev, 251 + dev_err_ratelimited(emu->card->dev, 252 252 "max memory size is 0x%lx (addr = 0x%lx)!!\n", 253 253 emu->dma_mask, (unsigned long)addr); 254 254 return 0; 255 255 } 256 256 if (addr & (EMUPAGESIZE-1)) { 257 - dev_err(emu->card->dev, "page is not aligned\n"); 257 + dev_err_ratelimited(emu->card->dev, "page is not aligned\n"); 258 258 return 0; 259 259 } 260 260 return 1; ··· 345 345 else 346 346 addr = snd_pcm_sgbuf_get_addr(substream, ofs); 347 347 if (! is_valid_page(emu, addr)) { 348 - dev_err(emu->card->dev, 348 + dev_err_ratelimited(emu->card->dev, 349 349 "emu: failure page = %d\n", idx); 350 350 mutex_unlock(&hdr->block_mutex); 351 351 return NULL;
+4
sound/pci/hda/Kconfig
··· 127 127 128 128 config SND_HDA_CODEC_HDMI 129 129 tristate "Build HDMI/DisplayPort HD-audio codec support" 130 + select SND_DYNAMIC_MINORS 130 131 help 131 132 Say Y or M here to include HDMI and DisplayPort HD-audio codec 132 133 support in snd-hda-intel driver. This includes all AMD/ATI, 133 134 Intel and Nvidia HDMI/DisplayPort codecs. 135 + 136 + Note that this option mandatorily enables CONFIG_SND_DYNAMIC_MINORS 137 + to assure the multiple streams for DP-MST support. 134 138 135 139 comment "Set to Y if you want auto-loading the codec driver" 136 140 depends on SND_HDA=y && SND_HDA_CODEC_HDMI=m
+5 -5
sound/pci/hda/hda_auto_parser.c
··· 793 793 */ 794 794 void snd_hda_apply_verbs(struct hda_codec *codec) 795 795 { 796 + const struct hda_verb **v; 796 797 int i; 797 - for (i = 0; i < codec->verbs.used; i++) { 798 - struct hda_verb **v = snd_array_elem(&codec->verbs, i); 798 + 799 + snd_array_for_each(&codec->verbs, i, v) 799 800 snd_hda_sequence_write(codec, *v); 800 - } 801 801 } 802 802 EXPORT_SYMBOL_GPL(snd_hda_apply_verbs); 803 803 ··· 890 890 static bool pin_config_match(struct hda_codec *codec, 891 891 const struct hda_pintbl *pins) 892 892 { 893 + const struct hda_pincfg *pin; 893 894 int i; 894 895 895 - for (i = 0; i < codec->init_pins.used; i++) { 896 - struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 896 + snd_array_for_each(&codec->init_pins, i, pin) { 897 897 hda_nid_t nid = pin->nid; 898 898 u32 cfg = pin->cfg; 899 899 const struct hda_pintbl *t_pins;
+41 -29
sound/pci/hda/hda_codec.c
··· 481 481 struct snd_array *array, 482 482 hda_nid_t nid) 483 483 { 484 + struct hda_pincfg *pin; 484 485 int i; 485 - for (i = 0; i < array->used; i++) { 486 - struct hda_pincfg *pin = snd_array_elem(array, i); 486 + 487 + snd_array_for_each(array, i, pin) { 487 488 if (pin->nid == nid) 488 489 return pin; 489 490 } ··· 619 618 */ 620 619 void snd_hda_shutup_pins(struct hda_codec *codec) 621 620 { 621 + const struct hda_pincfg *pin; 622 622 int i; 623 + 623 624 /* don't shut up pins when unloading the driver; otherwise it breaks 624 625 * the default pin setup at the next load of the driver 625 626 */ 626 627 if (codec->bus->shutdown) 627 628 return; 628 - for (i = 0; i < codec->init_pins.used; i++) { 629 - struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 629 + snd_array_for_each(&codec->init_pins, i, pin) { 630 630 /* use read here for syncing after issuing each verb */ 631 631 snd_hda_codec_read(codec, pin->nid, 0, 632 632 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); ··· 640 638 /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ 641 639 static void restore_shutup_pins(struct hda_codec *codec) 642 640 { 641 + const struct hda_pincfg *pin; 643 642 int i; 643 + 644 644 if (!codec->pins_shutup) 645 645 return; 646 646 if (codec->bus->shutdown) 647 647 return; 648 - for (i = 0; i < codec->init_pins.used; i++) { 649 - struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 648 + snd_array_for_each(&codec->init_pins, i, pin) { 650 649 snd_hda_codec_write(codec, pin->nid, 0, 651 650 AC_VERB_SET_PIN_WIDGET_CONTROL, 652 651 pin->ctrl); ··· 700 697 struct hda_cvt_setup *p; 701 698 int i; 702 699 703 - for (i = 0; i < codec->cvt_setups.used; i++) { 704 - p = snd_array_elem(&codec->cvt_setups, i); 700 + snd_array_for_each(&codec->cvt_setups, i, p) { 705 701 if (p->nid == nid) 706 702 return p; 707 703 } ··· 1078 1076 /* make other inactive cvts with the same stream-tag dirty */ 1079 1077 type = get_wcaps_type(get_wcaps(codec, nid)); 1080 1078 list_for_each_codec(c, codec->bus) { 1081 - for (i = 0; i < c->cvt_setups.used; i++) { 1082 - p = snd_array_elem(&c->cvt_setups, i); 1079 + snd_array_for_each(&c->cvt_setups, i, p) { 1083 1080 if (!p->active && p->stream_tag == stream_tag && 1084 1081 get_wcaps_type(get_wcaps(c, p->nid)) == type) 1085 1082 p->dirty = 1; ··· 1141 1140 static void purify_inactive_streams(struct hda_codec *codec) 1142 1141 { 1143 1142 struct hda_codec *c; 1143 + struct hda_cvt_setup *p; 1144 1144 int i; 1145 1145 1146 1146 list_for_each_codec(c, codec->bus) { 1147 - for (i = 0; i < c->cvt_setups.used; i++) { 1148 - struct hda_cvt_setup *p; 1149 - p = snd_array_elem(&c->cvt_setups, i); 1147 + snd_array_for_each(&c->cvt_setups, i, p) { 1150 1148 if (p->dirty) 1151 1149 really_cleanup_stream(c, p); 1152 1150 } ··· 1156 1156 /* clean up all streams; called from suspend */ 1157 1157 static void hda_cleanup_all_streams(struct hda_codec *codec) 1158 1158 { 1159 + struct hda_cvt_setup *p; 1159 1160 int i; 1160 1161 1161 - for (i = 0; i < codec->cvt_setups.used; i++) { 1162 - struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i); 1162 + snd_array_for_each(&codec->cvt_setups, i, p) { 1163 1163 if (p->stream_tag) 1164 1164 really_cleanup_stream(codec, p); 1165 1165 } ··· 1493 1493 val1 = ((int)val1) * ((int)val2); 1494 1494 if (min_mute || (caps & AC_AMPCAP_MIN_MUTE)) 1495 1495 val2 |= TLV_DB_SCALE_MUTE; 1496 - tlv[0] = SNDRV_CTL_TLVT_DB_SCALE; 1497 - tlv[1] = 2 * sizeof(unsigned int); 1498 - tlv[2] = val1; 1499 - tlv[3] = val2; 1496 + tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_SCALE; 1497 + tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int); 1498 + tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = val1; 1499 + tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = val2; 1500 1500 } 1501 1501 1502 1502 /** ··· 1544 1544 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; 1545 1545 step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; 1546 1546 step = (step + 1) * 25; 1547 - tlv[0] = SNDRV_CTL_TLVT_DB_SCALE; 1548 - tlv[1] = 2 * sizeof(unsigned int); 1549 - tlv[2] = -nums * step; 1550 - tlv[3] = step; 1547 + tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_SCALE; 1548 + tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int); 1549 + tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = -nums * step; 1550 + tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = step; 1551 1551 } 1552 1552 EXPORT_SYMBOL_GPL(snd_hda_set_vmaster_tlv); 1553 1553 ··· 1845 1845 } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) 1846 1846 tlv = kctl->tlv.p; 1847 1847 1848 - if (!tlv || tlv[0] != SNDRV_CTL_TLVT_DB_SCALE) 1848 + if (!tlv || tlv[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE) 1849 1849 return 0; 1850 1850 1851 - step = tlv[3]; 1851 + step = tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP]; 1852 1852 step &= ~TLV_DB_SCALE_MUTE; 1853 1853 if (!step) 1854 1854 return 0; ··· 1860 1860 } 1861 1861 1862 1862 arg->step = step; 1863 - val = -tlv[2] / step; 1863 + val = -tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] / step; 1864 1864 if (val > 0) { 1865 1865 put_kctl_with_value(slave, val); 1866 1866 return val; ··· 2175 2175 int idx = kcontrol->private_value; 2176 2176 struct hda_spdif_out *spdif; 2177 2177 2178 + if (WARN_ON(codec->spdif_out.used <= idx)) 2179 + return -EINVAL; 2178 2180 mutex_lock(&codec->spdif_mutex); 2179 2181 spdif = snd_array_elem(&codec->spdif_out, idx); 2180 2182 ucontrol->value.iec958.status[0] = spdif->status & 0xff; ··· 2284 2282 unsigned short val; 2285 2283 int change; 2286 2284 2285 + if (WARN_ON(codec->spdif_out.used <= idx)) 2286 + return -EINVAL; 2287 2287 mutex_lock(&codec->spdif_mutex); 2288 2288 spdif = snd_array_elem(&codec->spdif_out, idx); 2289 2289 nid = spdif->nid; ··· 2312 2308 int idx = kcontrol->private_value; 2313 2309 struct hda_spdif_out *spdif; 2314 2310 2311 + if (WARN_ON(codec->spdif_out.used <= idx)) 2312 + return -EINVAL; 2315 2313 mutex_lock(&codec->spdif_mutex); 2316 2314 spdif = snd_array_elem(&codec->spdif_out, idx); 2317 2315 ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE; ··· 2342 2336 unsigned short val; 2343 2337 int change; 2344 2338 2339 + if (WARN_ON(codec->spdif_out.used <= idx)) 2340 + return -EINVAL; 2345 2341 mutex_lock(&codec->spdif_mutex); 2346 2342 spdif = snd_array_elem(&codec->spdif_out, idx); 2347 2343 nid = spdif->nid; ··· 2469 2461 struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, 2470 2462 hda_nid_t nid) 2471 2463 { 2464 + struct hda_spdif_out *spdif; 2472 2465 int i; 2473 - for (i = 0; i < codec->spdif_out.used; i++) { 2474 - struct hda_spdif_out *spdif = 2475 - snd_array_elem(&codec->spdif_out, i); 2466 + 2467 + snd_array_for_each(&codec->spdif_out, i, spdif) { 2476 2468 if (spdif->nid == nid) 2477 2469 return spdif; 2478 2470 } ··· 2491 2483 { 2492 2484 struct hda_spdif_out *spdif; 2493 2485 2486 + if (WARN_ON(codec->spdif_out.used <= idx)) 2487 + return; 2494 2488 mutex_lock(&codec->spdif_mutex); 2495 2489 spdif = snd_array_elem(&codec->spdif_out, idx); 2496 2490 spdif->nid = (u16)-1; ··· 2513 2503 struct hda_spdif_out *spdif; 2514 2504 unsigned short val; 2515 2505 2506 + if (WARN_ON(codec->spdif_out.used <= idx)) 2507 + return; 2516 2508 mutex_lock(&codec->spdif_mutex); 2517 2509 spdif = snd_array_elem(&codec->spdif_out, idx); 2518 2510 if (spdif->nid != nid) {
+3 -1
sound/pci/hda/hda_controller.c
··· 748 748 return err; 749 749 strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); 750 750 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 751 - if (apcm == NULL) 751 + if (apcm == NULL) { 752 + snd_device_free(chip->card, pcm); 752 753 return -ENOMEM; 754 + } 753 755 apcm->chip = chip; 754 756 apcm->pcm = pcm; 755 757 apcm->codec = codec;
+14 -15
sound/pci/hda/hda_generic.c
··· 264 264 int anchor_nid) 265 265 { 266 266 struct hda_gen_spec *spec = codec->spec; 267 + struct nid_path *path; 267 268 int i; 268 269 269 - for (i = 0; i < spec->paths.used; i++) { 270 - struct nid_path *path = snd_array_elem(&spec->paths, i); 270 + snd_array_for_each(&spec->paths, i, path) { 271 271 if (path->depth <= 0) 272 272 continue; 273 273 if ((!from_nid || path->path[0] == from_nid) && ··· 325 325 static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid) 326 326 { 327 327 struct hda_gen_spec *spec = codec->spec; 328 + const struct nid_path *path; 328 329 int i; 329 330 330 - for (i = 0; i < spec->paths.used; i++) { 331 - struct nid_path *path = snd_array_elem(&spec->paths, i); 331 + snd_array_for_each(&spec->paths, i, path) { 332 332 if (path->path[0] == nid) 333 333 return true; 334 334 } ··· 351 351 static bool is_ctl_used(struct hda_codec *codec, unsigned int val, int type) 352 352 { 353 353 struct hda_gen_spec *spec = codec->spec; 354 + const struct nid_path *path; 354 355 int i; 355 356 356 357 val &= AMP_VAL_COMPARE_MASK; 357 - for (i = 0; i < spec->paths.used; i++) { 358 - struct nid_path *path = snd_array_elem(&spec->paths, i); 358 + snd_array_for_each(&spec->paths, i, path) { 359 359 if ((path->ctls[type] & AMP_VAL_COMPARE_MASK) == val) 360 360 return true; 361 361 } ··· 638 638 { 639 639 struct hda_gen_spec *spec = codec->spec; 640 640 int type = get_wcaps_type(get_wcaps(codec, nid)); 641 + const struct nid_path *path; 641 642 int i, n; 642 643 643 644 if (nid == codec->core.afg) 644 645 return true; 645 646 646 - for (n = 0; n < spec->paths.used; n++) { 647 - struct nid_path *path = snd_array_elem(&spec->paths, n); 647 + snd_array_for_each(&spec->paths, n, path) { 648 648 if (!path->active) 649 649 continue; 650 650 if (codec->power_save_node) { ··· 2065 2065 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2066 2066 HDA_OUTPUT, spec->vmaster_tlv); 2067 2067 if (spec->dac_min_mute) 2068 - spec->vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; 2068 + spec->vmaster_tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] |= TLV_DB_SCALE_MUTE; 2069 2069 } 2070 2070 } 2071 2071 ··· 2696 2696 static bool find_kctl_name(struct hda_codec *codec, const char *name, int idx) 2697 2697 { 2698 2698 struct hda_gen_spec *spec = codec->spec; 2699 + const struct snd_kcontrol_new *kctl; 2699 2700 int i; 2700 2701 2701 - for (i = 0; i < spec->kctls.used; i++) { 2702 - struct snd_kcontrol_new *kctl = snd_array_elem(&spec->kctls, i); 2702 + snd_array_for_each(&spec->kctls, i, kctl) { 2703 2703 if (!strcmp(kctl->name, name) && kctl->index == idx) 2704 2704 return true; 2705 2705 } ··· 4021 4021 struct nid_path *path; 4022 4022 int n; 4023 4023 4024 - for (n = 0; n < spec->paths.used; n++) { 4025 - path = snd_array_elem(&spec->paths, n); 4024 + snd_array_for_each(&spec->paths, n, path) { 4026 4025 if (!path->depth) 4027 4026 continue; 4028 4027 if (path->path[0] == nid || ··· 5830 5831 */ 5831 5832 static void clear_unsol_on_unused_pins(struct hda_codec *codec) 5832 5833 { 5834 + const struct hda_pincfg *pin; 5833 5835 int i; 5834 5836 5835 - for (i = 0; i < codec->init_pins.used; i++) { 5836 - struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 5837 + snd_array_for_each(&codec->init_pins, i, pin) { 5837 5838 hda_nid_t nid = pin->nid; 5838 5839 if (is_jack_detectable(codec, nid) && 5839 5840 !snd_hda_jack_tbl_get(codec, nid))
+11
sound/pci/hda/hda_intel.c
··· 2209 2209 /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ 2210 2210 SND_PCI_QUIRK(0x1849, 0x0c0c, "Asrock B85M-ITX", 0), 2211 2211 /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ 2212 + SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0), 2213 + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ 2212 2214 SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0), 2215 + /* https://bugzilla.redhat.com/show_bug.cgi?id=1581607 */ 2216 + SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", 0), 2217 + /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ 2218 + /* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */ 2219 + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P55A-UD3 / Z87-D3HP", 0), 2220 + /* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */ 2221 + SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0), 2222 + /* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */ 2223 + SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), 2213 2224 /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ 2214 2225 SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0), 2215 2226 /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */
+10 -10
sound/pci/hda/hda_sysfs.c
··· 80 80 struct snd_array *list, 81 81 char *buf) 82 82 { 83 + const struct hda_pincfg *pin; 83 84 int i, len = 0; 84 85 mutex_lock(&codec->user_mutex); 85 - for (i = 0; i < list->used; i++) { 86 - struct hda_pincfg *pin = snd_array_elem(list, i); 86 + snd_array_for_each(list, i, pin) { 87 87 len += sprintf(buf + len, "0x%02x 0x%08x\n", 88 88 pin->nid, pin->cfg); 89 89 } ··· 217 217 char *buf) 218 218 { 219 219 struct hda_codec *codec = dev_get_drvdata(dev); 220 + const struct hda_verb *v; 220 221 int i, len = 0; 221 222 mutex_lock(&codec->user_mutex); 222 - for (i = 0; i < codec->init_verbs.used; i++) { 223 - struct hda_verb *v = snd_array_elem(&codec->init_verbs, i); 223 + snd_array_for_each(&codec->init_verbs, i, v) { 224 224 len += snprintf(buf + len, PAGE_SIZE - len, 225 225 "0x%02x 0x%03x 0x%04x\n", 226 226 v->nid, v->verb, v->param); ··· 267 267 char *buf) 268 268 { 269 269 struct hda_codec *codec = dev_get_drvdata(dev); 270 + const struct hda_hint *hint; 270 271 int i, len = 0; 271 272 mutex_lock(&codec->user_mutex); 272 - for (i = 0; i < codec->hints.used; i++) { 273 - struct hda_hint *hint = snd_array_elem(&codec->hints, i); 273 + snd_array_for_each(&codec->hints, i, hint) { 274 274 len += snprintf(buf + len, PAGE_SIZE - len, 275 275 "%s = %s\n", hint->key, hint->val); 276 276 } ··· 280 280 281 281 static struct hda_hint *get_hint(struct hda_codec *codec, const char *key) 282 282 { 283 + struct hda_hint *hint; 283 284 int i; 284 285 285 - for (i = 0; i < codec->hints.used; i++) { 286 - struct hda_hint *hint = snd_array_elem(&codec->hints, i); 286 + snd_array_for_each(&codec->hints, i, hint) { 287 287 if (!strcmp(hint->key, key)) 288 288 return hint; 289 289 } ··· 783 783 void snd_hda_sysfs_clear(struct hda_codec *codec) 784 784 { 785 785 #ifdef CONFIG_SND_HDA_RECONFIG 786 + struct hda_hint *hint; 786 787 int i; 787 788 788 789 /* clear init verbs */ 789 790 snd_array_free(&codec->init_verbs); 790 791 /* clear hints */ 791 - for (i = 0; i < codec->hints.used; i++) { 792 - struct hda_hint *hint = snd_array_elem(&codec->hints, i); 792 + snd_array_for_each(&codec->hints, i, hint) { 793 793 kfree(hint->key); /* we don't need to free hint->val */ 794 794 } 795 795 snd_array_free(&codec->hints);
+95
sound/pci/hda/hp_x360_helper.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Fixes for HP X360 laptops with top B&O speakers 3 + * to be included from codec driver 4 + */ 5 + 6 + static void alc295_fixup_hp_top_speakers(struct hda_codec *codec, 7 + const struct hda_fixup *fix, int action) 8 + { 9 + static const struct hda_pintbl pincfgs[] = { 10 + { 0x17, 0x90170110 }, 11 + { } 12 + }; 13 + static const struct coef_fw alc295_hp_speakers_coefs[] = { 14 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0000), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 15 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003f), WRITE_COEF(0x28, 0x1000), WRITE_COEF(0x29, 0xb024), 16 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0004), WRITE_COEF(0x28, 0x0600), WRITE_COEF(0x29, 0xb024), 17 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x0006), WRITE_COEF(0x29, 0xb024), 18 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0xc0c0), WRITE_COEF(0x29, 0xb024), 19 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0008), WRITE_COEF(0x28, 0xb000), WRITE_COEF(0x29, 0xb024), 20 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x002e), WRITE_COEF(0x28, 0x0800), WRITE_COEF(0x29, 0xb024), 21 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x00c1), WRITE_COEF(0x29, 0xb024), 22 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x0320), WRITE_COEF(0x29, 0xb024), 23 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0039), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 24 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003b), WRITE_COEF(0x28, 0xffff), WRITE_COEF(0x29, 0xb024), 25 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003c), WRITE_COEF(0x28, 0xffd0), WRITE_COEF(0x29, 0xb024), 26 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003a), WRITE_COEF(0x28, 0x1dfe), WRITE_COEF(0x29, 0xb024), 27 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0080), WRITE_COEF(0x28, 0x0880), WRITE_COEF(0x29, 0xb024), 28 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003a), WRITE_COEF(0x28, 0x0dfe), WRITE_COEF(0x29, 0xb024), 29 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0018), WRITE_COEF(0x28, 0x0219), WRITE_COEF(0x29, 0xb024), 30 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x005d), WRITE_COEF(0x29, 0xb024), 31 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x9142), WRITE_COEF(0x29, 0xb024), 32 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c0), WRITE_COEF(0x28, 0x01ce), WRITE_COEF(0x29, 0xb024), 33 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c1), WRITE_COEF(0x28, 0xed0c), WRITE_COEF(0x29, 0xb024), 34 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c2), WRITE_COEF(0x28, 0x1c00), WRITE_COEF(0x29, 0xb024), 35 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c3), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 36 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c4), WRITE_COEF(0x28, 0x0200), WRITE_COEF(0x29, 0xb024), 37 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c5), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 38 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c6), WRITE_COEF(0x28, 0x0399), WRITE_COEF(0x29, 0xb024), 39 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c7), WRITE_COEF(0x28, 0x2330), WRITE_COEF(0x29, 0xb024), 40 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c8), WRITE_COEF(0x28, 0x1e5d), WRITE_COEF(0x29, 0xb024), 41 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00c9), WRITE_COEF(0x28, 0x6eff), WRITE_COEF(0x29, 0xb024), 42 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00ca), WRITE_COEF(0x28, 0x01c0), WRITE_COEF(0x29, 0xb024), 43 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cb), WRITE_COEF(0x28, 0xed0c), WRITE_COEF(0x29, 0xb024), 44 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cc), WRITE_COEF(0x28, 0x1c00), WRITE_COEF(0x29, 0xb024), 45 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cd), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 46 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00ce), WRITE_COEF(0x28, 0x0200), WRITE_COEF(0x29, 0xb024), 47 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00cf), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 48 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d0), WRITE_COEF(0x28, 0x0399), WRITE_COEF(0x29, 0xb024), 49 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d1), WRITE_COEF(0x28, 0x2330), WRITE_COEF(0x29, 0xb024), 50 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d2), WRITE_COEF(0x28, 0x1e5d), WRITE_COEF(0x29, 0xb024), 51 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x00d3), WRITE_COEF(0x28, 0x6eff), WRITE_COEF(0x29, 0xb024), 52 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0062), WRITE_COEF(0x28, 0x8000), WRITE_COEF(0x29, 0xb024), 53 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0063), WRITE_COEF(0x28, 0x5f5f), WRITE_COEF(0x29, 0xb024), 54 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0064), WRITE_COEF(0x28, 0x1000), WRITE_COEF(0x29, 0xb024), 55 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0065), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 56 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0066), WRITE_COEF(0x28, 0x4004), WRITE_COEF(0x29, 0xb024), 57 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0067), WRITE_COEF(0x28, 0x0802), WRITE_COEF(0x29, 0xb024), 58 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0068), WRITE_COEF(0x28, 0x890f), WRITE_COEF(0x29, 0xb024), 59 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0069), WRITE_COEF(0x28, 0xe021), WRITE_COEF(0x29, 0xb024), 60 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0070), WRITE_COEF(0x28, 0x8012), WRITE_COEF(0x29, 0xb024), 61 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0071), WRITE_COEF(0x28, 0x3450), WRITE_COEF(0x29, 0xb024), 62 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0072), WRITE_COEF(0x28, 0x0123), WRITE_COEF(0x29, 0xb024), 63 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0073), WRITE_COEF(0x28, 0x4543), WRITE_COEF(0x29, 0xb024), 64 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0074), WRITE_COEF(0x28, 0x2100), WRITE_COEF(0x29, 0xb024), 65 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0075), WRITE_COEF(0x28, 0x4321), WRITE_COEF(0x29, 0xb024), 66 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0076), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 67 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0050), WRITE_COEF(0x28, 0x8200), WRITE_COEF(0x29, 0xb024), 68 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003a), WRITE_COEF(0x28, 0x1dfe), WRITE_COEF(0x29, 0xb024), 69 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0051), WRITE_COEF(0x28, 0x0707), WRITE_COEF(0x29, 0xb024), 70 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0052), WRITE_COEF(0x28, 0x4090), WRITE_COEF(0x29, 0xb024), 71 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x0090), WRITE_COEF(0x29, 0xb024), 72 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x721f), WRITE_COEF(0x29, 0xb024), 73 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0012), WRITE_COEF(0x28, 0xebeb), WRITE_COEF(0x29, 0xb024), 74 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x009e), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 75 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0060), WRITE_COEF(0x28, 0x2213), WRITE_COEF(0x29, 0xb024), 76 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006a), WRITE_COEF(0x28, 0x0006), WRITE_COEF(0x29, 0xb024), 77 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x006c), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 78 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x003f), WRITE_COEF(0x28, 0x3000), WRITE_COEF(0x29, 0xb024), 79 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0004), WRITE_COEF(0x28, 0x0500), WRITE_COEF(0x29, 0xb024), 80 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0040), WRITE_COEF(0x28, 0x800c), WRITE_COEF(0x29, 0xb024), 81 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0046), WRITE_COEF(0x28, 0xc22e), WRITE_COEF(0x29, 0xb024), 82 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x004b), WRITE_COEF(0x28, 0x0000), WRITE_COEF(0x29, 0xb024), 83 + WRITE_COEF(0x24, 0x0012), WRITE_COEF(0x26, 0x0050), WRITE_COEF(0x28, 0x82ec), WRITE_COEF(0x29, 0xb024), 84 + }; 85 + 86 + switch (action) { 87 + case HDA_FIXUP_ACT_PRE_PROBE: 88 + snd_hda_apply_pincfgs(codec, pincfgs); 89 + alc295_fixup_disable_dac3(codec, fix, action); 90 + break; 91 + case HDA_FIXUP_ACT_INIT: 92 + alc_process_coef_fw(codec, alc295_hp_speakers_coefs); 93 + break; 94 + } 95 + }
-40
sound/pci/hda/local.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - */ 4 - 5 - #ifndef __HDAC_LOCAL_H 6 - #define __HDAC_LOCAL_H 7 - 8 - int hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm); 9 - 10 - #define get_wcaps(codec, nid) \ 11 - hdac_read_parm(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) 12 - /* get the widget type from widget capability bits */ 13 - static inline int get_wcaps_type(unsigned int wcaps) 14 - { 15 - if (!wcaps) 16 - return -1; /* invalid type */ 17 - return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 18 - } 19 - 20 - #define get_pin_caps(codec, nid) \ 21 - hdac_read_parm(codec, nid, AC_PAR_PIN_CAP) 22 - 23 - static inline 24 - unsigned int get_pin_cfg(struct hdac_device *codec, hda_nid_t nid) 25 - { 26 - unsigned int val; 27 - 28 - if (snd_hdac_read(codec, nid, AC_VERB_GET_CONFIG_DEFAULT, 0, &val)) 29 - return -1; 30 - return val; 31 - } 32 - 33 - #define get_amp_caps(codec, nid, dir) \ 34 - hdac_read_parm(codec, nid, (dir) == HDA_OUTPUT ? \ 35 - AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP) 36 - 37 - #define get_power_caps(codec, nid) \ 38 - hdac_read_parm(codec, nid, AC_PAR_POWER_STATE) 39 - 40 - #endif /* __HDAC_LOCAL_H */
+2913 -88
sound/pci/hda/patch_ca0132.c
··· 28 28 #include <linux/module.h> 29 29 #include <linux/firmware.h> 30 30 #include <linux/kernel.h> 31 + #include <linux/types.h> 32 + #include <linux/io.h> 33 + #include <linux/pci.h> 31 34 #include <sound/core.h> 32 35 #include "hda_codec.h" 33 36 #include "hda_local.h" ··· 42 39 /* Enable this to see controls for tuning purpose. */ 43 40 /*#define ENABLE_TUNING_CONTROLS*/ 44 41 42 + #ifdef ENABLE_TUNING_CONTROLS 43 + #include <sound/tlv.h> 44 + #endif 45 + 45 46 #define FLOAT_ZERO 0x00000000 46 47 #define FLOAT_ONE 0x3f800000 47 48 #define FLOAT_TWO 0x40000000 49 + #define FLOAT_THREE 0x40400000 50 + #define FLOAT_EIGHT 0x41000000 48 51 #define FLOAT_MINUS_5 0xc0a00000 49 52 50 53 #define UNSOL_TAG_DSP 0x16 ··· 81 72 #define SCP_GET 1 82 73 83 74 #define EFX_FILE "ctefx.bin" 75 + #define SBZ_EFX_FILE "ctefx-sbz.bin" 76 + #define R3DI_EFX_FILE "ctefx-r3di.bin" 84 77 85 78 #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP 86 79 MODULE_FIRMWARE(EFX_FILE); 80 + MODULE_FIRMWARE(SBZ_EFX_FILE); 81 + MODULE_FIRMWARE(R3DI_EFX_FILE); 87 82 #endif 88 83 89 - static char *dirstr[2] = { "Playback", "Capture" }; 84 + static const char *const dirstr[2] = { "Playback", "Capture" }; 90 85 86 + #define NUM_OF_OUTPUTS 3 91 87 enum { 92 88 SPEAKER_OUT, 93 - HEADPHONE_OUT 89 + HEADPHONE_OUT, 90 + SURROUND_OUT 94 91 }; 95 92 96 93 enum { 97 94 DIGITAL_MIC, 98 95 LINE_MIC_IN 96 + }; 97 + 98 + /* Strings for Input Source Enum Control */ 99 + static const char *const in_src_str[3] = {"Rear Mic", "Line", "Front Mic" }; 100 + #define IN_SRC_NUM_OF_INPUTS 3 101 + enum { 102 + REAR_MIC, 103 + REAR_LINE_IN, 104 + FRONT_MIC, 99 105 }; 100 106 101 107 enum { ··· 146 122 VOICEFX = IN_EFFECT_END_NID, 147 123 PLAY_ENHANCEMENT, 148 124 CRYSTAL_VOICE, 149 - EFFECT_END_NID 125 + EFFECT_END_NID, 126 + OUTPUT_SOURCE_ENUM, 127 + INPUT_SOURCE_ENUM, 128 + XBASS_XOVER, 129 + EQ_PRESET_ENUM, 130 + SMART_VOLUME_ENUM, 131 + MIC_BOOST_ENUM 150 132 #define EFFECTS_COUNT (EFFECT_END_NID - EFFECT_START_NID) 151 133 }; 152 134 153 135 /* Effects values size*/ 154 136 #define EFFECT_VALS_MAX_COUNT 12 137 + 138 + /* 139 + * Default values for the effect slider controls, they are in order of their 140 + * effect NID's. Surround, Crystalizer, Dialog Plus, Smart Volume, and then 141 + * X-bass. 142 + */ 143 + static const unsigned int effect_slider_defaults[] = {67, 65, 50, 74, 50}; 144 + /* Amount of effect level sliders for ca0132_alt controls. */ 145 + #define EFFECT_LEVEL_SLIDERS 5 155 146 156 147 /* Latency introduced by DSP blocks in milliseconds. */ 157 148 #define DSP_CAPTURE_INIT_LATENCY 0 ··· 189 150 #define EFX_DIR_OUT 0 190 151 #define EFX_DIR_IN 1 191 152 192 - static struct ct_effect ca0132_effects[EFFECTS_COUNT] = { 153 + static const struct ct_effect ca0132_effects[EFFECTS_COUNT] = { 193 154 { .name = "Surround", 194 155 .nid = SURROUND, 195 156 .mid = 0x96, ··· 316 277 unsigned int def_val;/*effect default values*/ 317 278 }; 318 279 319 - static struct ct_tuning_ctl ca0132_tuning_ctls[] = { 280 + static const struct ct_tuning_ctl ca0132_tuning_ctls[] = { 320 281 { .name = "Wedge Angle", 321 282 .parent_nid = VOICE_FOCUS, 322 283 .nid = WEDGE_ANGLE, ··· 431 392 unsigned int vals[VOICEFX_MAX_PARAM_COUNT]; 432 393 }; 433 394 434 - static struct ct_voicefx ca0132_voicefx = { 395 + static const struct ct_voicefx ca0132_voicefx = { 435 396 .name = "VoiceFX Capture Switch", 436 397 .nid = VOICEFX, 437 398 .mid = 0x95, 438 399 .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18} 439 400 }; 440 401 441 - static struct ct_voicefx_preset ca0132_voicefx_presets[] = { 402 + static const struct ct_voicefx_preset ca0132_voicefx_presets[] = { 442 403 { .name = "Neutral", 443 404 .vals = { 0x00000000, 0x43C80000, 0x44AF0000, 444 405 0x44FA0000, 0x3F800000, 0x3F800000, ··· 508 469 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000, 509 470 0x44FA0000, 0x3F800000, 0x3F1A043C, 510 471 0x3F800000, 0x00000000, 0x00000000 } 472 + } 473 + }; 474 + 475 + /* ca0132 EQ presets, taken from Windows Sound Blaster Z Driver */ 476 + 477 + #define EQ_PRESET_MAX_PARAM_COUNT 11 478 + 479 + struct ct_eq { 480 + char *name; 481 + hda_nid_t nid; 482 + int mid; 483 + int reqs[EQ_PRESET_MAX_PARAM_COUNT]; /*effect module request*/ 484 + }; 485 + 486 + struct ct_eq_preset { 487 + char *name; /*preset name*/ 488 + unsigned int vals[EQ_PRESET_MAX_PARAM_COUNT]; 489 + }; 490 + 491 + static const struct ct_eq ca0132_alt_eq_enum = { 492 + .name = "FX: Equalizer Preset Switch", 493 + .nid = EQ_PRESET_ENUM, 494 + .mid = 0x96, 495 + .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} 496 + }; 497 + 498 + 499 + static const struct ct_eq_preset ca0132_alt_eq_presets[] = { 500 + { .name = "Flat", 501 + .vals = { 0x00000000, 0x00000000, 0x00000000, 502 + 0x00000000, 0x00000000, 0x00000000, 503 + 0x00000000, 0x00000000, 0x00000000, 504 + 0x00000000, 0x00000000 } 505 + }, 506 + { .name = "Acoustic", 507 + .vals = { 0x00000000, 0x00000000, 0x3F8CCCCD, 508 + 0x40000000, 0x00000000, 0x00000000, 509 + 0x00000000, 0x00000000, 0x40000000, 510 + 0x40000000, 0x40000000 } 511 + }, 512 + { .name = "Classical", 513 + .vals = { 0x00000000, 0x00000000, 0x40C00000, 514 + 0x40C00000, 0x40466666, 0x00000000, 515 + 0x00000000, 0x00000000, 0x00000000, 516 + 0x40466666, 0x40466666 } 517 + }, 518 + { .name = "Country", 519 + .vals = { 0x00000000, 0xBF99999A, 0x00000000, 520 + 0x3FA66666, 0x3FA66666, 0x3F8CCCCD, 521 + 0x00000000, 0x00000000, 0x40000000, 522 + 0x40466666, 0x40800000 } 523 + }, 524 + { .name = "Dance", 525 + .vals = { 0x00000000, 0xBF99999A, 0x40000000, 526 + 0x40466666, 0x40866666, 0xBF99999A, 527 + 0xBF99999A, 0x00000000, 0x00000000, 528 + 0x40800000, 0x40800000 } 529 + }, 530 + { .name = "Jazz", 531 + .vals = { 0x00000000, 0x00000000, 0x00000000, 532 + 0x3F8CCCCD, 0x40800000, 0x40800000, 533 + 0x40800000, 0x00000000, 0x3F8CCCCD, 534 + 0x40466666, 0x40466666 } 535 + }, 536 + { .name = "New Age", 537 + .vals = { 0x00000000, 0x00000000, 0x40000000, 538 + 0x40000000, 0x00000000, 0x00000000, 539 + 0x00000000, 0x3F8CCCCD, 0x40000000, 540 + 0x40000000, 0x40000000 } 541 + }, 542 + { .name = "Pop", 543 + .vals = { 0x00000000, 0xBFCCCCCD, 0x00000000, 544 + 0x40000000, 0x40000000, 0x00000000, 545 + 0xBF99999A, 0xBF99999A, 0x00000000, 546 + 0x40466666, 0x40C00000 } 547 + }, 548 + { .name = "Rock", 549 + .vals = { 0x00000000, 0xBF99999A, 0xBF99999A, 550 + 0x3F8CCCCD, 0x40000000, 0xBF99999A, 551 + 0xBF99999A, 0x00000000, 0x00000000, 552 + 0x40800000, 0x40800000 } 553 + }, 554 + { .name = "Vocal", 555 + .vals = { 0x00000000, 0xC0000000, 0xBF99999A, 556 + 0xBF99999A, 0x00000000, 0x40466666, 557 + 0x40800000, 0x40466666, 0x00000000, 558 + 0x00000000, 0x3F8CCCCD } 559 + } 560 + }; 561 + 562 + /* DSP command sequences for ca0132_alt_select_out */ 563 + #define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */ 564 + struct ca0132_alt_out_set { 565 + char *name; /*preset name*/ 566 + unsigned char commands; 567 + unsigned int mids[ALT_OUT_SET_MAX_COMMANDS]; 568 + unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS]; 569 + unsigned int vals[ALT_OUT_SET_MAX_COMMANDS]; 570 + }; 571 + 572 + static const struct ca0132_alt_out_set alt_out_presets[] = { 573 + { .name = "Line Out", 574 + .commands = 7, 575 + .mids = { 0x96, 0x96, 0x96, 0x8F, 576 + 0x96, 0x96, 0x96 }, 577 + .reqs = { 0x19, 0x17, 0x18, 0x01, 578 + 0x1F, 0x15, 0x3A }, 579 + .vals = { 0x3F000000, 0x42A00000, 0x00000000, 580 + 0x00000000, 0x00000000, 0x00000000, 581 + 0x00000000 } 582 + }, 583 + { .name = "Headphone", 584 + .commands = 7, 585 + .mids = { 0x96, 0x96, 0x96, 0x8F, 586 + 0x96, 0x96, 0x96 }, 587 + .reqs = { 0x19, 0x17, 0x18, 0x01, 588 + 0x1F, 0x15, 0x3A }, 589 + .vals = { 0x3F000000, 0x42A00000, 0x00000000, 590 + 0x00000000, 0x00000000, 0x00000000, 591 + 0x00000000 } 592 + }, 593 + { .name = "Surround", 594 + .commands = 8, 595 + .mids = { 0x96, 0x8F, 0x96, 0x96, 596 + 0x96, 0x96, 0x96, 0x96 }, 597 + .reqs = { 0x18, 0x01, 0x1F, 0x15, 598 + 0x3A, 0x1A, 0x1B, 0x1C }, 599 + .vals = { 0x00000000, 0x00000000, 0x00000000, 600 + 0x00000000, 0x00000000, 0x00000000, 601 + 0x00000000, 0x00000000 } 602 + } 603 + }; 604 + 605 + /* 606 + * DSP volume setting structs. Req 1 is left volume, req 2 is right volume, 607 + * and I don't know what the third req is, but it's always zero. I assume it's 608 + * some sort of update or set command to tell the DSP there's new volume info. 609 + */ 610 + #define DSP_VOL_OUT 0 611 + #define DSP_VOL_IN 1 612 + 613 + struct ct_dsp_volume_ctl { 614 + hda_nid_t vnid; 615 + int mid; /* module ID*/ 616 + unsigned int reqs[3]; /* scp req ID */ 617 + }; 618 + 619 + static const struct ct_dsp_volume_ctl ca0132_alt_vol_ctls[] = { 620 + { .vnid = VNID_SPK, 621 + .mid = 0x32, 622 + .reqs = {3, 4, 2} 623 + }, 624 + { .vnid = VNID_MIC, 625 + .mid = 0x37, 626 + .reqs = {2, 3, 1} 511 627 } 512 628 }; 513 629 ··· 892 698 */ 893 699 894 700 struct ca0132_spec { 895 - struct snd_kcontrol_new *mixers[5]; 701 + const struct snd_kcontrol_new *mixers[5]; 896 702 unsigned int num_mixers; 897 703 const struct hda_verb *base_init_verbs; 898 704 const struct hda_verb *base_exit_verbs; 899 705 const struct hda_verb *chip_init_verbs; 706 + const struct hda_verb *sbz_init_verbs; 900 707 struct hda_verb *spec_init_verbs; 901 708 struct auto_pin_cfg autocfg; 902 709 ··· 914 719 hda_nid_t shared_mic_nid; 915 720 hda_nid_t shared_out_nid; 916 721 hda_nid_t unsol_tag_hp; 722 + hda_nid_t unsol_tag_front_hp; /* for desktop ca0132 codecs */ 917 723 hda_nid_t unsol_tag_amic1; 918 724 919 725 /* chip access */ ··· 930 734 unsigned int scp_resp_header; 931 735 unsigned int scp_resp_data[4]; 932 736 unsigned int scp_resp_count; 737 + bool alt_firmware_present; 738 + bool startup_check_entered; 739 + bool dsp_reload; 933 740 934 741 /* mixer and effects related */ 935 742 unsigned char dmic_ctl; ··· 945 746 long effects_switch[EFFECTS_COUNT]; 946 747 long voicefx_val; 947 748 long cur_mic_boost; 749 + /* ca0132_alt control related values */ 750 + unsigned char in_enum_val; 751 + unsigned char out_enum_val; 752 + unsigned char mic_boost_enum_val; 753 + unsigned char smart_volume_setting; 754 + long fx_ctl_val[EFFECT_LEVEL_SLIDERS]; 755 + long xbass_xover_freq; 756 + long eq_preset_val; 757 + unsigned int tlv[4]; 758 + struct hda_vmaster_mute_hook vmaster_mute; 759 + 948 760 949 761 struct hda_codec *codec; 950 762 struct delayed_work unsol_hp_work; ··· 964 754 #ifdef ENABLE_TUNING_CONTROLS 965 755 long cur_ctl_vals[TUNING_CTLS_COUNT]; 966 756 #endif 757 + /* 758 + * Sound Blaster Z PCI region 2 iomem, used for input and output 759 + * switching, and other unknown commands. 760 + */ 761 + void __iomem *mem_base; 762 + 763 + /* 764 + * Whether or not to use the alt functions like alt_select_out, 765 + * alt_select_in, etc. Only used on desktop codecs for now, because of 766 + * surround sound support. 767 + */ 768 + bool use_alt_functions; 769 + 770 + /* 771 + * Whether or not to use alt controls: volume effect sliders, EQ 772 + * presets, smart volume presets, and new control names with FX prefix. 773 + * Renames PlayEnhancement and CrystalVoice too. 774 + */ 775 + bool use_alt_controls; 967 776 }; 968 777 969 778 /* ··· 991 762 enum { 992 763 QUIRK_NONE, 993 764 QUIRK_ALIENWARE, 765 + QUIRK_SBZ, 766 + QUIRK_R3DI, 994 767 }; 995 768 996 769 static const struct hda_pintbl alienware_pincfgs[] = { ··· 1009 778 {} 1010 779 }; 1011 780 781 + /* Sound Blaster Z pin configs taken from Windows Driver */ 782 + static const struct hda_pintbl sbz_pincfgs[] = { 783 + { 0x0b, 0x01017010 }, /* Port G -- Lineout FRONT L/R */ 784 + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ 785 + { 0x0d, 0x014510f0 }, /* Digital Out */ 786 + { 0x0e, 0x01c510f0 }, /* SPDIF In */ 787 + { 0x0f, 0x0221701f }, /* Port A -- BackPanel HP */ 788 + { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */ 789 + { 0x11, 0x01017014 }, /* Port B -- LineMicIn2 / Rear L/R */ 790 + { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */ 791 + { 0x13, 0x908700f0 }, /* What U Hear In*/ 792 + { 0x18, 0x50d000f0 }, /* N/A */ 793 + {} 794 + }; 795 + 796 + /* Recon3D integrated pin configs taken from Windows Driver */ 797 + static const struct hda_pintbl r3di_pincfgs[] = { 798 + { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */ 799 + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ 800 + { 0x0d, 0x014510f0 }, /* Digital Out */ 801 + { 0x0e, 0x41c520f0 }, /* SPDIF In */ 802 + { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */ 803 + { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */ 804 + { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */ 805 + { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */ 806 + { 0x13, 0x908700f0 }, /* What U Hear In*/ 807 + { 0x18, 0x500000f0 }, /* N/A */ 808 + {} 809 + }; 810 + 1012 811 static const struct snd_pci_quirk ca0132_quirks[] = { 1013 812 SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE), 1014 813 SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE), 1015 814 SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE), 815 + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ), 816 + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ), 817 + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), 818 + SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI), 1016 819 {} 1017 820 }; 1018 821 ··· 1230 965 } 1231 966 1232 967 /* 968 + * Write given value to the given address through the chip I/O widget. 969 + * not protected by the Mutex 970 + */ 971 + static int chipio_write_no_mutex(struct hda_codec *codec, 972 + unsigned int chip_addx, const unsigned int data) 973 + { 974 + int err; 975 + 976 + 977 + /* write the address, and if successful proceed to write data */ 978 + err = chipio_write_address(codec, chip_addx); 979 + if (err < 0) 980 + goto exit; 981 + 982 + err = chipio_write_data(codec, data); 983 + if (err < 0) 984 + goto exit; 985 + 986 + exit: 987 + return err; 988 + } 989 + 990 + /* 1233 991 * Write multiple values to the given address through the chip I/O widget. 1234 992 * protected by the Mutex 1235 993 */ ··· 1343 1055 } 1344 1056 mutex_unlock(&spec->chipio_mutex); 1345 1057 } 1058 + } 1059 + 1060 + /* 1061 + * Set chip parameters through the chip I/O widget. NO MUTEX. 1062 + */ 1063 + static void chipio_set_control_param_no_mutex(struct hda_codec *codec, 1064 + enum control_param_id param_id, int param_val) 1065 + { 1066 + int val; 1067 + 1068 + if ((param_id < 32) && (param_val < 8)) { 1069 + val = (param_val << 5) | (param_id); 1070 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 1071 + VENDOR_CHIPIO_PARAM_SET, val); 1072 + } else { 1073 + if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) { 1074 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 1075 + VENDOR_CHIPIO_PARAM_EX_ID_SET, 1076 + param_id); 1077 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 1078 + VENDOR_CHIPIO_PARAM_EX_VALUE_SET, 1079 + param_val); 1080 + } 1081 + } 1082 + } 1083 + /* 1084 + * Connect stream to a source point, and then connect 1085 + * that source point to a destination point. 1086 + */ 1087 + static void chipio_set_stream_source_dest(struct hda_codec *codec, 1088 + int streamid, int source_point, int dest_point) 1089 + { 1090 + chipio_set_control_param_no_mutex(codec, 1091 + CONTROL_PARAM_STREAM_ID, streamid); 1092 + chipio_set_control_param_no_mutex(codec, 1093 + CONTROL_PARAM_STREAM_SOURCE_CONN_POINT, source_point); 1094 + chipio_set_control_param_no_mutex(codec, 1095 + CONTROL_PARAM_STREAM_DEST_CONN_POINT, dest_point); 1096 + } 1097 + 1098 + /* 1099 + * Set number of channels in the selected stream. 1100 + */ 1101 + static void chipio_set_stream_channels(struct hda_codec *codec, 1102 + int streamid, unsigned int channels) 1103 + { 1104 + chipio_set_control_param_no_mutex(codec, 1105 + CONTROL_PARAM_STREAM_ID, streamid); 1106 + chipio_set_control_param_no_mutex(codec, 1107 + CONTROL_PARAM_STREAMS_CHANNELS, channels); 1108 + } 1109 + 1110 + /* 1111 + * Enable/Disable audio stream. 1112 + */ 1113 + static void chipio_set_stream_control(struct hda_codec *codec, 1114 + int streamid, int enable) 1115 + { 1116 + chipio_set_control_param_no_mutex(codec, 1117 + CONTROL_PARAM_STREAM_ID, streamid); 1118 + chipio_set_control_param_no_mutex(codec, 1119 + CONTROL_PARAM_STREAM_CONTROL, enable); 1120 + } 1121 + 1122 + 1123 + /* 1124 + * Set sampling rate of the connection point. NO MUTEX. 1125 + */ 1126 + static void chipio_set_conn_rate_no_mutex(struct hda_codec *codec, 1127 + int connid, enum ca0132_sample_rate rate) 1128 + { 1129 + chipio_set_control_param_no_mutex(codec, 1130 + CONTROL_PARAM_CONN_POINT_ID, connid); 1131 + chipio_set_control_param_no_mutex(codec, 1132 + CONTROL_PARAM_CONN_POINT_SAMPLE_RATE, rate); 1346 1133 } 1347 1134 1348 1135 /* ··· 1783 1420 * Returns zero or a negative error code. 1784 1421 */ 1785 1422 static int dspio_scp(struct hda_codec *codec, 1786 - int mod_id, int req, int dir, void *data, unsigned int len, 1787 - void *reply, unsigned int *reply_len) 1423 + int mod_id, int src_id, int req, int dir, const void *data, 1424 + unsigned int len, void *reply, unsigned int *reply_len) 1788 1425 { 1789 1426 int status = 0; 1790 1427 struct scp_msg scp_send, scp_reply; ··· 1808 1445 return -EINVAL; 1809 1446 } 1810 1447 1811 - scp_send.hdr = make_scp_header(mod_id, 0x20, (dir == SCP_GET), req, 1448 + scp_send.hdr = make_scp_header(mod_id, src_id, (dir == SCP_GET), req, 1812 1449 0, 0, 0, len/sizeof(unsigned int)); 1813 1450 if (data != NULL && len > 0) { 1814 1451 len = min((unsigned int)(sizeof(scp_send.data)), len); ··· 1865 1502 * Set DSP parameters 1866 1503 */ 1867 1504 static int dspio_set_param(struct hda_codec *codec, int mod_id, 1868 - int req, void *data, unsigned int len) 1505 + int src_id, int req, const void *data, unsigned int len) 1869 1506 { 1870 - return dspio_scp(codec, mod_id, req, SCP_SET, data, len, NULL, NULL); 1507 + return dspio_scp(codec, mod_id, src_id, req, SCP_SET, data, len, NULL, 1508 + NULL); 1871 1509 } 1872 1510 1873 1511 static int dspio_set_uint_param(struct hda_codec *codec, int mod_id, 1874 - int req, unsigned int data) 1512 + int req, const unsigned int data) 1875 1513 { 1876 - return dspio_set_param(codec, mod_id, req, &data, sizeof(unsigned int)); 1514 + return dspio_set_param(codec, mod_id, 0x20, req, &data, 1515 + sizeof(unsigned int)); 1516 + } 1517 + 1518 + static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id, 1519 + int req, const unsigned int data) 1520 + { 1521 + return dspio_set_param(codec, mod_id, 0x00, req, &data, 1522 + sizeof(unsigned int)); 1877 1523 } 1878 1524 1879 1525 /* ··· 1894 1522 unsigned int size = sizeof(dma_chan); 1895 1523 1896 1524 codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n"); 1897 - status = dspio_scp(codec, MASTERCONTROL, MASTERCONTROL_ALLOC_DMA_CHAN, 1898 - SCP_GET, NULL, 0, dma_chan, &size); 1525 + status = dspio_scp(codec, MASTERCONTROL, 0x20, 1526 + MASTERCONTROL_ALLOC_DMA_CHAN, SCP_GET, NULL, 0, 1527 + dma_chan, &size); 1899 1528 1900 1529 if (status < 0) { 1901 1530 codec_dbg(codec, "dspio_alloc_dma_chan: SCP Failed\n"); ··· 1925 1552 codec_dbg(codec, " dspio_free_dma_chan() -- begin\n"); 1926 1553 codec_dbg(codec, "dspio_free_dma_chan: chan=%d\n", dma_chan); 1927 1554 1928 - status = dspio_scp(codec, MASTERCONTROL, MASTERCONTROL_ALLOC_DMA_CHAN, 1929 - SCP_SET, &dma_chan, sizeof(dma_chan), NULL, &dummy); 1555 + status = dspio_scp(codec, MASTERCONTROL, 0x20, 1556 + MASTERCONTROL_ALLOC_DMA_CHAN, SCP_SET, &dma_chan, 1557 + sizeof(dma_chan), NULL, &dummy); 1930 1558 1931 1559 if (status < 0) { 1932 1560 codec_dbg(codec, "dspio_free_dma_chan: SCP Failed\n"); ··· 2949 2575 */ 2950 2576 static void dspload_post_setup(struct hda_codec *codec) 2951 2577 { 2578 + struct ca0132_spec *spec = codec->spec; 2952 2579 codec_dbg(codec, "---- dspload_post_setup ------\n"); 2580 + if (!spec->use_alt_functions) { 2581 + /*set DSP speaker to 2.0 configuration*/ 2582 + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080); 2583 + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000); 2953 2584 2954 - /*set DSP speaker to 2.0 configuration*/ 2955 - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080); 2956 - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000); 2957 - 2958 - /*update write pointer*/ 2959 - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002); 2585 + /*update write pointer*/ 2586 + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002); 2587 + } 2960 2588 } 2961 2589 2962 2590 /** ··· 3063 2687 3064 2688 codec_err(codec, "ca0132 failed to download DSP\n"); 3065 2689 return false; 2690 + } 2691 + 2692 + /* 2693 + * Setup GPIO for the other variants of Core3D. 2694 + */ 2695 + 2696 + /* 2697 + * Sets up the GPIO pins so that they are discoverable. If this isn't done, 2698 + * the card shows as having no GPIO pins. 2699 + */ 2700 + static void ca0132_gpio_init(struct hda_codec *codec) 2701 + { 2702 + struct ca0132_spec *spec = codec->spec; 2703 + 2704 + switch (spec->quirk) { 2705 + case QUIRK_SBZ: 2706 + snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00); 2707 + snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53); 2708 + snd_hda_codec_write(codec, 0x01, 0, 0x790, 0x23); 2709 + break; 2710 + case QUIRK_R3DI: 2711 + snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00); 2712 + snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5B); 2713 + break; 2714 + } 2715 + 2716 + } 2717 + 2718 + /* Sets the GPIO for audio output. */ 2719 + static void ca0132_gpio_setup(struct hda_codec *codec) 2720 + { 2721 + struct ca0132_spec *spec = codec->spec; 2722 + 2723 + switch (spec->quirk) { 2724 + case QUIRK_SBZ: 2725 + snd_hda_codec_write(codec, 0x01, 0, 2726 + AC_VERB_SET_GPIO_DIRECTION, 0x07); 2727 + snd_hda_codec_write(codec, 0x01, 0, 2728 + AC_VERB_SET_GPIO_MASK, 0x07); 2729 + snd_hda_codec_write(codec, 0x01, 0, 2730 + AC_VERB_SET_GPIO_DATA, 0x04); 2731 + snd_hda_codec_write(codec, 0x01, 0, 2732 + AC_VERB_SET_GPIO_DATA, 0x06); 2733 + break; 2734 + case QUIRK_R3DI: 2735 + snd_hda_codec_write(codec, 0x01, 0, 2736 + AC_VERB_SET_GPIO_DIRECTION, 0x1E); 2737 + snd_hda_codec_write(codec, 0x01, 0, 2738 + AC_VERB_SET_GPIO_MASK, 0x1F); 2739 + snd_hda_codec_write(codec, 0x01, 0, 2740 + AC_VERB_SET_GPIO_DATA, 0x0C); 2741 + break; 2742 + } 2743 + } 2744 + 2745 + /* 2746 + * GPIO control functions for the Recon3D integrated. 2747 + */ 2748 + 2749 + enum r3di_gpio_bit { 2750 + /* Bit 1 - Switch between front/rear mic. 0 = rear, 1 = front */ 2751 + R3DI_MIC_SELECT_BIT = 1, 2752 + /* Bit 2 - Switch between headphone/line out. 0 = Headphone, 1 = Line */ 2753 + R3DI_OUT_SELECT_BIT = 2, 2754 + /* 2755 + * I dunno what this actually does, but it stays on until the dsp 2756 + * is downloaded. 2757 + */ 2758 + R3DI_GPIO_DSP_DOWNLOADING = 3, 2759 + /* 2760 + * Same as above, no clue what it does, but it comes on after the dsp 2761 + * is downloaded. 2762 + */ 2763 + R3DI_GPIO_DSP_DOWNLOADED = 4 2764 + }; 2765 + 2766 + enum r3di_mic_select { 2767 + /* Set GPIO bit 1 to 0 for rear mic */ 2768 + R3DI_REAR_MIC = 0, 2769 + /* Set GPIO bit 1 to 1 for front microphone*/ 2770 + R3DI_FRONT_MIC = 1 2771 + }; 2772 + 2773 + enum r3di_out_select { 2774 + /* Set GPIO bit 2 to 0 for headphone */ 2775 + R3DI_HEADPHONE_OUT = 0, 2776 + /* Set GPIO bit 2 to 1 for speaker */ 2777 + R3DI_LINE_OUT = 1 2778 + }; 2779 + enum r3di_dsp_status { 2780 + /* Set GPIO bit 3 to 1 until DSP is downloaded */ 2781 + R3DI_DSP_DOWNLOADING = 0, 2782 + /* Set GPIO bit 4 to 1 once DSP is downloaded */ 2783 + R3DI_DSP_DOWNLOADED = 1 2784 + }; 2785 + 2786 + 2787 + static void r3di_gpio_mic_set(struct hda_codec *codec, 2788 + enum r3di_mic_select cur_mic) 2789 + { 2790 + unsigned int cur_gpio; 2791 + 2792 + /* Get the current GPIO Data setup */ 2793 + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); 2794 + 2795 + switch (cur_mic) { 2796 + case R3DI_REAR_MIC: 2797 + cur_gpio &= ~(1 << R3DI_MIC_SELECT_BIT); 2798 + break; 2799 + case R3DI_FRONT_MIC: 2800 + cur_gpio |= (1 << R3DI_MIC_SELECT_BIT); 2801 + break; 2802 + } 2803 + snd_hda_codec_write(codec, codec->core.afg, 0, 2804 + AC_VERB_SET_GPIO_DATA, cur_gpio); 2805 + } 2806 + 2807 + static void r3di_gpio_out_set(struct hda_codec *codec, 2808 + enum r3di_out_select cur_out) 2809 + { 2810 + unsigned int cur_gpio; 2811 + 2812 + /* Get the current GPIO Data setup */ 2813 + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); 2814 + 2815 + switch (cur_out) { 2816 + case R3DI_HEADPHONE_OUT: 2817 + cur_gpio &= ~(1 << R3DI_OUT_SELECT_BIT); 2818 + break; 2819 + case R3DI_LINE_OUT: 2820 + cur_gpio |= (1 << R3DI_OUT_SELECT_BIT); 2821 + break; 2822 + } 2823 + snd_hda_codec_write(codec, codec->core.afg, 0, 2824 + AC_VERB_SET_GPIO_DATA, cur_gpio); 2825 + } 2826 + 2827 + static void r3di_gpio_dsp_status_set(struct hda_codec *codec, 2828 + enum r3di_dsp_status dsp_status) 2829 + { 2830 + unsigned int cur_gpio; 2831 + 2832 + /* Get the current GPIO Data setup */ 2833 + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0); 2834 + 2835 + switch (dsp_status) { 2836 + case R3DI_DSP_DOWNLOADING: 2837 + cur_gpio |= (1 << R3DI_GPIO_DSP_DOWNLOADING); 2838 + snd_hda_codec_write(codec, codec->core.afg, 0, 2839 + AC_VERB_SET_GPIO_DATA, cur_gpio); 2840 + break; 2841 + case R3DI_DSP_DOWNLOADED: 2842 + /* Set DOWNLOADING bit to 0. */ 2843 + cur_gpio &= ~(1 << R3DI_GPIO_DSP_DOWNLOADING); 2844 + 2845 + snd_hda_codec_write(codec, codec->core.afg, 0, 2846 + AC_VERB_SET_GPIO_DATA, cur_gpio); 2847 + 2848 + cur_gpio |= (1 << R3DI_GPIO_DSP_DOWNLOADED); 2849 + break; 2850 + } 2851 + 2852 + snd_hda_codec_write(codec, codec->core.afg, 0, 2853 + AC_VERB_SET_GPIO_DATA, cur_gpio); 3066 2854 } 3067 2855 3068 2856 /* ··· 3392 2852 .tlv = { .c = ca0132_volume_tlv }, \ 3393 2853 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) } 3394 2854 2855 + /* 2856 + * Creates a mixer control that uses defaults of HDA_CODEC_VOL except for the 2857 + * volume put, which is used for setting the DSP volume. This was done because 2858 + * the ca0132 functions were taking too much time and causing lag. 2859 + */ 2860 + #define CA0132_ALT_CODEC_VOL_MONO(xname, nid, channel, dir) \ 2861 + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2862 + .name = xname, \ 2863 + .subdevice = HDA_SUBDEV_AMP_FLAG, \ 2864 + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2865 + SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2866 + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ 2867 + .info = snd_hda_mixer_amp_volume_info, \ 2868 + .get = snd_hda_mixer_amp_volume_get, \ 2869 + .put = ca0132_alt_volume_put, \ 2870 + .tlv = { .c = snd_hda_mixer_amp_tlv }, \ 2871 + .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) } 2872 + 3395 2873 #define CA0132_CODEC_MUTE_MONO(xname, nid, channel, dir) \ 3396 2874 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3397 2875 .name = xname, \ ··· 3422 2864 /* stereo */ 3423 2865 #define CA0132_CODEC_VOL(xname, nid, dir) \ 3424 2866 CA0132_CODEC_VOL_MONO(xname, nid, 3, dir) 2867 + #define CA0132_ALT_CODEC_VOL(xname, nid, dir) \ 2868 + CA0132_ALT_CODEC_VOL_MONO(xname, nid, 3, dir) 3425 2869 #define CA0132_CODEC_MUTE(xname, nid, dir) \ 3426 2870 CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir) 2871 + 2872 + /* lookup tables */ 2873 + /* 2874 + * Lookup table with decibel values for the DSP. When volume is changed in 2875 + * Windows, the DSP is also sent the dB value in floating point. In Windows, 2876 + * these values have decimal points, probably because the Windows driver 2877 + * actually uses floating point. We can't here, so I made a lookup table of 2878 + * values -90 to 9. -90 is the lowest decibel value for both the ADC's and the 2879 + * DAC's, and 9 is the maximum. 2880 + */ 2881 + static const unsigned int float_vol_db_lookup[] = { 2882 + 0xC2B40000, 0xC2B20000, 0xC2B00000, 0xC2AE0000, 0xC2AC0000, 0xC2AA0000, 2883 + 0xC2A80000, 0xC2A60000, 0xC2A40000, 0xC2A20000, 0xC2A00000, 0xC29E0000, 2884 + 0xC29C0000, 0xC29A0000, 0xC2980000, 0xC2960000, 0xC2940000, 0xC2920000, 2885 + 0xC2900000, 0xC28E0000, 0xC28C0000, 0xC28A0000, 0xC2880000, 0xC2860000, 2886 + 0xC2840000, 0xC2820000, 0xC2800000, 0xC27C0000, 0xC2780000, 0xC2740000, 2887 + 0xC2700000, 0xC26C0000, 0xC2680000, 0xC2640000, 0xC2600000, 0xC25C0000, 2888 + 0xC2580000, 0xC2540000, 0xC2500000, 0xC24C0000, 0xC2480000, 0xC2440000, 2889 + 0xC2400000, 0xC23C0000, 0xC2380000, 0xC2340000, 0xC2300000, 0xC22C0000, 2890 + 0xC2280000, 0xC2240000, 0xC2200000, 0xC21C0000, 0xC2180000, 0xC2140000, 2891 + 0xC2100000, 0xC20C0000, 0xC2080000, 0xC2040000, 0xC2000000, 0xC1F80000, 2892 + 0xC1F00000, 0xC1E80000, 0xC1E00000, 0xC1D80000, 0xC1D00000, 0xC1C80000, 2893 + 0xC1C00000, 0xC1B80000, 0xC1B00000, 0xC1A80000, 0xC1A00000, 0xC1980000, 2894 + 0xC1900000, 0xC1880000, 0xC1800000, 0xC1700000, 0xC1600000, 0xC1500000, 2895 + 0xC1400000, 0xC1300000, 0xC1200000, 0xC1100000, 0xC1000000, 0xC0E00000, 2896 + 0xC0C00000, 0xC0A00000, 0xC0800000, 0xC0400000, 0xC0000000, 0xBF800000, 2897 + 0x00000000, 0x3F800000, 0x40000000, 0x40400000, 0x40800000, 0x40A00000, 2898 + 0x40C00000, 0x40E00000, 0x41000000, 0x41100000 2899 + }; 2900 + 2901 + /* 2902 + * This table counts from float 0 to 1 in increments of .01, which is 2903 + * useful for a few different sliders. 2904 + */ 2905 + static const unsigned int float_zero_to_one_lookup[] = { 2906 + 0x00000000, 0x3C23D70A, 0x3CA3D70A, 0x3CF5C28F, 0x3D23D70A, 0x3D4CCCCD, 2907 + 0x3D75C28F, 0x3D8F5C29, 0x3DA3D70A, 0x3DB851EC, 0x3DCCCCCD, 0x3DE147AE, 2908 + 0x3DF5C28F, 0x3E051EB8, 0x3E0F5C29, 0x3E19999A, 0x3E23D70A, 0x3E2E147B, 2909 + 0x3E3851EC, 0x3E428F5C, 0x3E4CCCCD, 0x3E570A3D, 0x3E6147AE, 0x3E6B851F, 2910 + 0x3E75C28F, 0x3E800000, 0x3E851EB8, 0x3E8A3D71, 0x3E8F5C29, 0x3E947AE1, 2911 + 0x3E99999A, 0x3E9EB852, 0x3EA3D70A, 0x3EA8F5C3, 0x3EAE147B, 0x3EB33333, 2912 + 0x3EB851EC, 0x3EBD70A4, 0x3EC28F5C, 0x3EC7AE14, 0x3ECCCCCD, 0x3ED1EB85, 2913 + 0x3ED70A3D, 0x3EDC28F6, 0x3EE147AE, 0x3EE66666, 0x3EEB851F, 0x3EF0A3D7, 2914 + 0x3EF5C28F, 0x3EFAE148, 0x3F000000, 0x3F028F5C, 0x3F051EB8, 0x3F07AE14, 2915 + 0x3F0A3D71, 0x3F0CCCCD, 0x3F0F5C29, 0x3F11EB85, 0x3F147AE1, 0x3F170A3D, 2916 + 0x3F19999A, 0x3F1C28F6, 0x3F1EB852, 0x3F2147AE, 0x3F23D70A, 0x3F266666, 2917 + 0x3F28F5C3, 0x3F2B851F, 0x3F2E147B, 0x3F30A3D7, 0x3F333333, 0x3F35C28F, 2918 + 0x3F3851EC, 0x3F3AE148, 0x3F3D70A4, 0x3F400000, 0x3F428F5C, 0x3F451EB8, 2919 + 0x3F47AE14, 0x3F4A3D71, 0x3F4CCCCD, 0x3F4F5C29, 0x3F51EB85, 0x3F547AE1, 2920 + 0x3F570A3D, 0x3F59999A, 0x3F5C28F6, 0x3F5EB852, 0x3F6147AE, 0x3F63D70A, 2921 + 0x3F666666, 0x3F68F5C3, 0x3F6B851F, 0x3F6E147B, 0x3F70A3D7, 0x3F733333, 2922 + 0x3F75C28F, 0x3F7851EC, 0x3F7AE148, 0x3F7D70A4, 0x3F800000 2923 + }; 2924 + 2925 + /* 2926 + * This table counts from float 10 to 1000, which is the range of the x-bass 2927 + * crossover slider in Windows. 2928 + */ 2929 + static const unsigned int float_xbass_xover_lookup[] = { 2930 + 0x41200000, 0x41A00000, 0x41F00000, 0x42200000, 0x42480000, 0x42700000, 2931 + 0x428C0000, 0x42A00000, 0x42B40000, 0x42C80000, 0x42DC0000, 0x42F00000, 2932 + 0x43020000, 0x430C0000, 0x43160000, 0x43200000, 0x432A0000, 0x43340000, 2933 + 0x433E0000, 0x43480000, 0x43520000, 0x435C0000, 0x43660000, 0x43700000, 2934 + 0x437A0000, 0x43820000, 0x43870000, 0x438C0000, 0x43910000, 0x43960000, 2935 + 0x439B0000, 0x43A00000, 0x43A50000, 0x43AA0000, 0x43AF0000, 0x43B40000, 2936 + 0x43B90000, 0x43BE0000, 0x43C30000, 0x43C80000, 0x43CD0000, 0x43D20000, 2937 + 0x43D70000, 0x43DC0000, 0x43E10000, 0x43E60000, 0x43EB0000, 0x43F00000, 2938 + 0x43F50000, 0x43FA0000, 0x43FF0000, 0x44020000, 0x44048000, 0x44070000, 2939 + 0x44098000, 0x440C0000, 0x440E8000, 0x44110000, 0x44138000, 0x44160000, 2940 + 0x44188000, 0x441B0000, 0x441D8000, 0x44200000, 0x44228000, 0x44250000, 2941 + 0x44278000, 0x442A0000, 0x442C8000, 0x442F0000, 0x44318000, 0x44340000, 2942 + 0x44368000, 0x44390000, 0x443B8000, 0x443E0000, 0x44408000, 0x44430000, 2943 + 0x44458000, 0x44480000, 0x444A8000, 0x444D0000, 0x444F8000, 0x44520000, 2944 + 0x44548000, 0x44570000, 0x44598000, 0x445C0000, 0x445E8000, 0x44610000, 2945 + 0x44638000, 0x44660000, 0x44688000, 0x446B0000, 0x446D8000, 0x44700000, 2946 + 0x44728000, 0x44750000, 0x44778000, 0x447A0000 2947 + }; 3427 2948 3428 2949 /* The following are for tuning of products */ 3429 2950 #ifdef ENABLE_TUNING_CONTROLS ··· 3579 2942 break; 3580 2943 3581 2944 snd_hda_power_up(codec); 3582 - dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 2945 + dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20, 3583 2946 ca0132_tuning_ctls[i].req, 3584 2947 &(lookup[idx]), sizeof(unsigned int)); 3585 2948 snd_hda_power_down(codec); ··· 3705 3068 return 1; 3706 3069 } 3707 3070 3708 - static const DECLARE_TLV_DB_SCALE(voice_focus_db_scale, 2000, 100, 0); 3709 - static const DECLARE_TLV_DB_SCALE(eq_db_scale, -2400, 100, 0); 3071 + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(voice_focus_db_scale, 2000, 100, 0); 3072 + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(eq_db_scale, -2400, 100, 0); 3710 3073 3711 3074 static int add_tuning_control(struct hda_codec *codec, 3712 3075 hda_nid_t pnid, hda_nid_t nid, ··· 3844 3207 pin_ctl & ~PIN_HP); 3845 3208 /* enable speaker node */ 3846 3209 pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, 3847 - AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3210 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3848 3211 snd_hda_set_pin_ctl(codec, spec->out_pins[0], 3849 3212 pin_ctl | PIN_OUT); 3850 3213 } else { ··· 3888 3251 return err < 0 ? err : 0; 3889 3252 } 3890 3253 3254 + /* 3255 + * This function behaves similarly to the ca0132_select_out funciton above, 3256 + * except with a few differences. It adds the ability to select the current 3257 + * output with an enumerated control "output source" if the auto detect 3258 + * mute switch is set to off. If the auto detect mute switch is enabled, it 3259 + * will detect either headphone or lineout(SPEAKER_OUT) from jack detection. 3260 + * It also adds the ability to auto-detect the front headphone port. The only 3261 + * way to select surround is to disable auto detect, and set Surround with the 3262 + * enumerated control. 3263 + */ 3264 + static int ca0132_alt_select_out(struct hda_codec *codec) 3265 + { 3266 + struct ca0132_spec *spec = codec->spec; 3267 + unsigned int pin_ctl; 3268 + int jack_present; 3269 + int auto_jack; 3270 + unsigned int i; 3271 + unsigned int tmp; 3272 + int err; 3273 + /* Default Headphone is rear headphone */ 3274 + hda_nid_t headphone_nid = spec->out_pins[1]; 3275 + 3276 + codec_dbg(codec, "%s\n", __func__); 3277 + 3278 + snd_hda_power_up_pm(codec); 3279 + 3280 + auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID]; 3281 + 3282 + /* 3283 + * If headphone rear or front is plugged in, set to headphone. 3284 + * If neither is plugged in, set to rear line out. Only if 3285 + * hp/speaker auto detect is enabled. 3286 + */ 3287 + if (auto_jack) { 3288 + jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_hp) || 3289 + snd_hda_jack_detect(codec, spec->unsol_tag_front_hp); 3290 + 3291 + if (jack_present) 3292 + spec->cur_out_type = HEADPHONE_OUT; 3293 + else 3294 + spec->cur_out_type = SPEAKER_OUT; 3295 + } else 3296 + spec->cur_out_type = spec->out_enum_val; 3297 + 3298 + /* Begin DSP output switch */ 3299 + tmp = FLOAT_ONE; 3300 + err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp); 3301 + if (err < 0) 3302 + goto exit; 3303 + 3304 + switch (spec->cur_out_type) { 3305 + case SPEAKER_OUT: 3306 + codec_dbg(codec, "%s speaker\n", __func__); 3307 + /*speaker out config*/ 3308 + switch (spec->quirk) { 3309 + case QUIRK_SBZ: 3310 + writew(0x0007, spec->mem_base + 0x320); 3311 + writew(0x0104, spec->mem_base + 0x320); 3312 + writew(0x0101, spec->mem_base + 0x320); 3313 + chipio_set_control_param(codec, 0x0D, 0x18); 3314 + break; 3315 + case QUIRK_R3DI: 3316 + chipio_set_control_param(codec, 0x0D, 0x24); 3317 + r3di_gpio_out_set(codec, R3DI_LINE_OUT); 3318 + break; 3319 + } 3320 + 3321 + /* disable headphone node */ 3322 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0, 3323 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3324 + snd_hda_set_pin_ctl(codec, spec->out_pins[1], 3325 + pin_ctl & ~PIN_HP); 3326 + /* enable line-out node */ 3327 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, 3328 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3329 + snd_hda_set_pin_ctl(codec, spec->out_pins[0], 3330 + pin_ctl | PIN_OUT); 3331 + /* Enable EAPD */ 3332 + snd_hda_codec_write(codec, spec->out_pins[0], 0, 3333 + AC_VERB_SET_EAPD_BTLENABLE, 0x01); 3334 + 3335 + /* If PlayEnhancement is enabled, set different source */ 3336 + if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) 3337 + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE); 3338 + else 3339 + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_EIGHT); 3340 + break; 3341 + case HEADPHONE_OUT: 3342 + codec_dbg(codec, "%s hp\n", __func__); 3343 + /* Headphone out config*/ 3344 + switch (spec->quirk) { 3345 + case QUIRK_SBZ: 3346 + writew(0x0107, spec->mem_base + 0x320); 3347 + writew(0x0104, spec->mem_base + 0x320); 3348 + writew(0x0001, spec->mem_base + 0x320); 3349 + chipio_set_control_param(codec, 0x0D, 0x12); 3350 + break; 3351 + case QUIRK_R3DI: 3352 + chipio_set_control_param(codec, 0x0D, 0x21); 3353 + r3di_gpio_out_set(codec, R3DI_HEADPHONE_OUT); 3354 + break; 3355 + } 3356 + 3357 + snd_hda_codec_write(codec, spec->out_pins[0], 0, 3358 + AC_VERB_SET_EAPD_BTLENABLE, 0x00); 3359 + 3360 + /* disable speaker*/ 3361 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, 3362 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3363 + snd_hda_set_pin_ctl(codec, spec->out_pins[0], 3364 + pin_ctl & ~PIN_HP); 3365 + 3366 + /* enable headphone, either front or rear */ 3367 + 3368 + if (snd_hda_jack_detect(codec, spec->unsol_tag_front_hp)) 3369 + headphone_nid = spec->out_pins[2]; 3370 + else if (snd_hda_jack_detect(codec, spec->unsol_tag_hp)) 3371 + headphone_nid = spec->out_pins[1]; 3372 + 3373 + pin_ctl = snd_hda_codec_read(codec, headphone_nid, 0, 3374 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3375 + snd_hda_set_pin_ctl(codec, headphone_nid, 3376 + pin_ctl | PIN_HP); 3377 + 3378 + if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) 3379 + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE); 3380 + else 3381 + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ZERO); 3382 + break; 3383 + case SURROUND_OUT: 3384 + codec_dbg(codec, "%s surround\n", __func__); 3385 + /* Surround out config*/ 3386 + switch (spec->quirk) { 3387 + case QUIRK_SBZ: 3388 + writew(0x0007, spec->mem_base + 0x320); 3389 + writew(0x0104, spec->mem_base + 0x320); 3390 + writew(0x0101, spec->mem_base + 0x320); 3391 + chipio_set_control_param(codec, 0x0D, 0x18); 3392 + break; 3393 + case QUIRK_R3DI: 3394 + chipio_set_control_param(codec, 0x0D, 0x24); 3395 + r3di_gpio_out_set(codec, R3DI_LINE_OUT); 3396 + break; 3397 + } 3398 + /* enable line out node */ 3399 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, 3400 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3401 + snd_hda_set_pin_ctl(codec, spec->out_pins[0], 3402 + pin_ctl | PIN_OUT); 3403 + /* Disable headphone out */ 3404 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0, 3405 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3406 + snd_hda_set_pin_ctl(codec, spec->out_pins[1], 3407 + pin_ctl & ~PIN_HP); 3408 + /* Enable EAPD on line out */ 3409 + snd_hda_codec_write(codec, spec->out_pins[0], 0, 3410 + AC_VERB_SET_EAPD_BTLENABLE, 0x01); 3411 + /* enable center/lfe out node */ 3412 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[2], 0, 3413 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3414 + snd_hda_set_pin_ctl(codec, spec->out_pins[2], 3415 + pin_ctl | PIN_OUT); 3416 + /* Now set rear surround node as out. */ 3417 + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[3], 0, 3418 + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3419 + snd_hda_set_pin_ctl(codec, spec->out_pins[3], 3420 + pin_ctl | PIN_OUT); 3421 + 3422 + if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) 3423 + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE); 3424 + else 3425 + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_EIGHT); 3426 + break; 3427 + } 3428 + 3429 + /* run through the output dsp commands for line-out */ 3430 + for (i = 0; i < alt_out_presets[spec->cur_out_type].commands; i++) { 3431 + err = dspio_set_uint_param(codec, 3432 + alt_out_presets[spec->cur_out_type].mids[i], 3433 + alt_out_presets[spec->cur_out_type].reqs[i], 3434 + alt_out_presets[spec->cur_out_type].vals[i]); 3435 + 3436 + if (err < 0) 3437 + goto exit; 3438 + } 3439 + 3440 + exit: 3441 + snd_hda_power_down_pm(codec); 3442 + 3443 + return err < 0 ? err : 0; 3444 + } 3445 + 3891 3446 static void ca0132_unsol_hp_delayed(struct work_struct *work) 3892 3447 { 3893 3448 struct ca0132_spec *spec = container_of( 3894 3449 to_delayed_work(work), struct ca0132_spec, unsol_hp_work); 3895 3450 struct hda_jack_tbl *jack; 3896 3451 3897 - ca0132_select_out(spec->codec); 3452 + if (spec->use_alt_functions) 3453 + ca0132_alt_select_out(spec->codec); 3454 + else 3455 + ca0132_select_out(spec->codec); 3456 + 3898 3457 jack = snd_hda_jack_tbl_get(spec->codec, spec->unsol_tag_hp); 3899 3458 if (jack) { 3900 3459 jack->block_report = 0; ··· 4101 3268 static void ca0132_set_dmic(struct hda_codec *codec, int enable); 4102 3269 static int ca0132_mic_boost_set(struct hda_codec *codec, long val); 4103 3270 static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val); 3271 + static void resume_mic1(struct hda_codec *codec, unsigned int oldval); 3272 + static int stop_mic1(struct hda_codec *codec); 3273 + static int ca0132_cvoice_switch_set(struct hda_codec *codec); 3274 + static int ca0132_alt_mic_boost_set(struct hda_codec *codec, long val); 4104 3275 4105 3276 /* 4106 3277 * Select the active VIP source ··· 4143 3306 msleep(20); 4144 3307 chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val); 4145 3308 } 3309 + 3310 + return 1; 3311 + } 3312 + 3313 + static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val) 3314 + { 3315 + struct ca0132_spec *spec = codec->spec; 3316 + unsigned int tmp; 3317 + 3318 + if (spec->dsp_state != DSP_DOWNLOADED) 3319 + return 0; 3320 + 3321 + codec_dbg(codec, "%s\n", __func__); 3322 + 3323 + chipio_set_stream_control(codec, 0x03, 0); 3324 + chipio_set_stream_control(codec, 0x04, 0); 3325 + 3326 + /* if CrystalVoice is off, vipsource should be 0 */ 3327 + if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] || 3328 + (val == 0) || spec->in_enum_val == REAR_LINE_IN) { 3329 + codec_dbg(codec, "%s: off.", __func__); 3330 + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); 3331 + 3332 + tmp = FLOAT_ZERO; 3333 + dspio_set_uint_param(codec, 0x80, 0x05, tmp); 3334 + 3335 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 3336 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 3337 + if (spec->quirk == QUIRK_R3DI) 3338 + chipio_set_conn_rate(codec, 0x0F, SR_96_000); 3339 + 3340 + 3341 + if (spec->in_enum_val == REAR_LINE_IN) 3342 + tmp = FLOAT_ZERO; 3343 + else { 3344 + if (spec->quirk == QUIRK_SBZ) 3345 + tmp = FLOAT_THREE; 3346 + else 3347 + tmp = FLOAT_ONE; 3348 + } 3349 + 3350 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 3351 + 3352 + } else { 3353 + codec_dbg(codec, "%s: on.", __func__); 3354 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000); 3355 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000); 3356 + if (spec->quirk == QUIRK_R3DI) 3357 + chipio_set_conn_rate(codec, 0x0F, SR_16_000); 3358 + 3359 + if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID]) 3360 + tmp = FLOAT_TWO; 3361 + else 3362 + tmp = FLOAT_ONE; 3363 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 3364 + 3365 + tmp = FLOAT_ONE; 3366 + dspio_set_uint_param(codec, 0x80, 0x05, tmp); 3367 + 3368 + msleep(20); 3369 + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val); 3370 + } 3371 + 3372 + chipio_set_stream_control(codec, 0x03, 1); 3373 + chipio_set_stream_control(codec, 0x04, 1); 4146 3374 4147 3375 return 1; 4148 3376 } ··· 4262 3360 snd_hda_power_down_pm(codec); 4263 3361 4264 3362 return 0; 3363 + } 3364 + 3365 + /* 3366 + * Select the active input. 3367 + * Mic detection isn't used, because it's kind of pointless on the SBZ. 3368 + * The front mic has no jack-detection, so the only way to switch to it 3369 + * is to do it manually in alsamixer. 3370 + */ 3371 + static int ca0132_alt_select_in(struct hda_codec *codec) 3372 + { 3373 + struct ca0132_spec *spec = codec->spec; 3374 + unsigned int tmp; 3375 + 3376 + codec_dbg(codec, "%s\n", __func__); 3377 + 3378 + snd_hda_power_up_pm(codec); 3379 + 3380 + chipio_set_stream_control(codec, 0x03, 0); 3381 + chipio_set_stream_control(codec, 0x04, 0); 3382 + 3383 + spec->cur_mic_type = spec->in_enum_val; 3384 + 3385 + switch (spec->cur_mic_type) { 3386 + case REAR_MIC: 3387 + switch (spec->quirk) { 3388 + case QUIRK_SBZ: 3389 + writew(0x0000, spec->mem_base + 0x320); 3390 + tmp = FLOAT_THREE; 3391 + break; 3392 + case QUIRK_R3DI: 3393 + r3di_gpio_mic_set(codec, R3DI_REAR_MIC); 3394 + tmp = FLOAT_ONE; 3395 + break; 3396 + default: 3397 + tmp = FLOAT_ONE; 3398 + break; 3399 + } 3400 + 3401 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 3402 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 3403 + if (spec->quirk == QUIRK_R3DI) 3404 + chipio_set_conn_rate(codec, 0x0F, SR_96_000); 3405 + 3406 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 3407 + 3408 + chipio_set_stream_control(codec, 0x03, 1); 3409 + chipio_set_stream_control(codec, 0x04, 1); 3410 + 3411 + if (spec->quirk == QUIRK_SBZ) { 3412 + chipio_write(codec, 0x18B098, 0x0000000C); 3413 + chipio_write(codec, 0x18B09C, 0x0000000C); 3414 + } 3415 + ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val); 3416 + break; 3417 + case REAR_LINE_IN: 3418 + ca0132_mic_boost_set(codec, 0); 3419 + switch (spec->quirk) { 3420 + case QUIRK_SBZ: 3421 + writew(0x0000, spec->mem_base + 0x320); 3422 + break; 3423 + case QUIRK_R3DI: 3424 + r3di_gpio_mic_set(codec, R3DI_REAR_MIC); 3425 + break; 3426 + } 3427 + 3428 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 3429 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 3430 + if (spec->quirk == QUIRK_R3DI) 3431 + chipio_set_conn_rate(codec, 0x0F, SR_96_000); 3432 + 3433 + tmp = FLOAT_ZERO; 3434 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 3435 + 3436 + if (spec->quirk == QUIRK_SBZ) { 3437 + chipio_write(codec, 0x18B098, 0x00000000); 3438 + chipio_write(codec, 0x18B09C, 0x00000000); 3439 + } 3440 + 3441 + chipio_set_stream_control(codec, 0x03, 1); 3442 + chipio_set_stream_control(codec, 0x04, 1); 3443 + break; 3444 + case FRONT_MIC: 3445 + switch (spec->quirk) { 3446 + case QUIRK_SBZ: 3447 + writew(0x0100, spec->mem_base + 0x320); 3448 + writew(0x0005, spec->mem_base + 0x320); 3449 + tmp = FLOAT_THREE; 3450 + break; 3451 + case QUIRK_R3DI: 3452 + r3di_gpio_mic_set(codec, R3DI_FRONT_MIC); 3453 + tmp = FLOAT_ONE; 3454 + break; 3455 + default: 3456 + tmp = FLOAT_ONE; 3457 + break; 3458 + } 3459 + 3460 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 3461 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 3462 + if (spec->quirk == QUIRK_R3DI) 3463 + chipio_set_conn_rate(codec, 0x0F, SR_96_000); 3464 + 3465 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 3466 + 3467 + chipio_set_stream_control(codec, 0x03, 1); 3468 + chipio_set_stream_control(codec, 0x04, 1); 3469 + 3470 + if (spec->quirk == QUIRK_SBZ) { 3471 + chipio_write(codec, 0x18B098, 0x0000000C); 3472 + chipio_write(codec, 0x18B09C, 0x000000CC); 3473 + } 3474 + ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val); 3475 + break; 3476 + } 3477 + ca0132_cvoice_switch_set(codec); 3478 + 3479 + snd_hda_power_down_pm(codec); 3480 + return 0; 3481 + 4265 3482 } 4266 3483 4267 3484 /* ··· 4439 3418 static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val) 4440 3419 { 4441 3420 struct ca0132_spec *spec = codec->spec; 4442 - unsigned int on; 3421 + unsigned int on, tmp; 4443 3422 int num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT; 4444 3423 int err = 0; 4445 3424 int idx = nid - EFFECT_START_NID; ··· 4462 3441 4463 3442 /* Voice Focus applies to 2-ch Mic, Digital Mic */ 4464 3443 if ((nid == VOICE_FOCUS) && (spec->cur_mic_type != DIGITAL_MIC)) 3444 + val = 0; 3445 + 3446 + /* If Voice Focus on SBZ, set to two channel. */ 3447 + if ((nid == VOICE_FOCUS) && (spec->quirk == QUIRK_SBZ) 3448 + && (spec->cur_mic_type != REAR_LINE_IN)) { 3449 + if (spec->effects_switch[CRYSTAL_VOICE - 3450 + EFFECT_START_NID]) { 3451 + 3452 + if (spec->effects_switch[VOICE_FOCUS - 3453 + EFFECT_START_NID]) { 3454 + tmp = FLOAT_TWO; 3455 + val = 1; 3456 + } else 3457 + tmp = FLOAT_ONE; 3458 + 3459 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 3460 + } 3461 + } 3462 + /* 3463 + * For SBZ noise reduction, there's an extra command 3464 + * to module ID 0x47. No clue why. 3465 + */ 3466 + if ((nid == NOISE_REDUCTION) && (spec->quirk == QUIRK_SBZ) 3467 + && (spec->cur_mic_type != REAR_LINE_IN)) { 3468 + if (spec->effects_switch[CRYSTAL_VOICE - 3469 + EFFECT_START_NID]) { 3470 + if (spec->effects_switch[NOISE_REDUCTION - 3471 + EFFECT_START_NID]) 3472 + tmp = FLOAT_ONE; 3473 + else 3474 + tmp = FLOAT_ZERO; 3475 + } else 3476 + tmp = FLOAT_ZERO; 3477 + 3478 + dspio_set_uint_param(codec, 0x47, 0x00, tmp); 3479 + } 3480 + 3481 + /* If rear line in disable effects. */ 3482 + if (spec->use_alt_functions && 3483 + spec->in_enum_val == REAR_LINE_IN) 4465 3484 val = 0; 4466 3485 } 4467 3486 ··· 4529 3468 4530 3469 codec_dbg(codec, "ca0132_pe_switch_set: val=%ld\n", 4531 3470 spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]); 3471 + 3472 + if (spec->use_alt_functions) 3473 + ca0132_alt_select_out(codec); 4532 3474 4533 3475 i = OUT_EFFECT_START_NID - EFFECT_START_NID; 4534 3476 nid = OUT_EFFECT_START_NID; ··· 4590 3526 4591 3527 /* set correct vipsource */ 4592 3528 oldval = stop_mic1(codec); 4593 - ret |= ca0132_set_vipsource(codec, 1); 3529 + if (spec->use_alt_functions) 3530 + ret |= ca0132_alt_set_vipsource(codec, 1); 3531 + else 3532 + ret |= ca0132_set_vipsource(codec, 1); 4594 3533 resume_mic1(codec, oldval); 4595 3534 return ret; 4596 3535 } ··· 4613 3546 return ret; 4614 3547 } 4615 3548 3549 + static int ca0132_alt_mic_boost_set(struct hda_codec *codec, long val) 3550 + { 3551 + struct ca0132_spec *spec = codec->spec; 3552 + int ret = 0; 3553 + 3554 + ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0, 3555 + HDA_INPUT, 0, HDA_AMP_VOLMASK, val); 3556 + return ret; 3557 + } 3558 + 4616 3559 static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol, 4617 3560 struct snd_ctl_elem_value *ucontrol) 4618 3561 { ··· 4637 3560 if (nid == VNID_HP_SEL) { 4638 3561 auto_jack = 4639 3562 spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID]; 4640 - if (!auto_jack) 4641 - ca0132_select_out(codec); 3563 + if (!auto_jack) { 3564 + if (spec->use_alt_functions) 3565 + ca0132_alt_select_out(codec); 3566 + else 3567 + ca0132_select_out(codec); 3568 + } 4642 3569 return 1; 4643 3570 } 4644 3571 ··· 4655 3574 } 4656 3575 4657 3576 if (nid == VNID_HP_ASEL) { 4658 - ca0132_select_out(codec); 3577 + if (spec->use_alt_functions) 3578 + ca0132_alt_select_out(codec); 3579 + else 3580 + ca0132_select_out(codec); 4659 3581 return 1; 4660 3582 } 4661 3583 ··· 4686 3602 return ret; 4687 3603 } 4688 3604 /* End of control change helpers. */ 3605 + /* 3606 + * Below I've added controls to mess with the effect levels, I've only enabled 3607 + * them on the Sound Blaster Z, but they would probably also work on the 3608 + * Chromebook. I figured they were probably tuned specifically for it, and left 3609 + * out for a reason. 3610 + */ 3611 + 3612 + /* Sets DSP effect level from the sliders above the controls */ 3613 + static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid, 3614 + const unsigned int *lookup, int idx) 3615 + { 3616 + int i = 0; 3617 + unsigned int y; 3618 + /* 3619 + * For X_BASS, req 2 is actually crossover freq instead of 3620 + * effect level 3621 + */ 3622 + if (nid == X_BASS) 3623 + y = 2; 3624 + else 3625 + y = 1; 3626 + 3627 + snd_hda_power_up(codec); 3628 + if (nid == XBASS_XOVER) { 3629 + for (i = 0; i < OUT_EFFECTS_COUNT; i++) 3630 + if (ca0132_effects[i].nid == X_BASS) 3631 + break; 3632 + 3633 + dspio_set_param(codec, ca0132_effects[i].mid, 0x20, 3634 + ca0132_effects[i].reqs[1], 3635 + &(lookup[idx - 1]), sizeof(unsigned int)); 3636 + } else { 3637 + /* Find the actual effect structure */ 3638 + for (i = 0; i < OUT_EFFECTS_COUNT; i++) 3639 + if (nid == ca0132_effects[i].nid) 3640 + break; 3641 + 3642 + dspio_set_param(codec, ca0132_effects[i].mid, 0x20, 3643 + ca0132_effects[i].reqs[y], 3644 + &(lookup[idx]), sizeof(unsigned int)); 3645 + } 3646 + 3647 + snd_hda_power_down(codec); 3648 + 3649 + return 0; 3650 + } 3651 + 3652 + static int ca0132_alt_xbass_xover_slider_ctl_get(struct snd_kcontrol *kcontrol, 3653 + struct snd_ctl_elem_value *ucontrol) 3654 + { 3655 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3656 + struct ca0132_spec *spec = codec->spec; 3657 + long *valp = ucontrol->value.integer.value; 3658 + 3659 + *valp = spec->xbass_xover_freq; 3660 + return 0; 3661 + } 3662 + 3663 + static int ca0132_alt_slider_ctl_get(struct snd_kcontrol *kcontrol, 3664 + struct snd_ctl_elem_value *ucontrol) 3665 + { 3666 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3667 + struct ca0132_spec *spec = codec->spec; 3668 + hda_nid_t nid = get_amp_nid(kcontrol); 3669 + long *valp = ucontrol->value.integer.value; 3670 + int idx = nid - OUT_EFFECT_START_NID; 3671 + 3672 + *valp = spec->fx_ctl_val[idx]; 3673 + return 0; 3674 + } 3675 + 3676 + /* 3677 + * The X-bass crossover starts at 10hz, so the min is 1. The 3678 + * frequency is set in multiples of 10. 3679 + */ 3680 + static int ca0132_alt_xbass_xover_slider_info(struct snd_kcontrol *kcontrol, 3681 + struct snd_ctl_elem_info *uinfo) 3682 + { 3683 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 3684 + uinfo->count = 1; 3685 + uinfo->value.integer.min = 1; 3686 + uinfo->value.integer.max = 100; 3687 + uinfo->value.integer.step = 1; 3688 + 3689 + return 0; 3690 + } 3691 + 3692 + static int ca0132_alt_effect_slider_info(struct snd_kcontrol *kcontrol, 3693 + struct snd_ctl_elem_info *uinfo) 3694 + { 3695 + int chs = get_amp_channels(kcontrol); 3696 + 3697 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 3698 + uinfo->count = chs == 3 ? 2 : 1; 3699 + uinfo->value.integer.min = 0; 3700 + uinfo->value.integer.max = 100; 3701 + uinfo->value.integer.step = 1; 3702 + 3703 + return 0; 3704 + } 3705 + 3706 + static int ca0132_alt_xbass_xover_slider_put(struct snd_kcontrol *kcontrol, 3707 + struct snd_ctl_elem_value *ucontrol) 3708 + { 3709 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3710 + struct ca0132_spec *spec = codec->spec; 3711 + hda_nid_t nid = get_amp_nid(kcontrol); 3712 + long *valp = ucontrol->value.integer.value; 3713 + int idx; 3714 + 3715 + /* any change? */ 3716 + if (spec->xbass_xover_freq == *valp) 3717 + return 0; 3718 + 3719 + spec->xbass_xover_freq = *valp; 3720 + 3721 + idx = *valp; 3722 + ca0132_alt_slider_ctl_set(codec, nid, float_xbass_xover_lookup, idx); 3723 + 3724 + return 0; 3725 + } 3726 + 3727 + static int ca0132_alt_effect_slider_put(struct snd_kcontrol *kcontrol, 3728 + struct snd_ctl_elem_value *ucontrol) 3729 + { 3730 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3731 + struct ca0132_spec *spec = codec->spec; 3732 + hda_nid_t nid = get_amp_nid(kcontrol); 3733 + long *valp = ucontrol->value.integer.value; 3734 + int idx; 3735 + 3736 + idx = nid - EFFECT_START_NID; 3737 + /* any change? */ 3738 + if (spec->fx_ctl_val[idx] == *valp) 3739 + return 0; 3740 + 3741 + spec->fx_ctl_val[idx] = *valp; 3742 + 3743 + idx = *valp; 3744 + ca0132_alt_slider_ctl_set(codec, nid, float_zero_to_one_lookup, idx); 3745 + 3746 + return 0; 3747 + } 3748 + 3749 + 3750 + /* 3751 + * Mic Boost Enum for alternative ca0132 codecs. I didn't like that the original 3752 + * only has off or full 30 dB, and didn't like making a volume slider that has 3753 + * traditional 0-100 in alsamixer that goes in big steps. I like enum better. 3754 + */ 3755 + #define MIC_BOOST_NUM_OF_STEPS 4 3756 + #define MIC_BOOST_ENUM_MAX_STRLEN 10 3757 + 3758 + static int ca0132_alt_mic_boost_info(struct snd_kcontrol *kcontrol, 3759 + struct snd_ctl_elem_info *uinfo) 3760 + { 3761 + char *sfx = "dB"; 3762 + char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 3763 + 3764 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3765 + uinfo->count = 1; 3766 + uinfo->value.enumerated.items = MIC_BOOST_NUM_OF_STEPS; 3767 + if (uinfo->value.enumerated.item >= MIC_BOOST_NUM_OF_STEPS) 3768 + uinfo->value.enumerated.item = MIC_BOOST_NUM_OF_STEPS - 1; 3769 + sprintf(namestr, "%d %s", (uinfo->value.enumerated.item * 10), sfx); 3770 + strcpy(uinfo->value.enumerated.name, namestr); 3771 + return 0; 3772 + } 3773 + 3774 + static int ca0132_alt_mic_boost_get(struct snd_kcontrol *kcontrol, 3775 + struct snd_ctl_elem_value *ucontrol) 3776 + { 3777 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3778 + struct ca0132_spec *spec = codec->spec; 3779 + 3780 + ucontrol->value.enumerated.item[0] = spec->mic_boost_enum_val; 3781 + return 0; 3782 + } 3783 + 3784 + static int ca0132_alt_mic_boost_put(struct snd_kcontrol *kcontrol, 3785 + struct snd_ctl_elem_value *ucontrol) 3786 + { 3787 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3788 + struct ca0132_spec *spec = codec->spec; 3789 + int sel = ucontrol->value.enumerated.item[0]; 3790 + unsigned int items = MIC_BOOST_NUM_OF_STEPS; 3791 + 3792 + if (sel >= items) 3793 + return 0; 3794 + 3795 + codec_dbg(codec, "ca0132_alt_mic_boost: boost=%d\n", 3796 + sel); 3797 + 3798 + spec->mic_boost_enum_val = sel; 3799 + 3800 + if (spec->in_enum_val != REAR_LINE_IN) 3801 + ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val); 3802 + 3803 + return 1; 3804 + } 3805 + 3806 + 3807 + /* 3808 + * Input Select Control for alternative ca0132 codecs. This exists because 3809 + * front microphone has no auto-detect, and we need a way to set the rear 3810 + * as line-in 3811 + */ 3812 + static int ca0132_alt_input_source_info(struct snd_kcontrol *kcontrol, 3813 + struct snd_ctl_elem_info *uinfo) 3814 + { 3815 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3816 + uinfo->count = 1; 3817 + uinfo->value.enumerated.items = IN_SRC_NUM_OF_INPUTS; 3818 + if (uinfo->value.enumerated.item >= IN_SRC_NUM_OF_INPUTS) 3819 + uinfo->value.enumerated.item = IN_SRC_NUM_OF_INPUTS - 1; 3820 + strcpy(uinfo->value.enumerated.name, 3821 + in_src_str[uinfo->value.enumerated.item]); 3822 + return 0; 3823 + } 3824 + 3825 + static int ca0132_alt_input_source_get(struct snd_kcontrol *kcontrol, 3826 + struct snd_ctl_elem_value *ucontrol) 3827 + { 3828 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3829 + struct ca0132_spec *spec = codec->spec; 3830 + 3831 + ucontrol->value.enumerated.item[0] = spec->in_enum_val; 3832 + return 0; 3833 + } 3834 + 3835 + static int ca0132_alt_input_source_put(struct snd_kcontrol *kcontrol, 3836 + struct snd_ctl_elem_value *ucontrol) 3837 + { 3838 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3839 + struct ca0132_spec *spec = codec->spec; 3840 + int sel = ucontrol->value.enumerated.item[0]; 3841 + unsigned int items = IN_SRC_NUM_OF_INPUTS; 3842 + 3843 + if (sel >= items) 3844 + return 0; 3845 + 3846 + codec_dbg(codec, "ca0132_alt_input_select: sel=%d, preset=%s\n", 3847 + sel, in_src_str[sel]); 3848 + 3849 + spec->in_enum_val = sel; 3850 + 3851 + ca0132_alt_select_in(codec); 3852 + 3853 + return 1; 3854 + } 3855 + 3856 + /* Sound Blaster Z Output Select Control */ 3857 + static int ca0132_alt_output_select_get_info(struct snd_kcontrol *kcontrol, 3858 + struct snd_ctl_elem_info *uinfo) 3859 + { 3860 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3861 + uinfo->count = 1; 3862 + uinfo->value.enumerated.items = NUM_OF_OUTPUTS; 3863 + if (uinfo->value.enumerated.item >= NUM_OF_OUTPUTS) 3864 + uinfo->value.enumerated.item = NUM_OF_OUTPUTS - 1; 3865 + strcpy(uinfo->value.enumerated.name, 3866 + alt_out_presets[uinfo->value.enumerated.item].name); 3867 + return 0; 3868 + } 3869 + 3870 + static int ca0132_alt_output_select_get(struct snd_kcontrol *kcontrol, 3871 + struct snd_ctl_elem_value *ucontrol) 3872 + { 3873 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3874 + struct ca0132_spec *spec = codec->spec; 3875 + 3876 + ucontrol->value.enumerated.item[0] = spec->out_enum_val; 3877 + return 0; 3878 + } 3879 + 3880 + static int ca0132_alt_output_select_put(struct snd_kcontrol *kcontrol, 3881 + struct snd_ctl_elem_value *ucontrol) 3882 + { 3883 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3884 + struct ca0132_spec *spec = codec->spec; 3885 + int sel = ucontrol->value.enumerated.item[0]; 3886 + unsigned int items = NUM_OF_OUTPUTS; 3887 + unsigned int auto_jack; 3888 + 3889 + if (sel >= items) 3890 + return 0; 3891 + 3892 + codec_dbg(codec, "ca0132_alt_output_select: sel=%d, preset=%s\n", 3893 + sel, alt_out_presets[sel].name); 3894 + 3895 + spec->out_enum_val = sel; 3896 + 3897 + auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID]; 3898 + 3899 + if (!auto_jack) 3900 + ca0132_alt_select_out(codec); 3901 + 3902 + return 1; 3903 + } 3904 + 3905 + /* 3906 + * Smart Volume output setting control. Three different settings, Normal, 3907 + * which takes the value from the smart volume slider. The two others, loud 3908 + * and night, disregard the slider value and have uneditable values. 3909 + */ 3910 + #define NUM_OF_SVM_SETTINGS 3 3911 + static const char *const out_svm_set_enum_str[3] = {"Normal", "Loud", "Night" }; 3912 + 3913 + static int ca0132_alt_svm_setting_info(struct snd_kcontrol *kcontrol, 3914 + struct snd_ctl_elem_info *uinfo) 3915 + { 3916 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3917 + uinfo->count = 1; 3918 + uinfo->value.enumerated.items = NUM_OF_SVM_SETTINGS; 3919 + if (uinfo->value.enumerated.item >= NUM_OF_SVM_SETTINGS) 3920 + uinfo->value.enumerated.item = NUM_OF_SVM_SETTINGS - 1; 3921 + strcpy(uinfo->value.enumerated.name, 3922 + out_svm_set_enum_str[uinfo->value.enumerated.item]); 3923 + return 0; 3924 + } 3925 + 3926 + static int ca0132_alt_svm_setting_get(struct snd_kcontrol *kcontrol, 3927 + struct snd_ctl_elem_value *ucontrol) 3928 + { 3929 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3930 + struct ca0132_spec *spec = codec->spec; 3931 + 3932 + ucontrol->value.enumerated.item[0] = spec->smart_volume_setting; 3933 + return 0; 3934 + } 3935 + 3936 + static int ca0132_alt_svm_setting_put(struct snd_kcontrol *kcontrol, 3937 + struct snd_ctl_elem_value *ucontrol) 3938 + { 3939 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3940 + struct ca0132_spec *spec = codec->spec; 3941 + int sel = ucontrol->value.enumerated.item[0]; 3942 + unsigned int items = NUM_OF_SVM_SETTINGS; 3943 + unsigned int idx = SMART_VOLUME - EFFECT_START_NID; 3944 + unsigned int tmp; 3945 + 3946 + if (sel >= items) 3947 + return 0; 3948 + 3949 + codec_dbg(codec, "ca0132_alt_svm_setting: sel=%d, preset=%s\n", 3950 + sel, out_svm_set_enum_str[sel]); 3951 + 3952 + spec->smart_volume_setting = sel; 3953 + 3954 + switch (sel) { 3955 + case 0: 3956 + tmp = FLOAT_ZERO; 3957 + break; 3958 + case 1: 3959 + tmp = FLOAT_ONE; 3960 + break; 3961 + case 2: 3962 + tmp = FLOAT_TWO; 3963 + break; 3964 + default: 3965 + tmp = FLOAT_ZERO; 3966 + break; 3967 + } 3968 + /* Req 2 is the Smart Volume Setting req. */ 3969 + dspio_set_uint_param(codec, ca0132_effects[idx].mid, 3970 + ca0132_effects[idx].reqs[2], tmp); 3971 + return 1; 3972 + } 3973 + 3974 + /* Sound Blaster Z EQ preset controls */ 3975 + static int ca0132_alt_eq_preset_info(struct snd_kcontrol *kcontrol, 3976 + struct snd_ctl_elem_info *uinfo) 3977 + { 3978 + unsigned int items = ARRAY_SIZE(ca0132_alt_eq_presets); 3979 + 3980 + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3981 + uinfo->count = 1; 3982 + uinfo->value.enumerated.items = items; 3983 + if (uinfo->value.enumerated.item >= items) 3984 + uinfo->value.enumerated.item = items - 1; 3985 + strcpy(uinfo->value.enumerated.name, 3986 + ca0132_alt_eq_presets[uinfo->value.enumerated.item].name); 3987 + return 0; 3988 + } 3989 + 3990 + static int ca0132_alt_eq_preset_get(struct snd_kcontrol *kcontrol, 3991 + struct snd_ctl_elem_value *ucontrol) 3992 + { 3993 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3994 + struct ca0132_spec *spec = codec->spec; 3995 + 3996 + ucontrol->value.enumerated.item[0] = spec->eq_preset_val; 3997 + return 0; 3998 + } 3999 + 4000 + static int ca0132_alt_eq_preset_put(struct snd_kcontrol *kcontrol, 4001 + struct snd_ctl_elem_value *ucontrol) 4002 + { 4003 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4004 + struct ca0132_spec *spec = codec->spec; 4005 + int i, err = 0; 4006 + int sel = ucontrol->value.enumerated.item[0]; 4007 + unsigned int items = ARRAY_SIZE(ca0132_alt_eq_presets); 4008 + 4009 + if (sel >= items) 4010 + return 0; 4011 + 4012 + codec_dbg(codec, "%s: sel=%d, preset=%s\n", __func__, sel, 4013 + ca0132_alt_eq_presets[sel].name); 4014 + /* 4015 + * Idx 0 is default. 4016 + * Default needs to qualify with CrystalVoice state. 4017 + */ 4018 + for (i = 0; i < EQ_PRESET_MAX_PARAM_COUNT; i++) { 4019 + err = dspio_set_uint_param(codec, ca0132_alt_eq_enum.mid, 4020 + ca0132_alt_eq_enum.reqs[i], 4021 + ca0132_alt_eq_presets[sel].vals[i]); 4022 + if (err < 0) 4023 + break; 4024 + } 4025 + 4026 + if (err >= 0) 4027 + spec->eq_preset_val = sel; 4028 + 4029 + return 1; 4030 + } 4689 4031 4690 4032 static int ca0132_voicefx_info(struct snd_kcontrol *kcontrol, 4691 4033 struct snd_ctl_elem_info *uinfo) ··· 5263 3753 /* mic boost */ 5264 3754 if (nid == spec->input_pins[0]) { 5265 3755 spec->cur_mic_boost = *valp; 3756 + if (spec->use_alt_functions) { 3757 + if (spec->in_enum_val != REAR_LINE_IN) 3758 + changed = ca0132_mic_boost_set(codec, *valp); 3759 + } else { 3760 + /* Mic boost does not apply to Digital Mic */ 3761 + if (spec->cur_mic_type != DIGITAL_MIC) 3762 + changed = ca0132_mic_boost_set(codec, *valp); 3763 + } 5266 3764 5267 - /* Mic boost does not apply to Digital Mic */ 5268 - if (spec->cur_mic_type != DIGITAL_MIC) 5269 - changed = ca0132_mic_boost_set(codec, *valp); 5270 3765 goto exit; 5271 3766 } 5272 3767 ··· 5283 3768 /* 5284 3769 * Volume related 5285 3770 */ 3771 + /* 3772 + * Sets the internal DSP decibel level to match the DAC for output, and the 3773 + * ADC for input. Currently only the SBZ sets dsp capture volume level, and 3774 + * all alternative codecs set DSP playback volume. 3775 + */ 3776 + static void ca0132_alt_dsp_volume_put(struct hda_codec *codec, hda_nid_t nid) 3777 + { 3778 + struct ca0132_spec *spec = codec->spec; 3779 + unsigned int dsp_dir; 3780 + unsigned int lookup_val; 3781 + 3782 + if (nid == VNID_SPK) 3783 + dsp_dir = DSP_VOL_OUT; 3784 + else 3785 + dsp_dir = DSP_VOL_IN; 3786 + 3787 + lookup_val = spec->vnode_lvol[nid - VNODE_START_NID]; 3788 + 3789 + dspio_set_uint_param(codec, 3790 + ca0132_alt_vol_ctls[dsp_dir].mid, 3791 + ca0132_alt_vol_ctls[dsp_dir].reqs[0], 3792 + float_vol_db_lookup[lookup_val]); 3793 + 3794 + lookup_val = spec->vnode_rvol[nid - VNODE_START_NID]; 3795 + 3796 + dspio_set_uint_param(codec, 3797 + ca0132_alt_vol_ctls[dsp_dir].mid, 3798 + ca0132_alt_vol_ctls[dsp_dir].reqs[1], 3799 + float_vol_db_lookup[lookup_val]); 3800 + 3801 + dspio_set_uint_param(codec, 3802 + ca0132_alt_vol_ctls[dsp_dir].mid, 3803 + ca0132_alt_vol_ctls[dsp_dir].reqs[2], FLOAT_ZERO); 3804 + } 3805 + 5286 3806 static int ca0132_volume_info(struct snd_kcontrol *kcontrol, 5287 3807 struct snd_ctl_elem_info *uinfo) 5288 3808 { ··· 5419 3869 return changed; 5420 3870 } 5421 3871 3872 + /* 3873 + * This function is the same as the one above, because using an if statement 3874 + * inside of the above volume control for the DSP volume would cause too much 3875 + * lag. This is a lot more smooth. 3876 + */ 3877 + static int ca0132_alt_volume_put(struct snd_kcontrol *kcontrol, 3878 + struct snd_ctl_elem_value *ucontrol) 3879 + { 3880 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3881 + struct ca0132_spec *spec = codec->spec; 3882 + hda_nid_t nid = get_amp_nid(kcontrol); 3883 + int ch = get_amp_channels(kcontrol); 3884 + long *valp = ucontrol->value.integer.value; 3885 + hda_nid_t vnid = 0; 3886 + int changed = 1; 3887 + 3888 + switch (nid) { 3889 + case 0x02: 3890 + vnid = VNID_SPK; 3891 + break; 3892 + case 0x07: 3893 + vnid = VNID_MIC; 3894 + break; 3895 + } 3896 + 3897 + /* store the left and right volume */ 3898 + if (ch & 1) { 3899 + spec->vnode_lvol[vnid - VNODE_START_NID] = *valp; 3900 + valp++; 3901 + } 3902 + if (ch & 2) { 3903 + spec->vnode_rvol[vnid - VNODE_START_NID] = *valp; 3904 + valp++; 3905 + } 3906 + 3907 + snd_hda_power_up(codec); 3908 + ca0132_alt_dsp_volume_put(codec, vnid); 3909 + mutex_lock(&codec->control_mutex); 3910 + changed = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); 3911 + mutex_unlock(&codec->control_mutex); 3912 + snd_hda_power_down(codec); 3913 + 3914 + return changed; 3915 + } 3916 + 5422 3917 static int ca0132_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag, 5423 3918 unsigned int size, unsigned int __user *tlv) 5424 3919 { ··· 5502 3907 return err; 5503 3908 } 5504 3909 5505 - static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid, 5506 - const char *pfx, int dir) 3910 + /* Add volume slider control for effect level */ 3911 + static int ca0132_alt_add_effect_slider(struct hda_codec *codec, hda_nid_t nid, 3912 + const char *pfx, int dir) 5507 3913 { 5508 3914 char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 5509 3915 int type = dir ? HDA_INPUT : HDA_OUTPUT; 5510 3916 struct snd_kcontrol_new knew = 3917 + HDA_CODEC_VOLUME_MONO(namestr, nid, 1, 0, type); 3918 + 3919 + sprintf(namestr, "FX: %s %s Volume", pfx, dirstr[dir]); 3920 + 3921 + knew.tlv.c = 0; 3922 + knew.tlv.p = 0; 3923 + 3924 + switch (nid) { 3925 + case XBASS_XOVER: 3926 + knew.info = ca0132_alt_xbass_xover_slider_info; 3927 + knew.get = ca0132_alt_xbass_xover_slider_ctl_get; 3928 + knew.put = ca0132_alt_xbass_xover_slider_put; 3929 + break; 3930 + default: 3931 + knew.info = ca0132_alt_effect_slider_info; 3932 + knew.get = ca0132_alt_slider_ctl_get; 3933 + knew.put = ca0132_alt_effect_slider_put; 3934 + knew.private_value = 3935 + HDA_COMPOSE_AMP_VAL(nid, 1, 0, type); 3936 + break; 3937 + } 3938 + 3939 + return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 3940 + } 3941 + 3942 + /* 3943 + * Added FX: prefix for the alternative codecs, because otherwise the surround 3944 + * effect would conflict with the Surround sound volume control. Also seems more 3945 + * clear as to what the switches do. Left alone for others. 3946 + */ 3947 + static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid, 3948 + const char *pfx, int dir) 3949 + { 3950 + struct ca0132_spec *spec = codec->spec; 3951 + char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 3952 + int type = dir ? HDA_INPUT : HDA_OUTPUT; 3953 + struct snd_kcontrol_new knew = 5511 3954 CA0132_CODEC_MUTE_MONO(namestr, nid, 1, type); 5512 - sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); 3955 + /* If using alt_controls, add FX: prefix. But, don't add FX: 3956 + * prefix to OutFX or InFX enable controls. 3957 + */ 3958 + if ((spec->use_alt_controls) && (nid <= IN_EFFECT_END_NID)) 3959 + sprintf(namestr, "FX: %s %s Switch", pfx, dirstr[dir]); 3960 + else 3961 + sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); 3962 + 5513 3963 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 5514 3964 } 5515 3965 ··· 5569 3929 return snd_hda_ctl_add(codec, VOICEFX, snd_ctl_new1(&knew, codec)); 5570 3930 } 5571 3931 3932 + /* Create the EQ Preset control */ 3933 + static int add_ca0132_alt_eq_presets(struct hda_codec *codec) 3934 + { 3935 + struct snd_kcontrol_new knew = 3936 + HDA_CODEC_MUTE_MONO(ca0132_alt_eq_enum.name, 3937 + EQ_PRESET_ENUM, 1, 0, HDA_OUTPUT); 3938 + knew.info = ca0132_alt_eq_preset_info; 3939 + knew.get = ca0132_alt_eq_preset_get; 3940 + knew.put = ca0132_alt_eq_preset_put; 3941 + return snd_hda_ctl_add(codec, EQ_PRESET_ENUM, 3942 + snd_ctl_new1(&knew, codec)); 3943 + } 3944 + 3945 + /* 3946 + * Add enumerated control for the three different settings of the smart volume 3947 + * output effect. Normal just uses the slider value, and loud and night are 3948 + * their own things that ignore that value. 3949 + */ 3950 + static int ca0132_alt_add_svm_enum(struct hda_codec *codec) 3951 + { 3952 + struct snd_kcontrol_new knew = 3953 + HDA_CODEC_MUTE_MONO("FX: Smart Volume Setting", 3954 + SMART_VOLUME_ENUM, 1, 0, HDA_OUTPUT); 3955 + knew.info = ca0132_alt_svm_setting_info; 3956 + knew.get = ca0132_alt_svm_setting_get; 3957 + knew.put = ca0132_alt_svm_setting_put; 3958 + return snd_hda_ctl_add(codec, SMART_VOLUME_ENUM, 3959 + snd_ctl_new1(&knew, codec)); 3960 + 3961 + } 3962 + 3963 + /* 3964 + * Create an Output Select enumerated control for codecs with surround 3965 + * out capabilities. 3966 + */ 3967 + static int ca0132_alt_add_output_enum(struct hda_codec *codec) 3968 + { 3969 + struct snd_kcontrol_new knew = 3970 + HDA_CODEC_MUTE_MONO("Output Select", 3971 + OUTPUT_SOURCE_ENUM, 1, 0, HDA_OUTPUT); 3972 + knew.info = ca0132_alt_output_select_get_info; 3973 + knew.get = ca0132_alt_output_select_get; 3974 + knew.put = ca0132_alt_output_select_put; 3975 + return snd_hda_ctl_add(codec, OUTPUT_SOURCE_ENUM, 3976 + snd_ctl_new1(&knew, codec)); 3977 + } 3978 + 3979 + /* 3980 + * Create an Input Source enumerated control for the alternate ca0132 codecs 3981 + * because the front microphone has no auto-detect, and Line-in has to be set 3982 + * somehow. 3983 + */ 3984 + static int ca0132_alt_add_input_enum(struct hda_codec *codec) 3985 + { 3986 + struct snd_kcontrol_new knew = 3987 + HDA_CODEC_MUTE_MONO("Input Source", 3988 + INPUT_SOURCE_ENUM, 1, 0, HDA_INPUT); 3989 + knew.info = ca0132_alt_input_source_info; 3990 + knew.get = ca0132_alt_input_source_get; 3991 + knew.put = ca0132_alt_input_source_put; 3992 + return snd_hda_ctl_add(codec, INPUT_SOURCE_ENUM, 3993 + snd_ctl_new1(&knew, codec)); 3994 + } 3995 + 3996 + /* 3997 + * Add mic boost enumerated control. Switches through 0dB to 30dB. This adds 3998 + * more control than the original mic boost, which is either full 30dB or off. 3999 + */ 4000 + static int ca0132_alt_add_mic_boost_enum(struct hda_codec *codec) 4001 + { 4002 + struct snd_kcontrol_new knew = 4003 + HDA_CODEC_MUTE_MONO("Mic Boost Capture Switch", 4004 + MIC_BOOST_ENUM, 1, 0, HDA_INPUT); 4005 + knew.info = ca0132_alt_mic_boost_info; 4006 + knew.get = ca0132_alt_mic_boost_get; 4007 + knew.put = ca0132_alt_mic_boost_put; 4008 + return snd_hda_ctl_add(codec, MIC_BOOST_ENUM, 4009 + snd_ctl_new1(&knew, codec)); 4010 + 4011 + } 4012 + 4013 + /* 4014 + * Need to create slave controls for the alternate codecs that have surround 4015 + * capabilities. 4016 + */ 4017 + static const char * const ca0132_alt_slave_pfxs[] = { 4018 + "Front", "Surround", "Center", "LFE", NULL, 4019 + }; 4020 + 4021 + /* 4022 + * Also need special channel map, because the default one is incorrect. 4023 + * I think this has to do with the pin for rear surround being 0x11, 4024 + * and the center/lfe being 0x10. Usually the pin order is the opposite. 4025 + */ 4026 + const struct snd_pcm_chmap_elem ca0132_alt_chmaps[] = { 4027 + { .channels = 2, 4028 + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, 4029 + { .channels = 4, 4030 + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, 4031 + SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, 4032 + { .channels = 6, 4033 + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, 4034 + SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE, 4035 + SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, 4036 + { } 4037 + }; 4038 + 4039 + /* Add the correct chmap for streams with 6 channels. */ 4040 + static void ca0132_alt_add_chmap_ctls(struct hda_codec *codec) 4041 + { 4042 + int err = 0; 4043 + struct hda_pcm *pcm; 4044 + 4045 + list_for_each_entry(pcm, &codec->pcm_list_head, list) { 4046 + struct hda_pcm_stream *hinfo = 4047 + &pcm->stream[SNDRV_PCM_STREAM_PLAYBACK]; 4048 + struct snd_pcm_chmap *chmap; 4049 + const struct snd_pcm_chmap_elem *elem; 4050 + 4051 + elem = ca0132_alt_chmaps; 4052 + if (hinfo->channels_max == 6) { 4053 + err = snd_pcm_add_chmap_ctls(pcm->pcm, 4054 + SNDRV_PCM_STREAM_PLAYBACK, 4055 + elem, hinfo->channels_max, 0, &chmap); 4056 + if (err < 0) 4057 + codec_dbg(codec, "snd_pcm_add_chmap_ctls failed!"); 4058 + } 4059 + } 4060 + } 4061 + 5572 4062 /* 5573 4063 * When changing Node IDs for Mixer Controls below, make sure to update 5574 4064 * Node IDs in ca0132_config() as well. 5575 4065 */ 5576 - static struct snd_kcontrol_new ca0132_mixer[] = { 4066 + static const struct snd_kcontrol_new ca0132_mixer[] = { 5577 4067 CA0132_CODEC_VOL("Master Playback Volume", VNID_SPK, HDA_OUTPUT), 5578 4068 CA0132_CODEC_MUTE("Master Playback Switch", VNID_SPK, HDA_OUTPUT), 5579 4069 CA0132_CODEC_VOL("Capture Volume", VNID_MIC, HDA_INPUT), ··· 5725 3955 { } /* end */ 5726 3956 }; 5727 3957 3958 + /* 3959 + * SBZ specific control mixer. Removes auto-detect for mic, and adds surround 3960 + * controls. Also sets both the Front Playback and Capture Volume controls to 3961 + * alt so they set the DSP's decibel level. 3962 + */ 3963 + static const struct snd_kcontrol_new sbz_mixer[] = { 3964 + CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT), 3965 + CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT), 3966 + HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT), 3967 + HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0, HDA_OUTPUT), 3968 + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x03, 1, 0, HDA_OUTPUT), 3969 + HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x03, 1, 0, HDA_OUTPUT), 3970 + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x03, 2, 0, HDA_OUTPUT), 3971 + HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x03, 2, 0, HDA_OUTPUT), 3972 + CA0132_ALT_CODEC_VOL("Capture Volume", 0x07, HDA_INPUT), 3973 + CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT), 3974 + HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT), 3975 + HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT), 3976 + CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch", 3977 + VNID_HP_ASEL, 1, HDA_OUTPUT), 3978 + { } /* end */ 3979 + }; 3980 + 3981 + /* 3982 + * Same as the Sound Blaster Z, except doesn't use the alt volume for capture 3983 + * because it doesn't set decibel levels for the DSP for capture. 3984 + */ 3985 + static const struct snd_kcontrol_new r3di_mixer[] = { 3986 + CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT), 3987 + CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT), 3988 + HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT), 3989 + HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0, HDA_OUTPUT), 3990 + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x03, 1, 0, HDA_OUTPUT), 3991 + HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x03, 1, 0, HDA_OUTPUT), 3992 + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x03, 2, 0, HDA_OUTPUT), 3993 + HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x03, 2, 0, HDA_OUTPUT), 3994 + CA0132_CODEC_VOL("Capture Volume", VNID_MIC, HDA_INPUT), 3995 + CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT), 3996 + HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT), 3997 + HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT), 3998 + CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch", 3999 + VNID_HP_ASEL, 1, HDA_OUTPUT), 4000 + { } /* end */ 4001 + }; 4002 + 5728 4003 static int ca0132_build_controls(struct hda_codec *codec) 5729 4004 { 5730 4005 struct ca0132_spec *spec = codec->spec; 5731 - int i, num_fx; 4006 + int i, num_fx, num_sliders; 5732 4007 int err = 0; 5733 4008 5734 4009 /* Add Mixer controls */ ··· 5782 3967 if (err < 0) 5783 3968 return err; 5784 3969 } 3970 + /* Setup vmaster with surround slaves for desktop ca0132 devices */ 3971 + if (spec->use_alt_functions) { 3972 + snd_hda_set_vmaster_tlv(codec, spec->dacs[0], HDA_OUTPUT, 3973 + spec->tlv); 3974 + snd_hda_add_vmaster(codec, "Master Playback Volume", 3975 + spec->tlv, ca0132_alt_slave_pfxs, 3976 + "Playback Volume"); 3977 + err = __snd_hda_add_vmaster(codec, "Master Playback Switch", 3978 + NULL, ca0132_alt_slave_pfxs, 3979 + "Playback Switch", 3980 + true, &spec->vmaster_mute.sw_kctl); 3981 + 3982 + } 5785 3983 5786 3984 /* Add in and out effects controls. 5787 3985 * VoiceFX, PE and CrystalVoice are added separately. 5788 3986 */ 5789 3987 num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT; 5790 3988 for (i = 0; i < num_fx; i++) { 3989 + /* SBZ breaks if Echo Cancellation is used */ 3990 + if (spec->quirk == QUIRK_SBZ) { 3991 + if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID + 3992 + OUT_EFFECTS_COUNT)) 3993 + continue; 3994 + } 3995 + 5791 3996 err = add_fx_switch(codec, ca0132_effects[i].nid, 5792 3997 ca0132_effects[i].name, 5793 3998 ca0132_effects[i].direct); 5794 3999 if (err < 0) 5795 4000 return err; 5796 4001 } 4002 + /* 4003 + * If codec has use_alt_controls set to true, add effect level sliders, 4004 + * EQ presets, and Smart Volume presets. Also, change names to add FX 4005 + * prefix, and change PlayEnhancement and CrystalVoice to match. 4006 + */ 4007 + if (spec->use_alt_controls) { 4008 + ca0132_alt_add_svm_enum(codec); 4009 + add_ca0132_alt_eq_presets(codec); 4010 + err = add_fx_switch(codec, PLAY_ENHANCEMENT, 4011 + "Enable OutFX", 0); 4012 + if (err < 0) 4013 + return err; 5797 4014 5798 - err = add_fx_switch(codec, PLAY_ENHANCEMENT, "PlayEnhancement", 0); 5799 - if (err < 0) 5800 - return err; 4015 + err = add_fx_switch(codec, CRYSTAL_VOICE, 4016 + "Enable InFX", 1); 4017 + if (err < 0) 4018 + return err; 5801 4019 5802 - err = add_fx_switch(codec, CRYSTAL_VOICE, "CrystalVoice", 1); 5803 - if (err < 0) 5804 - return err; 4020 + num_sliders = OUT_EFFECTS_COUNT - 1; 4021 + for (i = 0; i < num_sliders; i++) { 4022 + err = ca0132_alt_add_effect_slider(codec, 4023 + ca0132_effects[i].nid, 4024 + ca0132_effects[i].name, 4025 + ca0132_effects[i].direct); 4026 + if (err < 0) 4027 + return err; 4028 + } 5805 4029 4030 + err = ca0132_alt_add_effect_slider(codec, XBASS_XOVER, 4031 + "X-Bass Crossover", EFX_DIR_OUT); 4032 + 4033 + if (err < 0) 4034 + return err; 4035 + } else { 4036 + err = add_fx_switch(codec, PLAY_ENHANCEMENT, 4037 + "PlayEnhancement", 0); 4038 + if (err < 0) 4039 + return err; 4040 + 4041 + err = add_fx_switch(codec, CRYSTAL_VOICE, 4042 + "CrystalVoice", 1); 4043 + if (err < 0) 4044 + return err; 4045 + } 5806 4046 add_voicefx(codec); 5807 4047 4048 + /* 4049 + * If the codec uses alt_functions, you need the enumerated controls 4050 + * to select the new outputs and inputs, plus add the new mic boost 4051 + * setting control. 4052 + */ 4053 + if (spec->use_alt_functions) { 4054 + ca0132_alt_add_output_enum(codec); 4055 + ca0132_alt_add_input_enum(codec); 4056 + ca0132_alt_add_mic_boost_enum(codec); 4057 + } 5808 4058 #ifdef ENABLE_TUNING_CONTROLS 5809 4059 add_tuning_ctls(codec); 5810 4060 #endif ··· 5894 4014 if (err < 0) 5895 4015 return err; 5896 4016 } 4017 + 4018 + if (spec->use_alt_functions) 4019 + ca0132_alt_add_chmap_ctls(codec); 4020 + 5897 4021 return 0; 5898 4022 } 5899 4023 ··· 5952 4068 info = snd_hda_codec_pcm_new(codec, "CA0132 Analog"); 5953 4069 if (!info) 5954 4070 return -ENOMEM; 4071 + if (spec->use_alt_functions) { 4072 + info->own_chmap = true; 4073 + info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap 4074 + = ca0132_alt_chmaps; 4075 + } 5955 4076 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback; 5956 4077 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; 5957 4078 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = ··· 5965 4076 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; 5966 4077 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; 5967 4078 5968 - info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2"); 5969 - if (!info) 5970 - return -ENOMEM; 5971 - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; 5972 - info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; 5973 - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; 4079 + /* With the DSP enabled, desktops don't use this ADC. */ 4080 + if (spec->use_alt_functions) { 4081 + info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2"); 4082 + if (!info) 4083 + return -ENOMEM; 4084 + info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4085 + ca0132_pcm_analog_capture; 4086 + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; 4087 + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; 4088 + } 5974 4089 5975 4090 info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear"); 5976 4091 if (!info) ··· 6181 4288 } 6182 4289 6183 4290 /* 4291 + * Recon3Di r3di_setup_defaults sub functions. 4292 + */ 4293 + 4294 + static void r3di_dsp_scp_startup(struct hda_codec *codec) 4295 + { 4296 + unsigned int tmp; 4297 + 4298 + tmp = 0x00000000; 4299 + dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp); 4300 + 4301 + tmp = 0x00000001; 4302 + dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp); 4303 + 4304 + tmp = 0x00000004; 4305 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4306 + 4307 + tmp = 0x00000005; 4308 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4309 + 4310 + tmp = 0x00000000; 4311 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4312 + 4313 + } 4314 + 4315 + static void r3di_dsp_initial_mic_setup(struct hda_codec *codec) 4316 + { 4317 + unsigned int tmp; 4318 + 4319 + /* Mic 1 Setup */ 4320 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 4321 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 4322 + /* This ConnPointID is unique to Recon3Di. Haven't seen it elsewhere */ 4323 + chipio_set_conn_rate(codec, 0x0F, SR_96_000); 4324 + tmp = FLOAT_ONE; 4325 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 4326 + 4327 + /* Mic 2 Setup, even though it isn't connected on SBZ */ 4328 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN2, SR_96_000); 4329 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2, SR_96_000); 4330 + chipio_set_conn_rate(codec, 0x0F, SR_96_000); 4331 + tmp = FLOAT_ZERO; 4332 + dspio_set_uint_param(codec, 0x80, 0x01, tmp); 4333 + } 4334 + 4335 + /* 4336 + * Initialize Sound Blaster Z analog microphones. 4337 + */ 4338 + static void sbz_init_analog_mics(struct hda_codec *codec) 4339 + { 4340 + unsigned int tmp; 4341 + 4342 + /* Mic 1 Setup */ 4343 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 4344 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 4345 + tmp = FLOAT_THREE; 4346 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 4347 + 4348 + /* Mic 2 Setup, even though it isn't connected on SBZ */ 4349 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN2, SR_96_000); 4350 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2, SR_96_000); 4351 + tmp = FLOAT_ZERO; 4352 + dspio_set_uint_param(codec, 0x80, 0x01, tmp); 4353 + 4354 + } 4355 + 4356 + /* 4357 + * Sets the source of stream 0x14 to connpointID 0x48, and the destination 4358 + * connpointID to 0x91. If this isn't done, the destination is 0x71, and 4359 + * you get no sound. I'm guessing this has to do with the Sound Blaster Z 4360 + * having an updated DAC, which changes the destination to that DAC. 4361 + */ 4362 + static void sbz_connect_streams(struct hda_codec *codec) 4363 + { 4364 + struct ca0132_spec *spec = codec->spec; 4365 + 4366 + mutex_lock(&spec->chipio_mutex); 4367 + 4368 + codec_dbg(codec, "Connect Streams entered, mutex locked and loaded.\n"); 4369 + 4370 + chipio_set_stream_channels(codec, 0x0C, 6); 4371 + chipio_set_stream_control(codec, 0x0C, 1); 4372 + 4373 + /* This value is 0x43 for 96khz, and 0x83 for 192khz. */ 4374 + chipio_write_no_mutex(codec, 0x18a020, 0x00000043); 4375 + 4376 + /* Setup stream 0x14 with it's source and destination points */ 4377 + chipio_set_stream_source_dest(codec, 0x14, 0x48, 0x91); 4378 + chipio_set_conn_rate_no_mutex(codec, 0x48, SR_96_000); 4379 + chipio_set_conn_rate_no_mutex(codec, 0x91, SR_96_000); 4380 + chipio_set_stream_channels(codec, 0x14, 2); 4381 + chipio_set_stream_control(codec, 0x14, 1); 4382 + 4383 + codec_dbg(codec, "Connect Streams exited, mutex released.\n"); 4384 + 4385 + mutex_unlock(&spec->chipio_mutex); 4386 + 4387 + } 4388 + 4389 + /* 4390 + * Write data through ChipIO to setup proper stream destinations. 4391 + * Not sure how it exactly works, but it seems to direct data 4392 + * to different destinations. Example is f8 to c0, e0 to c0. 4393 + * All I know is, if you don't set these, you get no sound. 4394 + */ 4395 + static void sbz_chipio_startup_data(struct hda_codec *codec) 4396 + { 4397 + struct ca0132_spec *spec = codec->spec; 4398 + 4399 + mutex_lock(&spec->chipio_mutex); 4400 + codec_dbg(codec, "Startup Data entered, mutex locked and loaded.\n"); 4401 + 4402 + /* These control audio output */ 4403 + chipio_write_no_mutex(codec, 0x190060, 0x0001f8c0); 4404 + chipio_write_no_mutex(codec, 0x190064, 0x0001f9c1); 4405 + chipio_write_no_mutex(codec, 0x190068, 0x0001fac6); 4406 + chipio_write_no_mutex(codec, 0x19006c, 0x0001fbc7); 4407 + /* Signal to update I think */ 4408 + chipio_write_no_mutex(codec, 0x19042c, 0x00000001); 4409 + 4410 + chipio_set_stream_channels(codec, 0x0C, 6); 4411 + chipio_set_stream_control(codec, 0x0C, 1); 4412 + /* No clue what these control */ 4413 + chipio_write_no_mutex(codec, 0x190030, 0x0001e0c0); 4414 + chipio_write_no_mutex(codec, 0x190034, 0x0001e1c1); 4415 + chipio_write_no_mutex(codec, 0x190038, 0x0001e4c2); 4416 + chipio_write_no_mutex(codec, 0x19003c, 0x0001e5c3); 4417 + chipio_write_no_mutex(codec, 0x190040, 0x0001e2c4); 4418 + chipio_write_no_mutex(codec, 0x190044, 0x0001e3c5); 4419 + chipio_write_no_mutex(codec, 0x190048, 0x0001e8c6); 4420 + chipio_write_no_mutex(codec, 0x19004c, 0x0001e9c7); 4421 + chipio_write_no_mutex(codec, 0x190050, 0x0001ecc8); 4422 + chipio_write_no_mutex(codec, 0x190054, 0x0001edc9); 4423 + chipio_write_no_mutex(codec, 0x190058, 0x0001eaca); 4424 + chipio_write_no_mutex(codec, 0x19005c, 0x0001ebcb); 4425 + 4426 + chipio_write_no_mutex(codec, 0x19042c, 0x00000001); 4427 + 4428 + codec_dbg(codec, "Startup Data exited, mutex released.\n"); 4429 + mutex_unlock(&spec->chipio_mutex); 4430 + } 4431 + 4432 + /* 4433 + * Sound Blaster Z uses these after DSP is loaded. Weird SCP commands 4434 + * without a 0x20 source like normal. 4435 + */ 4436 + static void sbz_dsp_scp_startup(struct hda_codec *codec) 4437 + { 4438 + unsigned int tmp; 4439 + 4440 + tmp = 0x00000003; 4441 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4442 + 4443 + tmp = 0x00000000; 4444 + dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp); 4445 + 4446 + tmp = 0x00000001; 4447 + dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp); 4448 + 4449 + tmp = 0x00000004; 4450 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4451 + 4452 + tmp = 0x00000005; 4453 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4454 + 4455 + tmp = 0x00000000; 4456 + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp); 4457 + 4458 + } 4459 + 4460 + static void sbz_dsp_initial_mic_setup(struct hda_codec *codec) 4461 + { 4462 + unsigned int tmp; 4463 + 4464 + chipio_set_stream_control(codec, 0x03, 0); 4465 + chipio_set_stream_control(codec, 0x04, 0); 4466 + 4467 + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); 4468 + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); 4469 + 4470 + tmp = FLOAT_THREE; 4471 + dspio_set_uint_param(codec, 0x80, 0x00, tmp); 4472 + 4473 + chipio_set_stream_control(codec, 0x03, 1); 4474 + chipio_set_stream_control(codec, 0x04, 1); 4475 + 4476 + chipio_write(codec, 0x18b098, 0x0000000c); 4477 + chipio_write(codec, 0x18b09C, 0x0000000c); 4478 + } 4479 + 4480 + /* 6184 4481 * Setup default parameters for DSP 6185 4482 */ 6186 4483 static void ca0132_setup_defaults(struct hda_codec *codec) ··· 6415 4332 } 6416 4333 6417 4334 /* 4335 + * Setup default parameters for Recon3Di DSP. 4336 + */ 4337 + 4338 + static void r3di_setup_defaults(struct hda_codec *codec) 4339 + { 4340 + struct ca0132_spec *spec = codec->spec; 4341 + unsigned int tmp; 4342 + int num_fx; 4343 + int idx, i; 4344 + 4345 + if (spec->dsp_state != DSP_DOWNLOADED) 4346 + return; 4347 + 4348 + r3di_dsp_scp_startup(codec); 4349 + 4350 + r3di_dsp_initial_mic_setup(codec); 4351 + 4352 + /*remove DSP headroom*/ 4353 + tmp = FLOAT_ZERO; 4354 + dspio_set_uint_param(codec, 0x96, 0x3C, tmp); 4355 + 4356 + /* set WUH source */ 4357 + tmp = FLOAT_TWO; 4358 + dspio_set_uint_param(codec, 0x31, 0x00, tmp); 4359 + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000); 4360 + 4361 + /* Set speaker source? */ 4362 + dspio_set_uint_param(codec, 0x32, 0x00, tmp); 4363 + 4364 + r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED); 4365 + 4366 + /* Setup effect defaults */ 4367 + num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1; 4368 + for (idx = 0; idx < num_fx; idx++) { 4369 + for (i = 0; i <= ca0132_effects[idx].params; i++) { 4370 + dspio_set_uint_param(codec, 4371 + ca0132_effects[idx].mid, 4372 + ca0132_effects[idx].reqs[i], 4373 + ca0132_effects[idx].def_vals[i]); 4374 + } 4375 + } 4376 + 4377 + } 4378 + 4379 + /* 4380 + * Setup default parameters for the Sound Blaster Z DSP. A lot more going on 4381 + * than the Chromebook setup. 4382 + */ 4383 + static void sbz_setup_defaults(struct hda_codec *codec) 4384 + { 4385 + struct ca0132_spec *spec = codec->spec; 4386 + unsigned int tmp, stream_format; 4387 + int num_fx; 4388 + int idx, i; 4389 + 4390 + if (spec->dsp_state != DSP_DOWNLOADED) 4391 + return; 4392 + 4393 + sbz_dsp_scp_startup(codec); 4394 + 4395 + sbz_init_analog_mics(codec); 4396 + 4397 + sbz_connect_streams(codec); 4398 + 4399 + sbz_chipio_startup_data(codec); 4400 + 4401 + chipio_set_stream_control(codec, 0x03, 1); 4402 + chipio_set_stream_control(codec, 0x04, 1); 4403 + 4404 + /* 4405 + * Sets internal input loopback to off, used to have a switch to 4406 + * enable input loopback, but turned out to be way too buggy. 4407 + */ 4408 + tmp = FLOAT_ONE; 4409 + dspio_set_uint_param(codec, 0x37, 0x08, tmp); 4410 + dspio_set_uint_param(codec, 0x37, 0x10, tmp); 4411 + 4412 + /*remove DSP headroom*/ 4413 + tmp = FLOAT_ZERO; 4414 + dspio_set_uint_param(codec, 0x96, 0x3C, tmp); 4415 + 4416 + /* set WUH source */ 4417 + tmp = FLOAT_TWO; 4418 + dspio_set_uint_param(codec, 0x31, 0x00, tmp); 4419 + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000); 4420 + 4421 + /* Set speaker source? */ 4422 + dspio_set_uint_param(codec, 0x32, 0x00, tmp); 4423 + 4424 + sbz_dsp_initial_mic_setup(codec); 4425 + 4426 + 4427 + /* out, in effects + voicefx */ 4428 + num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1; 4429 + for (idx = 0; idx < num_fx; idx++) { 4430 + for (i = 0; i <= ca0132_effects[idx].params; i++) { 4431 + dspio_set_uint_param(codec, 4432 + ca0132_effects[idx].mid, 4433 + ca0132_effects[idx].reqs[i], 4434 + ca0132_effects[idx].def_vals[i]); 4435 + } 4436 + } 4437 + 4438 + /* 4439 + * Have to make a stream to bind the sound output to, otherwise 4440 + * you'll get dead audio. Before I did this, it would bind to an 4441 + * audio input, and would never work 4442 + */ 4443 + stream_format = snd_hdac_calc_stream_format(48000, 2, 4444 + SNDRV_PCM_FORMAT_S32_LE, 32, 0); 4445 + 4446 + snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id, 4447 + 0, stream_format); 4448 + 4449 + snd_hda_codec_cleanup_stream(codec, spec->dacs[0]); 4450 + 4451 + snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id, 4452 + 0, stream_format); 4453 + 4454 + snd_hda_codec_cleanup_stream(codec, spec->dacs[0]); 4455 + } 4456 + 4457 + /* 6418 4458 * Initialization of flags in chip 6419 4459 */ 6420 4460 static void ca0132_init_flags(struct hda_codec *codec) 6421 4461 { 6422 - chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); 6423 - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_COMMON_MODE, 0); 6424 - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_COMMON_MODE, 0); 6425 - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0); 6426 - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); 6427 - chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1); 4462 + struct ca0132_spec *spec = codec->spec; 4463 + 4464 + if (spec->use_alt_functions) { 4465 + chipio_set_control_flag(codec, CONTROL_FLAG_DSP_96KHZ, 1); 4466 + chipio_set_control_flag(codec, CONTROL_FLAG_DAC_96KHZ, 1); 4467 + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_B_96KHZ, 1); 4468 + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_96KHZ, 1); 4469 + chipio_set_control_flag(codec, CONTROL_FLAG_SRC_RATE_96KHZ, 1); 4470 + chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); 4471 + chipio_set_control_flag(codec, CONTROL_FLAG_SPDIF2OUT, 0); 4472 + chipio_set_control_flag(codec, 4473 + CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); 4474 + chipio_set_control_flag(codec, 4475 + CONTROL_FLAG_PORT_A_10KOHM_LOAD, 1); 4476 + } else { 4477 + chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); 4478 + chipio_set_control_flag(codec, 4479 + CONTROL_FLAG_PORT_A_COMMON_MODE, 0); 4480 + chipio_set_control_flag(codec, 4481 + CONTROL_FLAG_PORT_D_COMMON_MODE, 0); 4482 + chipio_set_control_flag(codec, 4483 + CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0); 4484 + chipio_set_control_flag(codec, 4485 + CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); 4486 + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1); 4487 + } 6428 4488 } 6429 4489 6430 4490 /* ··· 6575 4349 */ 6576 4350 static void ca0132_init_params(struct hda_codec *codec) 6577 4351 { 4352 + struct ca0132_spec *spec = codec->spec; 4353 + 4354 + if (spec->use_alt_functions) { 4355 + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000); 4356 + chipio_set_conn_rate(codec, 0x0B, SR_48_000); 4357 + chipio_set_control_param(codec, CONTROL_PARAM_SPDIF1_SOURCE, 0); 4358 + chipio_set_control_param(codec, 0, 0); 4359 + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); 4360 + } 4361 + 6578 4362 chipio_set_control_param(codec, CONTROL_PARAM_PORTA_160OHM_GAIN, 6); 6579 4363 chipio_set_control_param(codec, CONTROL_PARAM_PORTD_160OHM_GAIN, 6); 6580 4364 } ··· 6606 4370 static bool ca0132_download_dsp_images(struct hda_codec *codec) 6607 4371 { 6608 4372 bool dsp_loaded = false; 4373 + struct ca0132_spec *spec = codec->spec; 6609 4374 const struct dsp_image_seg *dsp_os_image; 6610 4375 const struct firmware *fw_entry; 6611 - 6612 - if (request_firmware(&fw_entry, EFX_FILE, codec->card->dev) != 0) 6613 - return false; 4376 + /* 4377 + * Alternate firmwares for different variants. The Recon3Di apparently 4378 + * can use the default firmware, but I'll leave the option in case 4379 + * it needs it again. 4380 + */ 4381 + switch (spec->quirk) { 4382 + case QUIRK_SBZ: 4383 + if (request_firmware(&fw_entry, SBZ_EFX_FILE, 4384 + codec->card->dev) != 0) { 4385 + codec_dbg(codec, "SBZ alt firmware not detected. "); 4386 + spec->alt_firmware_present = false; 4387 + } else { 4388 + codec_dbg(codec, "Sound Blaster Z firmware selected."); 4389 + spec->alt_firmware_present = true; 4390 + } 4391 + break; 4392 + case QUIRK_R3DI: 4393 + if (request_firmware(&fw_entry, R3DI_EFX_FILE, 4394 + codec->card->dev) != 0) { 4395 + codec_dbg(codec, "Recon3Di alt firmware not detected."); 4396 + spec->alt_firmware_present = false; 4397 + } else { 4398 + codec_dbg(codec, "Recon3Di firmware selected."); 4399 + spec->alt_firmware_present = true; 4400 + } 4401 + break; 4402 + default: 4403 + spec->alt_firmware_present = false; 4404 + break; 4405 + } 4406 + /* 4407 + * Use default ctefx.bin if no alt firmware is detected, or if none 4408 + * exists for your particular codec. 4409 + */ 4410 + if (!spec->alt_firmware_present) { 4411 + codec_dbg(codec, "Default firmware selected."); 4412 + if (request_firmware(&fw_entry, EFX_FILE, 4413 + codec->card->dev) != 0) 4414 + return false; 4415 + } 6614 4416 6615 4417 dsp_os_image = (struct dsp_image_seg *)(fw_entry->data); 6616 4418 if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) { ··· 6676 4402 return; /* don't retry failures */ 6677 4403 6678 4404 chipio_enable_clocks(codec); 6679 - spec->dsp_state = DSP_DOWNLOADING; 6680 - if (!ca0132_download_dsp_images(codec)) 6681 - spec->dsp_state = DSP_DOWNLOAD_FAILED; 6682 - else 6683 - spec->dsp_state = DSP_DOWNLOADED; 4405 + if (spec->dsp_state != DSP_DOWNLOADED) { 4406 + spec->dsp_state = DSP_DOWNLOADING; 6684 4407 6685 - if (spec->dsp_state == DSP_DOWNLOADED) 4408 + if (!ca0132_download_dsp_images(codec)) 4409 + spec->dsp_state = DSP_DOWNLOAD_FAILED; 4410 + else 4411 + spec->dsp_state = DSP_DOWNLOADED; 4412 + } 4413 + 4414 + /* For codecs using alt functions, this is already done earlier */ 4415 + if (spec->dsp_state == DSP_DOWNLOADED && (!spec->use_alt_functions)) 6686 4416 ca0132_set_dsp_msr(codec, true); 6687 4417 } 6688 4418 ··· 6732 4454 amic_callback); 6733 4455 snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP, 6734 4456 ca0132_process_dsp_response); 4457 + /* Front headphone jack detection */ 4458 + if (spec->use_alt_functions) 4459 + snd_hda_jack_detect_enable_callback(codec, 4460 + spec->unsol_tag_front_hp, hp_callback); 6735 4461 } 6736 4462 6737 4463 /* ··· 6758 4476 {} 6759 4477 }; 6760 4478 6761 - /* Other verbs tables. Sends after DSP download. */ 4479 + /* Other verbs tables. Sends after DSP download. */ 4480 + 6762 4481 static struct hda_verb ca0132_init_verbs0[] = { 6763 4482 /* chip init verbs */ 6764 4483 {0x15, 0x70D, 0xF0}, ··· 6789 4506 {0x15, 0x546, 0xC9}, 6790 4507 {0x15, 0x53B, 0xCE}, 6791 4508 {0x15, 0x5E8, 0xC9}, 6792 - {0x15, 0x717, 0x0D}, 6793 - {0x15, 0x718, 0x20}, 4509 + {} 4510 + }; 4511 + 4512 + /* Extra init verbs for SBZ */ 4513 + static struct hda_verb sbz_init_verbs[] = { 4514 + {0x15, 0x70D, 0x20}, 4515 + {0x15, 0x70E, 0x19}, 4516 + {0x15, 0x707, 0x00}, 4517 + {0x15, 0x539, 0xCE}, 4518 + {0x15, 0x546, 0xC9}, 4519 + {0x15, 0x70D, 0xB7}, 4520 + {0x15, 0x70E, 0x09}, 4521 + {0x15, 0x707, 0x10}, 4522 + {0x15, 0x70D, 0xAF}, 4523 + {0x15, 0x70E, 0x09}, 4524 + {0x15, 0x707, 0x01}, 4525 + {0x15, 0x707, 0x05}, 4526 + {0x15, 0x70D, 0x73}, 4527 + {0x15, 0x70E, 0x09}, 4528 + {0x15, 0x707, 0x14}, 4529 + {0x15, 0x6FF, 0xC4}, 6794 4530 {} 6795 4531 }; 6796 4532 ··· 6823 4521 mutex_init(&spec->chipio_mutex); 6824 4522 6825 4523 spec->cur_out_type = SPEAKER_OUT; 6826 - spec->cur_mic_type = DIGITAL_MIC; 4524 + if (!spec->use_alt_functions) 4525 + spec->cur_mic_type = DIGITAL_MIC; 4526 + else 4527 + spec->cur_mic_type = REAR_MIC; 4528 + 6827 4529 spec->cur_mic_boost = 0; 6828 4530 6829 4531 for (i = 0; i < VNODES_COUNT; i++) { ··· 6845 4539 on = (unsigned int)ca0132_effects[i].reqs[0]; 6846 4540 spec->effects_switch[i] = on ? 1 : 0; 6847 4541 } 4542 + /* 4543 + * Sets defaults for the effect slider controls, only for alternative 4544 + * ca0132 codecs. Also sets x-bass crossover frequency to 80hz. 4545 + */ 4546 + if (spec->use_alt_controls) { 4547 + spec->xbass_xover_freq = 8; 4548 + for (i = 0; i < EFFECT_LEVEL_SLIDERS; i++) 4549 + spec->fx_ctl_val[i] = effect_slider_defaults[i]; 4550 + } 6848 4551 6849 4552 spec->voicefx_val = 0; 6850 4553 spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID] = 1; ··· 6864 4549 #endif 6865 4550 } 6866 4551 4552 + /* 4553 + * Recon3Di exit specific commands. 4554 + */ 4555 + /* prevents popping noise on shutdown */ 4556 + static void r3di_gpio_shutdown(struct hda_codec *codec) 4557 + { 4558 + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0x00); 4559 + } 4560 + 4561 + /* 4562 + * Sound Blaster Z exit specific commands. 4563 + */ 4564 + static void sbz_region2_exit(struct hda_codec *codec) 4565 + { 4566 + struct ca0132_spec *spec = codec->spec; 4567 + unsigned int i; 4568 + 4569 + for (i = 0; i < 4; i++) 4570 + writeb(0x0, spec->mem_base + 0x100); 4571 + for (i = 0; i < 8; i++) 4572 + writeb(0xb3, spec->mem_base + 0x304); 4573 + /* 4574 + * I believe these are GPIO, with the right most hex digit being the 4575 + * gpio pin, and the second digit being on or off. We see this more in 4576 + * the input/output select functions. 4577 + */ 4578 + writew(0x0000, spec->mem_base + 0x320); 4579 + writew(0x0001, spec->mem_base + 0x320); 4580 + writew(0x0104, spec->mem_base + 0x320); 4581 + writew(0x0005, spec->mem_base + 0x320); 4582 + writew(0x0007, spec->mem_base + 0x320); 4583 + } 4584 + 4585 + static void sbz_set_pin_ctl_default(struct hda_codec *codec) 4586 + { 4587 + hda_nid_t pins[5] = {0x0B, 0x0C, 0x0E, 0x12, 0x13}; 4588 + unsigned int i; 4589 + 4590 + snd_hda_codec_write(codec, 0x11, 0, 4591 + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40); 4592 + 4593 + for (i = 0; i < 5; i++) 4594 + snd_hda_codec_write(codec, pins[i], 0, 4595 + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00); 4596 + } 4597 + 4598 + static void sbz_clear_unsolicited(struct hda_codec *codec) 4599 + { 4600 + hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13}; 4601 + unsigned int i; 4602 + 4603 + for (i = 0; i < 7; i++) { 4604 + snd_hda_codec_write(codec, pins[i], 0, 4605 + AC_VERB_SET_UNSOLICITED_ENABLE, 0x00); 4606 + } 4607 + } 4608 + 4609 + /* On shutdown, sends commands in sets of three */ 4610 + static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir, 4611 + int mask, int data) 4612 + { 4613 + if (dir >= 0) 4614 + snd_hda_codec_write(codec, 0x01, 0, 4615 + AC_VERB_SET_GPIO_DIRECTION, dir); 4616 + if (mask >= 0) 4617 + snd_hda_codec_write(codec, 0x01, 0, 4618 + AC_VERB_SET_GPIO_MASK, mask); 4619 + 4620 + if (data >= 0) 4621 + snd_hda_codec_write(codec, 0x01, 0, 4622 + AC_VERB_SET_GPIO_DATA, data); 4623 + } 4624 + 4625 + static void sbz_exit_chip(struct hda_codec *codec) 4626 + { 4627 + chipio_set_stream_control(codec, 0x03, 0); 4628 + chipio_set_stream_control(codec, 0x04, 0); 4629 + 4630 + /* Mess with GPIO */ 4631 + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1); 4632 + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05); 4633 + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01); 4634 + 4635 + chipio_set_stream_control(codec, 0x14, 0); 4636 + chipio_set_stream_control(codec, 0x0C, 0); 4637 + 4638 + chipio_set_conn_rate(codec, 0x41, SR_192_000); 4639 + chipio_set_conn_rate(codec, 0x91, SR_192_000); 4640 + 4641 + chipio_write(codec, 0x18a020, 0x00000083); 4642 + 4643 + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x03); 4644 + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07); 4645 + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06); 4646 + 4647 + chipio_set_stream_control(codec, 0x0C, 0); 4648 + 4649 + chipio_set_control_param(codec, 0x0D, 0x24); 4650 + 4651 + sbz_clear_unsolicited(codec); 4652 + sbz_set_pin_ctl_default(codec); 4653 + 4654 + snd_hda_codec_write(codec, 0x0B, 0, 4655 + AC_VERB_SET_EAPD_BTLENABLE, 0x00); 4656 + 4657 + if (dspload_is_loaded(codec)) 4658 + dsp_reset(codec); 4659 + 4660 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4661 + VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00); 4662 + 4663 + sbz_region2_exit(codec); 4664 + } 4665 + 6867 4666 static void ca0132_exit_chip(struct hda_codec *codec) 6868 4667 { 6869 4668 /* put any chip cleanup stuffs here. */ ··· 6986 4557 dsp_reset(codec); 6987 4558 } 6988 4559 4560 + /* 4561 + * This fixes a problem that was hard to reproduce. Very rarely, I would 4562 + * boot up, and there would be no sound, but the DSP indicated it had loaded 4563 + * properly. I did a few memory dumps to see if anything was different, and 4564 + * there were a few areas of memory uninitialized with a1a2a3a4. This function 4565 + * checks if those areas are uninitialized, and if they are, it'll attempt to 4566 + * reload the card 3 times. Usually it fixes by the second. 4567 + */ 4568 + static void sbz_dsp_startup_check(struct hda_codec *codec) 4569 + { 4570 + struct ca0132_spec *spec = codec->spec; 4571 + unsigned int dsp_data_check[4]; 4572 + unsigned int cur_address = 0x390; 4573 + unsigned int i; 4574 + unsigned int failure = 0; 4575 + unsigned int reload = 3; 4576 + 4577 + if (spec->startup_check_entered) 4578 + return; 4579 + 4580 + spec->startup_check_entered = true; 4581 + 4582 + for (i = 0; i < 4; i++) { 4583 + chipio_read(codec, cur_address, &dsp_data_check[i]); 4584 + cur_address += 0x4; 4585 + } 4586 + for (i = 0; i < 4; i++) { 4587 + if (dsp_data_check[i] == 0xa1a2a3a4) 4588 + failure = 1; 4589 + } 4590 + 4591 + codec_dbg(codec, "Startup Check: %d ", failure); 4592 + if (failure) 4593 + codec_info(codec, "DSP not initialized properly. Attempting to fix."); 4594 + /* 4595 + * While the failure condition is true, and we haven't reached our 4596 + * three reload limit, continue trying to reload the driver and 4597 + * fix the issue. 4598 + */ 4599 + while (failure && (reload != 0)) { 4600 + codec_info(codec, "Reloading... Tries left: %d", reload); 4601 + sbz_exit_chip(codec); 4602 + spec->dsp_state = DSP_DOWNLOAD_INIT; 4603 + codec->patch_ops.init(codec); 4604 + failure = 0; 4605 + for (i = 0; i < 4; i++) { 4606 + chipio_read(codec, cur_address, &dsp_data_check[i]); 4607 + cur_address += 0x4; 4608 + } 4609 + for (i = 0; i < 4; i++) { 4610 + if (dsp_data_check[i] == 0xa1a2a3a4) 4611 + failure = 1; 4612 + } 4613 + reload--; 4614 + } 4615 + 4616 + if (!failure && reload < 3) 4617 + codec_info(codec, "DSP fixed."); 4618 + 4619 + if (!failure) 4620 + return; 4621 + 4622 + codec_info(codec, "DSP failed to initialize properly. Either try a full shutdown or a suspend to clear the internal memory."); 4623 + } 4624 + 4625 + /* 4626 + * This is for the extra volume verbs 0x797 (left) and 0x798 (right). These add 4627 + * extra precision for decibel values. If you had the dB value in floating point 4628 + * you would take the value after the decimal point, multiply by 64, and divide 4629 + * by 2. So for 8.59, it's (59 * 64) / 100. Useful if someone wanted to 4630 + * implement fixed point or floating point dB volumes. For now, I'll set them 4631 + * to 0 just incase a value has lingered from a boot into Windows. 4632 + */ 4633 + static void ca0132_alt_vol_setup(struct hda_codec *codec) 4634 + { 4635 + snd_hda_codec_write(codec, 0x02, 0, 0x797, 0x00); 4636 + snd_hda_codec_write(codec, 0x02, 0, 0x798, 0x00); 4637 + snd_hda_codec_write(codec, 0x03, 0, 0x797, 0x00); 4638 + snd_hda_codec_write(codec, 0x03, 0, 0x798, 0x00); 4639 + snd_hda_codec_write(codec, 0x04, 0, 0x797, 0x00); 4640 + snd_hda_codec_write(codec, 0x04, 0, 0x798, 0x00); 4641 + snd_hda_codec_write(codec, 0x07, 0, 0x797, 0x00); 4642 + snd_hda_codec_write(codec, 0x07, 0, 0x798, 0x00); 4643 + } 4644 + 4645 + /* 4646 + * Extra commands that don't really fit anywhere else. 4647 + */ 4648 + static void sbz_pre_dsp_setup(struct hda_codec *codec) 4649 + { 4650 + struct ca0132_spec *spec = codec->spec; 4651 + 4652 + writel(0x00820680, spec->mem_base + 0x01C); 4653 + writel(0x00820680, spec->mem_base + 0x01C); 4654 + 4655 + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfc); 4656 + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfd); 4657 + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfe); 4658 + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xff); 4659 + 4660 + chipio_write(codec, 0x18b0a4, 0x000000c2); 4661 + 4662 + snd_hda_codec_write(codec, 0x11, 0, 4663 + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44); 4664 + } 4665 + 4666 + /* 4667 + * Extra commands that don't really fit anywhere else. 4668 + */ 4669 + static void r3di_pre_dsp_setup(struct hda_codec *codec) 4670 + { 4671 + chipio_write(codec, 0x18b0a4, 0x000000c2); 4672 + 4673 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4674 + VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x1E); 4675 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4676 + VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x1C); 4677 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4678 + VENDOR_CHIPIO_8051_DATA_WRITE, 0x5B); 4679 + 4680 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4681 + VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20); 4682 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4683 + VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19); 4684 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4685 + VENDOR_CHIPIO_8051_DATA_WRITE, 0x00); 4686 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4687 + VENDOR_CHIPIO_8051_DATA_WRITE, 0x40); 4688 + 4689 + snd_hda_codec_write(codec, 0x11, 0, 4690 + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x04); 4691 + } 4692 + 4693 + 4694 + /* 4695 + * These are sent before the DSP is downloaded. Not sure 4696 + * what they do, or if they're necessary. Could possibly 4697 + * be removed. Figure they're better to leave in. 4698 + */ 4699 + static void sbz_region2_startup(struct hda_codec *codec) 4700 + { 4701 + struct ca0132_spec *spec = codec->spec; 4702 + 4703 + writel(0x00000000, spec->mem_base + 0x400); 4704 + writel(0x00000000, spec->mem_base + 0x408); 4705 + writel(0x00000000, spec->mem_base + 0x40C); 4706 + writel(0x00880680, spec->mem_base + 0x01C); 4707 + writel(0x00000083, spec->mem_base + 0xC0C); 4708 + writel(0x00000030, spec->mem_base + 0xC00); 4709 + writel(0x00000000, spec->mem_base + 0xC04); 4710 + writel(0x00000003, spec->mem_base + 0xC0C); 4711 + writel(0x00000003, spec->mem_base + 0xC0C); 4712 + writel(0x00000003, spec->mem_base + 0xC0C); 4713 + writel(0x00000003, spec->mem_base + 0xC0C); 4714 + writel(0x000000C1, spec->mem_base + 0xC08); 4715 + writel(0x000000F1, spec->mem_base + 0xC08); 4716 + writel(0x00000001, spec->mem_base + 0xC08); 4717 + writel(0x000000C7, spec->mem_base + 0xC08); 4718 + writel(0x000000C1, spec->mem_base + 0xC08); 4719 + writel(0x00000080, spec->mem_base + 0xC04); 4720 + } 4721 + 4722 + /* 4723 + * Extra init functions for alternative ca0132 codecs. Done 4724 + * here so they don't clutter up the main ca0132_init function 4725 + * anymore than they have to. 4726 + */ 4727 + static void ca0132_alt_init(struct hda_codec *codec) 4728 + { 4729 + struct ca0132_spec *spec = codec->spec; 4730 + 4731 + ca0132_alt_vol_setup(codec); 4732 + 4733 + switch (spec->quirk) { 4734 + case QUIRK_SBZ: 4735 + codec_dbg(codec, "SBZ alt_init"); 4736 + ca0132_gpio_init(codec); 4737 + sbz_pre_dsp_setup(codec); 4738 + snd_hda_sequence_write(codec, spec->chip_init_verbs); 4739 + snd_hda_sequence_write(codec, spec->sbz_init_verbs); 4740 + break; 4741 + case QUIRK_R3DI: 4742 + codec_dbg(codec, "R3DI alt_init"); 4743 + ca0132_gpio_init(codec); 4744 + ca0132_gpio_setup(codec); 4745 + r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADING); 4746 + r3di_pre_dsp_setup(codec); 4747 + snd_hda_sequence_write(codec, spec->chip_init_verbs); 4748 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x6FF, 0xC4); 4749 + break; 4750 + } 4751 + } 4752 + 6989 4753 static int ca0132_init(struct hda_codec *codec) 6990 4754 { 6991 4755 struct ca0132_spec *spec = codec->spec; 6992 4756 struct auto_pin_cfg *cfg = &spec->autocfg; 6993 4757 int i; 4758 + bool dsp_loaded; 4759 + 4760 + /* 4761 + * If the DSP is already downloaded, and init has been entered again, 4762 + * there's only two reasons for it. One, the codec has awaken from a 4763 + * suspended state, and in that case dspload_is_loaded will return 4764 + * false, and the init will be ran again. The other reason it gets 4765 + * re entered is on startup for some reason it triggers a suspend and 4766 + * resume state. In this case, it will check if the DSP is downloaded, 4767 + * and not run the init function again. For codecs using alt_functions, 4768 + * it will check if the DSP is loaded properly. 4769 + */ 4770 + if (spec->dsp_state == DSP_DOWNLOADED) { 4771 + dsp_loaded = dspload_is_loaded(codec); 4772 + if (!dsp_loaded) { 4773 + spec->dsp_reload = true; 4774 + spec->dsp_state = DSP_DOWNLOAD_INIT; 4775 + } else { 4776 + if (spec->quirk == QUIRK_SBZ) 4777 + sbz_dsp_startup_check(codec); 4778 + return 0; 4779 + } 4780 + } 6994 4781 6995 4782 if (spec->dsp_state != DSP_DOWNLOAD_FAILED) 6996 4783 spec->dsp_state = DSP_DOWNLOAD_INIT; 6997 4784 spec->curr_chip_addx = INVALID_CHIP_ADDRESS; 6998 4785 4786 + if (spec->quirk == QUIRK_SBZ) 4787 + sbz_region2_startup(codec); 4788 + 6999 4789 snd_hda_power_up_pm(codec); 7000 4790 7001 4791 ca0132_init_unsol(codec); 7002 - 7003 4792 ca0132_init_params(codec); 7004 4793 ca0132_init_flags(codec); 4794 + 7005 4795 snd_hda_sequence_write(codec, spec->base_init_verbs); 4796 + 4797 + if (spec->quirk != QUIRK_NONE) 4798 + ca0132_alt_init(codec); 4799 + 7006 4800 ca0132_download_dsp(codec); 4801 + 7007 4802 ca0132_refresh_widget_caps(codec); 7008 - ca0132_setup_defaults(codec); 7009 - ca0132_init_analog_mic2(codec); 7010 - ca0132_init_dmic(codec); 4803 + 4804 + if (spec->quirk == QUIRK_SBZ) 4805 + writew(0x0107, spec->mem_base + 0x320); 4806 + 4807 + switch (spec->quirk) { 4808 + case QUIRK_R3DI: 4809 + r3di_setup_defaults(codec); 4810 + break; 4811 + case QUIRK_NONE: 4812 + case QUIRK_ALIENWARE: 4813 + ca0132_setup_defaults(codec); 4814 + ca0132_init_analog_mic2(codec); 4815 + ca0132_init_dmic(codec); 4816 + break; 4817 + } 7011 4818 7012 4819 for (i = 0; i < spec->num_outputs; i++) 7013 4820 init_output(codec, spec->out_pins[i], spec->dacs[0]); ··· 7255 4590 7256 4591 init_input(codec, cfg->dig_in_pin, spec->dig_in); 7257 4592 7258 - snd_hda_sequence_write(codec, spec->chip_init_verbs); 7259 - snd_hda_sequence_write(codec, spec->spec_init_verbs); 4593 + if (!spec->use_alt_functions) { 4594 + snd_hda_sequence_write(codec, spec->chip_init_verbs); 4595 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4596 + VENDOR_CHIPIO_PARAM_EX_ID_SET, 0x0D); 4597 + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 4598 + VENDOR_CHIPIO_PARAM_EX_VALUE_SET, 0x20); 4599 + } 7260 4600 7261 - ca0132_select_out(codec); 7262 - ca0132_select_mic(codec); 4601 + if (spec->quirk == QUIRK_SBZ) 4602 + ca0132_gpio_setup(codec); 4603 + 4604 + snd_hda_sequence_write(codec, spec->spec_init_verbs); 4605 + switch (spec->quirk) { 4606 + case QUIRK_SBZ: 4607 + sbz_setup_defaults(codec); 4608 + ca0132_alt_select_out(codec); 4609 + ca0132_alt_select_in(codec); 4610 + break; 4611 + case QUIRK_R3DI: 4612 + ca0132_alt_select_out(codec); 4613 + ca0132_alt_select_in(codec); 4614 + break; 4615 + default: 4616 + ca0132_select_out(codec); 4617 + ca0132_select_mic(codec); 4618 + break; 4619 + } 7263 4620 7264 4621 snd_hda_jack_report_sync(codec); 4622 + 4623 + /* 4624 + * Re set the PlayEnhancement switch on a resume event, because the 4625 + * controls will not be reloaded. 4626 + */ 4627 + if (spec->dsp_reload) { 4628 + spec->dsp_reload = false; 4629 + ca0132_pe_switch_set(codec); 4630 + } 7265 4631 7266 4632 snd_hda_power_down_pm(codec); 7267 4633 ··· 7305 4609 7306 4610 cancel_delayed_work_sync(&spec->unsol_hp_work); 7307 4611 snd_hda_power_up(codec); 7308 - snd_hda_sequence_write(codec, spec->base_exit_verbs); 7309 - ca0132_exit_chip(codec); 4612 + switch (spec->quirk) { 4613 + case QUIRK_SBZ: 4614 + sbz_exit_chip(codec); 4615 + break; 4616 + case QUIRK_R3DI: 4617 + r3di_gpio_shutdown(codec); 4618 + snd_hda_sequence_write(codec, spec->base_exit_verbs); 4619 + ca0132_exit_chip(codec); 4620 + break; 4621 + default: 4622 + snd_hda_sequence_write(codec, spec->base_exit_verbs); 4623 + ca0132_exit_chip(codec); 4624 + break; 4625 + } 7310 4626 snd_hda_power_down(codec); 4627 + if (spec->mem_base) 4628 + iounmap(spec->mem_base); 7311 4629 kfree(spec->spec_init_verbs); 7312 4630 kfree(codec->spec); 4631 + } 4632 + 4633 + static void ca0132_reboot_notify(struct hda_codec *codec) 4634 + { 4635 + codec->patch_ops.free(codec); 7313 4636 } 7314 4637 7315 4638 static const struct hda_codec_ops ca0132_patch_ops = { ··· 7337 4622 .init = ca0132_init, 7338 4623 .free = ca0132_free, 7339 4624 .unsol_event = snd_hda_jack_unsol_event, 4625 + .reboot_notify = ca0132_reboot_notify, 7340 4626 }; 7341 4627 7342 4628 static void ca0132_config(struct hda_codec *codec) ··· 7351 4635 7352 4636 spec->multiout.dac_nids = spec->dacs; 7353 4637 spec->multiout.num_dacs = 3; 7354 - spec->multiout.max_channels = 2; 7355 4638 7356 - if (spec->quirk == QUIRK_ALIENWARE) { 4639 + if (!spec->use_alt_functions) 4640 + spec->multiout.max_channels = 2; 4641 + else 4642 + spec->multiout.max_channels = 6; 4643 + 4644 + switch (spec->quirk) { 4645 + case QUIRK_ALIENWARE: 7357 4646 codec_dbg(codec, "ca0132_config: QUIRK_ALIENWARE applied.\n"); 7358 4647 snd_hda_apply_pincfgs(codec, alienware_pincfgs); 7359 4648 ··· 7378 4657 spec->input_pins[2] = 0x13; 7379 4658 spec->shared_mic_nid = 0x7; 7380 4659 spec->unsol_tag_amic1 = 0x11; 7381 - } else { 4660 + break; 4661 + case QUIRK_SBZ: 4662 + codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__); 4663 + snd_hda_apply_pincfgs(codec, sbz_pincfgs); 4664 + 4665 + spec->num_outputs = 2; 4666 + spec->out_pins[0] = 0x0B; /* Line out */ 4667 + spec->out_pins[1] = 0x0F; /* Rear headphone out */ 4668 + spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/ 4669 + spec->out_pins[3] = 0x11; /* Rear surround */ 4670 + spec->shared_out_nid = 0x2; 4671 + spec->unsol_tag_hp = spec->out_pins[1]; 4672 + spec->unsol_tag_front_hp = spec->out_pins[2]; 4673 + 4674 + spec->adcs[0] = 0x7; /* Rear Mic / Line-in */ 4675 + spec->adcs[1] = 0x8; /* Front Mic, but only if no DSP */ 4676 + spec->adcs[2] = 0xa; /* what u hear */ 4677 + 4678 + spec->num_inputs = 2; 4679 + spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */ 4680 + spec->input_pins[1] = 0x13; /* What U Hear */ 4681 + spec->shared_mic_nid = 0x7; 4682 + spec->unsol_tag_amic1 = spec->input_pins[0]; 4683 + 4684 + /* SPDIF I/O */ 4685 + spec->dig_out = 0x05; 4686 + spec->multiout.dig_out_nid = spec->dig_out; 4687 + cfg->dig_out_pins[0] = 0x0c; 4688 + cfg->dig_outs = 1; 4689 + cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; 4690 + spec->dig_in = 0x09; 4691 + cfg->dig_in_pin = 0x0e; 4692 + cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; 4693 + break; 4694 + case QUIRK_R3DI: 4695 + codec_dbg(codec, "%s: QUIRK_R3DI applied.\n", __func__); 4696 + snd_hda_apply_pincfgs(codec, r3di_pincfgs); 4697 + 4698 + spec->num_outputs = 2; 4699 + spec->out_pins[0] = 0x0B; /* Line out */ 4700 + spec->out_pins[1] = 0x0F; /* Rear headphone out */ 4701 + spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/ 4702 + spec->out_pins[3] = 0x11; /* Rear surround */ 4703 + spec->shared_out_nid = 0x2; 4704 + spec->unsol_tag_hp = spec->out_pins[1]; 4705 + spec->unsol_tag_front_hp = spec->out_pins[2]; 4706 + 4707 + spec->adcs[0] = 0x07; /* Rear Mic / Line-in */ 4708 + spec->adcs[1] = 0x08; /* Front Mic, but only if no DSP */ 4709 + spec->adcs[2] = 0x0a; /* what u hear */ 4710 + 4711 + spec->num_inputs = 2; 4712 + spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */ 4713 + spec->input_pins[1] = 0x13; /* What U Hear */ 4714 + spec->shared_mic_nid = 0x7; 4715 + spec->unsol_tag_amic1 = spec->input_pins[0]; 4716 + 4717 + /* SPDIF I/O */ 4718 + spec->dig_out = 0x05; 4719 + spec->multiout.dig_out_nid = spec->dig_out; 4720 + cfg->dig_out_pins[0] = 0x0c; 4721 + cfg->dig_outs = 1; 4722 + cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; 4723 + break; 4724 + default: 7382 4725 spec->num_outputs = 2; 7383 4726 spec->out_pins[0] = 0x0b; /* speaker out */ 7384 4727 spec->out_pins[1] = 0x10; /* headphone out */ ··· 7469 4684 spec->dig_in = 0x09; 7470 4685 cfg->dig_in_pin = 0x0e; 7471 4686 cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; 4687 + break; 7472 4688 } 7473 4689 } 7474 4690 ··· 7480 4694 struct ca0132_spec *spec = codec->spec; 7481 4695 7482 4696 spec->chip_init_verbs = ca0132_init_verbs0; 4697 + if (spec->quirk == QUIRK_SBZ) 4698 + spec->sbz_init_verbs = sbz_init_verbs; 7483 4699 spec->spec_init_verbs = kzalloc(sizeof(struct hda_verb) * NUM_SPEC_VERBS, GFP_KERNEL); 7484 4700 if (!spec->spec_init_verbs) 7485 4701 return -ENOMEM; ··· 7545 4757 else 7546 4758 spec->quirk = QUIRK_NONE; 7547 4759 4760 + /* Setup BAR Region 2 for Sound Blaster Z */ 4761 + if (spec->quirk == QUIRK_SBZ) { 4762 + spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20); 4763 + if (spec->mem_base == NULL) { 4764 + codec_warn(codec, "pci_iomap failed!"); 4765 + codec_info(codec, "perhaps this is not an SBZ?"); 4766 + spec->quirk = QUIRK_NONE; 4767 + } 4768 + } 4769 + 7548 4770 spec->dsp_state = DSP_DOWNLOAD_INIT; 7549 4771 spec->num_mixers = 1; 7550 - spec->mixers[0] = ca0132_mixer; 4772 + 4773 + /* Set which mixers each quirk uses. */ 4774 + switch (spec->quirk) { 4775 + case QUIRK_SBZ: 4776 + spec->mixers[0] = sbz_mixer; 4777 + snd_hda_codec_set_name(codec, "Sound Blaster Z"); 4778 + break; 4779 + case QUIRK_R3DI: 4780 + spec->mixers[0] = r3di_mixer; 4781 + snd_hda_codec_set_name(codec, "Recon3Di"); 4782 + break; 4783 + default: 4784 + spec->mixers[0] = ca0132_mixer; 4785 + break; 4786 + } 4787 + 4788 + /* Setup whether or not to use alt functions/controls */ 4789 + switch (spec->quirk) { 4790 + case QUIRK_SBZ: 4791 + case QUIRK_R3DI: 4792 + spec->use_alt_controls = true; 4793 + spec->use_alt_functions = true; 4794 + break; 4795 + default: 4796 + spec->use_alt_controls = false; 4797 + spec->use_alt_functions = false; 4798 + break; 4799 + } 7551 4800 7552 4801 spec->base_init_verbs = ca0132_base_init_verbs; 7553 4802 spec->base_exit_verbs = ca0132_base_exit_verbs;
+4 -3
sound/pci/hda/patch_conexant.c
··· 588 588 const struct hda_fixup *fix, int action) 589 589 { 590 590 struct conexant_spec *spec = codec->spec; 591 + struct snd_kcontrol_new *kctl; 591 592 int i; 592 593 593 594 if (action != HDA_FIXUP_ACT_PROBE) ··· 607 606 snd_hda_codec_set_pin_target(codec, 0x1a, PIN_VREF50); 608 607 609 608 /* override mic boost control */ 610 - for (i = 0; i < spec->gen.kctls.used; i++) { 611 - struct snd_kcontrol_new *kctl = 612 - snd_array_elem(&spec->gen.kctls, i); 609 + snd_array_for_each(&spec->gen.kctls, i, kctl) { 613 610 if (!strcmp(kctl->name, "Mic Boost Volume")) { 614 611 kctl->put = olpc_xo_mic_boost_put; 615 612 break; ··· 964 965 SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), 965 966 SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), 966 967 SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), 968 + SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE), 967 969 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 968 970 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 969 971 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), ··· 998 998 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, 999 999 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, 1000 1000 { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, 1001 + { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, 1001 1002 {} 1002 1003 }; 1003 1004
+1 -1
sound/pci/hda/patch_hdmi.c
··· 510 510 511 511 snd_info_set_text_ops(entry, per_pin, print_eld_info); 512 512 entry->c.text.write = write_eld_info; 513 - entry->mode |= S_IWUSR; 513 + entry->mode |= 0200; 514 514 per_pin->proc_entry = entry; 515 515 516 516 return 0;
+41 -14
sound/pci/hda/patch_realtek.c
··· 2830 2830 2831 2831 static void alc286_shutup(struct hda_codec *codec) 2832 2832 { 2833 + const struct hda_pincfg *pin; 2833 2834 int i; 2834 2835 int mic_pin = find_ext_mic_pin(codec); 2835 2836 /* don't shut up pins when unloading the driver; otherwise it breaks ··· 2838 2837 */ 2839 2838 if (codec->bus->shutdown) 2840 2839 return; 2841 - for (i = 0; i < codec->init_pins.used; i++) { 2842 - struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); 2840 + snd_array_for_each(&codec->init_pins, i, pin) { 2843 2841 /* use read here for syncing after issuing each verb */ 2844 2842 if (pin->nid != mic_pin) 2845 2843 snd_hda_codec_read(codec, pin->nid, 0, ··· 3653 3653 } 3654 3654 } 3655 3655 3656 - static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, 3657 - const struct hda_fixup *fix, int action) 3656 + static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec, 3657 + const struct hda_fixup *fix, 3658 + int action, hda_nid_t pin) 3658 3659 { 3659 3660 struct alc_spec *spec = codec->spec; 3661 + 3660 3662 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3661 3663 spec->mute_led_polarity = 0; 3662 - spec->mute_led_nid = 0x18; 3664 + spec->mute_led_nid = pin; 3663 3665 spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 3664 3666 spec->gen.vmaster_mute_enum = 1; 3665 3667 codec->power_filter = led_power_filter; 3666 3668 } 3667 3669 } 3668 3670 3671 + static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, 3672 + const struct hda_fixup *fix, int action) 3673 + { 3674 + alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x18); 3675 + } 3676 + 3669 3677 static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, 3670 3678 const struct hda_fixup *fix, int action) 3671 3679 { 3672 - struct alc_spec *spec = codec->spec; 3673 - if (action == HDA_FIXUP_ACT_PRE_PROBE) { 3674 - spec->mute_led_polarity = 0; 3675 - spec->mute_led_nid = 0x19; 3676 - spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; 3677 - spec->gen.vmaster_mute_enum = 1; 3678 - codec->power_filter = led_power_filter; 3679 - } 3680 + alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x19); 3681 + } 3682 + 3683 + static void alc269_fixup_hp_mute_led_mic3(struct hda_codec *codec, 3684 + const struct hda_fixup *fix, int action) 3685 + { 3686 + alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1b); 3680 3687 } 3681 3688 3682 3689 /* update LED status via GPIO */ ··· 5394 5387 /* for dell wmi mic mute led */ 5395 5388 #include "dell_wmi_helper.c" 5396 5389 5390 + /* for alc295_fixup_hp_top_speakers */ 5391 + #include "hp_x360_helper.c" 5392 + 5397 5393 enum { 5398 5394 ALC269_FIXUP_SONY_VAIO, 5399 5395 ALC275_FIXUP_SONY_VAIO_GPIO2, ··· 5423 5413 ALC269_FIXUP_HP_MUTE_LED, 5424 5414 ALC269_FIXUP_HP_MUTE_LED_MIC1, 5425 5415 ALC269_FIXUP_HP_MUTE_LED_MIC2, 5416 + ALC269_FIXUP_HP_MUTE_LED_MIC3, 5426 5417 ALC269_FIXUP_HP_GPIO_LED, 5427 5418 ALC269_FIXUP_HP_GPIO_MIC1_LED, 5428 5419 ALC269_FIXUP_HP_LINE1_MIC1_LED, ··· 5517 5506 ALC298_FIXUP_TPT470_DOCK, 5518 5507 ALC255_FIXUP_DUMMY_LINEOUT_VERB, 5519 5508 ALC255_FIXUP_DELL_HEADSET_MIC, 5509 + ALC295_FIXUP_HP_X360, 5520 5510 }; 5521 5511 5522 5512 static const struct hda_fixup alc269_fixups[] = { ··· 5683 5671 [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { 5684 5672 .type = HDA_FIXUP_FUNC, 5685 5673 .v.func = alc269_fixup_hp_mute_led_mic2, 5674 + }, 5675 + [ALC269_FIXUP_HP_MUTE_LED_MIC3] = { 5676 + .type = HDA_FIXUP_FUNC, 5677 + .v.func = alc269_fixup_hp_mute_led_mic3, 5686 5678 }, 5687 5679 [ALC269_FIXUP_HP_GPIO_LED] = { 5688 5680 .type = HDA_FIXUP_FUNC, ··· 6391 6375 .chained = true, 6392 6376 .chain_id = ALC269_FIXUP_HEADSET_MIC 6393 6377 }, 6378 + [ALC295_FIXUP_HP_X360] = { 6379 + .type = HDA_FIXUP_FUNC, 6380 + .v.func = alc295_fixup_hp_top_speakers, 6381 + .chained = true, 6382 + .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3 6383 + } 6394 6384 }; 6395 6385 6396 6386 static const struct snd_pci_quirk alc269_fixup_tbl[] = { ··· 6516 6494 SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), 6517 6495 SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), 6518 6496 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), 6497 + SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), 6519 6498 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 6520 6499 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 6521 6500 SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), ··· 6603 6580 SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), 6604 6581 SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), 6605 6582 SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), 6606 - SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), 6607 6583 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), 6608 6584 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), 6609 6585 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), ··· 6773 6751 SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, 6774 6752 {0x1b, 0x01111010}, 6775 6753 {0x1e, 0x01451130}, 6754 + {0x21, 0x02211020}), 6755 + SND_HDA_PIN_QUIRK(0x10ec0235, 0x17aa, "Lenovo", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, 6756 + {0x12, 0x90a60140}, 6757 + {0x14, 0x90170110}, 6758 + {0x19, 0x02a11030}, 6776 6759 {0x21, 0x02211020}), 6777 6760 SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 6778 6761 {0x12, 0x90a60140},
+1 -1
sound/pci/ice1712/pontis.c
··· 662 662 struct snd_info_entry *entry; 663 663 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) { 664 664 snd_info_set_text_ops(entry, ice, wm_proc_regs_read); 665 - entry->mode |= S_IWUSR; 665 + entry->mode |= 0200; 666 666 entry->c.text.write = wm_proc_regs_write; 667 667 } 668 668 }
+1 -1
sound/pci/ice1712/prodigy_hifi.c
··· 926 926 struct snd_info_entry *entry; 927 927 if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) { 928 928 snd_info_set_text_ops(entry, ice, wm_proc_regs_read); 929 - entry->mode |= S_IWUSR; 929 + entry->mode |= 0200; 930 930 entry->c.text.write = wm_proc_regs_write; 931 931 } 932 932 }
+1 -1
sound/pci/lola/lola_proc.c
··· 214 214 snd_info_set_text_ops(entry, chip, lola_proc_codec_read); 215 215 if (!snd_card_proc_new(chip->card, "codec_rw", &entry)) { 216 216 snd_info_set_text_ops(entry, chip, lola_proc_codec_rw_read); 217 - entry->mode |= S_IWUSR; 217 + entry->mode |= 0200; 218 218 entry->c.text.write = lola_proc_codec_rw_write; 219 219 } 220 220 if (!snd_card_proc_new(chip->card, "regs", &entry))
+7 -7
sound/pci/oxygen/oxygen_mixer.c
··· 1052 1052 [CONTROL_CD_CAPTURE_SWITCH] = "CD Capture Switch", 1053 1053 [CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch", 1054 1054 }; 1055 - unsigned int i, j; 1055 + unsigned int i; 1056 1056 struct snd_kcontrol_new template; 1057 1057 struct snd_kcontrol *ctl; 1058 - int err; 1058 + int j, err; 1059 1059 1060 1060 for (i = 0; i < count; ++i) { 1061 1061 template = controls[i]; ··· 1086 1086 err = snd_ctl_add(chip->card, ctl); 1087 1087 if (err < 0) 1088 1088 return err; 1089 - for (j = 0; j < CONTROL_COUNT; ++j) 1090 - if (!strcmp(ctl->id.name, known_ctl_names[j])) { 1091 - chip->controls[j] = ctl; 1092 - ctl->private_free = oxygen_any_ctl_free; 1093 - } 1089 + j = match_string(known_ctl_names, CONTROL_COUNT, ctl->id.name); 1090 + if (j >= 0) { 1091 + chip->controls[j] = ctl; 1092 + ctl->private_free = oxygen_any_ctl_free; 1093 + } 1094 1094 } 1095 1095 return 0; 1096 1096 }
+1 -1
sound/pci/pcxhr/pcxhr.c
··· 1465 1465 !snd_card_proc_new(chip->card, "gpio", &entry)) { 1466 1466 snd_info_set_text_ops(entry, chip, pcxhr_proc_gpio_read); 1467 1467 entry->c.text.write = pcxhr_proc_gpo_write; 1468 - entry->mode |= S_IWUSR; 1468 + entry->mode |= 0200; 1469 1469 } 1470 1470 if (!snd_card_proc_new(chip->card, "ltc", &entry)) 1471 1471 snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc);
+4 -4
sound/soc/codecs/cs43130.c
··· 1733 1733 return cs43130_show_ac(dev, buf, HP_RIGHT); 1734 1734 } 1735 1735 1736 - static DEVICE_ATTR(hpload_dc_l, S_IRUGO, cs43130_show_dc_l, NULL); 1737 - static DEVICE_ATTR(hpload_dc_r, S_IRUGO, cs43130_show_dc_r, NULL); 1738 - static DEVICE_ATTR(hpload_ac_l, S_IRUGO, cs43130_show_ac_l, NULL); 1739 - static DEVICE_ATTR(hpload_ac_r, S_IRUGO, cs43130_show_ac_r, NULL); 1736 + static DEVICE_ATTR(hpload_dc_l, 0444, cs43130_show_dc_l, NULL); 1737 + static DEVICE_ATTR(hpload_dc_r, 0444, cs43130_show_dc_r, NULL); 1738 + static DEVICE_ATTR(hpload_ac_l, 0444, cs43130_show_ac_l, NULL); 1739 + static DEVICE_ATTR(hpload_ac_r, 0444, cs43130_show_ac_r, NULL); 1740 1740 1741 1741 static struct reg_sequence hp_en_cal_seq[] = { 1742 1742 {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
+5 -6
sound/soc/codecs/wm_adsp.c
··· 627 627 if (!root) 628 628 goto err; 629 629 630 - if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted)) 630 + if (!debugfs_create_bool("booted", 0444, root, &dsp->booted)) 631 631 goto err; 632 632 633 - if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) 633 + if (!debugfs_create_bool("running", 0444, root, &dsp->running)) 634 634 goto err; 635 635 636 - if (!debugfs_create_x32("fw_id", S_IRUGO, root, &dsp->fw_id)) 636 + if (!debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id)) 637 637 goto err; 638 638 639 - if (!debugfs_create_x32("fw_version", S_IRUGO, root, 640 - &dsp->fw_id_version)) 639 + if (!debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version)) 641 640 goto err; 642 641 643 642 for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) { 644 643 if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name, 645 - S_IRUGO, root, dsp, 644 + 0444, root, dsp, 646 645 &wm_adsp_debugfs_fops[i].fops)) 647 646 goto err; 648 647 }
+1 -1
sound/soc/fsl/fsl_ssi_dbg.c
··· 146 146 if (!ssi_dbg->dbg_dir) 147 147 return -ENOMEM; 148 148 149 - ssi_dbg->dbg_stats = debugfs_create_file("stats", S_IRUGO, 149 + ssi_dbg->dbg_stats = debugfs_create_file("stats", 0444, 150 150 ssi_dbg->dbg_dir, ssi_dbg, 151 151 &fsl_ssi_stats_ops); 152 152 if (!ssi_dbg->dbg_stats) {
+3 -3
sound/sound_core.c
··· 413 413 break; 414 414 } 415 415 return sound_insert_unit(&chains[chain], fops, -1, unit, max_unit, 416 - name, S_IRUSR | S_IWUSR, dev); 416 + name, 0600, dev); 417 417 } 418 418 419 419 EXPORT_SYMBOL(register_sound_special_device); ··· 440 440 int register_sound_mixer(const struct file_operations *fops, int dev) 441 441 { 442 442 return sound_insert_unit(&chains[0], fops, dev, 0, 128, 443 - "mixer", S_IRUSR | S_IWUSR, NULL); 443 + "mixer", 0600, NULL); 444 444 } 445 445 446 446 EXPORT_SYMBOL(register_sound_mixer); ··· 468 468 int register_sound_dsp(const struct file_operations *fops, int dev) 469 469 { 470 470 return sound_insert_unit(&chains[3], fops, dev, 3, 131, 471 - "dsp", S_IWUSR | S_IRUSR, NULL); 471 + "dsp", 0600, NULL); 472 472 } 473 473 474 474 EXPORT_SYMBOL(register_sound_dsp);
+2 -2
sound/sparc/dbri.c
··· 2518 2518 #ifdef DBRI_DEBUG 2519 2519 if (!snd_card_proc_new(card, "debug", &entry)) { 2520 2520 snd_info_set_text_ops(entry, dbri, dbri_debug_read); 2521 - entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ 2521 + entry->mode = S_IFREG | 0444; /* Readable only. */ 2522 2522 } 2523 2523 #endif 2524 2524 } ··· 2542 2542 dbri->irq = irq; 2543 2543 2544 2544 dbri->dma = dma_zalloc_coherent(&op->dev, sizeof(struct dbri_dma), 2545 - &dbri->dma_dvma, GFP_ATOMIC); 2545 + &dbri->dma_dvma, GFP_KERNEL); 2546 2546 if (!dbri->dma) 2547 2547 return -ENOMEM; 2548 2548
+137 -111
sound/usb/card.c
··· 86 86 static bool autoclock = true; 87 87 static char *quirk_alias[SNDRV_CARDS]; 88 88 89 + bool snd_usb_use_vmalloc = true; 90 + 89 91 module_param_array(index, int, NULL, 0444); 90 92 MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); 91 93 module_param_array(id, charp, NULL, 0444); ··· 107 105 MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (default: yes)."); 108 106 module_param_array(quirk_alias, charp, NULL, 0444); 109 107 MODULE_PARM_DESC(quirk_alias, "Quirk aliases, e.g. 0123abcd:5678beef."); 108 + module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444); 109 + MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM intermediate buffers (default: yes)."); 110 110 111 111 /* 112 112 * we keep the snd_usb_audio_t instances by ourselves for merging ··· 225 221 struct usb_device *dev = chip->dev; 226 222 struct usb_host_interface *host_iface; 227 223 struct usb_interface_descriptor *altsd; 228 - void *control_header; 229 224 int i, protocol; 230 - int rest_bytes; 231 225 232 226 /* find audiocontrol interface */ 233 227 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; 234 - control_header = snd_usb_find_csint_desc(host_iface->extra, 235 - host_iface->extralen, 236 - NULL, UAC_HEADER); 237 228 altsd = get_iface_desc(host_iface); 238 229 protocol = altsd->bInterfaceProtocol; 239 - 240 - if (!control_header) { 241 - dev_err(&dev->dev, "cannot find UAC_HEADER\n"); 242 - return -EINVAL; 243 - } 244 - 245 - rest_bytes = (void *)(host_iface->extra + host_iface->extralen) - 246 - control_header; 247 - 248 - /* just to be sure -- this shouldn't hit at all */ 249 - if (rest_bytes <= 0) { 250 - dev_err(&dev->dev, "invalid control header\n"); 251 - return -EINVAL; 252 - } 253 230 254 231 switch (protocol) { 255 232 default: ··· 240 255 /* fall through */ 241 256 242 257 case UAC_VERSION_1: { 243 - struct uac1_ac_header_descriptor *h1 = control_header; 258 + struct uac1_ac_header_descriptor *h1; 259 + int rest_bytes; 260 + 261 + h1 = snd_usb_find_csint_desc(host_iface->extra, 262 + host_iface->extralen, 263 + NULL, UAC_HEADER); 264 + if (!h1) { 265 + dev_err(&dev->dev, "cannot find UAC_HEADER\n"); 266 + return -EINVAL; 267 + } 268 + 269 + rest_bytes = (void *)(host_iface->extra + 270 + host_iface->extralen) - (void *)h1; 271 + 272 + /* just to be sure -- this shouldn't hit at all */ 273 + if (rest_bytes <= 0) { 274 + dev_err(&dev->dev, "invalid control header\n"); 275 + return -EINVAL; 276 + } 244 277 245 278 if (rest_bytes < sizeof(*h1)) { 246 279 dev_err(&dev->dev, "too short v1 buffer descriptor\n"); ··· 311 308 return -EINVAL; 312 309 } 313 310 311 + if (protocol == UAC_VERSION_3) { 312 + int badd = assoc->bFunctionSubClass; 313 + 314 + if (badd != UAC3_FUNCTION_SUBCLASS_FULL_ADC_3_0 && 315 + (badd < UAC3_FUNCTION_SUBCLASS_GENERIC_IO || 316 + badd > UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE)) { 317 + dev_err(&dev->dev, 318 + "Unsupported UAC3 BADD profile\n"); 319 + return -EINVAL; 320 + } 321 + 322 + chip->badd_profile = badd; 323 + } 324 + 314 325 for (i = 0; i < assoc->bInterfaceCount; i++) { 315 326 int intf = assoc->bFirstInterface + i; 316 327 ··· 346 329 * 347 330 */ 348 331 349 - static int snd_usb_audio_free(struct snd_usb_audio *chip) 332 + static void snd_usb_audio_free(struct snd_card *card) 350 333 { 334 + struct snd_usb_audio *chip = card->private_data; 351 335 struct snd_usb_endpoint *ep, *n; 352 336 353 337 list_for_each_entry_safe(ep, n, &chip->ep_list, list) ··· 357 339 mutex_destroy(&chip->mutex); 358 340 if (!atomic_read(&chip->shutdown)) 359 341 dev_set_drvdata(&chip->dev->dev, NULL); 360 - kfree(chip); 361 - return 0; 362 342 } 363 343 364 - static int snd_usb_audio_dev_free(struct snd_device *device) 344 + static void usb_audio_make_shortname(struct usb_device *dev, 345 + struct snd_usb_audio *chip, 346 + const struct snd_usb_audio_quirk *quirk) 365 347 { 366 - struct snd_usb_audio *chip = device->device_data; 367 - return snd_usb_audio_free(chip); 368 - } 348 + struct snd_card *card = chip->card; 369 349 370 - /* 371 - * create a chip instance and set its names. 372 - */ 373 - static int snd_usb_audio_create(struct usb_interface *intf, 374 - struct usb_device *dev, int idx, 375 - const struct snd_usb_audio_quirk *quirk, 376 - unsigned int usb_id, 377 - struct snd_usb_audio **rchip) 378 - { 379 - struct snd_card *card; 380 - struct snd_usb_audio *chip; 381 - int err, len; 382 - char component[14]; 383 - static struct snd_device_ops ops = { 384 - .dev_free = snd_usb_audio_dev_free, 385 - }; 386 - 387 - *rchip = NULL; 388 - 389 - switch (snd_usb_get_speed(dev)) { 390 - case USB_SPEED_LOW: 391 - case USB_SPEED_FULL: 392 - case USB_SPEED_HIGH: 393 - case USB_SPEED_WIRELESS: 394 - case USB_SPEED_SUPER: 395 - case USB_SPEED_SUPER_PLUS: 396 - break; 397 - default: 398 - dev_err(&dev->dev, "unknown device speed %d\n", snd_usb_get_speed(dev)); 399 - return -ENXIO; 350 + if (quirk && quirk->product_name && *quirk->product_name) { 351 + strlcpy(card->shortname, quirk->product_name, 352 + sizeof(card->shortname)); 353 + return; 400 354 } 401 - 402 - err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, 403 - 0, &card); 404 - if (err < 0) { 405 - dev_err(&dev->dev, "cannot create card instance %d\n", idx); 406 - return err; 407 - } 408 - 409 - chip = kzalloc(sizeof(*chip), GFP_KERNEL); 410 - if (! chip) { 411 - snd_card_free(card); 412 - return -ENOMEM; 413 - } 414 - 415 - mutex_init(&chip->mutex); 416 - init_waitqueue_head(&chip->shutdown_wait); 417 - chip->index = idx; 418 - chip->dev = dev; 419 - chip->card = card; 420 - chip->setup = device_setup[idx]; 421 - chip->autoclock = autoclock; 422 - atomic_set(&chip->active, 1); /* avoid autopm during probing */ 423 - atomic_set(&chip->usage_count, 0); 424 - atomic_set(&chip->shutdown, 0); 425 - 426 - chip->usb_id = usb_id; 427 - INIT_LIST_HEAD(&chip->pcm_list); 428 - INIT_LIST_HEAD(&chip->ep_list); 429 - INIT_LIST_HEAD(&chip->midi_list); 430 - INIT_LIST_HEAD(&chip->mixer_list); 431 - 432 - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 433 - snd_usb_audio_free(chip); 434 - snd_card_free(card); 435 - return err; 436 - } 437 - 438 - strcpy(card->driver, "USB-Audio"); 439 - sprintf(component, "USB%04x:%04x", 440 - USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); 441 - snd_component_add(card, component); 442 355 443 356 /* retrieve the device string as shortname */ 444 - if (quirk && quirk->product_name && *quirk->product_name) { 445 - strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname)); 446 - } else { 447 - if (!dev->descriptor.iProduct || 448 - usb_string(dev, dev->descriptor.iProduct, 449 - card->shortname, sizeof(card->shortname)) <= 0) { 450 - /* no name available from anywhere, so use ID */ 451 - sprintf(card->shortname, "USB Device %#04x:%#04x", 452 - USB_ID_VENDOR(chip->usb_id), 453 - USB_ID_PRODUCT(chip->usb_id)); 454 - } 357 + if (!dev->descriptor.iProduct || 358 + usb_string(dev, dev->descriptor.iProduct, 359 + card->shortname, sizeof(card->shortname)) <= 0) { 360 + /* no name available from anywhere, so use ID */ 361 + sprintf(card->shortname, "USB Device %#04x:%#04x", 362 + USB_ID_VENDOR(chip->usb_id), 363 + USB_ID_PRODUCT(chip->usb_id)); 455 364 } 456 - strim(card->shortname); 457 365 458 - /* retrieve the vendor and device strings as longname */ 366 + strim(card->shortname); 367 + } 368 + 369 + static void usb_audio_make_longname(struct usb_device *dev, 370 + struct snd_usb_audio *chip, 371 + const struct snd_usb_audio_quirk *quirk) 372 + { 373 + struct snd_card *card = chip->card; 374 + int len; 375 + 376 + /* shortcut - if any pre-defined string is given, use it */ 377 + if (quirk && quirk->profile_name && *quirk->profile_name) { 378 + strlcpy(card->longname, quirk->profile_name, 379 + sizeof(card->longname)); 380 + return; 381 + } 382 + 459 383 if (quirk && quirk->vendor_name && *quirk->vendor_name) { 460 384 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname)); 461 385 } else { 386 + /* retrieve the vendor and device strings as longname */ 462 387 if (dev->descriptor.iManufacturer) 463 388 len = usb_string(dev, dev->descriptor.iManufacturer, 464 389 card->longname, sizeof(card->longname)); ··· 441 480 default: 442 481 break; 443 482 } 483 + } 484 + 485 + /* 486 + * create a chip instance and set its names. 487 + */ 488 + static int snd_usb_audio_create(struct usb_interface *intf, 489 + struct usb_device *dev, int idx, 490 + const struct snd_usb_audio_quirk *quirk, 491 + unsigned int usb_id, 492 + struct snd_usb_audio **rchip) 493 + { 494 + struct snd_card *card; 495 + struct snd_usb_audio *chip; 496 + int err; 497 + char component[14]; 498 + 499 + *rchip = NULL; 500 + 501 + switch (snd_usb_get_speed(dev)) { 502 + case USB_SPEED_LOW: 503 + case USB_SPEED_FULL: 504 + case USB_SPEED_HIGH: 505 + case USB_SPEED_WIRELESS: 506 + case USB_SPEED_SUPER: 507 + case USB_SPEED_SUPER_PLUS: 508 + break; 509 + default: 510 + dev_err(&dev->dev, "unknown device speed %d\n", snd_usb_get_speed(dev)); 511 + return -ENXIO; 512 + } 513 + 514 + err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE, 515 + sizeof(*chip), &card); 516 + if (err < 0) { 517 + dev_err(&dev->dev, "cannot create card instance %d\n", idx); 518 + return err; 519 + } 520 + 521 + chip = card->private_data; 522 + mutex_init(&chip->mutex); 523 + init_waitqueue_head(&chip->shutdown_wait); 524 + chip->index = idx; 525 + chip->dev = dev; 526 + chip->card = card; 527 + chip->setup = device_setup[idx]; 528 + chip->autoclock = autoclock; 529 + atomic_set(&chip->active, 1); /* avoid autopm during probing */ 530 + atomic_set(&chip->usage_count, 0); 531 + atomic_set(&chip->shutdown, 0); 532 + 533 + chip->usb_id = usb_id; 534 + INIT_LIST_HEAD(&chip->pcm_list); 535 + INIT_LIST_HEAD(&chip->ep_list); 536 + INIT_LIST_HEAD(&chip->midi_list); 537 + INIT_LIST_HEAD(&chip->mixer_list); 538 + 539 + card->private_free = snd_usb_audio_free; 540 + 541 + strcpy(card->driver, "USB-Audio"); 542 + sprintf(component, "USB%04x:%04x", 543 + USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); 544 + snd_component_add(card, component); 545 + 546 + usb_audio_make_shortname(dev, chip, quirk); 547 + usb_audio_make_longname(dev, chip, quirk); 444 548 445 549 snd_usb_audio_create_proc(chip); 446 550
+18 -9
sound/usb/clock.c
··· 443 443 data[0] = rate; 444 444 data[1] = rate >> 8; 445 445 data[2] = rate >> 16; 446 - if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, 447 - USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, 448 - UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, 449 - data, sizeof(data))) < 0) { 446 + err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, 447 + USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, 448 + UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, 449 + data, sizeof(data)); 450 + if (err < 0) { 450 451 dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n", 451 452 iface, fmt->altsetting, rate, ep); 452 453 return err; ··· 461 460 if (chip->sample_rate_read_error > 2) 462 461 return 0; 463 462 464 - if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, 465 - USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, 466 - UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, 467 - data, sizeof(data))) < 0) { 463 + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, 464 + USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, 465 + UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, 466 + data, sizeof(data)); 467 + if (err < 0) { 468 468 dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n", 469 469 iface, fmt->altsetting, ep); 470 470 chip->sample_rate_read_error++; ··· 589 587 default: 590 588 return set_sample_rate_v1(chip, iface, alts, fmt, rate); 591 589 592 - case UAC_VERSION_2: 593 590 case UAC_VERSION_3: 591 + if (chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { 592 + if (rate != UAC3_BADD_SAMPLING_RATE) 593 + return -ENXIO; 594 + else 595 + return 0; 596 + } 597 + /* fall through */ 598 + case UAC_VERSION_2: 594 599 return set_sample_rate_v2v3(chip, iface, alts, fmt, rate); 595 600 } 596 601 }
-4
sound/usb/helper.h
··· 18 18 * retrieve usb_interface descriptor from the host interface 19 19 * (conditional for compatibility with the older API) 20 20 */ 21 - #ifndef get_iface_desc 22 21 #define get_iface_desc(iface) (&(iface)->desc) 23 22 #define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc) 24 23 #define get_ep_desc(ep) (&(ep)->desc) 25 24 #define get_cfg_desc(cfg) (&(cfg)->desc) 26 - #endif 27 25 28 - #ifndef snd_usb_get_speed 29 26 #define snd_usb_get_speed(dev) ((dev)->speed) 30 - #endif 31 27 32 28 static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip) 33 29 {
+559 -80
sound/usb/mixer.c
··· 112 112 #include "mixer_maps.c" 113 113 114 114 static const struct usbmix_name_map * 115 - find_map(struct mixer_build *state, int unitid, int control) 115 + find_map(const struct usbmix_name_map *p, int unitid, int control) 116 116 { 117 - const struct usbmix_name_map *p = state->map; 118 - 119 117 if (!p) 120 118 return NULL; 121 119 122 - for (p = state->map; p->id; p++) { 120 + for (; p->id; p++) { 123 121 if (p->id == unitid && 124 122 (!control || !p->control || control == p->control)) 125 123 return p; ··· 199 201 /* 200 202 * copy a string with the given id 201 203 */ 202 - static int snd_usb_copy_string_desc(struct mixer_build *state, 204 + static int snd_usb_copy_string_desc(struct snd_usb_audio *chip, 203 205 int index, char *buf, int maxlen) 204 206 { 205 - int len = usb_string(state->chip->dev, index, buf, maxlen - 1); 207 + int len = usb_string(chip->dev, index, buf, maxlen - 1); 206 208 207 209 if (len < 0) 208 210 return 0; ··· 598 600 599 601 while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) 600 602 kctl->id.index++; 601 - if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) { 603 + err = snd_ctl_add(mixer->chip->card, kctl); 604 + if (err < 0) { 602 605 usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", 603 606 err); 604 607 return err; ··· 657 658 { 0 }, 658 659 }; 659 660 660 - static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm, 661 + static int get_term_name(struct snd_usb_audio *chip, struct usb_audio_term *iterm, 661 662 unsigned char *name, int maxlen, int term_only) 662 663 { 663 664 struct iterm_name_combo *names; 664 665 int len; 665 666 666 667 if (iterm->name) { 667 - len = snd_usb_copy_string_desc(state, iterm->name, 668 + len = snd_usb_copy_string_desc(chip, iterm->name, 668 669 name, maxlen); 669 670 if (len) 670 671 return len; ··· 715 716 } 716 717 717 718 return 0; 719 + } 720 + 721 + /* 722 + * Get logical cluster information for UAC3 devices. 723 + */ 724 + static int get_cluster_channels_v3(struct mixer_build *state, unsigned int cluster_id) 725 + { 726 + struct uac3_cluster_header_descriptor c_header; 727 + int err; 728 + 729 + err = snd_usb_ctl_msg(state->chip->dev, 730 + usb_rcvctrlpipe(state->chip->dev, 0), 731 + UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, 732 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 733 + cluster_id, 734 + snd_usb_ctrl_intf(state->chip), 735 + &c_header, sizeof(c_header)); 736 + if (err < 0) 737 + goto error; 738 + if (err != sizeof(c_header)) { 739 + err = -EIO; 740 + goto error; 741 + } 742 + 743 + return c_header.bNrChannels; 744 + 745 + error: 746 + usb_audio_err(state->chip, "cannot request logical cluster ID: %d (err: %d)\n", cluster_id, err); 747 + return err; 748 + } 749 + 750 + /* 751 + * Get number of channels for a Mixer Unit. 752 + */ 753 + static int uac_mixer_unit_get_channels(struct mixer_build *state, 754 + struct uac_mixer_unit_descriptor *desc) 755 + { 756 + int mu_channels; 757 + 758 + if (desc->bLength < 11) 759 + return -EINVAL; 760 + if (!desc->bNrInPins) 761 + return -EINVAL; 762 + 763 + switch (state->mixer->protocol) { 764 + case UAC_VERSION_1: 765 + case UAC_VERSION_2: 766 + default: 767 + mu_channels = uac_mixer_unit_bNrChannels(desc); 768 + break; 769 + case UAC_VERSION_3: 770 + mu_channels = get_cluster_channels_v3(state, 771 + uac3_mixer_unit_wClusterDescrID(desc)); 772 + break; 773 + } 774 + 775 + if (!mu_channels) 776 + return -EINVAL; 777 + 778 + return mu_channels; 718 779 } 719 780 720 781 /* ··· 903 844 term->id = id; 904 845 term->type = le16_to_cpu(d->wTerminalType); 905 846 906 - /* REVISIT: UAC3 IT doesn't have channels/cfg */ 907 - term->channels = 0; 847 + err = get_cluster_channels_v3(state, le16_to_cpu(d->wClusterDescrID)); 848 + if (err < 0) 849 + return err; 850 + term->channels = err; 851 + 852 + /* REVISIT: UAC3 IT doesn't have channels cfg */ 908 853 term->chconfig = 0; 909 854 910 855 term->name = le16_to_cpu(d->wTerminalDescrStr); ··· 926 863 term->type = d->bDescriptorSubtype << 16; /* virtual type */ 927 864 term->id = id; 928 865 term->name = le16_to_cpu(d->wClockSourceStr); 866 + return 0; 867 + } 868 + case UAC3_MIXER_UNIT: { 869 + struct uac_mixer_unit_descriptor *d = p1; 870 + 871 + err = uac_mixer_unit_get_channels(state, d); 872 + if (err < 0) 873 + return err; 874 + 875 + term->channels = err; 876 + term->type = d->bDescriptorSubtype << 16; /* virtual type */ 877 + 929 878 return 0; 930 879 } 931 880 default: ··· 1333 1258 return 0; 1334 1259 } 1335 1260 1261 + /* get the connectors status and report it as boolean type */ 1262 + static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol, 1263 + struct snd_ctl_elem_value *ucontrol) 1264 + { 1265 + struct usb_mixer_elem_info *cval = kcontrol->private_data; 1266 + struct snd_usb_audio *chip = cval->head.mixer->chip; 1267 + int idx = 0, validx, ret, val; 1268 + 1269 + validx = cval->control << 8 | 0; 1270 + 1271 + ret = snd_usb_lock_shutdown(chip) ? -EIO : 0; 1272 + if (ret) 1273 + goto error; 1274 + 1275 + idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); 1276 + if (cval->head.mixer->protocol == UAC_VERSION_2) { 1277 + struct uac2_connectors_ctl_blk uac2_conn; 1278 + 1279 + ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR, 1280 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 1281 + validx, idx, &uac2_conn, sizeof(uac2_conn)); 1282 + val = !!uac2_conn.bNrChannels; 1283 + } else { /* UAC_VERSION_3 */ 1284 + struct uac3_insertion_ctl_blk uac3_conn; 1285 + 1286 + ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR, 1287 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 1288 + validx, idx, &uac3_conn, sizeof(uac3_conn)); 1289 + val = !!uac3_conn.bmConInserted; 1290 + } 1291 + 1292 + snd_usb_unlock_shutdown(chip); 1293 + 1294 + if (ret < 0) { 1295 + error: 1296 + usb_audio_err(chip, 1297 + "cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", 1298 + UAC_GET_CUR, validx, idx, cval->val_type); 1299 + return ret; 1300 + } 1301 + 1302 + ucontrol->value.integer.value[0] = val; 1303 + return 0; 1304 + } 1305 + 1336 1306 static struct snd_kcontrol_new usb_feature_unit_ctl = { 1337 1307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1338 1308 .name = "", /* will be filled later manually */ ··· 1405 1285 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1406 1286 .info = snd_ctl_boolean_mono_info, 1407 1287 .get = mixer_ctl_master_bool_get, 1288 + .put = NULL, 1289 + }; 1290 + 1291 + static const struct snd_kcontrol_new usb_connector_ctl_ro = { 1292 + .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1293 + .name = "", /* will be filled later manually */ 1294 + .access = SNDRV_CTL_ELEM_ACCESS_READ, 1295 + .info = snd_ctl_boolean_mono_info, 1296 + .get = mixer_ctl_connector_get, 1408 1297 .put = NULL, 1409 1298 }; 1410 1299 ··· 1470 1341 return NULL; 1471 1342 } 1472 1343 1473 - static void build_feature_ctl(struct mixer_build *state, void *raw_desc, 1474 - unsigned int ctl_mask, int control, 1475 - struct usb_audio_term *iterm, int unitid, 1476 - int readonly_mask) 1344 + static void __build_feature_ctl(struct usb_mixer_interface *mixer, 1345 + const struct usbmix_name_map *imap, 1346 + unsigned int ctl_mask, int control, 1347 + struct usb_audio_term *iterm, 1348 + struct usb_audio_term *oterm, 1349 + int unitid, int nameid, int readonly_mask) 1477 1350 { 1478 - struct uac_feature_unit_descriptor *desc = raw_desc; 1479 1351 struct usb_feature_control_info *ctl_info; 1480 1352 unsigned int len = 0; 1481 1353 int mapped_name = 0; 1482 - int nameid = uac_feature_unit_iFeature(desc); 1483 1354 struct snd_kcontrol *kctl; 1484 1355 struct usb_mixer_elem_info *cval; 1485 1356 const struct usbmix_name_map *map; ··· 1490 1361 return; 1491 1362 } 1492 1363 1493 - map = find_map(state, unitid, control); 1364 + map = find_map(imap, unitid, control); 1494 1365 if (check_ignored_ctl(map)) 1495 1366 return; 1496 1367 1497 1368 cval = kzalloc(sizeof(*cval), GFP_KERNEL); 1498 1369 if (!cval) 1499 1370 return; 1500 - snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); 1371 + snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); 1501 1372 cval->control = control; 1502 1373 cval->cmask = ctl_mask; 1503 1374 ··· 1506 1377 kfree(cval); 1507 1378 return; 1508 1379 } 1509 - if (state->mixer->protocol == UAC_VERSION_1) 1380 + if (mixer->protocol == UAC_VERSION_1) 1510 1381 cval->val_type = ctl_info->type; 1511 1382 else /* UAC_VERSION_2 */ 1512 1383 cval->val_type = ctl_info->type_uac2 >= 0 ? ··· 1535 1406 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1536 1407 1537 1408 if (!kctl) { 1538 - usb_audio_err(state->chip, "cannot malloc kcontrol\n"); 1409 + usb_audio_err(mixer->chip, "cannot malloc kcontrol\n"); 1539 1410 kfree(cval); 1540 1411 return; 1541 1412 } ··· 1544 1415 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 1545 1416 mapped_name = len != 0; 1546 1417 if (!len && nameid) 1547 - len = snd_usb_copy_string_desc(state, nameid, 1418 + len = snd_usb_copy_string_desc(mixer->chip, nameid, 1548 1419 kctl->id.name, sizeof(kctl->id.name)); 1549 1420 1550 1421 switch (control) { ··· 1559 1430 * - otherwise, anonymous name. 1560 1431 */ 1561 1432 if (!len) { 1562 - len = get_term_name(state, iterm, kctl->id.name, 1563 - sizeof(kctl->id.name), 1); 1564 - if (!len) 1565 - len = get_term_name(state, &state->oterm, 1433 + if (iterm) 1434 + len = get_term_name(mixer->chip, iterm, 1435 + kctl->id.name, 1436 + sizeof(kctl->id.name), 1); 1437 + if (!len && oterm) 1438 + len = get_term_name(mixer->chip, oterm, 1566 1439 kctl->id.name, 1567 1440 sizeof(kctl->id.name), 1); 1568 1441 if (!len) ··· 1573 1442 } 1574 1443 1575 1444 if (!mapped_name) 1576 - check_no_speaker_on_headset(kctl, state->mixer->chip->card); 1445 + check_no_speaker_on_headset(kctl, mixer->chip->card); 1577 1446 1578 1447 /* 1579 1448 * determine the stream direction: 1580 1449 * if the connected output is USB stream, then it's likely a 1581 1450 * capture stream. otherwise it should be playback (hopefully :) 1582 1451 */ 1583 - if (!mapped_name && !(state->oterm.type >> 16)) { 1584 - if ((state->oterm.type & 0xff00) == 0x0100) 1452 + if (!mapped_name && oterm && !(oterm->type >> 16)) { 1453 + if ((oterm->type & 0xff00) == 0x0100) 1585 1454 append_ctl_name(kctl, " Capture"); 1586 1455 else 1587 1456 append_ctl_name(kctl, " Playback"); ··· 1609 1478 } 1610 1479 } 1611 1480 1612 - snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl); 1481 + snd_usb_mixer_fu_apply_quirk(mixer, cval, unitid, kctl); 1613 1482 1614 1483 range = (cval->max - cval->min) / cval->res; 1615 1484 /* ··· 1618 1487 * devices. It will definitively catch all buggy Logitech devices. 1619 1488 */ 1620 1489 if (range > 384) { 1621 - usb_audio_warn(state->chip, 1490 + usb_audio_warn(mixer->chip, 1622 1491 "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.", 1623 1492 range); 1624 - usb_audio_warn(state->chip, 1493 + usb_audio_warn(mixer->chip, 1625 1494 "[%d] FU [%s] ch = %d, val = %d/%d/%d", 1626 1495 cval->head.id, kctl->id.name, cval->channels, 1627 1496 cval->min, cval->max, cval->res); 1628 1497 } 1629 1498 1630 - usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", 1499 + usb_audio_dbg(mixer->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", 1631 1500 cval->head.id, kctl->id.name, cval->channels, 1632 1501 cval->min, cval->max, cval->res); 1633 1502 snd_usb_mixer_add_control(&cval->head, kctl); 1503 + } 1504 + 1505 + static void build_feature_ctl(struct mixer_build *state, void *raw_desc, 1506 + unsigned int ctl_mask, int control, 1507 + struct usb_audio_term *iterm, int unitid, 1508 + int readonly_mask) 1509 + { 1510 + struct uac_feature_unit_descriptor *desc = raw_desc; 1511 + int nameid = uac_feature_unit_iFeature(desc); 1512 + 1513 + __build_feature_ctl(state->mixer, state->map, ctl_mask, control, 1514 + iterm, &state->oterm, unitid, nameid, readonly_mask); 1515 + } 1516 + 1517 + static void build_feature_ctl_badd(struct usb_mixer_interface *mixer, 1518 + unsigned int ctl_mask, int control, int unitid, 1519 + const struct usbmix_name_map *badd_map) 1520 + { 1521 + __build_feature_ctl(mixer, badd_map, ctl_mask, control, 1522 + NULL, NULL, unitid, 0, 0); 1634 1523 } 1635 1524 1636 1525 static void get_connector_control_name(struct mixer_build *state, 1637 1526 struct usb_audio_term *term, 1638 1527 bool is_input, char *name, int name_size) 1639 1528 { 1640 - int name_len = get_term_name(state, term, name, name_size, 0); 1529 + int name_len = get_term_name(state->chip, term, name, name_size, 0); 1641 1530 1642 1531 if (name_len == 0) 1643 1532 strlcpy(name, "Unknown", name_size); ··· 1685 1534 return; 1686 1535 snd_usb_mixer_elem_init_std(&cval->head, state->mixer, term->id); 1687 1536 /* 1688 - * The first byte from reading the UAC2_TE_CONNECTOR control returns the 1689 - * number of channels connected. This boolean ctl will simply report 1690 - * if any channels are connected or not. 1691 - * (Audio20_final.pdf Table 5-10: Connector Control CUR Parameter Block) 1537 + * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the 1538 + * number of channels connected. 1539 + * 1540 + * UAC3: The first byte specifies size of bitmap for the inserted controls. The 1541 + * following byte(s) specifies which connectors are inserted. 1542 + * 1543 + * This boolean ctl will simply report if any channels are connected 1544 + * or not. 1692 1545 */ 1693 - cval->control = UAC2_TE_CONNECTOR; 1546 + if (state->mixer->protocol == UAC_VERSION_2) 1547 + cval->control = UAC2_TE_CONNECTOR; 1548 + else /* UAC_VERSION_3 */ 1549 + cval->control = UAC3_TE_INSERTION; 1550 + 1694 1551 cval->val_type = USB_MIXER_BOOLEAN; 1695 1552 cval->channels = 1; /* report true if any channel is connected */ 1696 1553 cval->min = 0; 1697 1554 cval->max = 1; 1698 - kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval); 1555 + kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval); 1699 1556 if (!kctl) { 1700 1557 usb_audio_err(state->chip, "cannot malloc kcontrol\n"); 1701 1558 kfree(cval); ··· 1764 1605 } 1765 1606 1766 1607 kctl->private_free = snd_usb_mixer_elem_free; 1767 - ret = snd_usb_copy_string_desc(state, hdr->iClockSource, 1608 + ret = snd_usb_copy_string_desc(state->chip, hdr->iClockSource, 1768 1609 name, sizeof(name)); 1769 1610 if (ret > 0) 1770 1611 snprintf(kctl->id.name, sizeof(kctl->id.name), ··· 1851 1692 } 1852 1693 1853 1694 /* parse the source unit */ 1854 - if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0) 1695 + err = parse_audio_unit(state, hdr->bSourceID); 1696 + if (err < 0) 1855 1697 return err; 1856 1698 1857 1699 /* determine the input source type and name */ ··· 1966 1806 */ 1967 1807 static void build_mixer_unit_ctl(struct mixer_build *state, 1968 1808 struct uac_mixer_unit_descriptor *desc, 1969 - int in_pin, int in_ch, int unitid, 1970 - struct usb_audio_term *iterm) 1809 + int in_pin, int in_ch, int num_outs, 1810 + int unitid, struct usb_audio_term *iterm) 1971 1811 { 1972 1812 struct usb_mixer_elem_info *cval; 1973 - unsigned int num_outs = uac_mixer_unit_bNrChannels(desc); 1974 1813 unsigned int i, len; 1975 1814 struct snd_kcontrol *kctl; 1976 1815 const struct usbmix_name_map *map; 1977 1816 1978 - map = find_map(state, unitid, 0); 1817 + map = find_map(state->map, unitid, 0); 1979 1818 if (check_ignored_ctl(map)) 1980 1819 return; 1981 1820 ··· 2007 1848 2008 1849 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 2009 1850 if (!len) 2010 - len = get_term_name(state, iterm, kctl->id.name, 1851 + len = get_term_name(state->chip, iterm, kctl->id.name, 2011 1852 sizeof(kctl->id.name), 0); 2012 1853 if (!len) 2013 1854 len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); ··· 2022 1863 void *raw_desc) 2023 1864 { 2024 1865 struct usb_audio_term iterm; 2025 - struct uac2_input_terminal_descriptor *d = raw_desc; 1866 + unsigned int control, bmctls, term_id; 2026 1867 2027 - check_input_term(state, d->bTerminalID, &iterm); 2028 1868 if (state->mixer->protocol == UAC_VERSION_2) { 2029 - /* Check for jack detection. */ 2030 - if (uac_v2v3_control_is_readable(le16_to_cpu(d->bmControls), 2031 - UAC2_TE_CONNECTOR)) { 2032 - build_connector_control(state, &iterm, true); 2033 - } 1869 + struct uac2_input_terminal_descriptor *d_v2 = raw_desc; 1870 + control = UAC2_TE_CONNECTOR; 1871 + term_id = d_v2->bTerminalID; 1872 + bmctls = le16_to_cpu(d_v2->bmControls); 1873 + } else if (state->mixer->protocol == UAC_VERSION_3) { 1874 + struct uac3_input_terminal_descriptor *d_v3 = raw_desc; 1875 + control = UAC3_TE_INSERTION; 1876 + term_id = d_v3->bTerminalID; 1877 + bmctls = le32_to_cpu(d_v3->bmControls); 1878 + } else { 1879 + return 0; /* UAC1. No Insertion control */ 2034 1880 } 1881 + 1882 + check_input_term(state, term_id, &iterm); 1883 + 1884 + /* Check for jack detection. */ 1885 + if (uac_v2v3_control_is_readable(bmctls, control)) 1886 + build_connector_control(state, &iterm, true); 1887 + 2035 1888 return 0; 2036 1889 } 2037 1890 ··· 2058 1887 int input_pins, num_ins, num_outs; 2059 1888 int pin, ich, err; 2060 1889 2061 - if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) || 2062 - !(num_outs = uac_mixer_unit_bNrChannels(desc))) { 1890 + err = uac_mixer_unit_get_channels(state, desc); 1891 + if (err < 0) { 2063 1892 usb_audio_err(state->chip, 2064 1893 "invalid MIXER UNIT descriptor %d\n", 2065 1894 unitid); 2066 - return -EINVAL; 1895 + return err; 2067 1896 } 1897 + 1898 + num_outs = err; 1899 + input_pins = desc->bNrInPins; 2068 1900 2069 1901 num_ins = 0; 2070 1902 ich = 0; ··· 2095 1921 } 2096 1922 } 2097 1923 if (ich_has_controls) 2098 - build_mixer_unit_ctl(state, desc, pin, ich, 1924 + build_mixer_unit_ctl(state, desc, pin, ich, num_outs, 2099 1925 unitid, &iterm); 2100 1926 } 2101 1927 } ··· 2272 2098 } 2273 2099 2274 2100 for (i = 0; i < num_ins; i++) { 2275 - if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0) 2101 + err = parse_audio_unit(state, desc->baSourceID[i]); 2102 + if (err < 0) 2276 2103 return err; 2277 2104 } 2278 2105 ··· 2289 2114 2290 2115 if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) 2291 2116 continue; 2292 - map = find_map(state, unitid, valinfo->control); 2117 + map = find_map(state->map, unitid, valinfo->control); 2293 2118 if (check_ignored_ctl(map)) 2294 2119 continue; 2295 2120 cval = kzalloc(sizeof(*cval), GFP_KERNEL); ··· 2337 2162 nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); 2338 2163 len = 0; 2339 2164 if (nameid) 2340 - len = snd_usb_copy_string_desc(state, nameid, 2165 + len = snd_usb_copy_string_desc(state->chip, 2166 + nameid, 2341 2167 kctl->id.name, 2342 2168 sizeof(kctl->id.name)); 2343 2169 if (!len) ··· 2486 2310 } 2487 2311 2488 2312 for (i = 0; i < desc->bNrInPins; i++) { 2489 - if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0) 2313 + err = parse_audio_unit(state, desc->baSourceID[i]); 2314 + if (err < 0) 2490 2315 return err; 2491 2316 } 2492 2317 2493 2318 if (desc->bNrInPins == 1) /* only one ? nonsense! */ 2494 2319 return 0; 2495 2320 2496 - map = find_map(state, unitid, 0); 2321 + map = find_map(state->map, unitid, 0); 2497 2322 if (check_ignored_ctl(map)) 2498 2323 return 0; 2499 2324 ··· 2535 2358 len = check_mapped_selector_name(state, unitid, i, namelist[i], 2536 2359 MAX_ITEM_NAME_LEN); 2537 2360 if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0) 2538 - len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); 2361 + len = get_term_name(state->chip, &iterm, namelist[i], 2362 + MAX_ITEM_NAME_LEN, 0); 2539 2363 if (! len) 2540 2364 sprintf(namelist[i], "Input %u", i); 2541 2365 } ··· 2558 2380 /* if iSelector is given, use it */ 2559 2381 nameid = uac_selector_unit_iSelector(desc); 2560 2382 if (nameid) 2561 - len = snd_usb_copy_string_desc(state, nameid, 2383 + len = snd_usb_copy_string_desc(state->chip, nameid, 2562 2384 kctl->id.name, 2563 2385 sizeof(kctl->id.name)); 2564 2386 /* ... or pick up the terminal name at next */ 2565 2387 if (!len) 2566 - len = get_term_name(state, &state->oterm, 2388 + len = get_term_name(state->chip, &state->oterm, 2567 2389 kctl->id.name, sizeof(kctl->id.name), 0); 2568 2390 /* ... or use the fixed string "USB" as the last resort */ 2569 2391 if (!len) ··· 2636 2458 } else { /* UAC_VERSION_3 */ 2637 2459 switch (p1[2]) { 2638 2460 case UAC_INPUT_TERMINAL: 2639 - return 0; /* NOP */ 2461 + return parse_audio_input_terminal(state, unitid, p1); 2640 2462 case UAC3_MIXER_UNIT: 2641 2463 return parse_audio_mixer_unit(state, unitid, p1); 2642 2464 case UAC3_CLOCK_SOURCE: ··· 2678 2500 { 2679 2501 struct usb_mixer_interface *mixer = device->device_data; 2680 2502 snd_usb_mixer_free(mixer); 2503 + return 0; 2504 + } 2505 + 2506 + /* UAC3 predefined channels configuration */ 2507 + struct uac3_badd_profile { 2508 + int subclass; 2509 + const char *name; 2510 + int c_chmask; /* capture channels mask */ 2511 + int p_chmask; /* playback channels mask */ 2512 + int st_chmask; /* side tone mixing channel mask */ 2513 + }; 2514 + 2515 + static struct uac3_badd_profile uac3_badd_profiles[] = { 2516 + { 2517 + /* 2518 + * BAIF, BAOF or combination of both 2519 + * IN: Mono or Stereo cfg, Mono alt possible 2520 + * OUT: Mono or Stereo cfg, Mono alt possible 2521 + */ 2522 + .subclass = UAC3_FUNCTION_SUBCLASS_GENERIC_IO, 2523 + .name = "GENERIC IO", 2524 + .c_chmask = -1, /* dynamic channels */ 2525 + .p_chmask = -1, /* dynamic channels */ 2526 + }, 2527 + { 2528 + /* BAOF; Stereo only cfg, Mono alt possible */ 2529 + .subclass = UAC3_FUNCTION_SUBCLASS_HEADPHONE, 2530 + .name = "HEADPHONE", 2531 + .p_chmask = 3, 2532 + }, 2533 + { 2534 + /* BAOF; Mono or Stereo cfg, Mono alt possible */ 2535 + .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKER, 2536 + .name = "SPEAKER", 2537 + .p_chmask = -1, /* dynamic channels */ 2538 + }, 2539 + { 2540 + /* BAIF; Mono or Stereo cfg, Mono alt possible */ 2541 + .subclass = UAC3_FUNCTION_SUBCLASS_MICROPHONE, 2542 + .name = "MICROPHONE", 2543 + .c_chmask = -1, /* dynamic channels */ 2544 + }, 2545 + { 2546 + /* 2547 + * BAIOF topology 2548 + * IN: Mono only 2549 + * OUT: Mono or Stereo cfg, Mono alt possible 2550 + */ 2551 + .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET, 2552 + .name = "HEADSET", 2553 + .c_chmask = 1, 2554 + .p_chmask = -1, /* dynamic channels */ 2555 + .st_chmask = 1, 2556 + }, 2557 + { 2558 + /* BAIOF; IN: Mono only; OUT: Stereo only, Mono alt possible */ 2559 + .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER, 2560 + .name = "HEADSET ADAPTER", 2561 + .c_chmask = 1, 2562 + .p_chmask = 3, 2563 + .st_chmask = 1, 2564 + }, 2565 + { 2566 + /* BAIF + BAOF; IN: Mono only; OUT: Mono only */ 2567 + .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE, 2568 + .name = "SPEAKERPHONE", 2569 + .c_chmask = 1, 2570 + .p_chmask = 1, 2571 + }, 2572 + { 0 } /* terminator */ 2573 + }; 2574 + 2575 + static bool uac3_badd_func_has_valid_channels(struct usb_mixer_interface *mixer, 2576 + struct uac3_badd_profile *f, 2577 + int c_chmask, int p_chmask) 2578 + { 2579 + /* 2580 + * If both playback/capture channels are dynamic, make sure 2581 + * at least one channel is present 2582 + */ 2583 + if (f->c_chmask < 0 && f->p_chmask < 0) { 2584 + if (!c_chmask && !p_chmask) { 2585 + usb_audio_warn(mixer->chip, "BAAD %s: no channels?", 2586 + f->name); 2587 + return false; 2588 + } 2589 + return true; 2590 + } 2591 + 2592 + if ((f->c_chmask < 0 && !c_chmask) || 2593 + (f->c_chmask >= 0 && f->c_chmask != c_chmask)) { 2594 + usb_audio_warn(mixer->chip, "BAAD %s c_chmask mismatch", 2595 + f->name); 2596 + return false; 2597 + } 2598 + if ((f->p_chmask < 0 && !p_chmask) || 2599 + (f->p_chmask >= 0 && f->p_chmask != p_chmask)) { 2600 + usb_audio_warn(mixer->chip, "BAAD %s p_chmask mismatch", 2601 + f->name); 2602 + return false; 2603 + } 2604 + return true; 2605 + } 2606 + 2607 + /* 2608 + * create mixer controls for UAC3 BADD profiles 2609 + * 2610 + * UAC3 BADD device doesn't contain CS descriptors thus we will guess everything 2611 + * 2612 + * BADD device may contain Mixer Unit, which doesn't have any controls, skip it 2613 + */ 2614 + static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, 2615 + int ctrlif) 2616 + { 2617 + struct usb_device *dev = mixer->chip->dev; 2618 + struct usb_interface_assoc_descriptor *assoc; 2619 + int badd_profile = mixer->chip->badd_profile; 2620 + struct uac3_badd_profile *f; 2621 + const struct usbmix_ctl_map *map; 2622 + int p_chmask = 0, c_chmask = 0, st_chmask = 0; 2623 + int i; 2624 + 2625 + assoc = usb_ifnum_to_if(dev, ctrlif)->intf_assoc; 2626 + 2627 + /* Detect BADD capture/playback channels from AS EP descriptors */ 2628 + for (i = 0; i < assoc->bInterfaceCount; i++) { 2629 + int intf = assoc->bFirstInterface + i; 2630 + 2631 + struct usb_interface *iface; 2632 + struct usb_host_interface *alts; 2633 + struct usb_interface_descriptor *altsd; 2634 + unsigned int maxpacksize; 2635 + char dir_in; 2636 + int chmask, num; 2637 + 2638 + if (intf == ctrlif) 2639 + continue; 2640 + 2641 + iface = usb_ifnum_to_if(dev, intf); 2642 + num = iface->num_altsetting; 2643 + 2644 + if (num < 2) 2645 + return -EINVAL; 2646 + 2647 + /* 2648 + * The number of Channels in an AudioStreaming interface 2649 + * and the audio sample bit resolution (16 bits or 24 2650 + * bits) can be derived from the wMaxPacketSize field in 2651 + * the Standard AS Audio Data Endpoint descriptor in 2652 + * Alternate Setting 1 2653 + */ 2654 + alts = &iface->altsetting[1]; 2655 + altsd = get_iface_desc(alts); 2656 + 2657 + if (altsd->bNumEndpoints < 1) 2658 + return -EINVAL; 2659 + 2660 + /* check direction */ 2661 + dir_in = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN); 2662 + maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 2663 + 2664 + switch (maxpacksize) { 2665 + default: 2666 + usb_audio_err(mixer->chip, 2667 + "incorrect wMaxPacketSize 0x%x for BADD profile\n", 2668 + maxpacksize); 2669 + return -EINVAL; 2670 + case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16: 2671 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16: 2672 + case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24: 2673 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24: 2674 + chmask = 1; 2675 + break; 2676 + case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16: 2677 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16: 2678 + case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24: 2679 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24: 2680 + chmask = 3; 2681 + break; 2682 + } 2683 + 2684 + if (dir_in) 2685 + c_chmask = chmask; 2686 + else 2687 + p_chmask = chmask; 2688 + } 2689 + 2690 + usb_audio_dbg(mixer->chip, 2691 + "UAC3 BADD profile 0x%x: detected c_chmask=%d p_chmask=%d\n", 2692 + badd_profile, c_chmask, p_chmask); 2693 + 2694 + /* check the mapping table */ 2695 + for (map = uac3_badd_usbmix_ctl_maps; map->id; map++) { 2696 + if (map->id == badd_profile) 2697 + break; 2698 + } 2699 + 2700 + if (!map->id) 2701 + return -EINVAL; 2702 + 2703 + for (f = uac3_badd_profiles; f->name; f++) { 2704 + if (badd_profile == f->subclass) 2705 + break; 2706 + } 2707 + if (!f->name) 2708 + return -EINVAL; 2709 + if (!uac3_badd_func_has_valid_channels(mixer, f, c_chmask, p_chmask)) 2710 + return -EINVAL; 2711 + st_chmask = f->st_chmask; 2712 + 2713 + /* Playback */ 2714 + if (p_chmask) { 2715 + /* Master channel, always writable */ 2716 + build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE, 2717 + UAC3_BADD_FU_ID2, map->map); 2718 + /* Mono/Stereo volume channels, always writable */ 2719 + build_feature_ctl_badd(mixer, p_chmask, UAC_FU_VOLUME, 2720 + UAC3_BADD_FU_ID2, map->map); 2721 + } 2722 + 2723 + /* Capture */ 2724 + if (c_chmask) { 2725 + /* Master channel, always writable */ 2726 + build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE, 2727 + UAC3_BADD_FU_ID5, map->map); 2728 + /* Mono/Stereo volume channels, always writable */ 2729 + build_feature_ctl_badd(mixer, c_chmask, UAC_FU_VOLUME, 2730 + UAC3_BADD_FU_ID5, map->map); 2731 + } 2732 + 2733 + /* Side tone-mixing */ 2734 + if (st_chmask) { 2735 + /* Master channel, always writable */ 2736 + build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE, 2737 + UAC3_BADD_FU_ID7, map->map); 2738 + /* Mono volume channel, always writable */ 2739 + build_feature_ctl_badd(mixer, 1, UAC_FU_VOLUME, 2740 + UAC3_BADD_FU_ID7, map->map); 2741 + } 2742 + 2681 2743 return 0; 2682 2744 } 2683 2745 ··· 3014 2596 err = parse_audio_unit(&state, desc->bCSourceID); 3015 2597 if (err < 0 && err != -EINVAL) 3016 2598 return err; 2599 + 2600 + if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls), 2601 + UAC3_TE_INSERTION)) { 2602 + build_connector_control(&state, &state.oterm, 2603 + false); 2604 + } 3017 2605 } 3018 2606 } 3019 2607 ··· 3030 2606 { 3031 2607 struct usb_mixer_elem_list *list; 3032 2608 3033 - for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { 2609 + for_each_mixer_elem(list, mixer, unitid) { 3034 2610 struct usb_mixer_elem_info *info = 3035 - (struct usb_mixer_elem_info *)list; 2611 + mixer_elem_list_to_info(list); 3036 2612 /* invalidate cache, so the value is read from the device */ 3037 2613 info->cached = 0; 3038 2614 snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, ··· 3043 2619 static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, 3044 2620 struct usb_mixer_elem_list *list) 3045 2621 { 3046 - struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; 2622 + struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list); 3047 2623 static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN", 3048 2624 "S8", "U8", "S16", "U16"}; 3049 2625 snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, " ··· 3069 2645 mixer->ignore_ctl_error); 3070 2646 snd_iprintf(buffer, "Card: %s\n", chip->card->longname); 3071 2647 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) { 3072 - for (list = mixer->id_elems[unitid]; list; 3073 - list = list->next_id_elem) { 2648 + for_each_mixer_elem(list, mixer, unitid) { 3074 2649 snd_iprintf(buffer, " Unit: %i\n", list->id); 3075 2650 if (list->kctl) 3076 2651 snd_iprintf(buffer, ··· 3099 2676 return; 3100 2677 } 3101 2678 3102 - for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) 2679 + for_each_mixer_elem(list, mixer, unitid) 3103 2680 count++; 3104 2681 3105 2682 if (count == 0) 3106 2683 return; 3107 2684 3108 - for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { 2685 + for_each_mixer_elem(list, mixer, unitid) { 3109 2686 struct usb_mixer_elem_info *info; 3110 2687 3111 2688 if (!list->kctl) 3112 2689 continue; 3113 2690 3114 - info = (struct usb_mixer_elem_info *)list; 2691 + info = mixer_elem_list_to_info(list); 3115 2692 if (count > 1 && info->control != control) 3116 2693 continue; 3117 2694 ··· 3232 2809 return 0; 3233 2810 } 3234 2811 2812 + static int keep_iface_ctl_get(struct snd_kcontrol *kcontrol, 2813 + struct snd_ctl_elem_value *ucontrol) 2814 + { 2815 + struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); 2816 + 2817 + ucontrol->value.integer.value[0] = mixer->chip->keep_iface; 2818 + return 0; 2819 + } 2820 + 2821 + static int keep_iface_ctl_put(struct snd_kcontrol *kcontrol, 2822 + struct snd_ctl_elem_value *ucontrol) 2823 + { 2824 + struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); 2825 + bool keep_iface = !!ucontrol->value.integer.value[0]; 2826 + 2827 + if (mixer->chip->keep_iface == keep_iface) 2828 + return 0; 2829 + mixer->chip->keep_iface = keep_iface; 2830 + return 1; 2831 + } 2832 + 2833 + static const struct snd_kcontrol_new keep_iface_ctl = { 2834 + .iface = SNDRV_CTL_ELEM_IFACE_CARD, 2835 + .name = "Keep Interface", 2836 + .info = snd_ctl_boolean_mono_info, 2837 + .get = keep_iface_ctl_get, 2838 + .put = keep_iface_ctl_put, 2839 + }; 2840 + 2841 + static int create_keep_iface_ctl(struct usb_mixer_interface *mixer) 2842 + { 2843 + struct snd_kcontrol *kctl = snd_ctl_new1(&keep_iface_ctl, mixer); 2844 + 2845 + /* need only one control per card */ 2846 + if (snd_ctl_find_id(mixer->chip->card, &kctl->id)) { 2847 + snd_ctl_free_one(kctl); 2848 + return 0; 2849 + } 2850 + 2851 + return snd_ctl_add(mixer->chip->card, kctl); 2852 + } 2853 + 3235 2854 int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 3236 2855 int ignore_error) 3237 2856 { ··· 3312 2847 break; 3313 2848 } 3314 2849 3315 - if ((err = snd_usb_mixer_controls(mixer)) < 0 || 3316 - (err = snd_usb_mixer_status_create(mixer)) < 0) 2850 + if (mixer->protocol == UAC_VERSION_3 && 2851 + chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { 2852 + err = snd_usb_mixer_controls_badd(mixer, ctrlif); 2853 + if (err < 0) 2854 + goto _error; 2855 + } else { 2856 + err = snd_usb_mixer_controls(mixer); 2857 + if (err < 0) 2858 + goto _error; 2859 + err = snd_usb_mixer_status_create(mixer); 2860 + if (err < 0) 2861 + goto _error; 2862 + } 2863 + err = create_keep_iface_ctl(mixer); 2864 + if (err < 0) 3317 2865 goto _error; 3318 2866 3319 2867 snd_usb_mixer_apply_create_quirk(mixer); ··· 3387 2909 3388 2910 static int restore_mixer_value(struct usb_mixer_elem_list *list) 3389 2911 { 3390 - struct usb_mixer_elem_info *cval = (struct usb_mixer_elem_info *)list; 2912 + struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list); 3391 2913 int c, err, idx; 3392 2914 3393 2915 if (cval->cmask) { ··· 3423 2945 if (reset_resume) { 3424 2946 /* restore cached mixer values */ 3425 2947 for (id = 0; id < MAX_ID_ELEMS; id++) { 3426 - for (list = mixer->id_elems[id]; list; 3427 - list = list->next_id_elem) { 2948 + for_each_mixer_elem(list, mixer, id) { 3428 2949 if (list->resume) { 3429 2950 err = list->resume(list); 3430 2951 if (err < 0) ··· 3432 2955 } 3433 2956 } 3434 2957 } 2958 + 2959 + snd_usb_mixer_resume_quirk(mixer); 3435 2960 3436 2961 return snd_usb_mixer_activate(mixer); 3437 2962 }
+6
sound/usb/mixer.h
··· 53 53 usb_mixer_elem_resume_func_t resume; 54 54 }; 55 55 56 + /* iterate over mixer element list of the given unit id */ 57 + #define for_each_mixer_elem(list, mixer, id) \ 58 + for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) 59 + #define mixer_elem_list_to_info(list) \ 60 + container_of(list, struct usb_mixer_elem_info, head) 61 + 56 62 struct usb_mixer_elem_info { 57 63 struct usb_mixer_elem_list head; 58 64 unsigned int control; /* CS or ICN (high byte) */
+65
sound/usb/mixer_maps.c
··· 485 485 { 0 } /* terminator */ 486 486 }; 487 487 488 + /* 489 + * Control map entries for UAC3 BADD profiles 490 + */ 491 + 492 + static struct usbmix_name_map uac3_badd_generic_io_map[] = { 493 + { UAC3_BADD_FU_ID2, "Generic Out Playback" }, 494 + { UAC3_BADD_FU_ID5, "Generic In Capture" }, 495 + { 0 } /* terminator */ 496 + }; 497 + static struct usbmix_name_map uac3_badd_headphone_map[] = { 498 + { UAC3_BADD_FU_ID2, "Headphone Playback" }, 499 + { 0 } /* terminator */ 500 + }; 501 + static struct usbmix_name_map uac3_badd_speaker_map[] = { 502 + { UAC3_BADD_FU_ID2, "Speaker Playback" }, 503 + { 0 } /* terminator */ 504 + }; 505 + static struct usbmix_name_map uac3_badd_microphone_map[] = { 506 + { UAC3_BADD_FU_ID5, "Mic Capture" }, 507 + { 0 } /* terminator */ 508 + }; 509 + /* Covers also 'headset adapter' profile */ 510 + static struct usbmix_name_map uac3_badd_headset_map[] = { 511 + { UAC3_BADD_FU_ID2, "Headset Playback" }, 512 + { UAC3_BADD_FU_ID5, "Headset Capture" }, 513 + { UAC3_BADD_FU_ID7, "Sidetone Mixing" }, 514 + { 0 } /* terminator */ 515 + }; 516 + static struct usbmix_name_map uac3_badd_speakerphone_map[] = { 517 + { UAC3_BADD_FU_ID2, "Speaker Playback" }, 518 + { UAC3_BADD_FU_ID5, "Mic Capture" }, 519 + { 0 } /* terminator */ 520 + }; 521 + 522 + static struct usbmix_ctl_map uac3_badd_usbmix_ctl_maps[] = { 523 + { 524 + .id = UAC3_FUNCTION_SUBCLASS_GENERIC_IO, 525 + .map = uac3_badd_generic_io_map, 526 + }, 527 + { 528 + .id = UAC3_FUNCTION_SUBCLASS_HEADPHONE, 529 + .map = uac3_badd_headphone_map, 530 + }, 531 + { 532 + .id = UAC3_FUNCTION_SUBCLASS_SPEAKER, 533 + .map = uac3_badd_speaker_map, 534 + }, 535 + { 536 + .id = UAC3_FUNCTION_SUBCLASS_MICROPHONE, 537 + .map = uac3_badd_microphone_map, 538 + }, 539 + { 540 + .id = UAC3_FUNCTION_SUBCLASS_HEADSET, 541 + .map = uac3_badd_headset_map, 542 + }, 543 + { 544 + .id = UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER, 545 + .map = uac3_badd_headset_map, 546 + }, 547 + { 548 + .id = UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE, 549 + .map = uac3_badd_speakerphone_map, 550 + }, 551 + { 0 } /* terminator */ 552 + };
+37 -2
sound/usb/mixer_quirks.c
··· 1172 1172 int unitid = 12; /* SamleRate ExtensionUnit ID */ 1173 1173 1174 1174 list_for_each_entry(mixer, &chip->mixer_list, list) { 1175 - cval = (struct usb_mixer_elem_info *)mixer->id_elems[unitid]; 1175 + cval = mixer_elem_list_to_info(mixer->id_elems[unitid]); 1176 1176 if (cval) { 1177 1177 snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, 1178 1178 cval->control << 8, ··· 1799 1799 NULL); 1800 1800 } 1801 1801 1802 + static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id) 1803 + { 1804 + u16 buf = 0; 1805 + 1806 + snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, 1807 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 1808 + ch, snd_usb_ctrl_intf(chip) | (id << 8), 1809 + &buf, 2); 1810 + } 1811 + 1812 + static int dell_dock_mixer_init(struct usb_mixer_interface *mixer) 1813 + { 1814 + /* fix to 0dB playback volumes */ 1815 + dell_dock_init_vol(mixer->chip, 1, 16); 1816 + dell_dock_init_vol(mixer->chip, 2, 16); 1817 + dell_dock_init_vol(mixer->chip, 1, 19); 1818 + dell_dock_init_vol(mixer->chip, 2, 19); 1819 + return 0; 1820 + } 1821 + 1802 1822 int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) 1803 1823 { 1804 1824 int err = 0; 1805 1825 struct snd_info_entry *entry; 1806 1826 1807 - if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) 1827 + err = snd_usb_soundblaster_remote_init(mixer); 1828 + if (err < 0) 1808 1829 return err; 1809 1830 1810 1831 switch (mixer->chip->usb_id) { ··· 1905 1884 case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ 1906 1885 err = snd_soundblaster_e1_switch_create(mixer); 1907 1886 break; 1887 + case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */ 1888 + err = dell_dock_mixer_init(mixer); 1889 + break; 1908 1890 } 1909 1891 1910 1892 return err; 1911 1893 } 1894 + 1895 + #ifdef CONFIG_PM 1896 + void snd_usb_mixer_resume_quirk(struct usb_mixer_interface *mixer) 1897 + { 1898 + switch (mixer->chip->usb_id) { 1899 + case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */ 1900 + dell_dock_mixer_init(mixer); 1901 + break; 1902 + } 1903 + } 1904 + #endif 1912 1905 1913 1906 void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, 1914 1907 int unitid)
+4
sound/usb/mixer_quirks.h
··· 14 14 struct usb_mixer_elem_info *cval, int unitid, 15 15 struct snd_kcontrol *kctl); 16 16 17 + #ifdef CONFIG_PM 18 + void snd_usb_mixer_resume_quirk(struct usb_mixer_interface *mixer); 19 + #endif 20 + 17 21 #endif /* SND_USB_MIXER_QUIRKS_H */ 18 22
+2 -4
sound/usb/mixer_scarlett.c
··· 287 287 288 288 static int scarlett_ctl_resume(struct usb_mixer_elem_list *list) 289 289 { 290 - struct usb_mixer_elem_info *elem = 291 - container_of(list, struct usb_mixer_elem_info, head); 290 + struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list); 292 291 int i; 293 292 294 293 for (i = 0; i < elem->channels; i++) ··· 446 447 447 448 static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list) 448 449 { 449 - struct usb_mixer_elem_info *elem = 450 - container_of(list, struct usb_mixer_elem_info, head); 450 + struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list); 451 451 452 452 if (elem->cached) 453 453 snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
+147 -121
sound/usb/pcm.c
··· 76 76 */ 77 77 static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream) 78 78 { 79 - struct snd_usb_substream *subs; 79 + struct snd_usb_substream *subs = substream->runtime->private_data; 80 80 unsigned int hwptr_done; 81 81 82 - subs = (struct snd_usb_substream *)substream->runtime->private_data; 83 82 if (atomic_read(&subs->stream->chip->shutdown)) 84 83 return SNDRV_PCM_POS_XRUN; 85 84 spin_lock(&subs->lock); ··· 163 164 ep = get_endpoint(alts, 0)->bEndpointAddress; 164 165 165 166 data[0] = 1; 166 - if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, 167 - USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 168 - UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, 169 - data, sizeof(data))) < 0) { 167 + err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, 168 + USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, 169 + UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, 170 + data, sizeof(data)); 171 + if (err < 0) { 170 172 usb_audio_err(chip, "%d:%d: cannot set enable PITCH\n", 171 173 iface, ep); 172 174 return err; ··· 185 185 int err; 186 186 187 187 data[0] = 1; 188 - if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, 189 - USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, 190 - UAC2_EP_CS_PITCH << 8, 0, 191 - data, sizeof(data))) < 0) { 188 + err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, 189 + USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, 190 + UAC2_EP_CS_PITCH << 8, 0, 191 + data, sizeof(data)); 192 + if (err < 0) { 192 193 usb_audio_err(chip, "%d:%d: cannot set enable PITCH (v2)\n", 193 194 iface, fmt->altsetting); 194 195 return err; ··· 322 321 struct usb_host_interface *alts; 323 322 struct usb_interface *iface; 324 323 unsigned int ep; 324 + unsigned int ifnum; 325 325 326 326 /* Implicit feedback sync EPs consumers are always playback EPs */ 327 327 if (subs->direction != SNDRV_PCM_STREAM_PLAYBACK) ··· 332 330 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ 333 331 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ 334 332 ep = 0x81; 335 - iface = usb_ifnum_to_if(dev, 3); 336 - 337 - if (!iface || iface->num_altsetting == 0) 338 - return -EINVAL; 339 - 340 - alts = &iface->altsetting[1]; 341 - goto add_sync_ep; 342 - break; 333 + ifnum = 3; 334 + goto add_sync_ep_from_ifnum; 343 335 case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */ 344 336 case USB_ID(0x0763, 0x2081): 345 337 ep = 0x81; 346 - iface = usb_ifnum_to_if(dev, 2); 347 - 348 - if (!iface || iface->num_altsetting == 0) 349 - return -EINVAL; 350 - 351 - alts = &iface->altsetting[1]; 352 - goto add_sync_ep; 353 - case USB_ID(0x2466, 0x8003): 338 + ifnum = 2; 339 + goto add_sync_ep_from_ifnum; 340 + case USB_ID(0x2466, 0x8003): /* Fractal Audio Axe-Fx II */ 354 341 ep = 0x86; 355 - iface = usb_ifnum_to_if(dev, 2); 356 - 357 - if (!iface || iface->num_altsetting == 0) 358 - return -EINVAL; 359 - 360 - alts = &iface->altsetting[1]; 361 - goto add_sync_ep; 362 - case USB_ID(0x1397, 0x0002): 342 + ifnum = 2; 343 + goto add_sync_ep_from_ifnum; 344 + case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx III */ 363 345 ep = 0x81; 364 - iface = usb_ifnum_to_if(dev, 1); 365 - 366 - if (!iface || iface->num_altsetting == 0) 367 - return -EINVAL; 368 - 369 - alts = &iface->altsetting[1]; 370 - goto add_sync_ep; 371 - 346 + ifnum = 2; 347 + goto add_sync_ep_from_ifnum; 348 + case USB_ID(0x1397, 0x0002): /* Behringer UFX1204 */ 349 + ep = 0x81; 350 + ifnum = 1; 351 + goto add_sync_ep_from_ifnum; 372 352 } 353 + 373 354 if (attr == USB_ENDPOINT_SYNC_ASYNC && 374 355 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && 375 356 altsd->bInterfaceProtocol == 2 && ··· 366 381 367 382 /* No quirk */ 368 383 return 0; 384 + 385 + add_sync_ep_from_ifnum: 386 + iface = usb_ifnum_to_if(dev, ifnum); 387 + 388 + if (!iface || iface->num_altsetting == 0) 389 + return -EINVAL; 390 + 391 + alts = &iface->altsetting[1]; 369 392 370 393 add_sync_ep: 371 394 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip, ··· 500 507 iface = usb_ifnum_to_if(dev, fmt->iface); 501 508 if (WARN_ON(!iface)) 502 509 return -EINVAL; 503 - alts = &iface->altsetting[fmt->altset_idx]; 510 + alts = usb_altnum_to_altsetting(iface, fmt->altsetting); 504 511 altsd = get_iface_desc(alts); 505 512 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting)) 506 513 return -EINVAL; ··· 510 517 511 518 /* close the old interface */ 512 519 if (subs->interface >= 0 && subs->interface != fmt->iface) { 513 - err = usb_set_interface(subs->dev, subs->interface, 0); 514 - if (err < 0) { 515 - dev_err(&dev->dev, 516 - "%d:%d: return to setting 0 failed (%d)\n", 517 - fmt->iface, fmt->altsetting, err); 518 - return -EIO; 520 + if (!subs->stream->chip->keep_iface) { 521 + err = usb_set_interface(subs->dev, subs->interface, 0); 522 + if (err < 0) { 523 + dev_err(&dev->dev, 524 + "%d:%d: return to setting 0 failed (%d)\n", 525 + fmt->iface, fmt->altsetting, err); 526 + return -EIO; 527 + } 519 528 } 520 529 subs->interface = -1; 521 530 subs->altset_idx = 0; 522 531 } 523 532 524 533 /* set interface */ 525 - if (subs->interface != fmt->iface || 526 - subs->altset_idx != fmt->altset_idx) { 527 - 534 + if (iface->cur_altsetting != alts) { 528 535 err = snd_usb_select_mode_quirk(subs, fmt); 529 536 if (err < 0) 530 537 return -EIO; ··· 538 545 } 539 546 dev_dbg(&dev->dev, "setting usb interface %d:%d\n", 540 547 fmt->iface, fmt->altsetting); 541 - subs->interface = fmt->iface; 542 - subs->altset_idx = fmt->altset_idx; 543 - 544 548 snd_usb_set_interface_quirk(dev); 545 549 } 546 550 551 + subs->interface = fmt->iface; 552 + subs->altset_idx = fmt->altset_idx; 547 553 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, 548 554 alts, fmt->endpoint, subs->direction, 549 555 SND_USB_ENDPOINT_TYPE_DATA); ··· 728 736 struct audioformat *fmt; 729 737 int ret; 730 738 731 - ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, 739 + if (snd_usb_use_vmalloc) 740 + ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, 741 + params_buffer_bytes(hw_params)); 742 + else 743 + ret = snd_pcm_lib_malloc_pages(substream, 732 744 params_buffer_bytes(hw_params)); 733 745 if (ret < 0) 734 746 return ret; ··· 785 789 snd_usb_endpoint_deactivate(subs->data_endpoint); 786 790 snd_usb_unlock_shutdown(subs->stream->chip); 787 791 } 788 - return snd_pcm_lib_free_vmalloc_buffer(substream); 792 + 793 + if (snd_usb_use_vmalloc) 794 + return snd_pcm_lib_free_vmalloc_buffer(substream); 795 + else 796 + return snd_pcm_lib_free_pages(substream); 789 797 } 790 798 791 799 /* ··· 1181 1181 pt = 125 * (1 << fp->datainterval); 1182 1182 ptmin = min(ptmin, pt); 1183 1183 } 1184 - err = snd_usb_autoresume(subs->stream->chip); 1185 - if (err < 0) 1186 - return err; 1187 1184 1188 1185 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; 1189 1186 if (subs->speed == USB_SPEED_FULL) ··· 1189 1192 if (ptmin == 1000) 1190 1193 /* if period time doesn't go below 1 ms, no rules needed */ 1191 1194 param_period_time_if_needed = -1; 1192 - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1193 - ptmin, UINT_MAX); 1194 1195 1195 - if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1196 - hw_rule_rate, subs, 1197 - SNDRV_PCM_HW_PARAM_FORMAT, 1198 - SNDRV_PCM_HW_PARAM_CHANNELS, 1199 - param_period_time_if_needed, 1200 - -1)) < 0) 1201 - goto rep_err; 1202 - if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1203 - hw_rule_channels, subs, 1204 - SNDRV_PCM_HW_PARAM_FORMAT, 1205 - SNDRV_PCM_HW_PARAM_RATE, 1206 - param_period_time_if_needed, 1207 - -1)) < 0) 1208 - goto rep_err; 1209 - if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, 1210 - hw_rule_format, subs, 1211 - SNDRV_PCM_HW_PARAM_RATE, 1212 - SNDRV_PCM_HW_PARAM_CHANNELS, 1213 - param_period_time_if_needed, 1214 - -1)) < 0) 1215 - goto rep_err; 1196 + err = snd_pcm_hw_constraint_minmax(runtime, 1197 + SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1198 + ptmin, UINT_MAX); 1199 + if (err < 0) 1200 + return err; 1201 + 1202 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1203 + hw_rule_rate, subs, 1204 + SNDRV_PCM_HW_PARAM_FORMAT, 1205 + SNDRV_PCM_HW_PARAM_CHANNELS, 1206 + param_period_time_if_needed, 1207 + -1); 1208 + if (err < 0) 1209 + return err; 1210 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1211 + hw_rule_channels, subs, 1212 + SNDRV_PCM_HW_PARAM_FORMAT, 1213 + SNDRV_PCM_HW_PARAM_RATE, 1214 + param_period_time_if_needed, 1215 + -1); 1216 + if (err < 0) 1217 + return err; 1218 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, 1219 + hw_rule_format, subs, 1220 + SNDRV_PCM_HW_PARAM_RATE, 1221 + SNDRV_PCM_HW_PARAM_CHANNELS, 1222 + param_period_time_if_needed, 1223 + -1); 1224 + if (err < 0) 1225 + return err; 1216 1226 if (param_period_time_if_needed >= 0) { 1217 1227 err = snd_pcm_hw_rule_add(runtime, 0, 1218 1228 SNDRV_PCM_HW_PARAM_PERIOD_TIME, ··· 1229 1225 SNDRV_PCM_HW_PARAM_RATE, 1230 1226 -1); 1231 1227 if (err < 0) 1232 - goto rep_err; 1228 + return err; 1233 1229 } 1234 - if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0) 1235 - goto rep_err; 1236 - return 0; 1230 + err = snd_usb_pcm_check_knot(runtime, subs); 1231 + if (err < 0) 1232 + return err; 1237 1233 1238 - rep_err: 1239 - snd_usb_autosuspend(subs->stream->chip); 1240 - return err; 1234 + return snd_usb_autoresume(subs->stream->chip); 1241 1235 } 1242 1236 1243 - static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) 1237 + static int snd_usb_pcm_open(struct snd_pcm_substream *substream) 1244 1238 { 1239 + int direction = substream->stream; 1245 1240 struct snd_usb_stream *as = snd_pcm_substream_chip(substream); 1246 1241 struct snd_pcm_runtime *runtime = substream->runtime; 1247 1242 struct snd_usb_substream *subs = &as->substream[direction]; ··· 1260 1257 return setup_hw_info(runtime, subs); 1261 1258 } 1262 1259 1263 - static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) 1260 + static int snd_usb_pcm_close(struct snd_pcm_substream *substream) 1264 1261 { 1262 + int direction = substream->stream; 1265 1263 struct snd_usb_stream *as = snd_pcm_substream_chip(substream); 1266 1264 struct snd_usb_substream *subs = &as->substream[direction]; 1267 1265 1268 1266 stop_endpoints(subs, true); 1269 1267 1270 - if (subs->interface >= 0 && 1268 + if (!as->chip->keep_iface && 1269 + subs->interface >= 0 && 1271 1270 !snd_usb_lock_shutdown(subs->stream->chip)) { 1272 1271 usb_set_interface(subs->dev, subs->interface, 0); 1273 1272 subs->interface = -1; ··· 1316 1311 if (bytes % (runtime->sample_bits >> 3) != 0) { 1317 1312 int oldbytes = bytes; 1318 1313 bytes = frames * stride; 1319 - dev_warn(&subs->dev->dev, 1314 + dev_warn_ratelimited(&subs->dev->dev, 1320 1315 "Corrected urb data len. %d->%d\n", 1321 1316 oldbytes, bytes); 1322 1317 } ··· 1624 1619 spin_unlock_irqrestore(&subs->lock, flags); 1625 1620 } 1626 1621 1627 - static int snd_usb_playback_open(struct snd_pcm_substream *substream) 1628 - { 1629 - return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK); 1630 - } 1631 - 1632 - static int snd_usb_playback_close(struct snd_pcm_substream *substream) 1633 - { 1634 - return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK); 1635 - } 1636 - 1637 - static int snd_usb_capture_open(struct snd_pcm_substream *substream) 1638 - { 1639 - return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE); 1640 - } 1641 - 1642 - static int snd_usb_capture_close(struct snd_pcm_substream *substream) 1643 - { 1644 - return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE); 1645 - } 1646 - 1647 1622 static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, 1648 1623 int cmd) 1649 1624 { ··· 1685 1700 } 1686 1701 1687 1702 static const struct snd_pcm_ops snd_usb_playback_ops = { 1688 - .open = snd_usb_playback_open, 1689 - .close = snd_usb_playback_close, 1703 + .open = snd_usb_pcm_open, 1704 + .close = snd_usb_pcm_close, 1690 1705 .ioctl = snd_pcm_lib_ioctl, 1691 1706 .hw_params = snd_usb_hw_params, 1692 1707 .hw_free = snd_usb_hw_free, ··· 1698 1713 }; 1699 1714 1700 1715 static const struct snd_pcm_ops snd_usb_capture_ops = { 1701 - .open = snd_usb_capture_open, 1702 - .close = snd_usb_capture_close, 1716 + .open = snd_usb_pcm_open, 1717 + .close = snd_usb_pcm_close, 1703 1718 .ioctl = snd_pcm_lib_ioctl, 1704 1719 .hw_params = snd_usb_hw_params, 1705 1720 .hw_free = snd_usb_hw_free, ··· 1710 1725 .mmap = snd_pcm_lib_mmap_vmalloc, 1711 1726 }; 1712 1727 1728 + static const struct snd_pcm_ops snd_usb_playback_dev_ops = { 1729 + .open = snd_usb_pcm_open, 1730 + .close = snd_usb_pcm_close, 1731 + .ioctl = snd_pcm_lib_ioctl, 1732 + .hw_params = snd_usb_hw_params, 1733 + .hw_free = snd_usb_hw_free, 1734 + .prepare = snd_usb_pcm_prepare, 1735 + .trigger = snd_usb_substream_playback_trigger, 1736 + .pointer = snd_usb_pcm_pointer, 1737 + .page = snd_pcm_sgbuf_ops_page, 1738 + }; 1739 + 1740 + static const struct snd_pcm_ops snd_usb_capture_dev_ops = { 1741 + .open = snd_usb_pcm_open, 1742 + .close = snd_usb_pcm_close, 1743 + .ioctl = snd_pcm_lib_ioctl, 1744 + .hw_params = snd_usb_hw_params, 1745 + .hw_free = snd_usb_hw_free, 1746 + .prepare = snd_usb_pcm_prepare, 1747 + .trigger = snd_usb_substream_capture_trigger, 1748 + .pointer = snd_usb_pcm_pointer, 1749 + .page = snd_pcm_sgbuf_ops_page, 1750 + }; 1751 + 1713 1752 void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream) 1714 1753 { 1715 - snd_pcm_set_ops(pcm, stream, 1716 - stream == SNDRV_PCM_STREAM_PLAYBACK ? 1717 - &snd_usb_playback_ops : &snd_usb_capture_ops); 1754 + const struct snd_pcm_ops *ops; 1755 + 1756 + if (snd_usb_use_vmalloc) 1757 + ops = stream == SNDRV_PCM_STREAM_PLAYBACK ? 1758 + &snd_usb_playback_ops : &snd_usb_capture_ops; 1759 + else 1760 + ops = stream == SNDRV_PCM_STREAM_PLAYBACK ? 1761 + &snd_usb_playback_dev_ops : &snd_usb_capture_dev_ops; 1762 + snd_pcm_set_ops(pcm, stream, ops); 1763 + } 1764 + 1765 + void snd_usb_preallocate_buffer(struct snd_usb_substream *subs) 1766 + { 1767 + struct snd_pcm *pcm = subs->stream->pcm; 1768 + struct snd_pcm_substream *s = pcm->streams[subs->direction].substream; 1769 + struct device *dev = subs->dev->bus->controller; 1770 + 1771 + if (!snd_usb_use_vmalloc) 1772 + snd_pcm_lib_preallocate_pages(s, SNDRV_DMA_TYPE_DEV_SG, 1773 + dev, 64*1024, 512*1024); 1718 1774 }
+1
sound/usb/pcm.h
··· 10 10 int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, 11 11 struct usb_host_interface *alts, 12 12 struct audioformat *fmt); 13 + void snd_usb_preallocate_buffer(struct snd_usb_substream *subs); 13 14 14 15 15 16 #endif /* __USBAUDIO_PCM_H */
+10
sound/usb/quirks-table.h
··· 3371 3371 } 3372 3372 } 3373 3373 }, 3374 + /* Dell WD15 Dock */ 3375 + { 3376 + USB_DEVICE(0x0bda, 0x4014), 3377 + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 3378 + .vendor_name = "Dell", 3379 + .product_name = "WD15 Dock", 3380 + .profile_name = "Dell-WD15-Dock", 3381 + .ifnum = QUIRK_NO_INTERFACE 3382 + } 3383 + }, 3374 3384 3375 3385 #undef USB_DEVICE_VENDOR_SPEC
+59
sound/usb/quirks.c
··· 851 851 return 0; /* Successful boot */ 852 852 } 853 853 854 + static int snd_usb_axefx3_boot_quirk(struct usb_device *dev) 855 + { 856 + int err; 857 + 858 + dev_dbg(&dev->dev, "Waiting for Axe-Fx III to boot up...\n"); 859 + 860 + /* If the Axe-Fx III has not fully booted, it will timeout when trying 861 + * to enable the audio streaming interface. A more generous timeout is 862 + * used here to detect when the Axe-Fx III has finished booting as the 863 + * set interface message will be acked once it has 864 + */ 865 + err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 866 + USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, 867 + 1, 1, NULL, 0, 120000); 868 + if (err < 0) { 869 + dev_err(&dev->dev, 870 + "failed waiting for Axe-Fx III to boot: %d\n", err); 871 + return err; 872 + } 873 + 874 + dev_dbg(&dev->dev, "Axe-Fx III is now ready\n"); 875 + 876 + err = usb_set_interface(dev, 1, 0); 877 + if (err < 0) 878 + dev_dbg(&dev->dev, 879 + "error stopping Axe-Fx III interface: %d\n", err); 880 + 881 + return 0; 882 + } 883 + 854 884 /* 855 885 * Setup quirks 856 886 */ ··· 1056 1026 return snd_usb_fasttrackpro_boot_quirk(dev); 1057 1027 case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */ 1058 1028 return snd_usb_gamecon780_boot_quirk(dev); 1029 + case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */ 1030 + return snd_usb_axefx3_boot_quirk(dev); 1059 1031 } 1060 1032 1061 1033 return 0; ··· 1359 1327 1360 1328 /* XMOS based USB DACs */ 1361 1329 switch (chip->usb_id) { 1330 + case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ 1331 + case USB_ID(0x20b1, 0x0002): /* Wyred 4 Sound DAC-2 DSD */ 1332 + case USB_ID(0x20b1, 0x2004): /* Matrix Audio X-SPDIF 2 */ 1362 1333 case USB_ID(0x20b1, 0x3008): /* iFi Audio micro/nano iDSD */ 1363 1334 case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ 1364 1335 case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ 1365 1336 case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ 1337 + case USB_ID(0x22d9, 0x0436): /* OPPO Sonica */ 1338 + case USB_ID(0x22d9, 0x0461): /* OPPO UDP-205 */ 1339 + case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ 1340 + case USB_ID(0x25ce, 0x001f): /* Mytek Brooklyn DAC */ 1341 + case USB_ID(0x25ce, 0x0021): /* Mytek Manhattan DAC */ 1342 + case USB_ID(0x25ce, 0x8025): /* Mytek Brooklyn DAC+ */ 1366 1343 case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ 1367 1344 if (fp->altsetting == 2) 1368 1345 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1369 1346 break; 1370 1347 1348 + case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ 1349 + case USB_ID(0x16b0, 0x06b2): /* NuPrime DAC-10 */ 1350 + case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ 1351 + case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ 1352 + case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */ 1371 1353 case USB_ID(0x20b1, 0x000a): /* Gustard DAC-X20U */ 1354 + case USB_ID(0x20b1, 0x2005): /* Denafrips Ares DAC */ 1372 1355 case USB_ID(0x20b1, 0x2009): /* DIYINHK DSD DXD 384kHz USB to I2S/DSD */ 1373 1356 case USB_ID(0x20b1, 0x2023): /* JLsounds I2SoverUSB */ 1357 + case USB_ID(0x20b1, 0x3021): /* Eastern El. MiniMax Tube DAC Supreme */ 1374 1358 case USB_ID(0x20b1, 0x3023): /* Aune X1S 32BIT/384 DSD DAC */ 1359 + case USB_ID(0x20b1, 0x302d): /* Unison Research Unico CD Due */ 1360 + case USB_ID(0x20b1, 0x3036): /* Holo Springs Level 3 R2R DAC */ 1361 + case USB_ID(0x20b1, 0x307b): /* CH Precision C1 DAC */ 1362 + case USB_ID(0x20b1, 0x3086): /* Singxer F-1 converter board */ 1363 + case USB_ID(0x22d9, 0x0426): /* OPPO HA-2 */ 1364 + case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */ 1365 + case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */ 1375 1366 case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ 1367 + case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */ 1368 + case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */ 1369 + case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */ 1370 + case USB_ID(0x6b42, 0x0042): /* MSB Technology */ 1376 1371 if (fp->altsetting == 3) 1377 1372 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1378 1373 break;
+412 -281
sound/usb/stream.c
··· 106 106 subs->ep_num = fp->endpoint; 107 107 if (fp->channels > subs->channels_max) 108 108 subs->channels_max = fp->channels; 109 + 110 + snd_usb_preallocate_buffer(subs); 109 111 } 110 112 111 113 /* kctl callbacks for usb-audio channel maps */ ··· 635 633 return NULL; 636 634 } 637 635 636 + static struct audioformat * 637 + audio_format_alloc_init(struct snd_usb_audio *chip, 638 + struct usb_host_interface *alts, 639 + int protocol, int iface_no, int altset_idx, 640 + int altno, int num_channels, int clock) 641 + { 642 + struct audioformat *fp; 643 + 644 + fp = kzalloc(sizeof(*fp), GFP_KERNEL); 645 + if (!fp) 646 + return NULL; 647 + 648 + fp->iface = iface_no; 649 + fp->altsetting = altno; 650 + fp->altset_idx = altset_idx; 651 + fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; 652 + fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; 653 + fp->datainterval = snd_usb_parse_datainterval(chip, alts); 654 + fp->protocol = protocol; 655 + fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 656 + fp->channels = num_channels; 657 + if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH) 658 + fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 659 + * (fp->maxpacksize & 0x7ff); 660 + fp->clock = clock; 661 + INIT_LIST_HEAD(&fp->list); 662 + 663 + return fp; 664 + } 665 + 666 + static struct audioformat * 667 + snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip, 668 + struct usb_host_interface *alts, 669 + int protocol, int iface_no, int altset_idx, 670 + int altno, int stream, int bm_quirk) 671 + { 672 + struct usb_device *dev = chip->dev; 673 + struct uac_format_type_i_continuous_descriptor *fmt; 674 + unsigned int num_channels = 0, chconfig = 0; 675 + struct audioformat *fp; 676 + int clock = 0; 677 + u64 format; 678 + 679 + /* get audio formats */ 680 + if (protocol == UAC_VERSION_1) { 681 + struct uac1_as_header_descriptor *as = 682 + snd_usb_find_csint_desc(alts->extra, alts->extralen, 683 + NULL, UAC_AS_GENERAL); 684 + struct uac_input_terminal_descriptor *iterm; 685 + 686 + if (!as) { 687 + dev_err(&dev->dev, 688 + "%u:%d : UAC_AS_GENERAL descriptor not found\n", 689 + iface_no, altno); 690 + return NULL; 691 + } 692 + 693 + if (as->bLength < sizeof(*as)) { 694 + dev_err(&dev->dev, 695 + "%u:%d : invalid UAC_AS_GENERAL desc\n", 696 + iface_no, altno); 697 + return NULL; 698 + } 699 + 700 + format = le16_to_cpu(as->wFormatTag); /* remember the format value */ 701 + 702 + iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, 703 + as->bTerminalLink); 704 + if (iterm) { 705 + num_channels = iterm->bNrChannels; 706 + chconfig = le16_to_cpu(iterm->wChannelConfig); 707 + } 708 + } else { /* UAC_VERSION_2 */ 709 + struct uac2_input_terminal_descriptor *input_term; 710 + struct uac2_output_terminal_descriptor *output_term; 711 + struct uac2_as_header_descriptor *as = 712 + snd_usb_find_csint_desc(alts->extra, alts->extralen, 713 + NULL, UAC_AS_GENERAL); 714 + 715 + if (!as) { 716 + dev_err(&dev->dev, 717 + "%u:%d : UAC_AS_GENERAL descriptor not found\n", 718 + iface_no, altno); 719 + return NULL; 720 + } 721 + 722 + if (as->bLength < sizeof(*as)) { 723 + dev_err(&dev->dev, 724 + "%u:%d : invalid UAC_AS_GENERAL desc\n", 725 + iface_no, altno); 726 + return NULL; 727 + } 728 + 729 + num_channels = as->bNrChannels; 730 + format = le32_to_cpu(as->bmFormats); 731 + chconfig = le32_to_cpu(as->bmChannelConfig); 732 + 733 + /* 734 + * lookup the terminal associated to this interface 735 + * to extract the clock 736 + */ 737 + input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, 738 + as->bTerminalLink); 739 + if (input_term) { 740 + clock = input_term->bCSourceID; 741 + if (!chconfig && (num_channels == input_term->bNrChannels)) 742 + chconfig = le32_to_cpu(input_term->bmChannelConfig); 743 + goto found_clock; 744 + } 745 + 746 + output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, 747 + as->bTerminalLink); 748 + if (output_term) { 749 + clock = output_term->bCSourceID; 750 + goto found_clock; 751 + } 752 + 753 + dev_err(&dev->dev, 754 + "%u:%d : bogus bTerminalLink %d\n", 755 + iface_no, altno, as->bTerminalLink); 756 + return NULL; 757 + } 758 + 759 + found_clock: 760 + /* get format type */ 761 + fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, 762 + NULL, UAC_FORMAT_TYPE); 763 + if (!fmt) { 764 + dev_err(&dev->dev, 765 + "%u:%d : no UAC_FORMAT_TYPE desc\n", 766 + iface_no, altno); 767 + return NULL; 768 + } 769 + if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) 770 + || ((protocol == UAC_VERSION_2) && 771 + (fmt->bLength < 6))) { 772 + dev_err(&dev->dev, 773 + "%u:%d : invalid UAC_FORMAT_TYPE desc\n", 774 + iface_no, altno); 775 + return NULL; 776 + } 777 + 778 + /* 779 + * Blue Microphones workaround: The last altsetting is 780 + * identical with the previous one, except for a larger 781 + * packet size, but is actually a mislabeled two-channel 782 + * setting; ignore it. 783 + * 784 + * Part 2: analyze quirk flag and format 785 + */ 786 + if (bm_quirk && fmt->bNrChannels == 1 && fmt->bSubframeSize == 2) 787 + return NULL; 788 + 789 + fp = audio_format_alloc_init(chip, alts, protocol, iface_no, 790 + altset_idx, altno, num_channels, clock); 791 + if (!fp) 792 + return ERR_PTR(-ENOMEM); 793 + 794 + fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, 795 + iface_no); 796 + 797 + /* some quirks for attributes here */ 798 + snd_usb_audioformat_attributes_quirk(chip, fp, stream); 799 + 800 + /* ok, let's parse further... */ 801 + if (snd_usb_parse_audio_format(chip, fp, format, 802 + fmt, stream) < 0) { 803 + kfree(fp->rate_table); 804 + kfree(fp); 805 + return NULL; 806 + } 807 + 808 + /* Create chmap */ 809 + if (fp->channels != num_channels) 810 + chconfig = 0; 811 + 812 + fp->chmap = convert_chmap(fp->channels, chconfig, protocol); 813 + 814 + return fp; 815 + } 816 + 817 + static struct audioformat * 818 + snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, 819 + struct usb_host_interface *alts, 820 + int iface_no, int altset_idx, 821 + int altno, int stream) 822 + { 823 + struct usb_device *dev = chip->dev; 824 + struct uac3_input_terminal_descriptor *input_term; 825 + struct uac3_output_terminal_descriptor *output_term; 826 + struct uac3_cluster_header_descriptor *cluster; 827 + struct uac3_as_header_descriptor *as = NULL; 828 + struct uac3_hc_descriptor_header hc_header; 829 + struct snd_pcm_chmap_elem *chmap; 830 + unsigned char badd_profile; 831 + u64 badd_formats = 0; 832 + unsigned int num_channels; 833 + struct audioformat *fp; 834 + u16 cluster_id, wLength; 835 + int clock = 0; 836 + int err; 837 + 838 + badd_profile = chip->badd_profile; 839 + 840 + if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { 841 + unsigned int maxpacksize = 842 + le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 843 + 844 + switch (maxpacksize) { 845 + default: 846 + dev_err(&dev->dev, 847 + "%u:%d : incorrect wMaxPacketSize for BADD profile\n", 848 + iface_no, altno); 849 + return NULL; 850 + case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16: 851 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16: 852 + badd_formats = SNDRV_PCM_FMTBIT_S16_LE; 853 + num_channels = 1; 854 + break; 855 + case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24: 856 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24: 857 + badd_formats = SNDRV_PCM_FMTBIT_S24_3LE; 858 + num_channels = 1; 859 + break; 860 + case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16: 861 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16: 862 + badd_formats = SNDRV_PCM_FMTBIT_S16_LE; 863 + num_channels = 2; 864 + break; 865 + case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24: 866 + case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24: 867 + badd_formats = SNDRV_PCM_FMTBIT_S24_3LE; 868 + num_channels = 2; 869 + break; 870 + } 871 + 872 + chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); 873 + if (!chmap) 874 + return ERR_PTR(-ENOMEM); 875 + 876 + if (num_channels == 1) { 877 + chmap->map[0] = SNDRV_CHMAP_MONO; 878 + } else { 879 + chmap->map[0] = SNDRV_CHMAP_FL; 880 + chmap->map[1] = SNDRV_CHMAP_FR; 881 + } 882 + 883 + chmap->channels = num_channels; 884 + clock = UAC3_BADD_CS_ID9; 885 + goto found_clock; 886 + } 887 + 888 + as = snd_usb_find_csint_desc(alts->extra, alts->extralen, 889 + NULL, UAC_AS_GENERAL); 890 + if (!as) { 891 + dev_err(&dev->dev, 892 + "%u:%d : UAC_AS_GENERAL descriptor not found\n", 893 + iface_no, altno); 894 + return NULL; 895 + } 896 + 897 + if (as->bLength < sizeof(*as)) { 898 + dev_err(&dev->dev, 899 + "%u:%d : invalid UAC_AS_GENERAL desc\n", 900 + iface_no, altno); 901 + return NULL; 902 + } 903 + 904 + cluster_id = le16_to_cpu(as->wClusterDescrID); 905 + if (!cluster_id) { 906 + dev_err(&dev->dev, 907 + "%u:%d : no cluster descriptor\n", 908 + iface_no, altno); 909 + return NULL; 910 + } 911 + 912 + /* 913 + * Get number of channels and channel map through 914 + * High Capability Cluster Descriptor 915 + * 916 + * First step: get High Capability header and 917 + * read size of Cluster Descriptor 918 + */ 919 + err = snd_usb_ctl_msg(chip->dev, 920 + usb_rcvctrlpipe(chip->dev, 0), 921 + UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, 922 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 923 + cluster_id, 924 + snd_usb_ctrl_intf(chip), 925 + &hc_header, sizeof(hc_header)); 926 + if (err < 0) 927 + return ERR_PTR(err); 928 + else if (err != sizeof(hc_header)) { 929 + dev_err(&dev->dev, 930 + "%u:%d : can't get High Capability descriptor\n", 931 + iface_no, altno); 932 + return ERR_PTR(-EIO); 933 + } 934 + 935 + /* 936 + * Second step: allocate needed amount of memory 937 + * and request Cluster Descriptor 938 + */ 939 + wLength = le16_to_cpu(hc_header.wLength); 940 + cluster = kzalloc(wLength, GFP_KERNEL); 941 + if (!cluster) 942 + return ERR_PTR(-ENOMEM); 943 + err = snd_usb_ctl_msg(chip->dev, 944 + usb_rcvctrlpipe(chip->dev, 0), 945 + UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, 946 + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 947 + cluster_id, 948 + snd_usb_ctrl_intf(chip), 949 + cluster, wLength); 950 + if (err < 0) { 951 + kfree(cluster); 952 + return ERR_PTR(err); 953 + } else if (err != wLength) { 954 + dev_err(&dev->dev, 955 + "%u:%d : can't get Cluster Descriptor\n", 956 + iface_no, altno); 957 + kfree(cluster); 958 + return ERR_PTR(-EIO); 959 + } 960 + 961 + num_channels = cluster->bNrChannels; 962 + chmap = convert_chmap_v3(cluster); 963 + kfree(cluster); 964 + 965 + /* 966 + * lookup the terminal associated to this interface 967 + * to extract the clock 968 + */ 969 + input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, 970 + as->bTerminalLink); 971 + if (input_term) { 972 + clock = input_term->bCSourceID; 973 + goto found_clock; 974 + } 975 + 976 + output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, 977 + as->bTerminalLink); 978 + if (output_term) { 979 + clock = output_term->bCSourceID; 980 + goto found_clock; 981 + } 982 + 983 + dev_err(&dev->dev, "%u:%d : bogus bTerminalLink %d\n", 984 + iface_no, altno, as->bTerminalLink); 985 + kfree(chmap); 986 + return NULL; 987 + 988 + found_clock: 989 + fp = audio_format_alloc_init(chip, alts, UAC_VERSION_3, iface_no, 990 + altset_idx, altno, num_channels, clock); 991 + if (!fp) { 992 + kfree(chmap); 993 + return ERR_PTR(-ENOMEM); 994 + } 995 + 996 + fp->chmap = chmap; 997 + 998 + if (badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) { 999 + fp->attributes = 0; /* No attributes */ 1000 + 1001 + fp->fmt_type = UAC_FORMAT_TYPE_I; 1002 + fp->formats = badd_formats; 1003 + 1004 + fp->nr_rates = 0; /* SNDRV_PCM_RATE_CONTINUOUS */ 1005 + fp->rate_min = UAC3_BADD_SAMPLING_RATE; 1006 + fp->rate_max = UAC3_BADD_SAMPLING_RATE; 1007 + fp->rates = SNDRV_PCM_RATE_CONTINUOUS; 1008 + 1009 + } else { 1010 + fp->attributes = parse_uac_endpoint_attributes(chip, alts, 1011 + UAC_VERSION_3, 1012 + iface_no); 1013 + /* ok, let's parse further... */ 1014 + if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) { 1015 + kfree(fp->chmap); 1016 + kfree(fp->rate_table); 1017 + kfree(fp); 1018 + return NULL; 1019 + } 1020 + } 1021 + 1022 + return fp; 1023 + } 1024 + 638 1025 int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) 639 1026 { 640 1027 struct usb_device *dev; ··· 1031 640 struct usb_host_interface *alts; 1032 641 struct usb_interface_descriptor *altsd; 1033 642 int i, altno, err, stream; 1034 - u64 format = 0; 1035 - unsigned int num_channels = 0; 1036 643 struct audioformat *fp = NULL; 1037 - int num, protocol, clock = 0; 1038 - struct uac_format_type_i_continuous_descriptor *fmt = NULL; 1039 - struct snd_pcm_chmap_elem *chmap_v3 = NULL; 1040 - unsigned int chconfig; 644 + int num, protocol; 1041 645 1042 646 dev = chip->dev; 1043 647 ··· 1081 695 protocol <= 2) 1082 696 protocol = UAC_VERSION_1; 1083 697 1084 - chconfig = 0; 1085 - /* get audio formats */ 1086 698 switch (protocol) { 1087 699 default: 1088 700 dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n", 1089 701 iface_no, altno, protocol); 1090 702 protocol = UAC_VERSION_1; 1091 703 /* fall through */ 1092 - 1093 - case UAC_VERSION_1: { 1094 - struct uac1_as_header_descriptor *as = 1095 - snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 1096 - struct uac_input_terminal_descriptor *iterm; 1097 - 1098 - if (!as) { 1099 - dev_err(&dev->dev, 1100 - "%u:%d : UAC_AS_GENERAL descriptor not found\n", 1101 - iface_no, altno); 1102 - continue; 1103 - } 1104 - 1105 - if (as->bLength < sizeof(*as)) { 1106 - dev_err(&dev->dev, 1107 - "%u:%d : invalid UAC_AS_GENERAL desc\n", 1108 - iface_no, altno); 1109 - continue; 1110 - } 1111 - 1112 - format = le16_to_cpu(as->wFormatTag); /* remember the format value */ 1113 - 1114 - iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, 1115 - as->bTerminalLink); 1116 - if (iterm) { 1117 - num_channels = iterm->bNrChannels; 1118 - chconfig = le16_to_cpu(iterm->wChannelConfig); 1119 - } 1120 - 1121 - break; 1122 - } 1123 - 704 + case UAC_VERSION_1: 705 + /* fall through */ 1124 706 case UAC_VERSION_2: { 1125 - struct uac2_input_terminal_descriptor *input_term; 1126 - struct uac2_output_terminal_descriptor *output_term; 1127 - struct uac2_as_header_descriptor *as = 1128 - snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); 1129 - 1130 - if (!as) { 1131 - dev_err(&dev->dev, 1132 - "%u:%d : UAC_AS_GENERAL descriptor not found\n", 1133 - iface_no, altno); 1134 - continue; 1135 - } 1136 - 1137 - if (as->bLength < sizeof(*as)) { 1138 - dev_err(&dev->dev, 1139 - "%u:%d : invalid UAC_AS_GENERAL desc\n", 1140 - iface_no, altno); 1141 - continue; 1142 - } 1143 - 1144 - num_channels = as->bNrChannels; 1145 - format = le32_to_cpu(as->bmFormats); 1146 - chconfig = le32_to_cpu(as->bmChannelConfig); 1147 - 1148 - /* lookup the terminal associated to this interface 1149 - * to extract the clock */ 1150 - input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, 1151 - as->bTerminalLink); 1152 - if (input_term) { 1153 - clock = input_term->bCSourceID; 1154 - if (!chconfig && (num_channels == input_term->bNrChannels)) 1155 - chconfig = le32_to_cpu(input_term->bmChannelConfig); 1156 - break; 1157 - } 1158 - 1159 - output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, 1160 - as->bTerminalLink); 1161 - if (output_term) { 1162 - clock = output_term->bCSourceID; 1163 - break; 1164 - } 1165 - 1166 - dev_err(&dev->dev, 1167 - "%u:%d : bogus bTerminalLink %d\n", 1168 - iface_no, altno, as->bTerminalLink); 1169 - continue; 1170 - } 1171 - 1172 - case UAC_VERSION_3: { 1173 - struct uac3_input_terminal_descriptor *input_term; 1174 - struct uac3_output_terminal_descriptor *output_term; 1175 - struct uac3_as_header_descriptor *as; 1176 - struct uac3_cluster_header_descriptor *cluster; 1177 - struct uac3_hc_descriptor_header hc_header; 1178 - u16 cluster_id, wLength; 1179 - 1180 - as = snd_usb_find_csint_desc(alts->extra, 1181 - alts->extralen, 1182 - NULL, UAC_AS_GENERAL); 1183 - 1184 - if (!as) { 1185 - dev_err(&dev->dev, 1186 - "%u:%d : UAC_AS_GENERAL descriptor not found\n", 1187 - iface_no, altno); 1188 - continue; 1189 - } 1190 - 1191 - if (as->bLength < sizeof(*as)) { 1192 - dev_err(&dev->dev, 1193 - "%u:%d : invalid UAC_AS_GENERAL desc\n", 1194 - iface_no, altno); 1195 - continue; 1196 - } 1197 - 1198 - cluster_id = le16_to_cpu(as->wClusterDescrID); 1199 - if (!cluster_id) { 1200 - dev_err(&dev->dev, 1201 - "%u:%d : no cluster descriptor\n", 1202 - iface_no, altno); 1203 - continue; 1204 - } 1205 - 1206 - /* 1207 - * Get number of channels and channel map through 1208 - * High Capability Cluster Descriptor 1209 - * 1210 - * First step: get High Capability header and 1211 - * read size of Cluster Descriptor 1212 - */ 1213 - err = snd_usb_ctl_msg(chip->dev, 1214 - usb_rcvctrlpipe(chip->dev, 0), 1215 - UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, 1216 - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 1217 - cluster_id, 1218 - snd_usb_ctrl_intf(chip), 1219 - &hc_header, sizeof(hc_header)); 1220 - if (err < 0) 1221 - return err; 1222 - else if (err != sizeof(hc_header)) { 1223 - dev_err(&dev->dev, 1224 - "%u:%d : can't get High Capability descriptor\n", 1225 - iface_no, altno); 1226 - return -EIO; 1227 - } 1228 - 1229 - /* 1230 - * Second step: allocate needed amount of memory 1231 - * and request Cluster Descriptor 1232 - */ 1233 - wLength = le16_to_cpu(hc_header.wLength); 1234 - cluster = kzalloc(wLength, GFP_KERNEL); 1235 - if (!cluster) 1236 - return -ENOMEM; 1237 - err = snd_usb_ctl_msg(chip->dev, 1238 - usb_rcvctrlpipe(chip->dev, 0), 1239 - UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, 1240 - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, 1241 - cluster_id, 1242 - snd_usb_ctrl_intf(chip), 1243 - cluster, wLength); 1244 - if (err < 0) { 1245 - kfree(cluster); 1246 - return err; 1247 - } else if (err != wLength) { 1248 - dev_err(&dev->dev, 1249 - "%u:%d : can't get Cluster Descriptor\n", 1250 - iface_no, altno); 1251 - kfree(cluster); 1252 - return -EIO; 1253 - } 1254 - 1255 - num_channels = cluster->bNrChannels; 1256 - chmap_v3 = convert_chmap_v3(cluster); 1257 - 1258 - kfree(cluster); 1259 - 1260 - format = le64_to_cpu(as->bmFormats); 1261 - 1262 - /* lookup the terminal associated to this interface 1263 - * to extract the clock */ 1264 - input_term = snd_usb_find_input_terminal_descriptor( 1265 - chip->ctrl_intf, 1266 - as->bTerminalLink); 1267 - 1268 - if (input_term) { 1269 - clock = input_term->bCSourceID; 1270 - break; 1271 - } 1272 - 1273 - output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, 1274 - as->bTerminalLink); 1275 - if (output_term) { 1276 - clock = output_term->bCSourceID; 1277 - break; 1278 - } 1279 - 1280 - dev_err(&dev->dev, 1281 - "%u:%d : bogus bTerminalLink %d\n", 1282 - iface_no, altno, as->bTerminalLink); 1283 - continue; 1284 - } 1285 - } 1286 - 1287 - if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { 1288 - /* get format type */ 1289 - fmt = snd_usb_find_csint_desc(alts->extra, 1290 - alts->extralen, 1291 - NULL, UAC_FORMAT_TYPE); 1292 - if (!fmt) { 1293 - dev_err(&dev->dev, 1294 - "%u:%d : no UAC_FORMAT_TYPE desc\n", 1295 - iface_no, altno); 1296 - continue; 1297 - } 1298 - if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) 1299 - || ((protocol == UAC_VERSION_2) && 1300 - (fmt->bLength < 6))) { 1301 - dev_err(&dev->dev, 1302 - "%u:%d : invalid UAC_FORMAT_TYPE desc\n", 1303 - iface_no, altno); 1304 - continue; 1305 - } 707 + int bm_quirk = 0; 1306 708 1307 709 /* 1308 710 * Blue Microphones workaround: The last altsetting is 1309 711 * identical with the previous one, except for a larger 1310 712 * packet size, but is actually a mislabeled two-channel 1311 713 * setting; ignore it. 714 + * 715 + * Part 1: prepare quirk flag 1312 716 */ 1313 - if (fmt->bNrChannels == 1 && 1314 - fmt->bSubframeSize == 2 && 1315 - altno == 2 && num == 3 && 717 + if (altno == 2 && num == 3 && 1316 718 fp && fp->altsetting == 1 && fp->channels == 1 && 1317 719 fp->formats == SNDRV_PCM_FMTBIT_S16_LE && 1318 720 protocol == UAC_VERSION_1 && 1319 721 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 1320 722 fp->maxpacksize * 2) 1321 - continue; 723 + bm_quirk = 1; 724 + 725 + fp = snd_usb_get_audioformat_uac12(chip, alts, protocol, 726 + iface_no, i, altno, 727 + stream, bm_quirk); 728 + break; 729 + } 730 + case UAC_VERSION_3: 731 + fp = snd_usb_get_audioformat_uac3(chip, alts, 732 + iface_no, i, altno, stream); 733 + break; 1322 734 } 1323 735 1324 - fp = kzalloc(sizeof(*fp), GFP_KERNEL); 1325 736 if (!fp) 1326 - return -ENOMEM; 1327 - 1328 - fp->iface = iface_no; 1329 - fp->altsetting = altno; 1330 - fp->altset_idx = i; 1331 - fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; 1332 - fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; 1333 - fp->datainterval = snd_usb_parse_datainterval(chip, alts); 1334 - fp->protocol = protocol; 1335 - fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); 1336 - fp->channels = num_channels; 1337 - if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) 1338 - fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) 1339 - * (fp->maxpacksize & 0x7ff); 1340 - fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); 1341 - fp->clock = clock; 1342 - INIT_LIST_HEAD(&fp->list); 1343 - 1344 - /* some quirks for attributes here */ 1345 - snd_usb_audioformat_attributes_quirk(chip, fp, stream); 1346 - 1347 - /* ok, let's parse further... */ 1348 - if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { 1349 - if (snd_usb_parse_audio_format(chip, fp, format, 1350 - fmt, stream) < 0) { 1351 - kfree(fp->rate_table); 1352 - kfree(fp); 1353 - fp = NULL; 1354 - continue; 1355 - } 1356 - } else { 1357 - struct uac3_as_header_descriptor *as; 1358 - 1359 - as = snd_usb_find_csint_desc(alts->extra, 1360 - alts->extralen, 1361 - NULL, UAC_AS_GENERAL); 1362 - 1363 - if (snd_usb_parse_audio_format_v3(chip, fp, as, 1364 - stream) < 0) { 1365 - kfree(fp->rate_table); 1366 - kfree(fp); 1367 - fp = NULL; 1368 - continue; 1369 - } 1370 - } 1371 - 1372 - /* Create chmap */ 1373 - if (fp->channels != num_channels) 1374 - chconfig = 0; 1375 - 1376 - if (protocol == UAC_VERSION_3) 1377 - fp->chmap = chmap_v3; 1378 - else 1379 - fp->chmap = convert_chmap(fp->channels, chconfig, 1380 - protocol); 737 + continue; 738 + else if (IS_ERR(fp)) 739 + return PTR_ERR(fp); 1381 740 1382 741 dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); 1383 742 err = snd_usb_add_audio_stream(chip, stream, fp);
+8
sound/usb/usbaudio.h
··· 49 49 int num_suspended_intf; 50 50 int sample_rate_read_error; 51 51 52 + int badd_profile; /* UAC3 BADD profile */ 53 + 52 54 struct list_head pcm_list; /* list of pcm streams */ 53 55 struct list_head ep_list; /* list of audio-related endpoints */ 54 56 int pcm_devs; ··· 61 59 62 60 int setup; /* from the 'device_setup' module param */ 63 61 bool autoclock; /* from the 'autoclock' module param */ 62 + bool keep_iface; /* keep interface/altset after closing 63 + * or parameter change 64 + */ 64 65 65 66 struct usb_host_interface *ctrl_intf; /* the audio control interface */ 66 67 }; ··· 114 109 struct snd_usb_audio_quirk { 115 110 const char *vendor_name; 116 111 const char *product_name; 112 + const char *profile_name; /* override the card->longname */ 117 113 int16_t ifnum; 118 114 uint16_t type; 119 115 const void *data; ··· 126 120 127 121 int snd_usb_lock_shutdown(struct snd_usb_audio *chip); 128 122 void snd_usb_unlock_shutdown(struct snd_usb_audio *chip); 123 + 124 + extern bool snd_usb_use_vmalloc; 129 125 130 126 #endif /* __USBAUDIO_H */
+10
sound/xen/Kconfig
··· 1 + # ALSA Xen drivers 2 + 3 + config SND_XEN_FRONTEND 4 + tristate "Xen para-virtualized sound frontend driver" 5 + depends on XEN 6 + select SND_PCM 7 + select XEN_XENBUS_FRONTEND 8 + help 9 + Choose this option if you want to enable a para-virtualized 10 + frontend sound driver for Xen guest OSes.
+9
sound/xen/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + snd_xen_front-objs := xen_snd_front.o \ 4 + xen_snd_front_cfg.o \ 5 + xen_snd_front_evtchnl.o \ 6 + xen_snd_front_shbuf.o \ 7 + xen_snd_front_alsa.o 8 + 9 + obj-$(CONFIG_SND_XEN_FRONTEND) += snd_xen_front.o
+397
sound/xen/xen_snd_front.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #include <linux/delay.h> 12 + #include <linux/module.h> 13 + 14 + #include <xen/page.h> 15 + #include <xen/platform_pci.h> 16 + #include <xen/xen.h> 17 + #include <xen/xenbus.h> 18 + 19 + #include <xen/interface/io/sndif.h> 20 + 21 + #include "xen_snd_front.h" 22 + #include "xen_snd_front_alsa.h" 23 + #include "xen_snd_front_evtchnl.h" 24 + #include "xen_snd_front_shbuf.h" 25 + 26 + static struct xensnd_req * 27 + be_stream_prepare_req(struct xen_snd_front_evtchnl *evtchnl, u8 operation) 28 + { 29 + struct xensnd_req *req; 30 + 31 + req = RING_GET_REQUEST(&evtchnl->u.req.ring, 32 + evtchnl->u.req.ring.req_prod_pvt); 33 + req->operation = operation; 34 + req->id = evtchnl->evt_next_id++; 35 + evtchnl->evt_id = req->id; 36 + return req; 37 + } 38 + 39 + static int be_stream_do_io(struct xen_snd_front_evtchnl *evtchnl) 40 + { 41 + if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED)) 42 + return -EIO; 43 + 44 + reinit_completion(&evtchnl->u.req.completion); 45 + xen_snd_front_evtchnl_flush(evtchnl); 46 + return 0; 47 + } 48 + 49 + static int be_stream_wait_io(struct xen_snd_front_evtchnl *evtchnl) 50 + { 51 + if (wait_for_completion_timeout(&evtchnl->u.req.completion, 52 + msecs_to_jiffies(VSND_WAIT_BACK_MS)) <= 0) 53 + return -ETIMEDOUT; 54 + 55 + return evtchnl->u.req.resp_status; 56 + } 57 + 58 + int xen_snd_front_stream_query_hw_param(struct xen_snd_front_evtchnl *evtchnl, 59 + struct xensnd_query_hw_param *hw_param_req, 60 + struct xensnd_query_hw_param *hw_param_resp) 61 + { 62 + struct xensnd_req *req; 63 + int ret; 64 + 65 + mutex_lock(&evtchnl->u.req.req_io_lock); 66 + 67 + mutex_lock(&evtchnl->ring_io_lock); 68 + req = be_stream_prepare_req(evtchnl, XENSND_OP_HW_PARAM_QUERY); 69 + req->op.hw_param = *hw_param_req; 70 + mutex_unlock(&evtchnl->ring_io_lock); 71 + 72 + ret = be_stream_do_io(evtchnl); 73 + 74 + if (ret == 0) 75 + ret = be_stream_wait_io(evtchnl); 76 + 77 + if (ret == 0) 78 + *hw_param_resp = evtchnl->u.req.resp.hw_param; 79 + 80 + mutex_unlock(&evtchnl->u.req.req_io_lock); 81 + return ret; 82 + } 83 + 84 + int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl, 85 + struct xen_snd_front_shbuf *sh_buf, 86 + u8 format, unsigned int channels, 87 + unsigned int rate, u32 buffer_sz, 88 + u32 period_sz) 89 + { 90 + struct xensnd_req *req; 91 + int ret; 92 + 93 + mutex_lock(&evtchnl->u.req.req_io_lock); 94 + 95 + mutex_lock(&evtchnl->ring_io_lock); 96 + req = be_stream_prepare_req(evtchnl, XENSND_OP_OPEN); 97 + req->op.open.pcm_format = format; 98 + req->op.open.pcm_channels = channels; 99 + req->op.open.pcm_rate = rate; 100 + req->op.open.buffer_sz = buffer_sz; 101 + req->op.open.period_sz = period_sz; 102 + req->op.open.gref_directory = xen_snd_front_shbuf_get_dir_start(sh_buf); 103 + mutex_unlock(&evtchnl->ring_io_lock); 104 + 105 + ret = be_stream_do_io(evtchnl); 106 + 107 + if (ret == 0) 108 + ret = be_stream_wait_io(evtchnl); 109 + 110 + mutex_unlock(&evtchnl->u.req.req_io_lock); 111 + return ret; 112 + } 113 + 114 + int xen_snd_front_stream_close(struct xen_snd_front_evtchnl *evtchnl) 115 + { 116 + struct xensnd_req *req; 117 + int ret; 118 + 119 + mutex_lock(&evtchnl->u.req.req_io_lock); 120 + 121 + mutex_lock(&evtchnl->ring_io_lock); 122 + req = be_stream_prepare_req(evtchnl, XENSND_OP_CLOSE); 123 + mutex_unlock(&evtchnl->ring_io_lock); 124 + 125 + ret = be_stream_do_io(evtchnl); 126 + 127 + if (ret == 0) 128 + ret = be_stream_wait_io(evtchnl); 129 + 130 + mutex_unlock(&evtchnl->u.req.req_io_lock); 131 + return ret; 132 + } 133 + 134 + int xen_snd_front_stream_write(struct xen_snd_front_evtchnl *evtchnl, 135 + unsigned long pos, unsigned long count) 136 + { 137 + struct xensnd_req *req; 138 + int ret; 139 + 140 + mutex_lock(&evtchnl->u.req.req_io_lock); 141 + 142 + mutex_lock(&evtchnl->ring_io_lock); 143 + req = be_stream_prepare_req(evtchnl, XENSND_OP_WRITE); 144 + req->op.rw.length = count; 145 + req->op.rw.offset = pos; 146 + mutex_unlock(&evtchnl->ring_io_lock); 147 + 148 + ret = be_stream_do_io(evtchnl); 149 + 150 + if (ret == 0) 151 + ret = be_stream_wait_io(evtchnl); 152 + 153 + mutex_unlock(&evtchnl->u.req.req_io_lock); 154 + return ret; 155 + } 156 + 157 + int xen_snd_front_stream_read(struct xen_snd_front_evtchnl *evtchnl, 158 + unsigned long pos, unsigned long count) 159 + { 160 + struct xensnd_req *req; 161 + int ret; 162 + 163 + mutex_lock(&evtchnl->u.req.req_io_lock); 164 + 165 + mutex_lock(&evtchnl->ring_io_lock); 166 + req = be_stream_prepare_req(evtchnl, XENSND_OP_READ); 167 + req->op.rw.length = count; 168 + req->op.rw.offset = pos; 169 + mutex_unlock(&evtchnl->ring_io_lock); 170 + 171 + ret = be_stream_do_io(evtchnl); 172 + 173 + if (ret == 0) 174 + ret = be_stream_wait_io(evtchnl); 175 + 176 + mutex_unlock(&evtchnl->u.req.req_io_lock); 177 + return ret; 178 + } 179 + 180 + int xen_snd_front_stream_trigger(struct xen_snd_front_evtchnl *evtchnl, 181 + int type) 182 + { 183 + struct xensnd_req *req; 184 + int ret; 185 + 186 + mutex_lock(&evtchnl->u.req.req_io_lock); 187 + 188 + mutex_lock(&evtchnl->ring_io_lock); 189 + req = be_stream_prepare_req(evtchnl, XENSND_OP_TRIGGER); 190 + req->op.trigger.type = type; 191 + mutex_unlock(&evtchnl->ring_io_lock); 192 + 193 + ret = be_stream_do_io(evtchnl); 194 + 195 + if (ret == 0) 196 + ret = be_stream_wait_io(evtchnl); 197 + 198 + mutex_unlock(&evtchnl->u.req.req_io_lock); 199 + return ret; 200 + } 201 + 202 + static void xen_snd_drv_fini(struct xen_snd_front_info *front_info) 203 + { 204 + xen_snd_front_alsa_fini(front_info); 205 + xen_snd_front_evtchnl_free_all(front_info); 206 + } 207 + 208 + static int sndback_initwait(struct xen_snd_front_info *front_info) 209 + { 210 + int num_streams; 211 + int ret; 212 + 213 + ret = xen_snd_front_cfg_card(front_info, &num_streams); 214 + if (ret < 0) 215 + return ret; 216 + 217 + /* create event channels for all streams and publish */ 218 + ret = xen_snd_front_evtchnl_create_all(front_info, num_streams); 219 + if (ret < 0) 220 + return ret; 221 + 222 + return xen_snd_front_evtchnl_publish_all(front_info); 223 + } 224 + 225 + static int sndback_connect(struct xen_snd_front_info *front_info) 226 + { 227 + return xen_snd_front_alsa_init(front_info); 228 + } 229 + 230 + static void sndback_disconnect(struct xen_snd_front_info *front_info) 231 + { 232 + xen_snd_drv_fini(front_info); 233 + xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); 234 + } 235 + 236 + static void sndback_changed(struct xenbus_device *xb_dev, 237 + enum xenbus_state backend_state) 238 + { 239 + struct xen_snd_front_info *front_info = dev_get_drvdata(&xb_dev->dev); 240 + int ret; 241 + 242 + dev_dbg(&xb_dev->dev, "Backend state is %s, front is %s\n", 243 + xenbus_strstate(backend_state), 244 + xenbus_strstate(xb_dev->state)); 245 + 246 + switch (backend_state) { 247 + case XenbusStateReconfiguring: 248 + /* fall through */ 249 + case XenbusStateReconfigured: 250 + /* fall through */ 251 + case XenbusStateInitialised: 252 + /* fall through */ 253 + break; 254 + 255 + case XenbusStateInitialising: 256 + /* Recovering after backend unexpected closure. */ 257 + sndback_disconnect(front_info); 258 + break; 259 + 260 + case XenbusStateInitWait: 261 + /* Recovering after backend unexpected closure. */ 262 + sndback_disconnect(front_info); 263 + 264 + ret = sndback_initwait(front_info); 265 + if (ret < 0) 266 + xenbus_dev_fatal(xb_dev, ret, "initializing frontend"); 267 + else 268 + xenbus_switch_state(xb_dev, XenbusStateInitialised); 269 + break; 270 + 271 + case XenbusStateConnected: 272 + if (xb_dev->state != XenbusStateInitialised) 273 + break; 274 + 275 + ret = sndback_connect(front_info); 276 + if (ret < 0) 277 + xenbus_dev_fatal(xb_dev, ret, "initializing frontend"); 278 + else 279 + xenbus_switch_state(xb_dev, XenbusStateConnected); 280 + break; 281 + 282 + case XenbusStateClosing: 283 + /* 284 + * In this state backend starts freeing resources, 285 + * so let it go into closed state first, so we can also 286 + * remove ours. 287 + */ 288 + break; 289 + 290 + case XenbusStateUnknown: 291 + /* fall through */ 292 + case XenbusStateClosed: 293 + if (xb_dev->state == XenbusStateClosed) 294 + break; 295 + 296 + sndback_disconnect(front_info); 297 + break; 298 + } 299 + } 300 + 301 + static int xen_drv_probe(struct xenbus_device *xb_dev, 302 + const struct xenbus_device_id *id) 303 + { 304 + struct xen_snd_front_info *front_info; 305 + 306 + front_info = devm_kzalloc(&xb_dev->dev, 307 + sizeof(*front_info), GFP_KERNEL); 308 + if (!front_info) 309 + return -ENOMEM; 310 + 311 + front_info->xb_dev = xb_dev; 312 + dev_set_drvdata(&xb_dev->dev, front_info); 313 + 314 + return xenbus_switch_state(xb_dev, XenbusStateInitialising); 315 + } 316 + 317 + static int xen_drv_remove(struct xenbus_device *dev) 318 + { 319 + struct xen_snd_front_info *front_info = dev_get_drvdata(&dev->dev); 320 + int to = 100; 321 + 322 + xenbus_switch_state(dev, XenbusStateClosing); 323 + 324 + /* 325 + * On driver removal it is disconnected from XenBus, 326 + * so no backend state change events come via .otherend_changed 327 + * callback. This prevents us from exiting gracefully, e.g. 328 + * signaling the backend to free event channels, waiting for its 329 + * state to change to XenbusStateClosed and cleaning at our end. 330 + * Normally when front driver removed backend will finally go into 331 + * XenbusStateInitWait state. 332 + * 333 + * Workaround: read backend's state manually and wait with time-out. 334 + */ 335 + while ((xenbus_read_unsigned(front_info->xb_dev->otherend, "state", 336 + XenbusStateUnknown) != XenbusStateInitWait) && 337 + --to) 338 + msleep(10); 339 + 340 + if (!to) { 341 + unsigned int state; 342 + 343 + state = xenbus_read_unsigned(front_info->xb_dev->otherend, 344 + "state", XenbusStateUnknown); 345 + pr_err("Backend state is %s while removing driver\n", 346 + xenbus_strstate(state)); 347 + } 348 + 349 + xen_snd_drv_fini(front_info); 350 + xenbus_frontend_closed(dev); 351 + return 0; 352 + } 353 + 354 + static const struct xenbus_device_id xen_drv_ids[] = { 355 + { XENSND_DRIVER_NAME }, 356 + { "" } 357 + }; 358 + 359 + static struct xenbus_driver xen_driver = { 360 + .ids = xen_drv_ids, 361 + .probe = xen_drv_probe, 362 + .remove = xen_drv_remove, 363 + .otherend_changed = sndback_changed, 364 + }; 365 + 366 + static int __init xen_drv_init(void) 367 + { 368 + if (!xen_domain()) 369 + return -ENODEV; 370 + 371 + if (!xen_has_pv_devices()) 372 + return -ENODEV; 373 + 374 + /* At the moment we only support case with XEN_PAGE_SIZE == PAGE_SIZE */ 375 + if (XEN_PAGE_SIZE != PAGE_SIZE) { 376 + pr_err(XENSND_DRIVER_NAME ": different kernel and Xen page sizes are not supported: XEN_PAGE_SIZE (%lu) != PAGE_SIZE (%lu)\n", 377 + XEN_PAGE_SIZE, PAGE_SIZE); 378 + return -ENODEV; 379 + } 380 + 381 + pr_info("Initialising Xen " XENSND_DRIVER_NAME " frontend driver\n"); 382 + return xenbus_register_frontend(&xen_driver); 383 + } 384 + 385 + static void __exit xen_drv_fini(void) 386 + { 387 + pr_info("Unregistering Xen " XENSND_DRIVER_NAME " frontend driver\n"); 388 + xenbus_unregister_driver(&xen_driver); 389 + } 390 + 391 + module_init(xen_drv_init); 392 + module_exit(xen_drv_fini); 393 + 394 + MODULE_DESCRIPTION("Xen virtual sound device frontend"); 395 + MODULE_LICENSE("GPL"); 396 + MODULE_ALIAS("xen:" XENSND_DRIVER_NAME); 397 + MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual soundcard}}");
+54
sound/xen/xen_snd_front.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #ifndef __XEN_SND_FRONT_H 12 + #define __XEN_SND_FRONT_H 13 + 14 + #include "xen_snd_front_cfg.h" 15 + 16 + struct xen_snd_front_card_info; 17 + struct xen_snd_front_evtchnl; 18 + struct xen_snd_front_evtchnl_pair; 19 + struct xen_snd_front_shbuf; 20 + struct xensnd_query_hw_param; 21 + 22 + struct xen_snd_front_info { 23 + struct xenbus_device *xb_dev; 24 + 25 + struct xen_snd_front_card_info *card_info; 26 + 27 + int num_evt_pairs; 28 + struct xen_snd_front_evtchnl_pair *evt_pairs; 29 + 30 + struct xen_front_cfg_card cfg; 31 + }; 32 + 33 + int xen_snd_front_stream_query_hw_param(struct xen_snd_front_evtchnl *evtchnl, 34 + struct xensnd_query_hw_param *hw_param_req, 35 + struct xensnd_query_hw_param *hw_param_resp); 36 + 37 + int xen_snd_front_stream_prepare(struct xen_snd_front_evtchnl *evtchnl, 38 + struct xen_snd_front_shbuf *sh_buf, 39 + u8 format, unsigned int channels, 40 + unsigned int rate, u32 buffer_sz, 41 + u32 period_sz); 42 + 43 + int xen_snd_front_stream_close(struct xen_snd_front_evtchnl *evtchnl); 44 + 45 + int xen_snd_front_stream_write(struct xen_snd_front_evtchnl *evtchnl, 46 + unsigned long pos, unsigned long count); 47 + 48 + int xen_snd_front_stream_read(struct xen_snd_front_evtchnl *evtchnl, 49 + unsigned long pos, unsigned long count); 50 + 51 + int xen_snd_front_stream_trigger(struct xen_snd_front_evtchnl *evtchnl, 52 + int type); 53 + 54 + #endif /* __XEN_SND_FRONT_H */
+822
sound/xen/xen_snd_front_alsa.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #include <linux/platform_device.h> 12 + 13 + #include <sound/core.h> 14 + #include <sound/pcm.h> 15 + #include <sound/pcm_params.h> 16 + 17 + #include <xen/xenbus.h> 18 + 19 + #include "xen_snd_front.h" 20 + #include "xen_snd_front_alsa.h" 21 + #include "xen_snd_front_cfg.h" 22 + #include "xen_snd_front_evtchnl.h" 23 + #include "xen_snd_front_shbuf.h" 24 + 25 + struct xen_snd_front_pcm_stream_info { 26 + struct xen_snd_front_info *front_info; 27 + struct xen_snd_front_evtchnl_pair *evt_pair; 28 + struct xen_snd_front_shbuf sh_buf; 29 + int index; 30 + 31 + bool is_open; 32 + struct snd_pcm_hardware pcm_hw; 33 + 34 + /* Number of processed frames as reported by the backend. */ 35 + snd_pcm_uframes_t be_cur_frame; 36 + /* Current HW pointer to be reported via .period callback. */ 37 + atomic_t hw_ptr; 38 + /* Modulo of the number of processed frames - for period detection. */ 39 + u32 out_frames; 40 + }; 41 + 42 + struct xen_snd_front_pcm_instance_info { 43 + struct xen_snd_front_card_info *card_info; 44 + struct snd_pcm *pcm; 45 + struct snd_pcm_hardware pcm_hw; 46 + int num_pcm_streams_pb; 47 + struct xen_snd_front_pcm_stream_info *streams_pb; 48 + int num_pcm_streams_cap; 49 + struct xen_snd_front_pcm_stream_info *streams_cap; 50 + }; 51 + 52 + struct xen_snd_front_card_info { 53 + struct xen_snd_front_info *front_info; 54 + struct snd_card *card; 55 + struct snd_pcm_hardware pcm_hw; 56 + int num_pcm_instances; 57 + struct xen_snd_front_pcm_instance_info *pcm_instances; 58 + }; 59 + 60 + struct alsa_sndif_sample_format { 61 + u8 sndif; 62 + snd_pcm_format_t alsa; 63 + }; 64 + 65 + struct alsa_sndif_hw_param { 66 + u8 sndif; 67 + snd_pcm_hw_param_t alsa; 68 + }; 69 + 70 + static const struct alsa_sndif_sample_format ALSA_SNDIF_FORMATS[] = { 71 + { 72 + .sndif = XENSND_PCM_FORMAT_U8, 73 + .alsa = SNDRV_PCM_FORMAT_U8 74 + }, 75 + { 76 + .sndif = XENSND_PCM_FORMAT_S8, 77 + .alsa = SNDRV_PCM_FORMAT_S8 78 + }, 79 + { 80 + .sndif = XENSND_PCM_FORMAT_U16_LE, 81 + .alsa = SNDRV_PCM_FORMAT_U16_LE 82 + }, 83 + { 84 + .sndif = XENSND_PCM_FORMAT_U16_BE, 85 + .alsa = SNDRV_PCM_FORMAT_U16_BE 86 + }, 87 + { 88 + .sndif = XENSND_PCM_FORMAT_S16_LE, 89 + .alsa = SNDRV_PCM_FORMAT_S16_LE 90 + }, 91 + { 92 + .sndif = XENSND_PCM_FORMAT_S16_BE, 93 + .alsa = SNDRV_PCM_FORMAT_S16_BE 94 + }, 95 + { 96 + .sndif = XENSND_PCM_FORMAT_U24_LE, 97 + .alsa = SNDRV_PCM_FORMAT_U24_LE 98 + }, 99 + { 100 + .sndif = XENSND_PCM_FORMAT_U24_BE, 101 + .alsa = SNDRV_PCM_FORMAT_U24_BE 102 + }, 103 + { 104 + .sndif = XENSND_PCM_FORMAT_S24_LE, 105 + .alsa = SNDRV_PCM_FORMAT_S24_LE 106 + }, 107 + { 108 + .sndif = XENSND_PCM_FORMAT_S24_BE, 109 + .alsa = SNDRV_PCM_FORMAT_S24_BE 110 + }, 111 + { 112 + .sndif = XENSND_PCM_FORMAT_U32_LE, 113 + .alsa = SNDRV_PCM_FORMAT_U32_LE 114 + }, 115 + { 116 + .sndif = XENSND_PCM_FORMAT_U32_BE, 117 + .alsa = SNDRV_PCM_FORMAT_U32_BE 118 + }, 119 + { 120 + .sndif = XENSND_PCM_FORMAT_S32_LE, 121 + .alsa = SNDRV_PCM_FORMAT_S32_LE 122 + }, 123 + { 124 + .sndif = XENSND_PCM_FORMAT_S32_BE, 125 + .alsa = SNDRV_PCM_FORMAT_S32_BE 126 + }, 127 + { 128 + .sndif = XENSND_PCM_FORMAT_A_LAW, 129 + .alsa = SNDRV_PCM_FORMAT_A_LAW 130 + }, 131 + { 132 + .sndif = XENSND_PCM_FORMAT_MU_LAW, 133 + .alsa = SNDRV_PCM_FORMAT_MU_LAW 134 + }, 135 + { 136 + .sndif = XENSND_PCM_FORMAT_F32_LE, 137 + .alsa = SNDRV_PCM_FORMAT_FLOAT_LE 138 + }, 139 + { 140 + .sndif = XENSND_PCM_FORMAT_F32_BE, 141 + .alsa = SNDRV_PCM_FORMAT_FLOAT_BE 142 + }, 143 + { 144 + .sndif = XENSND_PCM_FORMAT_F64_LE, 145 + .alsa = SNDRV_PCM_FORMAT_FLOAT64_LE 146 + }, 147 + { 148 + .sndif = XENSND_PCM_FORMAT_F64_BE, 149 + .alsa = SNDRV_PCM_FORMAT_FLOAT64_BE 150 + }, 151 + { 152 + .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE, 153 + .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE 154 + }, 155 + { 156 + .sndif = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE, 157 + .alsa = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE 158 + }, 159 + { 160 + .sndif = XENSND_PCM_FORMAT_IMA_ADPCM, 161 + .alsa = SNDRV_PCM_FORMAT_IMA_ADPCM 162 + }, 163 + { 164 + .sndif = XENSND_PCM_FORMAT_MPEG, 165 + .alsa = SNDRV_PCM_FORMAT_MPEG 166 + }, 167 + { 168 + .sndif = XENSND_PCM_FORMAT_GSM, 169 + .alsa = SNDRV_PCM_FORMAT_GSM 170 + }, 171 + }; 172 + 173 + static int to_sndif_format(snd_pcm_format_t format) 174 + { 175 + int i; 176 + 177 + for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++) 178 + if (ALSA_SNDIF_FORMATS[i].alsa == format) 179 + return ALSA_SNDIF_FORMATS[i].sndif; 180 + 181 + return -EINVAL; 182 + } 183 + 184 + static u64 to_sndif_formats_mask(u64 alsa_formats) 185 + { 186 + u64 mask; 187 + int i; 188 + 189 + mask = 0; 190 + for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++) 191 + if (1 << ALSA_SNDIF_FORMATS[i].alsa & alsa_formats) 192 + mask |= 1 << ALSA_SNDIF_FORMATS[i].sndif; 193 + 194 + return mask; 195 + } 196 + 197 + static u64 to_alsa_formats_mask(u64 sndif_formats) 198 + { 199 + u64 mask; 200 + int i; 201 + 202 + mask = 0; 203 + for (i = 0; i < ARRAY_SIZE(ALSA_SNDIF_FORMATS); i++) 204 + if (1 << ALSA_SNDIF_FORMATS[i].sndif & sndif_formats) 205 + mask |= 1 << ALSA_SNDIF_FORMATS[i].alsa; 206 + 207 + return mask; 208 + } 209 + 210 + static void stream_clear(struct xen_snd_front_pcm_stream_info *stream) 211 + { 212 + stream->is_open = false; 213 + stream->be_cur_frame = 0; 214 + stream->out_frames = 0; 215 + atomic_set(&stream->hw_ptr, 0); 216 + xen_snd_front_evtchnl_pair_clear(stream->evt_pair); 217 + xen_snd_front_shbuf_clear(&stream->sh_buf); 218 + } 219 + 220 + static void stream_free(struct xen_snd_front_pcm_stream_info *stream) 221 + { 222 + xen_snd_front_shbuf_free(&stream->sh_buf); 223 + stream_clear(stream); 224 + } 225 + 226 + static struct xen_snd_front_pcm_stream_info * 227 + stream_get(struct snd_pcm_substream *substream) 228 + { 229 + struct xen_snd_front_pcm_instance_info *pcm_instance = 230 + snd_pcm_substream_chip(substream); 231 + struct xen_snd_front_pcm_stream_info *stream; 232 + 233 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 234 + stream = &pcm_instance->streams_pb[substream->number]; 235 + else 236 + stream = &pcm_instance->streams_cap[substream->number]; 237 + 238 + return stream; 239 + } 240 + 241 + static int alsa_hw_rule(struct snd_pcm_hw_params *params, 242 + struct snd_pcm_hw_rule *rule) 243 + { 244 + struct xen_snd_front_pcm_stream_info *stream = rule->private; 245 + struct device *dev = &stream->front_info->xb_dev->dev; 246 + struct snd_mask *formats = 247 + hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 248 + struct snd_interval *rates = 249 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 250 + struct snd_interval *channels = 251 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 252 + struct snd_interval *period = 253 + hw_param_interval(params, 254 + SNDRV_PCM_HW_PARAM_PERIOD_SIZE); 255 + struct snd_interval *buffer = 256 + hw_param_interval(params, 257 + SNDRV_PCM_HW_PARAM_BUFFER_SIZE); 258 + struct xensnd_query_hw_param req; 259 + struct xensnd_query_hw_param resp; 260 + struct snd_interval interval; 261 + struct snd_mask mask; 262 + u64 sndif_formats; 263 + int changed, ret; 264 + 265 + /* Collect all the values we need for the query. */ 266 + 267 + req.formats = to_sndif_formats_mask((u64)formats->bits[0] | 268 + (u64)(formats->bits[1]) << 32); 269 + 270 + req.rates.min = rates->min; 271 + req.rates.max = rates->max; 272 + 273 + req.channels.min = channels->min; 274 + req.channels.max = channels->max; 275 + 276 + req.buffer.min = buffer->min; 277 + req.buffer.max = buffer->max; 278 + 279 + req.period.min = period->min; 280 + req.period.max = period->max; 281 + 282 + ret = xen_snd_front_stream_query_hw_param(&stream->evt_pair->req, 283 + &req, &resp); 284 + if (ret < 0) { 285 + /* Check if this is due to backend communication error. */ 286 + if (ret == -EIO || ret == -ETIMEDOUT) 287 + dev_err(dev, "Failed to query ALSA HW parameters\n"); 288 + return ret; 289 + } 290 + 291 + /* Refine HW parameters after the query. */ 292 + changed = 0; 293 + 294 + sndif_formats = to_alsa_formats_mask(resp.formats); 295 + snd_mask_none(&mask); 296 + mask.bits[0] = (u32)sndif_formats; 297 + mask.bits[1] = (u32)(sndif_formats >> 32); 298 + ret = snd_mask_refine(formats, &mask); 299 + if (ret < 0) 300 + return ret; 301 + changed |= ret; 302 + 303 + interval.openmin = 0; 304 + interval.openmax = 0; 305 + interval.integer = 1; 306 + 307 + interval.min = resp.rates.min; 308 + interval.max = resp.rates.max; 309 + ret = snd_interval_refine(rates, &interval); 310 + if (ret < 0) 311 + return ret; 312 + changed |= ret; 313 + 314 + interval.min = resp.channels.min; 315 + interval.max = resp.channels.max; 316 + ret = snd_interval_refine(channels, &interval); 317 + if (ret < 0) 318 + return ret; 319 + changed |= ret; 320 + 321 + interval.min = resp.buffer.min; 322 + interval.max = resp.buffer.max; 323 + ret = snd_interval_refine(buffer, &interval); 324 + if (ret < 0) 325 + return ret; 326 + changed |= ret; 327 + 328 + interval.min = resp.period.min; 329 + interval.max = resp.period.max; 330 + ret = snd_interval_refine(period, &interval); 331 + if (ret < 0) 332 + return ret; 333 + changed |= ret; 334 + 335 + return changed; 336 + } 337 + 338 + static int alsa_open(struct snd_pcm_substream *substream) 339 + { 340 + struct xen_snd_front_pcm_instance_info *pcm_instance = 341 + snd_pcm_substream_chip(substream); 342 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 343 + struct snd_pcm_runtime *runtime = substream->runtime; 344 + struct xen_snd_front_info *front_info = 345 + pcm_instance->card_info->front_info; 346 + struct device *dev = &front_info->xb_dev->dev; 347 + int ret; 348 + 349 + /* 350 + * Return our HW properties: override defaults with those configured 351 + * via XenStore. 352 + */ 353 + runtime->hw = stream->pcm_hw; 354 + runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | 355 + SNDRV_PCM_INFO_MMAP_VALID | 356 + SNDRV_PCM_INFO_DOUBLE | 357 + SNDRV_PCM_INFO_BATCH | 358 + SNDRV_PCM_INFO_NONINTERLEAVED | 359 + SNDRV_PCM_INFO_RESUME | 360 + SNDRV_PCM_INFO_PAUSE); 361 + runtime->hw.info |= SNDRV_PCM_INFO_INTERLEAVED; 362 + 363 + stream->evt_pair = &front_info->evt_pairs[stream->index]; 364 + 365 + stream->front_info = front_info; 366 + 367 + stream->evt_pair->evt.u.evt.substream = substream; 368 + 369 + stream_clear(stream); 370 + 371 + xen_snd_front_evtchnl_pair_set_connected(stream->evt_pair, true); 372 + 373 + ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, 374 + alsa_hw_rule, stream, 375 + SNDRV_PCM_HW_PARAM_FORMAT, -1); 376 + if (ret) { 377 + dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_FORMAT\n"); 378 + return ret; 379 + } 380 + 381 + ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 382 + alsa_hw_rule, stream, 383 + SNDRV_PCM_HW_PARAM_RATE, -1); 384 + if (ret) { 385 + dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_RATE\n"); 386 + return ret; 387 + } 388 + 389 + ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 390 + alsa_hw_rule, stream, 391 + SNDRV_PCM_HW_PARAM_CHANNELS, -1); 392 + if (ret) { 393 + dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_CHANNELS\n"); 394 + return ret; 395 + } 396 + 397 + ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 398 + alsa_hw_rule, stream, 399 + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); 400 + if (ret) { 401 + dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_PERIOD_SIZE\n"); 402 + return ret; 403 + } 404 + 405 + ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 406 + alsa_hw_rule, stream, 407 + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); 408 + if (ret) { 409 + dev_err(dev, "Failed to add HW rule for SNDRV_PCM_HW_PARAM_BUFFER_SIZE\n"); 410 + return ret; 411 + } 412 + 413 + return 0; 414 + } 415 + 416 + static int alsa_close(struct snd_pcm_substream *substream) 417 + { 418 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 419 + 420 + xen_snd_front_evtchnl_pair_set_connected(stream->evt_pair, false); 421 + return 0; 422 + } 423 + 424 + static int alsa_hw_params(struct snd_pcm_substream *substream, 425 + struct snd_pcm_hw_params *params) 426 + { 427 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 428 + int ret; 429 + 430 + /* 431 + * This callback may be called multiple times, 432 + * so free the previously allocated shared buffer if any. 433 + */ 434 + stream_free(stream); 435 + 436 + ret = xen_snd_front_shbuf_alloc(stream->front_info->xb_dev, 437 + &stream->sh_buf, 438 + params_buffer_bytes(params)); 439 + if (ret < 0) { 440 + stream_free(stream); 441 + dev_err(&stream->front_info->xb_dev->dev, 442 + "Failed to allocate buffers for stream with index %d\n", 443 + stream->index); 444 + return ret; 445 + } 446 + 447 + return 0; 448 + } 449 + 450 + static int alsa_hw_free(struct snd_pcm_substream *substream) 451 + { 452 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 453 + int ret; 454 + 455 + ret = xen_snd_front_stream_close(&stream->evt_pair->req); 456 + stream_free(stream); 457 + return ret; 458 + } 459 + 460 + static int alsa_prepare(struct snd_pcm_substream *substream) 461 + { 462 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 463 + 464 + if (!stream->is_open) { 465 + struct snd_pcm_runtime *runtime = substream->runtime; 466 + u8 sndif_format; 467 + int ret; 468 + 469 + ret = to_sndif_format(runtime->format); 470 + if (ret < 0) { 471 + dev_err(&stream->front_info->xb_dev->dev, 472 + "Unsupported sample format: %d\n", 473 + runtime->format); 474 + return ret; 475 + } 476 + sndif_format = ret; 477 + 478 + ret = xen_snd_front_stream_prepare(&stream->evt_pair->req, 479 + &stream->sh_buf, 480 + sndif_format, 481 + runtime->channels, 482 + runtime->rate, 483 + snd_pcm_lib_buffer_bytes(substream), 484 + snd_pcm_lib_period_bytes(substream)); 485 + if (ret < 0) 486 + return ret; 487 + 488 + stream->is_open = true; 489 + } 490 + 491 + return 0; 492 + } 493 + 494 + static int alsa_trigger(struct snd_pcm_substream *substream, int cmd) 495 + { 496 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 497 + int type; 498 + 499 + switch (cmd) { 500 + case SNDRV_PCM_TRIGGER_START: 501 + type = XENSND_OP_TRIGGER_START; 502 + break; 503 + 504 + case SNDRV_PCM_TRIGGER_RESUME: 505 + type = XENSND_OP_TRIGGER_RESUME; 506 + break; 507 + 508 + case SNDRV_PCM_TRIGGER_STOP: 509 + type = XENSND_OP_TRIGGER_STOP; 510 + break; 511 + 512 + case SNDRV_PCM_TRIGGER_SUSPEND: 513 + type = XENSND_OP_TRIGGER_PAUSE; 514 + break; 515 + 516 + default: 517 + return -EINVAL; 518 + } 519 + 520 + return xen_snd_front_stream_trigger(&stream->evt_pair->req, type); 521 + } 522 + 523 + void xen_snd_front_alsa_handle_cur_pos(struct xen_snd_front_evtchnl *evtchnl, 524 + u64 pos_bytes) 525 + { 526 + struct snd_pcm_substream *substream = evtchnl->u.evt.substream; 527 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 528 + snd_pcm_uframes_t delta, new_hw_ptr, cur_frame; 529 + 530 + cur_frame = bytes_to_frames(substream->runtime, pos_bytes); 531 + 532 + delta = cur_frame - stream->be_cur_frame; 533 + stream->be_cur_frame = cur_frame; 534 + 535 + new_hw_ptr = (snd_pcm_uframes_t)atomic_read(&stream->hw_ptr); 536 + new_hw_ptr = (new_hw_ptr + delta) % substream->runtime->buffer_size; 537 + atomic_set(&stream->hw_ptr, (int)new_hw_ptr); 538 + 539 + stream->out_frames += delta; 540 + if (stream->out_frames > substream->runtime->period_size) { 541 + stream->out_frames %= substream->runtime->period_size; 542 + snd_pcm_period_elapsed(substream); 543 + } 544 + } 545 + 546 + static snd_pcm_uframes_t alsa_pointer(struct snd_pcm_substream *substream) 547 + { 548 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 549 + 550 + return (snd_pcm_uframes_t)atomic_read(&stream->hw_ptr); 551 + } 552 + 553 + static int alsa_pb_copy_user(struct snd_pcm_substream *substream, 554 + int channel, unsigned long pos, void __user *src, 555 + unsigned long count) 556 + { 557 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 558 + 559 + if (unlikely(pos + count > stream->sh_buf.buffer_sz)) 560 + return -EINVAL; 561 + 562 + if (copy_from_user(stream->sh_buf.buffer + pos, src, count)) 563 + return -EFAULT; 564 + 565 + return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count); 566 + } 567 + 568 + static int alsa_pb_copy_kernel(struct snd_pcm_substream *substream, 569 + int channel, unsigned long pos, void *src, 570 + unsigned long count) 571 + { 572 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 573 + 574 + if (unlikely(pos + count > stream->sh_buf.buffer_sz)) 575 + return -EINVAL; 576 + 577 + memcpy(stream->sh_buf.buffer + pos, src, count); 578 + 579 + return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count); 580 + } 581 + 582 + static int alsa_cap_copy_user(struct snd_pcm_substream *substream, 583 + int channel, unsigned long pos, void __user *dst, 584 + unsigned long count) 585 + { 586 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 587 + int ret; 588 + 589 + if (unlikely(pos + count > stream->sh_buf.buffer_sz)) 590 + return -EINVAL; 591 + 592 + ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count); 593 + if (ret < 0) 594 + return ret; 595 + 596 + return copy_to_user(dst, stream->sh_buf.buffer + pos, count) ? 597 + -EFAULT : 0; 598 + } 599 + 600 + static int alsa_cap_copy_kernel(struct snd_pcm_substream *substream, 601 + int channel, unsigned long pos, void *dst, 602 + unsigned long count) 603 + { 604 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 605 + int ret; 606 + 607 + if (unlikely(pos + count > stream->sh_buf.buffer_sz)) 608 + return -EINVAL; 609 + 610 + ret = xen_snd_front_stream_read(&stream->evt_pair->req, pos, count); 611 + if (ret < 0) 612 + return ret; 613 + 614 + memcpy(dst, stream->sh_buf.buffer + pos, count); 615 + 616 + return 0; 617 + } 618 + 619 + static int alsa_pb_fill_silence(struct snd_pcm_substream *substream, 620 + int channel, unsigned long pos, 621 + unsigned long count) 622 + { 623 + struct xen_snd_front_pcm_stream_info *stream = stream_get(substream); 624 + 625 + if (unlikely(pos + count > stream->sh_buf.buffer_sz)) 626 + return -EINVAL; 627 + 628 + memset(stream->sh_buf.buffer + pos, 0, count); 629 + 630 + return xen_snd_front_stream_write(&stream->evt_pair->req, pos, count); 631 + } 632 + 633 + /* 634 + * FIXME: The mmaped data transfer is asynchronous and there is no 635 + * ack signal from user-space when it is done. This is the 636 + * reason it is not implemented in the PV driver as we do need 637 + * to know when the buffer can be transferred to the backend. 638 + */ 639 + 640 + static struct snd_pcm_ops snd_drv_alsa_playback_ops = { 641 + .open = alsa_open, 642 + .close = alsa_close, 643 + .ioctl = snd_pcm_lib_ioctl, 644 + .hw_params = alsa_hw_params, 645 + .hw_free = alsa_hw_free, 646 + .prepare = alsa_prepare, 647 + .trigger = alsa_trigger, 648 + .pointer = alsa_pointer, 649 + .copy_user = alsa_pb_copy_user, 650 + .copy_kernel = alsa_pb_copy_kernel, 651 + .fill_silence = alsa_pb_fill_silence, 652 + }; 653 + 654 + static struct snd_pcm_ops snd_drv_alsa_capture_ops = { 655 + .open = alsa_open, 656 + .close = alsa_close, 657 + .ioctl = snd_pcm_lib_ioctl, 658 + .hw_params = alsa_hw_params, 659 + .hw_free = alsa_hw_free, 660 + .prepare = alsa_prepare, 661 + .trigger = alsa_trigger, 662 + .pointer = alsa_pointer, 663 + .copy_user = alsa_cap_copy_user, 664 + .copy_kernel = alsa_cap_copy_kernel, 665 + }; 666 + 667 + static int new_pcm_instance(struct xen_snd_front_card_info *card_info, 668 + struct xen_front_cfg_pcm_instance *instance_cfg, 669 + struct xen_snd_front_pcm_instance_info *pcm_instance_info) 670 + { 671 + struct snd_pcm *pcm; 672 + int ret, i; 673 + 674 + dev_dbg(&card_info->front_info->xb_dev->dev, 675 + "New PCM device \"%s\" with id %d playback %d capture %d", 676 + instance_cfg->name, 677 + instance_cfg->device_id, 678 + instance_cfg->num_streams_pb, 679 + instance_cfg->num_streams_cap); 680 + 681 + pcm_instance_info->card_info = card_info; 682 + 683 + pcm_instance_info->pcm_hw = instance_cfg->pcm_hw; 684 + 685 + if (instance_cfg->num_streams_pb) { 686 + pcm_instance_info->streams_pb = 687 + devm_kcalloc(&card_info->card->card_dev, 688 + instance_cfg->num_streams_pb, 689 + sizeof(struct xen_snd_front_pcm_stream_info), 690 + GFP_KERNEL); 691 + if (!pcm_instance_info->streams_pb) 692 + return -ENOMEM; 693 + } 694 + 695 + if (instance_cfg->num_streams_cap) { 696 + pcm_instance_info->streams_cap = 697 + devm_kcalloc(&card_info->card->card_dev, 698 + instance_cfg->num_streams_cap, 699 + sizeof(struct xen_snd_front_pcm_stream_info), 700 + GFP_KERNEL); 701 + if (!pcm_instance_info->streams_cap) 702 + return -ENOMEM; 703 + } 704 + 705 + pcm_instance_info->num_pcm_streams_pb = 706 + instance_cfg->num_streams_pb; 707 + pcm_instance_info->num_pcm_streams_cap = 708 + instance_cfg->num_streams_cap; 709 + 710 + for (i = 0; i < pcm_instance_info->num_pcm_streams_pb; i++) { 711 + pcm_instance_info->streams_pb[i].pcm_hw = 712 + instance_cfg->streams_pb[i].pcm_hw; 713 + pcm_instance_info->streams_pb[i].index = 714 + instance_cfg->streams_pb[i].index; 715 + } 716 + 717 + for (i = 0; i < pcm_instance_info->num_pcm_streams_cap; i++) { 718 + pcm_instance_info->streams_cap[i].pcm_hw = 719 + instance_cfg->streams_cap[i].pcm_hw; 720 + pcm_instance_info->streams_cap[i].index = 721 + instance_cfg->streams_cap[i].index; 722 + } 723 + 724 + ret = snd_pcm_new(card_info->card, instance_cfg->name, 725 + instance_cfg->device_id, 726 + instance_cfg->num_streams_pb, 727 + instance_cfg->num_streams_cap, 728 + &pcm); 729 + if (ret < 0) 730 + return ret; 731 + 732 + pcm->private_data = pcm_instance_info; 733 + pcm->info_flags = 0; 734 + /* we want to handle all PCM operations in non-atomic context */ 735 + pcm->nonatomic = true; 736 + strncpy(pcm->name, "Virtual card PCM", sizeof(pcm->name)); 737 + 738 + if (instance_cfg->num_streams_pb) 739 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 740 + &snd_drv_alsa_playback_ops); 741 + 742 + if (instance_cfg->num_streams_cap) 743 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, 744 + &snd_drv_alsa_capture_ops); 745 + 746 + pcm_instance_info->pcm = pcm; 747 + return 0; 748 + } 749 + 750 + int xen_snd_front_alsa_init(struct xen_snd_front_info *front_info) 751 + { 752 + struct device *dev = &front_info->xb_dev->dev; 753 + struct xen_front_cfg_card *cfg = &front_info->cfg; 754 + struct xen_snd_front_card_info *card_info; 755 + struct snd_card *card; 756 + int ret, i; 757 + 758 + dev_dbg(dev, "Creating virtual sound card\n"); 759 + 760 + ret = snd_card_new(dev, 0, XENSND_DRIVER_NAME, THIS_MODULE, 761 + sizeof(struct xen_snd_front_card_info), &card); 762 + if (ret < 0) 763 + return ret; 764 + 765 + card_info = card->private_data; 766 + card_info->front_info = front_info; 767 + front_info->card_info = card_info; 768 + card_info->card = card; 769 + card_info->pcm_instances = 770 + devm_kcalloc(dev, cfg->num_pcm_instances, 771 + sizeof(struct xen_snd_front_pcm_instance_info), 772 + GFP_KERNEL); 773 + if (!card_info->pcm_instances) { 774 + ret = -ENOMEM; 775 + goto fail; 776 + } 777 + 778 + card_info->num_pcm_instances = cfg->num_pcm_instances; 779 + card_info->pcm_hw = cfg->pcm_hw; 780 + 781 + for (i = 0; i < cfg->num_pcm_instances; i++) { 782 + ret = new_pcm_instance(card_info, &cfg->pcm_instances[i], 783 + &card_info->pcm_instances[i]); 784 + if (ret < 0) 785 + goto fail; 786 + } 787 + 788 + strncpy(card->driver, XENSND_DRIVER_NAME, sizeof(card->driver)); 789 + strncpy(card->shortname, cfg->name_short, sizeof(card->shortname)); 790 + strncpy(card->longname, cfg->name_long, sizeof(card->longname)); 791 + 792 + ret = snd_card_register(card); 793 + if (ret < 0) 794 + goto fail; 795 + 796 + return 0; 797 + 798 + fail: 799 + snd_card_free(card); 800 + return ret; 801 + } 802 + 803 + void xen_snd_front_alsa_fini(struct xen_snd_front_info *front_info) 804 + { 805 + struct xen_snd_front_card_info *card_info; 806 + struct snd_card *card; 807 + 808 + card_info = front_info->card_info; 809 + if (!card_info) 810 + return; 811 + 812 + card = card_info->card; 813 + if (!card) 814 + return; 815 + 816 + dev_dbg(&front_info->xb_dev->dev, "Removing virtual sound card %d\n", 817 + card->number); 818 + snd_card_free(card); 819 + 820 + /* Card_info will be freed when destroying front_info->xb_dev->dev. */ 821 + card_info->card = NULL; 822 + }
+23
sound/xen/xen_snd_front_alsa.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #ifndef __XEN_SND_FRONT_ALSA_H 12 + #define __XEN_SND_FRONT_ALSA_H 13 + 14 + struct xen_snd_front_info; 15 + 16 + int xen_snd_front_alsa_init(struct xen_snd_front_info *front_info); 17 + 18 + void xen_snd_front_alsa_fini(struct xen_snd_front_info *front_info); 19 + 20 + void xen_snd_front_alsa_handle_cur_pos(struct xen_snd_front_evtchnl *evtchnl, 21 + u64 pos_bytes); 22 + 23 + #endif /* __XEN_SND_FRONT_ALSA_H */
+519
sound/xen/xen_snd_front_cfg.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #include <xen/xenbus.h> 12 + 13 + #include <xen/interface/io/sndif.h> 14 + 15 + #include "xen_snd_front.h" 16 + #include "xen_snd_front_cfg.h" 17 + 18 + /* Maximum number of supported streams. */ 19 + #define VSND_MAX_STREAM 8 20 + 21 + struct cfg_hw_sample_rate { 22 + const char *name; 23 + unsigned int mask; 24 + unsigned int value; 25 + }; 26 + 27 + static const struct cfg_hw_sample_rate CFG_HW_SUPPORTED_RATES[] = { 28 + { .name = "5512", .mask = SNDRV_PCM_RATE_5512, .value = 5512 }, 29 + { .name = "8000", .mask = SNDRV_PCM_RATE_8000, .value = 8000 }, 30 + { .name = "11025", .mask = SNDRV_PCM_RATE_11025, .value = 11025 }, 31 + { .name = "16000", .mask = SNDRV_PCM_RATE_16000, .value = 16000 }, 32 + { .name = "22050", .mask = SNDRV_PCM_RATE_22050, .value = 22050 }, 33 + { .name = "32000", .mask = SNDRV_PCM_RATE_32000, .value = 32000 }, 34 + { .name = "44100", .mask = SNDRV_PCM_RATE_44100, .value = 44100 }, 35 + { .name = "48000", .mask = SNDRV_PCM_RATE_48000, .value = 48000 }, 36 + { .name = "64000", .mask = SNDRV_PCM_RATE_64000, .value = 64000 }, 37 + { .name = "96000", .mask = SNDRV_PCM_RATE_96000, .value = 96000 }, 38 + { .name = "176400", .mask = SNDRV_PCM_RATE_176400, .value = 176400 }, 39 + { .name = "192000", .mask = SNDRV_PCM_RATE_192000, .value = 192000 }, 40 + }; 41 + 42 + struct cfg_hw_sample_format { 43 + const char *name; 44 + u64 mask; 45 + }; 46 + 47 + static const struct cfg_hw_sample_format CFG_HW_SUPPORTED_FORMATS[] = { 48 + { 49 + .name = XENSND_PCM_FORMAT_U8_STR, 50 + .mask = SNDRV_PCM_FMTBIT_U8 51 + }, 52 + { 53 + .name = XENSND_PCM_FORMAT_S8_STR, 54 + .mask = SNDRV_PCM_FMTBIT_S8 55 + }, 56 + { 57 + .name = XENSND_PCM_FORMAT_U16_LE_STR, 58 + .mask = SNDRV_PCM_FMTBIT_U16_LE 59 + }, 60 + { 61 + .name = XENSND_PCM_FORMAT_U16_BE_STR, 62 + .mask = SNDRV_PCM_FMTBIT_U16_BE 63 + }, 64 + { 65 + .name = XENSND_PCM_FORMAT_S16_LE_STR, 66 + .mask = SNDRV_PCM_FMTBIT_S16_LE 67 + }, 68 + { 69 + .name = XENSND_PCM_FORMAT_S16_BE_STR, 70 + .mask = SNDRV_PCM_FMTBIT_S16_BE 71 + }, 72 + { 73 + .name = XENSND_PCM_FORMAT_U24_LE_STR, 74 + .mask = SNDRV_PCM_FMTBIT_U24_LE 75 + }, 76 + { 77 + .name = XENSND_PCM_FORMAT_U24_BE_STR, 78 + .mask = SNDRV_PCM_FMTBIT_U24_BE 79 + }, 80 + { 81 + .name = XENSND_PCM_FORMAT_S24_LE_STR, 82 + .mask = SNDRV_PCM_FMTBIT_S24_LE 83 + }, 84 + { 85 + .name = XENSND_PCM_FORMAT_S24_BE_STR, 86 + .mask = SNDRV_PCM_FMTBIT_S24_BE 87 + }, 88 + { 89 + .name = XENSND_PCM_FORMAT_U32_LE_STR, 90 + .mask = SNDRV_PCM_FMTBIT_U32_LE 91 + }, 92 + { 93 + .name = XENSND_PCM_FORMAT_U32_BE_STR, 94 + .mask = SNDRV_PCM_FMTBIT_U32_BE 95 + }, 96 + { 97 + .name = XENSND_PCM_FORMAT_S32_LE_STR, 98 + .mask = SNDRV_PCM_FMTBIT_S32_LE 99 + }, 100 + { 101 + .name = XENSND_PCM_FORMAT_S32_BE_STR, 102 + .mask = SNDRV_PCM_FMTBIT_S32_BE 103 + }, 104 + { 105 + .name = XENSND_PCM_FORMAT_A_LAW_STR, 106 + .mask = SNDRV_PCM_FMTBIT_A_LAW 107 + }, 108 + { 109 + .name = XENSND_PCM_FORMAT_MU_LAW_STR, 110 + .mask = SNDRV_PCM_FMTBIT_MU_LAW 111 + }, 112 + { 113 + .name = XENSND_PCM_FORMAT_F32_LE_STR, 114 + .mask = SNDRV_PCM_FMTBIT_FLOAT_LE 115 + }, 116 + { 117 + .name = XENSND_PCM_FORMAT_F32_BE_STR, 118 + .mask = SNDRV_PCM_FMTBIT_FLOAT_BE 119 + }, 120 + { 121 + .name = XENSND_PCM_FORMAT_F64_LE_STR, 122 + .mask = SNDRV_PCM_FMTBIT_FLOAT64_LE 123 + }, 124 + { 125 + .name = XENSND_PCM_FORMAT_F64_BE_STR, 126 + .mask = SNDRV_PCM_FMTBIT_FLOAT64_BE 127 + }, 128 + { 129 + .name = XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR, 130 + .mask = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE 131 + }, 132 + { 133 + .name = XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR, 134 + .mask = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE 135 + }, 136 + { 137 + .name = XENSND_PCM_FORMAT_IMA_ADPCM_STR, 138 + .mask = SNDRV_PCM_FMTBIT_IMA_ADPCM 139 + }, 140 + { 141 + .name = XENSND_PCM_FORMAT_MPEG_STR, 142 + .mask = SNDRV_PCM_FMTBIT_MPEG 143 + }, 144 + { 145 + .name = XENSND_PCM_FORMAT_GSM_STR, 146 + .mask = SNDRV_PCM_FMTBIT_GSM 147 + }, 148 + }; 149 + 150 + static void cfg_hw_rates(char *list, unsigned int len, 151 + const char *path, struct snd_pcm_hardware *pcm_hw) 152 + { 153 + char *cur_rate; 154 + unsigned int cur_mask; 155 + unsigned int cur_value; 156 + unsigned int rates; 157 + unsigned int rate_min; 158 + unsigned int rate_max; 159 + int i; 160 + 161 + rates = 0; 162 + rate_min = -1; 163 + rate_max = 0; 164 + while ((cur_rate = strsep(&list, XENSND_LIST_SEPARATOR))) { 165 + for (i = 0; i < ARRAY_SIZE(CFG_HW_SUPPORTED_RATES); i++) 166 + if (!strncasecmp(cur_rate, 167 + CFG_HW_SUPPORTED_RATES[i].name, 168 + XENSND_SAMPLE_RATE_MAX_LEN)) { 169 + cur_mask = CFG_HW_SUPPORTED_RATES[i].mask; 170 + cur_value = CFG_HW_SUPPORTED_RATES[i].value; 171 + rates |= cur_mask; 172 + if (rate_min > cur_value) 173 + rate_min = cur_value; 174 + if (rate_max < cur_value) 175 + rate_max = cur_value; 176 + } 177 + } 178 + 179 + if (rates) { 180 + pcm_hw->rates = rates; 181 + pcm_hw->rate_min = rate_min; 182 + pcm_hw->rate_max = rate_max; 183 + } 184 + } 185 + 186 + static void cfg_formats(char *list, unsigned int len, 187 + const char *path, struct snd_pcm_hardware *pcm_hw) 188 + { 189 + u64 formats; 190 + char *cur_format; 191 + int i; 192 + 193 + formats = 0; 194 + while ((cur_format = strsep(&list, XENSND_LIST_SEPARATOR))) { 195 + for (i = 0; i < ARRAY_SIZE(CFG_HW_SUPPORTED_FORMATS); i++) 196 + if (!strncasecmp(cur_format, 197 + CFG_HW_SUPPORTED_FORMATS[i].name, 198 + XENSND_SAMPLE_FORMAT_MAX_LEN)) 199 + formats |= CFG_HW_SUPPORTED_FORMATS[i].mask; 200 + } 201 + 202 + if (formats) 203 + pcm_hw->formats = formats; 204 + } 205 + 206 + #define MAX_BUFFER_SIZE (64 * 1024) 207 + #define MIN_PERIOD_SIZE 64 208 + #define MAX_PERIOD_SIZE MAX_BUFFER_SIZE 209 + #define USE_FORMATS (SNDRV_PCM_FMTBIT_U8 | \ 210 + SNDRV_PCM_FMTBIT_S16_LE) 211 + #define USE_RATE (SNDRV_PCM_RATE_CONTINUOUS | \ 212 + SNDRV_PCM_RATE_8000_48000) 213 + #define USE_RATE_MIN 5512 214 + #define USE_RATE_MAX 48000 215 + #define USE_CHANNELS_MIN 1 216 + #define USE_CHANNELS_MAX 2 217 + #define USE_PERIODS_MIN 2 218 + #define USE_PERIODS_MAX (MAX_BUFFER_SIZE / MIN_PERIOD_SIZE) 219 + 220 + static const struct snd_pcm_hardware SND_DRV_PCM_HW_DEFAULT = { 221 + .info = (SNDRV_PCM_INFO_MMAP | 222 + SNDRV_PCM_INFO_INTERLEAVED | 223 + SNDRV_PCM_INFO_RESUME | 224 + SNDRV_PCM_INFO_MMAP_VALID), 225 + .formats = USE_FORMATS, 226 + .rates = USE_RATE, 227 + .rate_min = USE_RATE_MIN, 228 + .rate_max = USE_RATE_MAX, 229 + .channels_min = USE_CHANNELS_MIN, 230 + .channels_max = USE_CHANNELS_MAX, 231 + .buffer_bytes_max = MAX_BUFFER_SIZE, 232 + .period_bytes_min = MIN_PERIOD_SIZE, 233 + .period_bytes_max = MAX_PERIOD_SIZE, 234 + .periods_min = USE_PERIODS_MIN, 235 + .periods_max = USE_PERIODS_MAX, 236 + .fifo_size = 0, 237 + }; 238 + 239 + static void cfg_read_pcm_hw(const char *path, 240 + struct snd_pcm_hardware *parent_pcm_hw, 241 + struct snd_pcm_hardware *pcm_hw) 242 + { 243 + char *list; 244 + int val; 245 + size_t buf_sz; 246 + unsigned int len; 247 + 248 + /* Inherit parent's PCM HW and read overrides from XenStore. */ 249 + if (parent_pcm_hw) 250 + *pcm_hw = *parent_pcm_hw; 251 + else 252 + *pcm_hw = SND_DRV_PCM_HW_DEFAULT; 253 + 254 + val = xenbus_read_unsigned(path, XENSND_FIELD_CHANNELS_MIN, 0); 255 + if (val) 256 + pcm_hw->channels_min = val; 257 + 258 + val = xenbus_read_unsigned(path, XENSND_FIELD_CHANNELS_MAX, 0); 259 + if (val) 260 + pcm_hw->channels_max = val; 261 + 262 + list = xenbus_read(XBT_NIL, path, XENSND_FIELD_SAMPLE_RATES, &len); 263 + if (!IS_ERR(list)) { 264 + cfg_hw_rates(list, len, path, pcm_hw); 265 + kfree(list); 266 + } 267 + 268 + list = xenbus_read(XBT_NIL, path, XENSND_FIELD_SAMPLE_FORMATS, &len); 269 + if (!IS_ERR(list)) { 270 + cfg_formats(list, len, path, pcm_hw); 271 + kfree(list); 272 + } 273 + 274 + buf_sz = xenbus_read_unsigned(path, XENSND_FIELD_BUFFER_SIZE, 0); 275 + if (buf_sz) 276 + pcm_hw->buffer_bytes_max = buf_sz; 277 + 278 + /* Update configuration to match new values. */ 279 + if (pcm_hw->channels_min > pcm_hw->channels_max) 280 + pcm_hw->channels_min = pcm_hw->channels_max; 281 + 282 + if (pcm_hw->rate_min > pcm_hw->rate_max) 283 + pcm_hw->rate_min = pcm_hw->rate_max; 284 + 285 + pcm_hw->period_bytes_max = pcm_hw->buffer_bytes_max; 286 + 287 + pcm_hw->periods_max = pcm_hw->period_bytes_max / 288 + pcm_hw->period_bytes_min; 289 + } 290 + 291 + static int cfg_get_stream_type(const char *path, int index, 292 + int *num_pb, int *num_cap) 293 + { 294 + char *str = NULL; 295 + char *stream_path; 296 + int ret; 297 + 298 + *num_pb = 0; 299 + *num_cap = 0; 300 + stream_path = kasprintf(GFP_KERNEL, "%s/%d", path, index); 301 + if (!stream_path) { 302 + ret = -ENOMEM; 303 + goto fail; 304 + } 305 + 306 + str = xenbus_read(XBT_NIL, stream_path, XENSND_FIELD_TYPE, NULL); 307 + if (IS_ERR(str)) { 308 + ret = PTR_ERR(str); 309 + str = NULL; 310 + goto fail; 311 + } 312 + 313 + if (!strncasecmp(str, XENSND_STREAM_TYPE_PLAYBACK, 314 + sizeof(XENSND_STREAM_TYPE_PLAYBACK))) { 315 + (*num_pb)++; 316 + } else if (!strncasecmp(str, XENSND_STREAM_TYPE_CAPTURE, 317 + sizeof(XENSND_STREAM_TYPE_CAPTURE))) { 318 + (*num_cap)++; 319 + } else { 320 + ret = -EINVAL; 321 + goto fail; 322 + } 323 + ret = 0; 324 + 325 + fail: 326 + kfree(stream_path); 327 + kfree(str); 328 + return ret; 329 + } 330 + 331 + static int cfg_stream(struct xen_snd_front_info *front_info, 332 + struct xen_front_cfg_pcm_instance *pcm_instance, 333 + const char *path, int index, int *cur_pb, int *cur_cap, 334 + int *stream_cnt) 335 + { 336 + char *str = NULL; 337 + char *stream_path; 338 + struct xen_front_cfg_stream *stream; 339 + int ret; 340 + 341 + stream_path = devm_kasprintf(&front_info->xb_dev->dev, 342 + GFP_KERNEL, "%s/%d", path, index); 343 + if (!stream_path) { 344 + ret = -ENOMEM; 345 + goto fail; 346 + } 347 + 348 + str = xenbus_read(XBT_NIL, stream_path, XENSND_FIELD_TYPE, NULL); 349 + if (IS_ERR(str)) { 350 + ret = PTR_ERR(str); 351 + str = NULL; 352 + goto fail; 353 + } 354 + 355 + if (!strncasecmp(str, XENSND_STREAM_TYPE_PLAYBACK, 356 + sizeof(XENSND_STREAM_TYPE_PLAYBACK))) { 357 + stream = &pcm_instance->streams_pb[(*cur_pb)++]; 358 + } else if (!strncasecmp(str, XENSND_STREAM_TYPE_CAPTURE, 359 + sizeof(XENSND_STREAM_TYPE_CAPTURE))) { 360 + stream = &pcm_instance->streams_cap[(*cur_cap)++]; 361 + } else { 362 + ret = -EINVAL; 363 + goto fail; 364 + } 365 + 366 + /* Get next stream index. */ 367 + stream->index = (*stream_cnt)++; 368 + stream->xenstore_path = stream_path; 369 + /* 370 + * Check XenStore if PCM HW configuration exists for this stream 371 + * and update if so, e.g. we inherit all values from device's PCM HW, 372 + * but can still override some of the values for the stream. 373 + */ 374 + cfg_read_pcm_hw(stream->xenstore_path, 375 + &pcm_instance->pcm_hw, &stream->pcm_hw); 376 + ret = 0; 377 + 378 + fail: 379 + kfree(str); 380 + return ret; 381 + } 382 + 383 + static int cfg_device(struct xen_snd_front_info *front_info, 384 + struct xen_front_cfg_pcm_instance *pcm_instance, 385 + struct snd_pcm_hardware *parent_pcm_hw, 386 + const char *path, int node_index, int *stream_cnt) 387 + { 388 + char *str; 389 + char *device_path; 390 + int ret, i, num_streams; 391 + int num_pb, num_cap; 392 + int cur_pb, cur_cap; 393 + char node[3]; 394 + 395 + device_path = kasprintf(GFP_KERNEL, "%s/%d", path, node_index); 396 + if (!device_path) 397 + return -ENOMEM; 398 + 399 + str = xenbus_read(XBT_NIL, device_path, XENSND_FIELD_DEVICE_NAME, NULL); 400 + if (!IS_ERR(str)) { 401 + strlcpy(pcm_instance->name, str, sizeof(pcm_instance->name)); 402 + kfree(str); 403 + } 404 + 405 + pcm_instance->device_id = node_index; 406 + 407 + /* 408 + * Check XenStore if PCM HW configuration exists for this device 409 + * and update if so, e.g. we inherit all values from card's PCM HW, 410 + * but can still override some of the values for the device. 411 + */ 412 + cfg_read_pcm_hw(device_path, parent_pcm_hw, &pcm_instance->pcm_hw); 413 + 414 + /* Find out how many streams were configured in Xen store. */ 415 + num_streams = 0; 416 + do { 417 + snprintf(node, sizeof(node), "%d", num_streams); 418 + if (!xenbus_exists(XBT_NIL, device_path, node)) 419 + break; 420 + 421 + num_streams++; 422 + } while (num_streams < VSND_MAX_STREAM); 423 + 424 + pcm_instance->num_streams_pb = 0; 425 + pcm_instance->num_streams_cap = 0; 426 + /* Get number of playback and capture streams. */ 427 + for (i = 0; i < num_streams; i++) { 428 + ret = cfg_get_stream_type(device_path, i, &num_pb, &num_cap); 429 + if (ret < 0) 430 + goto fail; 431 + 432 + pcm_instance->num_streams_pb += num_pb; 433 + pcm_instance->num_streams_cap += num_cap; 434 + } 435 + 436 + if (pcm_instance->num_streams_pb) { 437 + pcm_instance->streams_pb = 438 + devm_kcalloc(&front_info->xb_dev->dev, 439 + pcm_instance->num_streams_pb, 440 + sizeof(struct xen_front_cfg_stream), 441 + GFP_KERNEL); 442 + if (!pcm_instance->streams_pb) { 443 + ret = -ENOMEM; 444 + goto fail; 445 + } 446 + } 447 + 448 + if (pcm_instance->num_streams_cap) { 449 + pcm_instance->streams_cap = 450 + devm_kcalloc(&front_info->xb_dev->dev, 451 + pcm_instance->num_streams_cap, 452 + sizeof(struct xen_front_cfg_stream), 453 + GFP_KERNEL); 454 + if (!pcm_instance->streams_cap) { 455 + ret = -ENOMEM; 456 + goto fail; 457 + } 458 + } 459 + 460 + cur_pb = 0; 461 + cur_cap = 0; 462 + for (i = 0; i < num_streams; i++) { 463 + ret = cfg_stream(front_info, pcm_instance, device_path, i, 464 + &cur_pb, &cur_cap, stream_cnt); 465 + if (ret < 0) 466 + goto fail; 467 + } 468 + ret = 0; 469 + 470 + fail: 471 + kfree(device_path); 472 + return ret; 473 + } 474 + 475 + int xen_snd_front_cfg_card(struct xen_snd_front_info *front_info, 476 + int *stream_cnt) 477 + { 478 + struct xenbus_device *xb_dev = front_info->xb_dev; 479 + struct xen_front_cfg_card *cfg = &front_info->cfg; 480 + int ret, num_devices, i; 481 + char node[3]; 482 + 483 + *stream_cnt = 0; 484 + num_devices = 0; 485 + do { 486 + snprintf(node, sizeof(node), "%d", num_devices); 487 + if (!xenbus_exists(XBT_NIL, xb_dev->nodename, node)) 488 + break; 489 + 490 + num_devices++; 491 + } while (num_devices < SNDRV_PCM_DEVICES); 492 + 493 + if (!num_devices) { 494 + dev_warn(&xb_dev->dev, 495 + "No devices configured for sound card at %s\n", 496 + xb_dev->nodename); 497 + return -ENODEV; 498 + } 499 + 500 + /* Start from default PCM HW configuration for the card. */ 501 + cfg_read_pcm_hw(xb_dev->nodename, NULL, &cfg->pcm_hw); 502 + 503 + cfg->pcm_instances = 504 + devm_kcalloc(&front_info->xb_dev->dev, num_devices, 505 + sizeof(struct xen_front_cfg_pcm_instance), 506 + GFP_KERNEL); 507 + if (!cfg->pcm_instances) 508 + return -ENOMEM; 509 + 510 + for (i = 0; i < num_devices; i++) { 511 + ret = cfg_device(front_info, &cfg->pcm_instances[i], 512 + &cfg->pcm_hw, xb_dev->nodename, i, stream_cnt); 513 + if (ret < 0) 514 + return ret; 515 + } 516 + cfg->num_pcm_instances = num_devices; 517 + return 0; 518 + } 519 +
+46
sound/xen/xen_snd_front_cfg.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #ifndef __XEN_SND_FRONT_CFG_H 12 + #define __XEN_SND_FRONT_CFG_H 13 + 14 + #include <sound/core.h> 15 + #include <sound/pcm.h> 16 + 17 + struct xen_snd_front_info; 18 + 19 + struct xen_front_cfg_stream { 20 + int index; 21 + char *xenstore_path; 22 + struct snd_pcm_hardware pcm_hw; 23 + }; 24 + 25 + struct xen_front_cfg_pcm_instance { 26 + char name[80]; 27 + int device_id; 28 + struct snd_pcm_hardware pcm_hw; 29 + int num_streams_pb; 30 + struct xen_front_cfg_stream *streams_pb; 31 + int num_streams_cap; 32 + struct xen_front_cfg_stream *streams_cap; 33 + }; 34 + 35 + struct xen_front_cfg_card { 36 + char name_short[32]; 37 + char name_long[80]; 38 + struct snd_pcm_hardware pcm_hw; 39 + int num_pcm_instances; 40 + struct xen_front_cfg_pcm_instance *pcm_instances; 41 + }; 42 + 43 + int xen_snd_front_cfg_card(struct xen_snd_front_info *front_info, 44 + int *stream_cnt); 45 + 46 + #endif /* __XEN_SND_FRONT_CFG_H */
+494
sound/xen/xen_snd_front_evtchnl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #include <xen/events.h> 12 + #include <xen/grant_table.h> 13 + #include <xen/xen.h> 14 + #include <xen/xenbus.h> 15 + 16 + #include "xen_snd_front.h" 17 + #include "xen_snd_front_alsa.h" 18 + #include "xen_snd_front_cfg.h" 19 + #include "xen_snd_front_evtchnl.h" 20 + 21 + static irqreturn_t evtchnl_interrupt_req(int irq, void *dev_id) 22 + { 23 + struct xen_snd_front_evtchnl *channel = dev_id; 24 + struct xen_snd_front_info *front_info = channel->front_info; 25 + struct xensnd_resp *resp; 26 + RING_IDX i, rp; 27 + 28 + if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED)) 29 + return IRQ_HANDLED; 30 + 31 + mutex_lock(&channel->ring_io_lock); 32 + 33 + again: 34 + rp = channel->u.req.ring.sring->rsp_prod; 35 + /* Ensure we see queued responses up to rp. */ 36 + rmb(); 37 + 38 + /* 39 + * Assume that the backend is trusted to always write sane values 40 + * to the ring counters, so no overflow checks on frontend side 41 + * are required. 42 + */ 43 + for (i = channel->u.req.ring.rsp_cons; i != rp; i++) { 44 + resp = RING_GET_RESPONSE(&channel->u.req.ring, i); 45 + if (resp->id != channel->evt_id) 46 + continue; 47 + switch (resp->operation) { 48 + case XENSND_OP_OPEN: 49 + /* fall through */ 50 + case XENSND_OP_CLOSE: 51 + /* fall through */ 52 + case XENSND_OP_READ: 53 + /* fall through */ 54 + case XENSND_OP_WRITE: 55 + /* fall through */ 56 + case XENSND_OP_TRIGGER: 57 + channel->u.req.resp_status = resp->status; 58 + complete(&channel->u.req.completion); 59 + break; 60 + case XENSND_OP_HW_PARAM_QUERY: 61 + channel->u.req.resp_status = resp->status; 62 + channel->u.req.resp.hw_param = 63 + resp->resp.hw_param; 64 + complete(&channel->u.req.completion); 65 + break; 66 + 67 + default: 68 + dev_err(&front_info->xb_dev->dev, 69 + "Operation %d is not supported\n", 70 + resp->operation); 71 + break; 72 + } 73 + } 74 + 75 + channel->u.req.ring.rsp_cons = i; 76 + if (i != channel->u.req.ring.req_prod_pvt) { 77 + int more_to_do; 78 + 79 + RING_FINAL_CHECK_FOR_RESPONSES(&channel->u.req.ring, 80 + more_to_do); 81 + if (more_to_do) 82 + goto again; 83 + } else { 84 + channel->u.req.ring.sring->rsp_event = i + 1; 85 + } 86 + 87 + mutex_unlock(&channel->ring_io_lock); 88 + return IRQ_HANDLED; 89 + } 90 + 91 + static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id) 92 + { 93 + struct xen_snd_front_evtchnl *channel = dev_id; 94 + struct xensnd_event_page *page = channel->u.evt.page; 95 + u32 cons, prod; 96 + 97 + if (unlikely(channel->state != EVTCHNL_STATE_CONNECTED)) 98 + return IRQ_HANDLED; 99 + 100 + mutex_lock(&channel->ring_io_lock); 101 + 102 + prod = page->in_prod; 103 + /* Ensure we see ring contents up to prod. */ 104 + virt_rmb(); 105 + if (prod == page->in_cons) 106 + goto out; 107 + 108 + /* 109 + * Assume that the backend is trusted to always write sane values 110 + * to the ring counters, so no overflow checks on frontend side 111 + * are required. 112 + */ 113 + for (cons = page->in_cons; cons != prod; cons++) { 114 + struct xensnd_evt *event; 115 + 116 + event = &XENSND_IN_RING_REF(page, cons); 117 + if (unlikely(event->id != channel->evt_id++)) 118 + continue; 119 + 120 + switch (event->type) { 121 + case XENSND_EVT_CUR_POS: 122 + xen_snd_front_alsa_handle_cur_pos(channel, 123 + event->op.cur_pos.position); 124 + break; 125 + } 126 + } 127 + 128 + page->in_cons = cons; 129 + /* Ensure ring contents. */ 130 + virt_wmb(); 131 + 132 + out: 133 + mutex_unlock(&channel->ring_io_lock); 134 + return IRQ_HANDLED; 135 + } 136 + 137 + void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *channel) 138 + { 139 + int notify; 140 + 141 + channel->u.req.ring.req_prod_pvt++; 142 + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&channel->u.req.ring, notify); 143 + if (notify) 144 + notify_remote_via_irq(channel->irq); 145 + } 146 + 147 + static void evtchnl_free(struct xen_snd_front_info *front_info, 148 + struct xen_snd_front_evtchnl *channel) 149 + { 150 + unsigned long page = 0; 151 + 152 + if (channel->type == EVTCHNL_TYPE_REQ) 153 + page = (unsigned long)channel->u.req.ring.sring; 154 + else if (channel->type == EVTCHNL_TYPE_EVT) 155 + page = (unsigned long)channel->u.evt.page; 156 + 157 + if (!page) 158 + return; 159 + 160 + channel->state = EVTCHNL_STATE_DISCONNECTED; 161 + if (channel->type == EVTCHNL_TYPE_REQ) { 162 + /* Release all who still waits for response if any. */ 163 + channel->u.req.resp_status = -EIO; 164 + complete_all(&channel->u.req.completion); 165 + } 166 + 167 + if (channel->irq) 168 + unbind_from_irqhandler(channel->irq, channel); 169 + 170 + if (channel->port) 171 + xenbus_free_evtchn(front_info->xb_dev, channel->port); 172 + 173 + /* End access and free the page. */ 174 + if (channel->gref != GRANT_INVALID_REF) 175 + gnttab_end_foreign_access(channel->gref, 0, page); 176 + else 177 + free_page(page); 178 + 179 + memset(channel, 0, sizeof(*channel)); 180 + } 181 + 182 + void xen_snd_front_evtchnl_free_all(struct xen_snd_front_info *front_info) 183 + { 184 + int i; 185 + 186 + if (!front_info->evt_pairs) 187 + return; 188 + 189 + for (i = 0; i < front_info->num_evt_pairs; i++) { 190 + evtchnl_free(front_info, &front_info->evt_pairs[i].req); 191 + evtchnl_free(front_info, &front_info->evt_pairs[i].evt); 192 + } 193 + 194 + kfree(front_info->evt_pairs); 195 + front_info->evt_pairs = NULL; 196 + } 197 + 198 + static int evtchnl_alloc(struct xen_snd_front_info *front_info, int index, 199 + struct xen_snd_front_evtchnl *channel, 200 + enum xen_snd_front_evtchnl_type type) 201 + { 202 + struct xenbus_device *xb_dev = front_info->xb_dev; 203 + unsigned long page; 204 + grant_ref_t gref; 205 + irq_handler_t handler; 206 + char *handler_name = NULL; 207 + int ret; 208 + 209 + memset(channel, 0, sizeof(*channel)); 210 + channel->type = type; 211 + channel->index = index; 212 + channel->front_info = front_info; 213 + channel->state = EVTCHNL_STATE_DISCONNECTED; 214 + channel->gref = GRANT_INVALID_REF; 215 + page = get_zeroed_page(GFP_KERNEL); 216 + if (!page) { 217 + ret = -ENOMEM; 218 + goto fail; 219 + } 220 + 221 + handler_name = kasprintf(GFP_KERNEL, "%s-%s", XENSND_DRIVER_NAME, 222 + type == EVTCHNL_TYPE_REQ ? 223 + XENSND_FIELD_RING_REF : 224 + XENSND_FIELD_EVT_RING_REF); 225 + if (!handler_name) { 226 + ret = -ENOMEM; 227 + goto fail; 228 + } 229 + 230 + mutex_init(&channel->ring_io_lock); 231 + 232 + if (type == EVTCHNL_TYPE_REQ) { 233 + struct xen_sndif_sring *sring = (struct xen_sndif_sring *)page; 234 + 235 + init_completion(&channel->u.req.completion); 236 + mutex_init(&channel->u.req.req_io_lock); 237 + SHARED_RING_INIT(sring); 238 + FRONT_RING_INIT(&channel->u.req.ring, sring, XEN_PAGE_SIZE); 239 + 240 + ret = xenbus_grant_ring(xb_dev, sring, 1, &gref); 241 + if (ret < 0) { 242 + channel->u.req.ring.sring = NULL; 243 + goto fail; 244 + } 245 + 246 + handler = evtchnl_interrupt_req; 247 + } else { 248 + ret = gnttab_grant_foreign_access(xb_dev->otherend_id, 249 + virt_to_gfn((void *)page), 0); 250 + if (ret < 0) 251 + goto fail; 252 + 253 + channel->u.evt.page = (struct xensnd_event_page *)page; 254 + gref = ret; 255 + handler = evtchnl_interrupt_evt; 256 + } 257 + 258 + channel->gref = gref; 259 + 260 + ret = xenbus_alloc_evtchn(xb_dev, &channel->port); 261 + if (ret < 0) 262 + goto fail; 263 + 264 + ret = bind_evtchn_to_irq(channel->port); 265 + if (ret < 0) { 266 + dev_err(&xb_dev->dev, 267 + "Failed to bind IRQ for domid %d port %d: %d\n", 268 + front_info->xb_dev->otherend_id, channel->port, ret); 269 + goto fail; 270 + } 271 + 272 + channel->irq = ret; 273 + 274 + ret = request_threaded_irq(channel->irq, NULL, handler, 275 + IRQF_ONESHOT, handler_name, channel); 276 + if (ret < 0) { 277 + dev_err(&xb_dev->dev, "Failed to request IRQ %d: %d\n", 278 + channel->irq, ret); 279 + goto fail; 280 + } 281 + 282 + kfree(handler_name); 283 + return 0; 284 + 285 + fail: 286 + if (page) 287 + free_page(page); 288 + kfree(handler_name); 289 + dev_err(&xb_dev->dev, "Failed to allocate ring: %d\n", ret); 290 + return ret; 291 + } 292 + 293 + int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info, 294 + int num_streams) 295 + { 296 + struct xen_front_cfg_card *cfg = &front_info->cfg; 297 + struct device *dev = &front_info->xb_dev->dev; 298 + int d, ret = 0; 299 + 300 + front_info->evt_pairs = 301 + kcalloc(num_streams, 302 + sizeof(struct xen_snd_front_evtchnl_pair), 303 + GFP_KERNEL); 304 + if (!front_info->evt_pairs) 305 + return -ENOMEM; 306 + 307 + /* Iterate over devices and their streams and create event channels. */ 308 + for (d = 0; d < cfg->num_pcm_instances; d++) { 309 + struct xen_front_cfg_pcm_instance *pcm_instance; 310 + int s, index; 311 + 312 + pcm_instance = &cfg->pcm_instances[d]; 313 + 314 + for (s = 0; s < pcm_instance->num_streams_pb; s++) { 315 + index = pcm_instance->streams_pb[s].index; 316 + 317 + ret = evtchnl_alloc(front_info, index, 318 + &front_info->evt_pairs[index].req, 319 + EVTCHNL_TYPE_REQ); 320 + if (ret < 0) { 321 + dev_err(dev, "Error allocating control channel\n"); 322 + goto fail; 323 + } 324 + 325 + ret = evtchnl_alloc(front_info, index, 326 + &front_info->evt_pairs[index].evt, 327 + EVTCHNL_TYPE_EVT); 328 + if (ret < 0) { 329 + dev_err(dev, "Error allocating in-event channel\n"); 330 + goto fail; 331 + } 332 + } 333 + 334 + for (s = 0; s < pcm_instance->num_streams_cap; s++) { 335 + index = pcm_instance->streams_cap[s].index; 336 + 337 + ret = evtchnl_alloc(front_info, index, 338 + &front_info->evt_pairs[index].req, 339 + EVTCHNL_TYPE_REQ); 340 + if (ret < 0) { 341 + dev_err(dev, "Error allocating control channel\n"); 342 + goto fail; 343 + } 344 + 345 + ret = evtchnl_alloc(front_info, index, 346 + &front_info->evt_pairs[index].evt, 347 + EVTCHNL_TYPE_EVT); 348 + if (ret < 0) { 349 + dev_err(dev, "Error allocating in-event channel\n"); 350 + goto fail; 351 + } 352 + } 353 + } 354 + 355 + front_info->num_evt_pairs = num_streams; 356 + return 0; 357 + 358 + fail: 359 + xen_snd_front_evtchnl_free_all(front_info); 360 + return ret; 361 + } 362 + 363 + static int evtchnl_publish(struct xenbus_transaction xbt, 364 + struct xen_snd_front_evtchnl *channel, 365 + const char *path, const char *node_ring, 366 + const char *node_chnl) 367 + { 368 + struct xenbus_device *xb_dev = channel->front_info->xb_dev; 369 + int ret; 370 + 371 + /* Write control channel ring reference. */ 372 + ret = xenbus_printf(xbt, path, node_ring, "%u", channel->gref); 373 + if (ret < 0) { 374 + dev_err(&xb_dev->dev, "Error writing ring-ref: %d\n", ret); 375 + return ret; 376 + } 377 + 378 + /* Write event channel ring reference. */ 379 + ret = xenbus_printf(xbt, path, node_chnl, "%u", channel->port); 380 + if (ret < 0) { 381 + dev_err(&xb_dev->dev, "Error writing event channel: %d\n", ret); 382 + return ret; 383 + } 384 + 385 + return 0; 386 + } 387 + 388 + int xen_snd_front_evtchnl_publish_all(struct xen_snd_front_info *front_info) 389 + { 390 + struct xen_front_cfg_card *cfg = &front_info->cfg; 391 + struct xenbus_transaction xbt; 392 + int ret, d; 393 + 394 + again: 395 + ret = xenbus_transaction_start(&xbt); 396 + if (ret < 0) { 397 + xenbus_dev_fatal(front_info->xb_dev, ret, 398 + "starting transaction"); 399 + return ret; 400 + } 401 + 402 + for (d = 0; d < cfg->num_pcm_instances; d++) { 403 + struct xen_front_cfg_pcm_instance *pcm_instance; 404 + int s, index; 405 + 406 + pcm_instance = &cfg->pcm_instances[d]; 407 + 408 + for (s = 0; s < pcm_instance->num_streams_pb; s++) { 409 + index = pcm_instance->streams_pb[s].index; 410 + 411 + ret = evtchnl_publish(xbt, 412 + &front_info->evt_pairs[index].req, 413 + pcm_instance->streams_pb[s].xenstore_path, 414 + XENSND_FIELD_RING_REF, 415 + XENSND_FIELD_EVT_CHNL); 416 + if (ret < 0) 417 + goto fail; 418 + 419 + ret = evtchnl_publish(xbt, 420 + &front_info->evt_pairs[index].evt, 421 + pcm_instance->streams_pb[s].xenstore_path, 422 + XENSND_FIELD_EVT_RING_REF, 423 + XENSND_FIELD_EVT_EVT_CHNL); 424 + if (ret < 0) 425 + goto fail; 426 + } 427 + 428 + for (s = 0; s < pcm_instance->num_streams_cap; s++) { 429 + index = pcm_instance->streams_cap[s].index; 430 + 431 + ret = evtchnl_publish(xbt, 432 + &front_info->evt_pairs[index].req, 433 + pcm_instance->streams_cap[s].xenstore_path, 434 + XENSND_FIELD_RING_REF, 435 + XENSND_FIELD_EVT_CHNL); 436 + if (ret < 0) 437 + goto fail; 438 + 439 + ret = evtchnl_publish(xbt, 440 + &front_info->evt_pairs[index].evt, 441 + pcm_instance->streams_cap[s].xenstore_path, 442 + XENSND_FIELD_EVT_RING_REF, 443 + XENSND_FIELD_EVT_EVT_CHNL); 444 + if (ret < 0) 445 + goto fail; 446 + } 447 + } 448 + ret = xenbus_transaction_end(xbt, 0); 449 + if (ret < 0) { 450 + if (ret == -EAGAIN) 451 + goto again; 452 + 453 + xenbus_dev_fatal(front_info->xb_dev, ret, 454 + "completing transaction"); 455 + goto fail_to_end; 456 + } 457 + return 0; 458 + fail: 459 + xenbus_transaction_end(xbt, 1); 460 + fail_to_end: 461 + xenbus_dev_fatal(front_info->xb_dev, ret, "writing XenStore"); 462 + return ret; 463 + } 464 + 465 + void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair *evt_pair, 466 + bool is_connected) 467 + { 468 + enum xen_snd_front_evtchnl_state state; 469 + 470 + if (is_connected) 471 + state = EVTCHNL_STATE_CONNECTED; 472 + else 473 + state = EVTCHNL_STATE_DISCONNECTED; 474 + 475 + mutex_lock(&evt_pair->req.ring_io_lock); 476 + evt_pair->req.state = state; 477 + mutex_unlock(&evt_pair->req.ring_io_lock); 478 + 479 + mutex_lock(&evt_pair->evt.ring_io_lock); 480 + evt_pair->evt.state = state; 481 + mutex_unlock(&evt_pair->evt.ring_io_lock); 482 + } 483 + 484 + void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair) 485 + { 486 + mutex_lock(&evt_pair->req.ring_io_lock); 487 + evt_pair->req.evt_next_id = 0; 488 + mutex_unlock(&evt_pair->req.ring_io_lock); 489 + 490 + mutex_lock(&evt_pair->evt.ring_io_lock); 491 + evt_pair->evt.evt_next_id = 0; 492 + mutex_unlock(&evt_pair->evt.ring_io_lock); 493 + } 494 +
+95
sound/xen/xen_snd_front_evtchnl.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #ifndef __XEN_SND_FRONT_EVTCHNL_H 12 + #define __XEN_SND_FRONT_EVTCHNL_H 13 + 14 + #include <xen/interface/io/sndif.h> 15 + 16 + struct xen_snd_front_info; 17 + 18 + #ifndef GRANT_INVALID_REF 19 + /* 20 + * FIXME: usage of grant reference 0 as invalid grant reference: 21 + * grant reference 0 is valid, but never exposed to a PV driver, 22 + * because of the fact it is already in use/reserved by the PV console. 23 + */ 24 + #define GRANT_INVALID_REF 0 25 + #endif 26 + 27 + /* Timeout in ms to wait for backend to respond. */ 28 + #define VSND_WAIT_BACK_MS 3000 29 + 30 + enum xen_snd_front_evtchnl_state { 31 + EVTCHNL_STATE_DISCONNECTED, 32 + EVTCHNL_STATE_CONNECTED, 33 + }; 34 + 35 + enum xen_snd_front_evtchnl_type { 36 + EVTCHNL_TYPE_REQ, 37 + EVTCHNL_TYPE_EVT, 38 + }; 39 + 40 + struct xen_snd_front_evtchnl { 41 + struct xen_snd_front_info *front_info; 42 + int gref; 43 + int port; 44 + int irq; 45 + int index; 46 + /* State of the event channel. */ 47 + enum xen_snd_front_evtchnl_state state; 48 + enum xen_snd_front_evtchnl_type type; 49 + /* Either response id or incoming event id. */ 50 + u16 evt_id; 51 + /* Next request id or next expected event id. */ 52 + u16 evt_next_id; 53 + /* Shared ring access lock. */ 54 + struct mutex ring_io_lock; 55 + union { 56 + struct { 57 + struct xen_sndif_front_ring ring; 58 + struct completion completion; 59 + /* Serializer for backend IO: request/response. */ 60 + struct mutex req_io_lock; 61 + 62 + /* Latest response status. */ 63 + int resp_status; 64 + union { 65 + struct xensnd_query_hw_param hw_param; 66 + } resp; 67 + } req; 68 + struct { 69 + struct xensnd_event_page *page; 70 + /* This is needed to handle XENSND_EVT_CUR_POS event. */ 71 + struct snd_pcm_substream *substream; 72 + } evt; 73 + } u; 74 + }; 75 + 76 + struct xen_snd_front_evtchnl_pair { 77 + struct xen_snd_front_evtchnl req; 78 + struct xen_snd_front_evtchnl evt; 79 + }; 80 + 81 + int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info, 82 + int num_streams); 83 + 84 + void xen_snd_front_evtchnl_free_all(struct xen_snd_front_info *front_info); 85 + 86 + int xen_snd_front_evtchnl_publish_all(struct xen_snd_front_info *front_info); 87 + 88 + void xen_snd_front_evtchnl_flush(struct xen_snd_front_evtchnl *evtchnl); 89 + 90 + void xen_snd_front_evtchnl_pair_set_connected(struct xen_snd_front_evtchnl_pair *evt_pair, 91 + bool is_connected); 92 + 93 + void xen_snd_front_evtchnl_pair_clear(struct xen_snd_front_evtchnl_pair *evt_pair); 94 + 95 + #endif /* __XEN_SND_FRONT_EVTCHNL_H */
+194
sound/xen/xen_snd_front_shbuf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <xen/xen.h> 13 + #include <xen/xenbus.h> 14 + 15 + #include "xen_snd_front_shbuf.h" 16 + 17 + grant_ref_t xen_snd_front_shbuf_get_dir_start(struct xen_snd_front_shbuf *buf) 18 + { 19 + if (!buf->grefs) 20 + return GRANT_INVALID_REF; 21 + 22 + return buf->grefs[0]; 23 + } 24 + 25 + void xen_snd_front_shbuf_clear(struct xen_snd_front_shbuf *buf) 26 + { 27 + memset(buf, 0, sizeof(*buf)); 28 + } 29 + 30 + void xen_snd_front_shbuf_free(struct xen_snd_front_shbuf *buf) 31 + { 32 + int i; 33 + 34 + if (buf->grefs) { 35 + for (i = 0; i < buf->num_grefs; i++) 36 + if (buf->grefs[i] != GRANT_INVALID_REF) 37 + gnttab_end_foreign_access(buf->grefs[i], 38 + 0, 0UL); 39 + kfree(buf->grefs); 40 + } 41 + kfree(buf->directory); 42 + free_pages_exact(buf->buffer, buf->buffer_sz); 43 + xen_snd_front_shbuf_clear(buf); 44 + } 45 + 46 + /* 47 + * number of grant references a page can hold with respect to the 48 + * xensnd_page_directory header 49 + */ 50 + #define XENSND_NUM_GREFS_PER_PAGE ((XEN_PAGE_SIZE - \ 51 + offsetof(struct xensnd_page_directory, gref)) / \ 52 + sizeof(grant_ref_t)) 53 + 54 + static void fill_page_dir(struct xen_snd_front_shbuf *buf, 55 + int num_pages_dir) 56 + { 57 + struct xensnd_page_directory *page_dir; 58 + unsigned char *ptr; 59 + int i, cur_gref, grefs_left, to_copy; 60 + 61 + ptr = buf->directory; 62 + grefs_left = buf->num_grefs - num_pages_dir; 63 + /* 64 + * skip grant references at the beginning, they are for pages granted 65 + * for the page directory itself 66 + */ 67 + cur_gref = num_pages_dir; 68 + for (i = 0; i < num_pages_dir; i++) { 69 + page_dir = (struct xensnd_page_directory *)ptr; 70 + if (grefs_left <= XENSND_NUM_GREFS_PER_PAGE) { 71 + to_copy = grefs_left; 72 + page_dir->gref_dir_next_page = GRANT_INVALID_REF; 73 + } else { 74 + to_copy = XENSND_NUM_GREFS_PER_PAGE; 75 + page_dir->gref_dir_next_page = buf->grefs[i + 1]; 76 + } 77 + 78 + memcpy(&page_dir->gref, &buf->grefs[cur_gref], 79 + to_copy * sizeof(grant_ref_t)); 80 + 81 + ptr += XEN_PAGE_SIZE; 82 + grefs_left -= to_copy; 83 + cur_gref += to_copy; 84 + } 85 + } 86 + 87 + static int grant_references(struct xenbus_device *xb_dev, 88 + struct xen_snd_front_shbuf *buf, 89 + int num_pages_dir, int num_pages_buffer, 90 + int num_grefs) 91 + { 92 + grant_ref_t priv_gref_head; 93 + unsigned long frame; 94 + int ret, i, j, cur_ref; 95 + int otherend_id; 96 + 97 + ret = gnttab_alloc_grant_references(num_grefs, &priv_gref_head); 98 + if (ret) 99 + return ret; 100 + 101 + buf->num_grefs = num_grefs; 102 + otherend_id = xb_dev->otherend_id; 103 + j = 0; 104 + 105 + for (i = 0; i < num_pages_dir; i++) { 106 + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); 107 + if (cur_ref < 0) { 108 + ret = cur_ref; 109 + goto fail; 110 + } 111 + 112 + frame = xen_page_to_gfn(virt_to_page(buf->directory + 113 + XEN_PAGE_SIZE * i)); 114 + gnttab_grant_foreign_access_ref(cur_ref, otherend_id, frame, 0); 115 + buf->grefs[j++] = cur_ref; 116 + } 117 + 118 + for (i = 0; i < num_pages_buffer; i++) { 119 + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); 120 + if (cur_ref < 0) { 121 + ret = cur_ref; 122 + goto fail; 123 + } 124 + 125 + frame = xen_page_to_gfn(virt_to_page(buf->buffer + 126 + XEN_PAGE_SIZE * i)); 127 + gnttab_grant_foreign_access_ref(cur_ref, otherend_id, frame, 0); 128 + buf->grefs[j++] = cur_ref; 129 + } 130 + 131 + gnttab_free_grant_references(priv_gref_head); 132 + fill_page_dir(buf, num_pages_dir); 133 + return 0; 134 + 135 + fail: 136 + gnttab_free_grant_references(priv_gref_head); 137 + return ret; 138 + } 139 + 140 + static int alloc_int_buffers(struct xen_snd_front_shbuf *buf, 141 + int num_pages_dir, int num_pages_buffer, 142 + int num_grefs) 143 + { 144 + buf->grefs = kcalloc(num_grefs, sizeof(*buf->grefs), GFP_KERNEL); 145 + if (!buf->grefs) 146 + return -ENOMEM; 147 + 148 + buf->directory = kcalloc(num_pages_dir, XEN_PAGE_SIZE, GFP_KERNEL); 149 + if (!buf->directory) 150 + goto fail; 151 + 152 + buf->buffer_sz = num_pages_buffer * XEN_PAGE_SIZE; 153 + buf->buffer = alloc_pages_exact(buf->buffer_sz, GFP_KERNEL); 154 + if (!buf->buffer) 155 + goto fail; 156 + 157 + return 0; 158 + 159 + fail: 160 + kfree(buf->grefs); 161 + buf->grefs = NULL; 162 + kfree(buf->directory); 163 + buf->directory = NULL; 164 + return -ENOMEM; 165 + } 166 + 167 + int xen_snd_front_shbuf_alloc(struct xenbus_device *xb_dev, 168 + struct xen_snd_front_shbuf *buf, 169 + unsigned int buffer_sz) 170 + { 171 + int num_pages_buffer, num_pages_dir, num_grefs; 172 + int ret; 173 + 174 + xen_snd_front_shbuf_clear(buf); 175 + 176 + num_pages_buffer = DIV_ROUND_UP(buffer_sz, XEN_PAGE_SIZE); 177 + /* number of pages the page directory consumes itself */ 178 + num_pages_dir = DIV_ROUND_UP(num_pages_buffer, 179 + XENSND_NUM_GREFS_PER_PAGE); 180 + num_grefs = num_pages_buffer + num_pages_dir; 181 + 182 + ret = alloc_int_buffers(buf, num_pages_dir, 183 + num_pages_buffer, num_grefs); 184 + if (ret < 0) 185 + return ret; 186 + 187 + ret = grant_references(xb_dev, buf, num_pages_dir, num_pages_buffer, 188 + num_grefs); 189 + if (ret < 0) 190 + return ret; 191 + 192 + fill_page_dir(buf, num_pages_dir); 193 + return 0; 194 + }
+36
sound/xen/xen_snd_front_shbuf.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + 3 + /* 4 + * Xen para-virtual sound device 5 + * 6 + * Copyright (C) 2016-2018 EPAM Systems Inc. 7 + * 8 + * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 9 + */ 10 + 11 + #ifndef __XEN_SND_FRONT_SHBUF_H 12 + #define __XEN_SND_FRONT_SHBUF_H 13 + 14 + #include <xen/grant_table.h> 15 + 16 + #include "xen_snd_front_evtchnl.h" 17 + 18 + struct xen_snd_front_shbuf { 19 + int num_grefs; 20 + grant_ref_t *grefs; 21 + u8 *directory; 22 + u8 *buffer; 23 + size_t buffer_sz; 24 + }; 25 + 26 + grant_ref_t xen_snd_front_shbuf_get_dir_start(struct xen_snd_front_shbuf *buf); 27 + 28 + int xen_snd_front_shbuf_alloc(struct xenbus_device *xb_dev, 29 + struct xen_snd_front_shbuf *buf, 30 + unsigned int buffer_sz); 31 + 32 + void xen_snd_front_shbuf_clear(struct xen_snd_front_shbuf *buf); 33 + 34 + void xen_snd_front_shbuf_free(struct xen_snd_front_shbuf *buf); 35 + 36 + #endif /* __XEN_SND_FRONT_SHBUF_H */