162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __USBMIXER_H 362306a36Sopenharmony_ci#define __USBMIXER_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <sound/info.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_cistruct media_mixer_ctl; 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistruct usbmix_connector_map { 1062306a36Sopenharmony_ci u8 id; 1162306a36Sopenharmony_ci u8 delegated_id; 1262306a36Sopenharmony_ci u8 control; 1362306a36Sopenharmony_ci u8 channel; 1462306a36Sopenharmony_ci}; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistruct usb_mixer_interface { 1762306a36Sopenharmony_ci struct snd_usb_audio *chip; 1862306a36Sopenharmony_ci struct usb_host_interface *hostif; 1962306a36Sopenharmony_ci struct list_head list; 2062306a36Sopenharmony_ci unsigned int ignore_ctl_error; 2162306a36Sopenharmony_ci struct urb *urb; 2262306a36Sopenharmony_ci /* array[MAX_ID_ELEMS], indexed by unit id */ 2362306a36Sopenharmony_ci struct usb_mixer_elem_list **id_elems; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci /* the usb audio specification version this interface complies to */ 2662306a36Sopenharmony_ci int protocol; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci /* optional connector delegation map */ 2962306a36Sopenharmony_ci const struct usbmix_connector_map *connector_map; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci /* Sound Blaster remote control stuff */ 3262306a36Sopenharmony_ci const struct rc_config *rc_cfg; 3362306a36Sopenharmony_ci u32 rc_code; 3462306a36Sopenharmony_ci wait_queue_head_t rc_waitq; 3562306a36Sopenharmony_ci struct urb *rc_urb; 3662306a36Sopenharmony_ci struct usb_ctrlrequest *rc_setup_packet; 3762306a36Sopenharmony_ci u8 rc_buffer[6]; 3862306a36Sopenharmony_ci struct media_mixer_ctl *media_mixer_ctl; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci bool disconnected; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci void *private_data; 4362306a36Sopenharmony_ci void (*private_free)(struct usb_mixer_interface *mixer); 4462306a36Sopenharmony_ci void (*private_suspend)(struct usb_mixer_interface *mixer); 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define MAX_CHANNELS 16 /* max logical channels */ 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cienum { 5062306a36Sopenharmony_ci USB_MIXER_BOOLEAN, 5162306a36Sopenharmony_ci USB_MIXER_INV_BOOLEAN, 5262306a36Sopenharmony_ci USB_MIXER_S8, 5362306a36Sopenharmony_ci USB_MIXER_U8, 5462306a36Sopenharmony_ci USB_MIXER_S16, 5562306a36Sopenharmony_ci USB_MIXER_U16, 5662306a36Sopenharmony_ci USB_MIXER_S32, 5762306a36Sopenharmony_ci USB_MIXER_U32, 5862306a36Sopenharmony_ci USB_MIXER_BESPOKEN, /* non-standard type */ 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_citypedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, 6262306a36Sopenharmony_ci struct usb_mixer_elem_list *list); 6362306a36Sopenharmony_citypedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistruct usb_mixer_elem_list { 6662306a36Sopenharmony_ci struct usb_mixer_interface *mixer; 6762306a36Sopenharmony_ci struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ 6862306a36Sopenharmony_ci struct snd_kcontrol *kctl; 6962306a36Sopenharmony_ci unsigned int id; 7062306a36Sopenharmony_ci bool is_std_info; 7162306a36Sopenharmony_ci usb_mixer_elem_dump_func_t dump; 7262306a36Sopenharmony_ci usb_mixer_elem_resume_func_t resume; 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* iterate over mixer element list of the given unit id */ 7662306a36Sopenharmony_ci#define for_each_mixer_elem(list, mixer, id) \ 7762306a36Sopenharmony_ci for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) 7862306a36Sopenharmony_ci#define mixer_elem_list_to_info(list) \ 7962306a36Sopenharmony_ci container_of(list, struct usb_mixer_elem_info, head) 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistruct usb_mixer_elem_info { 8262306a36Sopenharmony_ci struct usb_mixer_elem_list head; 8362306a36Sopenharmony_ci unsigned int control; /* CS or ICN (high byte) */ 8462306a36Sopenharmony_ci unsigned int cmask; /* channel mask bitmap: 0 = master */ 8562306a36Sopenharmony_ci unsigned int idx_off; /* Control index offset */ 8662306a36Sopenharmony_ci unsigned int ch_readonly; 8762306a36Sopenharmony_ci unsigned int master_readonly; 8862306a36Sopenharmony_ci int channels; 8962306a36Sopenharmony_ci int val_type; 9062306a36Sopenharmony_ci int min, max, res; 9162306a36Sopenharmony_ci int dBmin, dBmax; 9262306a36Sopenharmony_ci int cached; 9362306a36Sopenharmony_ci int cache_val[MAX_CHANNELS]; 9462306a36Sopenharmony_ci u8 initialized; 9562306a36Sopenharmony_ci u8 min_mute; 9662306a36Sopenharmony_ci void *private_data; 9762306a36Sopenharmony_ci}; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ciint snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif); 10062306a36Sopenharmony_civoid snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_civoid snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciint snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 10562306a36Sopenharmony_ci int request, int validx, int value_set); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ciint snd_usb_mixer_add_list(struct usb_mixer_elem_list *list, 10862306a36Sopenharmony_ci struct snd_kcontrol *kctl, 10962306a36Sopenharmony_ci bool is_std_info); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define snd_usb_mixer_add_control(list, kctl) \ 11262306a36Sopenharmony_ci snd_usb_mixer_add_list(list, kctl, true) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_civoid snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, 11562306a36Sopenharmony_ci struct usb_mixer_interface *mixer, 11662306a36Sopenharmony_ci int unitid); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 11962306a36Sopenharmony_ci unsigned int size, unsigned int __user *_tlv); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciint snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); 12262306a36Sopenharmony_ciint snd_usb_mixer_resume(struct usb_mixer_interface *mixer); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ciint snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 12562306a36Sopenharmony_ci int index, int value); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ciint snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, 12862306a36Sopenharmony_ci int channel, int index, int *value); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ciextern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ciextern const struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#endif /* __USBMIXER_H */ 135