1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2f0b5e634SDaniel Mack #ifndef __USBMIXER_H 3f0b5e634SDaniel Mack #define __USBMIXER_H 4f0b5e634SDaniel Mack 53360b84bSTakashi Iwai #include <sound/info.h> 63360b84bSTakashi Iwai 7f0b5e634SDaniel Mack struct usb_mixer_interface { 8f0b5e634SDaniel Mack struct snd_usb_audio *chip; 91faa5d07SDaniel Mack struct usb_host_interface *hostif; 10f0b5e634SDaniel Mack struct list_head list; 11f0b5e634SDaniel Mack unsigned int ignore_ctl_error; 12f0b5e634SDaniel Mack struct urb *urb; 13f0b5e634SDaniel Mack /* array[MAX_ID_ELEMS], indexed by unit id */ 143360b84bSTakashi Iwai struct usb_mixer_elem_list **id_elems; 15f0b5e634SDaniel Mack 1623caaf19SDaniel Mack /* the usb audio specification version this interface complies to */ 1723caaf19SDaniel Mack int protocol; 1823caaf19SDaniel Mack 19f0b5e634SDaniel Mack /* Sound Blaster remote control stuff */ 20f0b5e634SDaniel Mack const struct rc_config *rc_cfg; 21f0b5e634SDaniel Mack u32 rc_code; 22f0b5e634SDaniel Mack wait_queue_head_t rc_waitq; 23f0b5e634SDaniel Mack struct urb *rc_urb; 24f0b5e634SDaniel Mack struct usb_ctrlrequest *rc_setup_packet; 25f0b5e634SDaniel Mack u8 rc_buffer[6]; 26124751d5STakashi Iwai 27124751d5STakashi Iwai bool disconnected; 28f0b5e634SDaniel Mack }; 29f0b5e634SDaniel Mack 309e38658fSDaniel Mack #define MAX_CHANNELS 16 /* max logical channels */ 319e38658fSDaniel Mack 329e38658fSDaniel Mack enum { 339e38658fSDaniel Mack USB_MIXER_BOOLEAN, 349e38658fSDaniel Mack USB_MIXER_INV_BOOLEAN, 359e38658fSDaniel Mack USB_MIXER_S8, 369e38658fSDaniel Mack USB_MIXER_U8, 379e38658fSDaniel Mack USB_MIXER_S16, 389e38658fSDaniel Mack USB_MIXER_U16, 39bc18e31cSJulian Scheel USB_MIXER_S32, 40bc18e31cSJulian Scheel USB_MIXER_U32, 419e38658fSDaniel Mack }; 42f0b5e634SDaniel Mack 433360b84bSTakashi Iwai typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, 443360b84bSTakashi Iwai struct usb_mixer_elem_list *list); 453360b84bSTakashi Iwai typedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); 463360b84bSTakashi Iwai 473360b84bSTakashi Iwai struct usb_mixer_elem_list { 48f0b5e634SDaniel Mack struct usb_mixer_interface *mixer; 493360b84bSTakashi Iwai struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ 503360b84bSTakashi Iwai struct snd_kcontrol *kctl; 51f0b5e634SDaniel Mack unsigned int id; 523360b84bSTakashi Iwai usb_mixer_elem_dump_func_t dump; 533360b84bSTakashi Iwai usb_mixer_elem_resume_func_t resume; 543360b84bSTakashi Iwai }; 553360b84bSTakashi Iwai 568c558076STakashi Iwai /* iterate over mixer element list of the given unit id */ 578c558076STakashi Iwai #define for_each_mixer_elem(list, mixer, id) \ 588c558076STakashi Iwai for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) 598c558076STakashi Iwai #define mixer_elem_list_to_info(list) \ 608c558076STakashi Iwai container_of(list, struct usb_mixer_elem_info, head) 618c558076STakashi Iwai 623360b84bSTakashi Iwai struct usb_mixer_elem_info { 633360b84bSTakashi Iwai struct usb_mixer_elem_list head; 64f0b5e634SDaniel Mack unsigned int control; /* CS or ICN (high byte) */ 65f0b5e634SDaniel Mack unsigned int cmask; /* channel mask bitmap: 0 = master */ 669f814105SEldad Zack unsigned int idx_off; /* Control index offset */ 67a6a33259SDaniel Mack unsigned int ch_readonly; 68a6a33259SDaniel Mack unsigned int master_readonly; 69f0b5e634SDaniel Mack int channels; 70f0b5e634SDaniel Mack int val_type; 71f0b5e634SDaniel Mack int min, max, res; 72f0b5e634SDaniel Mack int dBmin, dBmax; 73f0b5e634SDaniel Mack int cached; 74f0b5e634SDaniel Mack int cache_val[MAX_CHANNELS]; 75f0b5e634SDaniel Mack u8 initialized; 760f174b35STakashi Iwai u8 min_mute; 77f41d6049SChris J Arges void *private_data; 78f0b5e634SDaniel Mack }; 79f0b5e634SDaniel Mack 80f0b5e634SDaniel Mack int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 81f0b5e634SDaniel Mack int ignore_error); 82a6cece9dSTakashi Iwai void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); 83f0b5e634SDaniel Mack 84f0b5e634SDaniel Mack void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); 85f0b5e634SDaniel Mack 86f0b5e634SDaniel Mack int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 87f0b5e634SDaniel Mack int request, int validx, int value_set); 88f0b5e634SDaniel Mack 893360b84bSTakashi Iwai int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list, 90ef9d5970SDaniel Mack struct snd_kcontrol *kctl); 91ef9d5970SDaniel Mack 923360b84bSTakashi Iwai void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, 933360b84bSTakashi Iwai struct usb_mixer_interface *mixer, 943360b84bSTakashi Iwai int unitid); 953360b84bSTakashi Iwai 96285de9c0SFelix Homann int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 97285de9c0SFelix Homann unsigned int size, unsigned int __user *_tlv); 98285de9c0SFelix Homann 99400362f1STakashi Iwai #ifdef CONFIG_PM 100400362f1STakashi Iwai int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); 101400362f1STakashi Iwai int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume); 102400362f1STakashi Iwai #endif 103400362f1STakashi Iwai 104eef90451SChris J Arges int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 105eef90451SChris J Arges int index, int value); 106eef90451SChris J Arges 107eef90451SChris J Arges int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, 108eef90451SChris J Arges int channel, int index, int *value); 109eef90451SChris J Arges 110eef90451SChris J Arges extern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl); 111eef90451SChris J Arges 112*00966dcdSTakashi Iwai extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 113*00966dcdSTakashi Iwai 114f0b5e634SDaniel Mack #endif /* __USBMIXER_H */ 115