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