18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __USBMIXER_H 38c2ecf20Sopenharmony_ci#define __USBMIXER_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <sound/info.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_cistruct media_mixer_ctl; 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct usbmix_connector_map { 108c2ecf20Sopenharmony_ci u8 id; 118c2ecf20Sopenharmony_ci u8 delegated_id; 128c2ecf20Sopenharmony_ci u8 control; 138c2ecf20Sopenharmony_ci u8 channel; 148c2ecf20Sopenharmony_ci}; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistruct usb_mixer_interface { 178c2ecf20Sopenharmony_ci struct snd_usb_audio *chip; 188c2ecf20Sopenharmony_ci struct usb_host_interface *hostif; 198c2ecf20Sopenharmony_ci struct list_head list; 208c2ecf20Sopenharmony_ci unsigned int ignore_ctl_error; 218c2ecf20Sopenharmony_ci struct urb *urb; 228c2ecf20Sopenharmony_ci /* array[MAX_ID_ELEMS], indexed by unit id */ 238c2ecf20Sopenharmony_ci struct usb_mixer_elem_list **id_elems; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci /* the usb audio specification version this interface complies to */ 268c2ecf20Sopenharmony_ci int protocol; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci /* optional connector delegation map */ 298c2ecf20Sopenharmony_ci const struct usbmix_connector_map *connector_map; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci /* Sound Blaster remote control stuff */ 328c2ecf20Sopenharmony_ci const struct rc_config *rc_cfg; 338c2ecf20Sopenharmony_ci u32 rc_code; 348c2ecf20Sopenharmony_ci wait_queue_head_t rc_waitq; 358c2ecf20Sopenharmony_ci struct urb *rc_urb; 368c2ecf20Sopenharmony_ci struct usb_ctrlrequest *rc_setup_packet; 378c2ecf20Sopenharmony_ci u8 rc_buffer[6]; 388c2ecf20Sopenharmony_ci struct media_mixer_ctl *media_mixer_ctl; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci bool disconnected; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci void *private_data; 438c2ecf20Sopenharmony_ci void (*private_free)(struct usb_mixer_interface *mixer); 448c2ecf20Sopenharmony_ci void (*private_suspend)(struct usb_mixer_interface *mixer); 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define MAX_CHANNELS 16 /* max logical channels */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cienum { 508c2ecf20Sopenharmony_ci USB_MIXER_BOOLEAN, 518c2ecf20Sopenharmony_ci USB_MIXER_INV_BOOLEAN, 528c2ecf20Sopenharmony_ci USB_MIXER_S8, 538c2ecf20Sopenharmony_ci USB_MIXER_U8, 548c2ecf20Sopenharmony_ci USB_MIXER_S16, 558c2ecf20Sopenharmony_ci USB_MIXER_U16, 568c2ecf20Sopenharmony_ci USB_MIXER_S32, 578c2ecf20Sopenharmony_ci USB_MIXER_U32, 588c2ecf20Sopenharmony_ci USB_MIXER_BESPOKEN, /* non-standard type */ 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_citypedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, 628c2ecf20Sopenharmony_ci struct usb_mixer_elem_list *list); 638c2ecf20Sopenharmony_citypedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistruct usb_mixer_elem_list { 668c2ecf20Sopenharmony_ci struct usb_mixer_interface *mixer; 678c2ecf20Sopenharmony_ci struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ 688c2ecf20Sopenharmony_ci struct snd_kcontrol *kctl; 698c2ecf20Sopenharmony_ci unsigned int id; 708c2ecf20Sopenharmony_ci bool is_std_info; 718c2ecf20Sopenharmony_ci usb_mixer_elem_dump_func_t dump; 728c2ecf20Sopenharmony_ci usb_mixer_elem_resume_func_t resume; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci/* iterate over mixer element list of the given unit id */ 768c2ecf20Sopenharmony_ci#define for_each_mixer_elem(list, mixer, id) \ 778c2ecf20Sopenharmony_ci for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) 788c2ecf20Sopenharmony_ci#define mixer_elem_list_to_info(list) \ 798c2ecf20Sopenharmony_ci container_of(list, struct usb_mixer_elem_info, head) 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistruct usb_mixer_elem_info { 828c2ecf20Sopenharmony_ci struct usb_mixer_elem_list head; 838c2ecf20Sopenharmony_ci unsigned int control; /* CS or ICN (high byte) */ 848c2ecf20Sopenharmony_ci unsigned int cmask; /* channel mask bitmap: 0 = master */ 858c2ecf20Sopenharmony_ci unsigned int idx_off; /* Control index offset */ 868c2ecf20Sopenharmony_ci unsigned int ch_readonly; 878c2ecf20Sopenharmony_ci unsigned int master_readonly; 888c2ecf20Sopenharmony_ci int channels; 898c2ecf20Sopenharmony_ci int val_type; 908c2ecf20Sopenharmony_ci int min, max, res; 918c2ecf20Sopenharmony_ci int dBmin, dBmax; 928c2ecf20Sopenharmony_ci int cached; 938c2ecf20Sopenharmony_ci int cache_val[MAX_CHANNELS]; 948c2ecf20Sopenharmony_ci u8 initialized; 958c2ecf20Sopenharmony_ci u8 min_mute; 968c2ecf20Sopenharmony_ci void *private_data; 978c2ecf20Sopenharmony_ci}; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ciint snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 1008c2ecf20Sopenharmony_ci int ignore_error); 1018c2ecf20Sopenharmony_civoid snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_civoid snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ciint snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, 1068c2ecf20Sopenharmony_ci int request, int validx, int value_set); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ciint snd_usb_mixer_add_list(struct usb_mixer_elem_list *list, 1098c2ecf20Sopenharmony_ci struct snd_kcontrol *kctl, 1108c2ecf20Sopenharmony_ci bool is_std_info); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define snd_usb_mixer_add_control(list, kctl) \ 1138c2ecf20Sopenharmony_ci snd_usb_mixer_add_list(list, kctl, true) 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_civoid snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, 1168c2ecf20Sopenharmony_ci struct usb_mixer_interface *mixer, 1178c2ecf20Sopenharmony_ci int unitid); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ciint snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1208c2ecf20Sopenharmony_ci unsigned int size, unsigned int __user *_tlv); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 1238c2ecf20Sopenharmony_ciint snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); 1248c2ecf20Sopenharmony_ciint snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume); 1258c2ecf20Sopenharmony_ci#endif 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ciint snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 1288c2ecf20Sopenharmony_ci int index, int value); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ciint snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, 1318c2ecf20Sopenharmony_ci int channel, int index, int *value); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ciextern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ciextern const struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci#endif /* __USBMIXER_H */ 138