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 766354f18SShuah Khan struct media_mixer_ctl; 866354f18SShuah Khan 9fef66ae7STakashi Iwai struct usbmix_connector_map { 10fef66ae7STakashi Iwai u8 id; 11fef66ae7STakashi Iwai u8 delegated_id; 12fef66ae7STakashi Iwai u8 control; 13fef66ae7STakashi Iwai u8 channel; 14fef66ae7STakashi Iwai }; 15fef66ae7STakashi Iwai 16f0b5e634SDaniel Mack struct usb_mixer_interface { 17f0b5e634SDaniel Mack struct snd_usb_audio *chip; 181faa5d07SDaniel Mack struct usb_host_interface *hostif; 19f0b5e634SDaniel Mack struct list_head list; 20f0b5e634SDaniel Mack unsigned int ignore_ctl_error; 21f0b5e634SDaniel Mack struct urb *urb; 22f0b5e634SDaniel Mack /* array[MAX_ID_ELEMS], indexed by unit id */ 233360b84bSTakashi Iwai struct usb_mixer_elem_list **id_elems; 24f0b5e634SDaniel Mack 2523caaf19SDaniel Mack /* the usb audio specification version this interface complies to */ 2623caaf19SDaniel Mack int protocol; 2723caaf19SDaniel Mack 28fef66ae7STakashi Iwai /* optional connector delegation map */ 29fef66ae7STakashi Iwai const struct usbmix_connector_map *connector_map; 30fef66ae7STakashi Iwai 31f0b5e634SDaniel Mack /* Sound Blaster remote control stuff */ 32f0b5e634SDaniel Mack const struct rc_config *rc_cfg; 33f0b5e634SDaniel Mack u32 rc_code; 34f0b5e634SDaniel Mack wait_queue_head_t rc_waitq; 35f0b5e634SDaniel Mack struct urb *rc_urb; 36f0b5e634SDaniel Mack struct usb_ctrlrequest *rc_setup_packet; 37f0b5e634SDaniel Mack u8 rc_buffer[6]; 3866354f18SShuah Khan struct media_mixer_ctl *media_mixer_ctl; 39124751d5STakashi Iwai 40124751d5STakashi Iwai bool disconnected; 419e4d5c1bSGeoffrey D. Bennett 429e4d5c1bSGeoffrey D. Bennett void *private_data; 439e4d5c1bSGeoffrey D. Bennett void (*private_free)(struct usb_mixer_interface *mixer); 449e4d5c1bSGeoffrey D. Bennett void (*private_suspend)(struct usb_mixer_interface *mixer); 45f0b5e634SDaniel Mack }; 46f0b5e634SDaniel Mack 479e38658fSDaniel Mack #define MAX_CHANNELS 16 /* max logical channels */ 489e38658fSDaniel Mack 499e38658fSDaniel Mack enum { 509e38658fSDaniel Mack USB_MIXER_BOOLEAN, 519e38658fSDaniel Mack USB_MIXER_INV_BOOLEAN, 529e38658fSDaniel Mack USB_MIXER_S8, 539e38658fSDaniel Mack USB_MIXER_U8, 549e38658fSDaniel Mack USB_MIXER_S16, 559e38658fSDaniel Mack USB_MIXER_U16, 56bc18e31cSJulian Scheel USB_MIXER_S32, 57bc18e31cSJulian Scheel USB_MIXER_U32, 58785b6f29STakashi Iwai USB_MIXER_BESPOKEN, /* non-standard type */ 599e38658fSDaniel Mack }; 60f0b5e634SDaniel Mack 613360b84bSTakashi Iwai typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, 623360b84bSTakashi Iwai struct usb_mixer_elem_list *list); 633360b84bSTakashi Iwai typedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); 643360b84bSTakashi Iwai 653360b84bSTakashi Iwai struct usb_mixer_elem_list { 66f0b5e634SDaniel Mack struct usb_mixer_interface *mixer; 673360b84bSTakashi Iwai struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ 683360b84bSTakashi Iwai struct snd_kcontrol *kctl; 69f0b5e634SDaniel Mack unsigned int id; 70220345e9STakashi Iwai bool is_std_info; 713360b84bSTakashi Iwai usb_mixer_elem_dump_func_t dump; 723360b84bSTakashi Iwai usb_mixer_elem_resume_func_t resume; 733360b84bSTakashi Iwai }; 743360b84bSTakashi Iwai 758c558076STakashi Iwai /* iterate over mixer element list of the given unit id */ 768c558076STakashi Iwai #define for_each_mixer_elem(list, mixer, id) \ 778c558076STakashi Iwai for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) 788c558076STakashi Iwai #define mixer_elem_list_to_info(list) \ 798c558076STakashi Iwai container_of(list, struct usb_mixer_elem_info, head) 808c558076STakashi Iwai 813360b84bSTakashi Iwai struct usb_mixer_elem_info { 823360b84bSTakashi Iwai struct usb_mixer_elem_list head; 83f0b5e634SDaniel Mack unsigned int control; /* CS or ICN (high byte) */ 84f0b5e634SDaniel Mack unsigned int cmask; /* channel mask bitmap: 0 = master */ 859f814105SEldad Zack unsigned int idx_off; /* Control index offset */ 86a6a33259SDaniel Mack unsigned int ch_readonly; 87a6a33259SDaniel Mack unsigned int master_readonly; 88f0b5e634SDaniel Mack int channels; 89f0b5e634SDaniel Mack int val_type; 90f0b5e634SDaniel Mack int min, max, res; 91*901e8567STakashi Iwai int max_exposed; /* control API exposes the value in 0..max_exposed */ 92f0b5e634SDaniel Mack int dBmin, dBmax; 93f0b5e634SDaniel Mack int cached; 94f0b5e634SDaniel Mack int cache_val[MAX_CHANNELS]; 95f0b5e634SDaniel Mack u8 initialized; 960f174b35STakashi Iwai u8 min_mute; 97f41d6049SChris J Arges void *private_data; 98f0b5e634SDaniel Mack }; 99f0b5e634SDaniel Mack 1003c69dc91STakashi Iwai int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif); 101a6cece9dSTakashi Iwai void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); 102f0b5e634SDaniel Mack 103f0b5e634SDaniel Mack void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); 104f0b5e634SDaniel Mack 105f0b5e634SDaniel Mack int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 106f0b5e634SDaniel Mack int request, int validx, int value_set); 107f0b5e634SDaniel Mack 108220345e9STakashi Iwai int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list, 109220345e9STakashi Iwai struct snd_kcontrol *kctl, 110220345e9STakashi Iwai bool is_std_info); 111220345e9STakashi Iwai 112220345e9STakashi Iwai #define snd_usb_mixer_add_control(list, kctl) \ 113220345e9STakashi Iwai snd_usb_mixer_add_list(list, kctl, true) 114ef9d5970SDaniel Mack 1153360b84bSTakashi Iwai void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, 1163360b84bSTakashi Iwai struct usb_mixer_interface *mixer, 1173360b84bSTakashi Iwai int unitid); 1183360b84bSTakashi Iwai 119285de9c0SFelix Homann int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 120285de9c0SFelix Homann unsigned int size, unsigned int __user *_tlv); 121285de9c0SFelix Homann 122400362f1STakashi Iwai int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); 1237b9cf903STakashi Iwai int snd_usb_mixer_resume(struct usb_mixer_interface *mixer); 124400362f1STakashi Iwai 125eef90451SChris J Arges int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 126eef90451SChris J Arges int index, int value); 127eef90451SChris J Arges 128eef90451SChris J Arges int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, 129eef90451SChris J Arges int channel, int index, int *value); 130eef90451SChris J Arges 131eef90451SChris J Arges extern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl); 132eef90451SChris J Arges 133195727e8STakashi Iwai extern const struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 13400966dcdSTakashi Iwai 135f0b5e634SDaniel Mack #endif /* __USBMIXER_H */ 136