1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3 * u_audio.h -- interface to USB gadget "ALSA sound card" utilities
4 *
5 * Copyright (C) 2016
6 * Author: Ruslan Bilovol <ruslan.bilovol@gmail.com>
7 */
8
9 #ifndef __U_AUDIO_H
10 #define __U_AUDIO_H
11
12 #include <linux/usb/composite.h>
13 #include "uac_common.h"
14
15 /*
16 * Same maximum frequency deviation on the slower side as in
17 * sound/usb/endpoint.c. Value is expressed in per-mil deviation.
18 */
19 #define FBACK_SLOW_MAX 250
20
21 /*
22 * Maximum frequency deviation on the faster side, default value for UAC1/2.
23 * Value is expressed in per-mil deviation.
24 * UAC2 provides the value as a parameter as it impacts the endpoint required
25 * bandwidth.
26 */
27 #define FBACK_FAST_MAX 5
28
29 /* Feature Unit parameters */
30 struct uac_fu_params {
31 int id; /* Feature Unit ID */
32
33 bool mute_present; /* mute control enable */
34
35 bool volume_present; /* volume control enable */
36 s16 volume_min; /* min volume in 1/256 dB */
37 s16 volume_max; /* max volume in 1/256 dB */
38 s16 volume_res; /* volume resolution in 1/256 dB */
39 };
40
41 struct uac_params {
42 /* playback */
43 int p_chmask; /* channel mask */
44 int p_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */
45 int p_ssize; /* sample size */
46 struct uac_fu_params p_fu; /* Feature Unit parameters */
47
48 /* capture */
49 int c_chmask; /* channel mask */
50 int c_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */
51 int c_ssize; /* sample size */
52 struct uac_fu_params c_fu; /* Feature Unit parameters */
53
54 /* rates are dynamic, in uac_rtd_params */
55
56 int ppm; /* difference between audio clk and usb clk */
57
58 int req_number; /* number of preallocated requests */
59 int fb_max; /* upper frequency drift feedback limit per-mil */
60 };
61
62 enum usb_state_index {
63 SET_INTERFACE_OUT,
64 SET_INTERFACE_IN,
65 SET_SAMPLE_RATE_OUT,
66 SET_SAMPLE_RATE_IN,
67 SET_VOLUME_OUT,
68 SET_VOLUME_IN,
69 SET_MUTE_OUT,
70 SET_MUTE_IN,
71 SET_AUDIO_CLK,
72 SET_USB_STATE_MAX,
73 };
74
75 enum stream_state_index {
76 STATE_OUT,
77 STATE_IN,
78 };
79
80 struct frame_number_data {
81 uint32_t fn_begin; /* frame number when starting statistics */
82 uint32_t fn_last; /* frame number in the latest statistics */
83 uint32_t fn_overflow; /* the time of frame number overflow */
84 uint32_t second; /* total seconds counted */
85 ktime_t time_begin; /* system time when starting statistics */
86 ktime_t time_last; /* system time in the latest statistics */
87 };
88
89 struct g_audio {
90 struct device *device;
91 bool usb_state[SET_USB_STATE_MAX];
92 bool stream_state[2];
93 struct work_struct work;
94
95 struct frame_number_data *fn;
96 struct delayed_work ppm_work;
97
98 struct usb_function func;
99 struct usb_gadget *gadget;
100
101 struct usb_ep *in_ep;
102
103 struct usb_ep *out_ep;
104 /* feedback IN endpoint corresponding to out_ep */
105 struct usb_ep *in_ep_fback;
106
107 /* Max packet size for all in_ep possible speeds */
108 unsigned int in_ep_maxpsize;
109 /* Max packet size for all out_ep possible speeds */
110 unsigned int out_ep_maxpsize;
111
112 /* Notify UAC driver about control change */
113 int (*notify)(struct g_audio *g_audio, int unit_id, int cs);
114
115 /* The ALSA Sound Card it represents on the USB-Client side */
116 struct snd_uac_chip *uac;
117
118 struct uac_params params;
119 };
120
func_to_g_audio(struct usb_function * f)121 static inline struct g_audio *func_to_g_audio(struct usb_function *f)
122 {
123 return container_of(f, struct g_audio, func);
124 }
125
num_channels(uint chanmask)126 static inline uint num_channels(uint chanmask)
127 {
128 uint num = 0;
129
130 while (chanmask) {
131 num += (chanmask & 1);
132 chanmask >>= 1;
133 }
134
135 return num;
136 }
137
138 /*
139 * g_audio_setup - initialize one virtual ALSA sound card
140 * @g_audio: struct with filled params, in_ep_maxpsize, out_ep_maxpsize
141 * @pcm_name: the id string for a PCM instance of this sound card
142 * @card_name: name of this soundcard
143 *
144 * This sets up the single virtual ALSA sound card that may be exported by a
145 * gadget driver using this framework.
146 *
147 * Context: may sleep
148 *
149 * Returns zero on success, or a negative error on failure.
150 */
151 int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
152 const char *card_name);
153 void g_audio_cleanup(struct g_audio *g_audio);
154
155 int u_audio_start_capture(struct g_audio *g_audio);
156 void u_audio_stop_capture(struct g_audio *g_audio);
157 int u_audio_start_playback(struct g_audio *g_audio);
158 void u_audio_stop_playback(struct g_audio *g_audio);
159
160 int u_audio_get_capture_srate(struct g_audio *audio_dev, u32 *val);
161 int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate);
162 int u_audio_get_playback_srate(struct g_audio *audio_dev, u32 *val);
163 int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate);
164
165 int u_audio_get_volume(struct g_audio *g_audio, int playback, s16 *val);
166 int u_audio_set_volume(struct g_audio *g_audio, int playback, s16 val);
167 int u_audio_get_mute(struct g_audio *g_audio, int playback, int *val);
168 int u_audio_set_mute(struct g_audio *g_audio, int playback, int val);
169
170 void u_audio_suspend(struct g_audio *g_audio);
171
172 #endif /* __U_AUDIO_H */
173