1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __USBMIXER_H |
3 | #define __USBMIXER_H |
4 | |
5 | #include <sound/info.h> |
6 | |
7 | struct media_mixer_ctl; |
8 | |
9 | struct usbmix_connector_map { |
10 | u8 id; |
11 | u8 delegated_id; |
12 | u8 control; |
13 | u8 channel; |
14 | }; |
15 | |
16 | struct usb_mixer_interface { |
17 | struct snd_usb_audio *chip; |
18 | struct usb_host_interface *hostif; |
19 | struct list_head list; |
20 | unsigned int ignore_ctl_error; |
21 | struct urb *urb; |
22 | /* array[MAX_ID_ELEMS], indexed by unit id */ |
23 | struct usb_mixer_elem_list **id_elems; |
24 | |
25 | /* the usb audio specification version this interface complies to */ |
26 | int protocol; |
27 | |
28 | /* optional connector delegation map */ |
29 | const struct usbmix_connector_map *connector_map; |
30 | |
31 | /* Sound Blaster remote control stuff */ |
32 | const struct rc_config *rc_cfg; |
33 | u32 rc_code; |
34 | wait_queue_head_t rc_waitq; |
35 | struct urb *rc_urb; |
36 | struct usb_ctrlrequest *rc_setup_packet; |
37 | u8 rc_buffer[6]; |
38 | struct media_mixer_ctl *media_mixer_ctl; |
39 | |
40 | bool disconnected; |
41 | |
42 | void *private_data; |
43 | void (*private_free)(struct usb_mixer_interface *mixer); |
44 | void (*private_suspend)(struct usb_mixer_interface *mixer); |
45 | }; |
46 | |
47 | #define MAX_CHANNELS 16 /* max logical channels */ |
48 | |
49 | enum { |
50 | USB_MIXER_BOOLEAN, |
51 | USB_MIXER_INV_BOOLEAN, |
52 | USB_MIXER_S8, |
53 | USB_MIXER_U8, |
54 | USB_MIXER_S16, |
55 | USB_MIXER_U16, |
56 | USB_MIXER_S32, |
57 | USB_MIXER_U32, |
58 | USB_MIXER_BESPOKEN, /* non-standard type */ |
59 | }; |
60 | |
61 | typedef void (*usb_mixer_elem_dump_func_t)(struct snd_info_buffer *buffer, |
62 | struct usb_mixer_elem_list *list); |
63 | typedef int (*usb_mixer_elem_resume_func_t)(struct usb_mixer_elem_list *elem); |
64 | |
65 | struct usb_mixer_elem_list { |
66 | struct usb_mixer_interface *mixer; |
67 | struct usb_mixer_elem_list *next_id_elem; /* list of controls with same id */ |
68 | struct snd_kcontrol *kctl; |
69 | unsigned int id; |
70 | bool is_std_info; |
71 | usb_mixer_elem_dump_func_t dump; |
72 | usb_mixer_elem_resume_func_t resume; |
73 | }; |
74 | |
75 | /* iterate over mixer element list of the given unit id */ |
76 | #define for_each_mixer_elem(list, mixer, id) \ |
77 | for ((list) = (mixer)->id_elems[id]; (list); (list) = (list)->next_id_elem) |
78 | #define mixer_elem_list_to_info(list) \ |
79 | container_of(list, struct usb_mixer_elem_info, head) |
80 | |
81 | struct usb_mixer_elem_info { |
82 | struct usb_mixer_elem_list head; |
83 | unsigned int control; /* CS or ICN (high byte) */ |
84 | unsigned int cmask; /* channel mask bitmap: 0 = master */ |
85 | unsigned int idx_off; /* Control index offset */ |
86 | unsigned int ch_readonly; |
87 | unsigned int master_readonly; |
88 | int channels; |
89 | int val_type; |
90 | int min, max, res; |
91 | int dBmin, dBmax; |
92 | int cached; |
93 | int cache_val[MAX_CHANNELS]; |
94 | u8 initialized; |
95 | u8 min_mute; |
96 | void *private_data; |
97 | }; |
98 | |
99 | int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif); |
100 | void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer); |
101 | |
102 | void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid); |
103 | |
104 | int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, |
105 | int request, int validx, int value_set); |
106 | |
107 | int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list, |
108 | struct snd_kcontrol *kctl, |
109 | bool is_std_info); |
110 | |
111 | #define snd_usb_mixer_add_control(list, kctl) \ |
112 | snd_usb_mixer_add_list(list, kctl, true) |
113 | |
114 | void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list, |
115 | struct usb_mixer_interface *mixer, |
116 | int unitid); |
117 | |
118 | int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, |
119 | unsigned int size, unsigned int __user *_tlv); |
120 | |
121 | int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer); |
122 | int snd_usb_mixer_resume(struct usb_mixer_interface *mixer); |
123 | |
124 | int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, |
125 | int index, int value); |
126 | |
127 | int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval, |
128 | int channel, int index, int *value); |
129 | |
130 | extern void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl); |
131 | |
132 | extern const struct snd_kcontrol_new *snd_usb_feature_unit_ctl; |
133 | |
134 | #endif /* __USBMIXER_H */ |
135 | |