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 req_number; /* number of preallocated requests */ |
57 | int fb_max; /* upper frequency drift feedback limit per-mil */ |
58 | }; |
59 | |
60 | struct g_audio { |
61 | struct usb_function func; |
62 | struct usb_gadget *gadget; |
63 | |
64 | struct usb_ep *in_ep; |
65 | |
66 | struct usb_ep *out_ep; |
67 | /* feedback IN endpoint corresponding to out_ep */ |
68 | struct usb_ep *in_ep_fback; |
69 | |
70 | /* Max packet size for all in_ep possible speeds */ |
71 | unsigned int in_ep_maxpsize; |
72 | /* Max packet size for all out_ep possible speeds */ |
73 | unsigned int out_ep_maxpsize; |
74 | |
75 | /* Notify UAC driver about control change */ |
76 | int (*notify)(struct g_audio *g_audio, int unit_id, int cs); |
77 | |
78 | /* The ALSA Sound Card it represents on the USB-Client side */ |
79 | struct snd_uac_chip *uac; |
80 | |
81 | struct uac_params params; |
82 | }; |
83 | |
84 | static inline struct g_audio *func_to_g_audio(struct usb_function *f) |
85 | { |
86 | return container_of(f, struct g_audio, func); |
87 | } |
88 | |
89 | static inline uint num_channels(uint chanmask) |
90 | { |
91 | uint num = 0; |
92 | |
93 | while (chanmask) { |
94 | num += (chanmask & 1); |
95 | chanmask >>= 1; |
96 | } |
97 | |
98 | return num; |
99 | } |
100 | |
101 | /* |
102 | * g_audio_setup - initialize one virtual ALSA sound card |
103 | * @g_audio: struct with filled params, in_ep_maxpsize, out_ep_maxpsize |
104 | * @pcm_name: the id string for a PCM instance of this sound card |
105 | * @card_name: name of this soundcard |
106 | * |
107 | * This sets up the single virtual ALSA sound card that may be exported by a |
108 | * gadget driver using this framework. |
109 | * |
110 | * Context: may sleep |
111 | * |
112 | * Returns zero on success, or a negative error on failure. |
113 | */ |
114 | int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, |
115 | const char *card_name); |
116 | void g_audio_cleanup(struct g_audio *g_audio); |
117 | |
118 | int u_audio_start_capture(struct g_audio *g_audio); |
119 | void u_audio_stop_capture(struct g_audio *g_audio); |
120 | int u_audio_start_playback(struct g_audio *g_audio); |
121 | void u_audio_stop_playback(struct g_audio *g_audio); |
122 | |
123 | int u_audio_get_capture_srate(struct g_audio *audio_dev, u32 *val); |
124 | int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate); |
125 | int u_audio_get_playback_srate(struct g_audio *audio_dev, u32 *val); |
126 | int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate); |
127 | |
128 | int u_audio_get_volume(struct g_audio *g_audio, int playback, s16 *val); |
129 | int u_audio_set_volume(struct g_audio *g_audio, int playback, s16 val); |
130 | int u_audio_get_mute(struct g_audio *g_audio, int playback, int *val); |
131 | int u_audio_set_mute(struct g_audio *g_audio, int playback, int val); |
132 | |
133 | void u_audio_suspend(struct g_audio *g_audio); |
134 | |
135 | #endif /* __U_AUDIO_H */ |
136 | |