xref: /OK3568_Linux_fs/kernel/drivers/usb/gadget/function/u_uac.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * u_uac.h - Utility definitions for UAC function
3  *
4  * Copyright (C) 2016 Ruslan Bilovol <ruslan.bilovol@gmail.com>
5  * Copyright (C) 2017 Julian Scheel <julian@juss.de>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 #ifndef __U_UAC_H
13 #define __U_UAC_H
14 
15 #include <linux/usb/composite.h>
16 #include "u_audio.h"
17 
18 #define UAC_DEF_CCHMASK		0x3
19 #define UAC_DEF_CSRATE		48000
20 #define UAC_DEF_CSSIZE		2
21 #define UAC_DEF_CFU		0
22 #define UAC_DEF_PCHMASK		0x3
23 #define UAC_DEF_PSRATE		48000
24 #define UAC_DEF_PSSIZE		2
25 #define UAC_DEF_PFU		0
26 #define UAC_DEF_REQ_NUM		2
27 
28 #define UAC1_OUT_EP_MAX_PACKET_SIZE 200
29 
30 #define EPIN_EN(_opts) ((_opts)->p_chmask != 0)
31 #define EPOUT_EN(_opts) ((_opts)->c_chmask != 0)
32 #define EPIN_FU(_opts) ((_opts)->p_feature_unit != 0)
33 #define EPOUT_FU(_opts) ((_opts)->c_feature_unit != 0)
34 
35 struct f_uac_opts {
36 	struct usb_function_instance	func_inst;
37 	int				c_chmask;
38 	int				c_srate[UAC_MAX_RATES];
39 	int				c_srate_active;
40 	int				c_ssize;
41 	int				c_feature_unit;
42 	int				p_chmask;
43 	int				p_srate[UAC_MAX_RATES];
44 	int				p_srate_active;
45 	int				p_ssize;
46 	int				p_feature_unit;
47 	int				req_number;
48 	unsigned			bound:1;
49 
50 	struct mutex			lock;
51 	int				refcnt;
52 };
53 
54 #define UAC_ATTRIBUTE(name)						\
55 static ssize_t f_uac_opts_##name##_show(				\
56 					  struct config_item *item,	\
57 					  char *page)			\
58 {									\
59 	struct f_uac_opts *opts = to_f_uac_opts(item);		\
60 	int result;							\
61 									\
62 	mutex_lock(&opts->lock);					\
63 	result = sprintf(page, "%u\n", opts->name);			\
64 	mutex_unlock(&opts->lock);					\
65 									\
66 	return result;							\
67 }									\
68 									\
69 static ssize_t f_uac_opts_##name##_store(				\
70 					  struct config_item *item,	\
71 					  const char *page, size_t len)	\
72 {									\
73 	struct f_uac_opts *opts = to_f_uac_opts(item);		\
74 	int ret;							\
75 	u32 num;							\
76 									\
77 	mutex_lock(&opts->lock);					\
78 	if (opts->refcnt) {						\
79 		ret = -EBUSY;						\
80 		goto end;						\
81 	}								\
82 									\
83 	ret = kstrtou32(page, 0, &num);					\
84 	if (ret)							\
85 		goto end;						\
86 									\
87 	opts->name = num;						\
88 	ret = len;							\
89 									\
90 end:									\
91 	mutex_unlock(&opts->lock);					\
92 	return ret;							\
93 }									\
94 									\
95 CONFIGFS_ATTR(f_uac_opts_, name)
96 
97 #define UAC_RATE_ATTRIBUTE(name)					\
98 static ssize_t f_uac_opts_##name##_show(struct config_item *item,	\
99 					 char *page)			\
100 {									\
101 	struct f_uac_opts *opts = to_f_uac_opts(item);			\
102 	int result = 0;							\
103 	int i;								\
104 									\
105 	mutex_lock(&opts->lock);					\
106 	page[0] = '\0';							\
107 	for (i = 0; i < UAC_MAX_RATES; i++) {				\
108 		if (opts->name[i] == 0)					\
109 			continue;					\
110 		result += sprintf(page + strlen(page), "%u,",		\
111 				opts->name[i]);				\
112 	}								\
113 	if (strlen(page) > 0)						\
114 		page[strlen(page) - 1] = '\n';				\
115 	mutex_unlock(&opts->lock);					\
116 									\
117 	return result;							\
118 }									\
119 									\
120 static ssize_t f_uac_opts_##name##_store(struct config_item *item,	\
121 					  const char *page, size_t len)	\
122 {									\
123 	struct f_uac_opts *opts = to_f_uac_opts(item);			\
124 	char *split_page = NULL;					\
125 	int ret = -EINVAL;						\
126 	char *token;							\
127 	u32 num;							\
128 	int i;								\
129 									\
130 	mutex_lock(&opts->lock);					\
131 	if (opts->refcnt) {						\
132 		ret = -EBUSY;						\
133 		goto end;						\
134 	}								\
135 									\
136 	i = 0;								\
137 	memset(opts->name, 0x00, sizeof(opts->name));			\
138 	split_page = kstrdup(page, GFP_KERNEL);				\
139 	while ((token = strsep(&split_page, ",")) != NULL) {		\
140 		ret = kstrtou32(token, 0, &num);			\
141 		if (ret)						\
142 			goto end;					\
143 									\
144 		opts->name[i++] = num;					\
145 		opts->name##_active = num;				\
146 		ret = len;						\
147 	};								\
148 									\
149 end:									\
150 	kfree(split_page);						\
151 	mutex_unlock(&opts->lock);					\
152 	return ret;							\
153 }									\
154 									\
155 CONFIGFS_ATTR(f_uac_opts_, name)
156 
157 struct f_uac {
158 	struct g_audio g_audio;
159 	u8 ac_intf, as_in_intf, as_out_intf;
160 	u8 ac_alt, as_in_alt, as_out_alt;	/* needed for get_alt() */
161 	int ctl_id;
162 
163 	struct list_head cs;
164 	u8 set_cmd;
165 	u8 get_cmd;
166 	struct usb_audio_control *set_con;
167 	struct usb_audio_control *get_con;
168 };
169 
func_to_uac(struct usb_function * f)170 static inline struct f_uac *func_to_uac(struct usb_function *f)
171 {
172 	return container_of(f, struct f_uac, g_audio.func);
173 }
174 
175 static inline
g_audio_to_uac_opts(struct g_audio * agdev)176 struct f_uac_opts *g_audio_to_uac_opts(struct g_audio *agdev)
177 {
178 	return container_of(agdev->func.fi, struct f_uac_opts, func_inst);
179 }
180 
to_f_uac_opts(struct config_item * item)181 static inline struct f_uac_opts *to_f_uac_opts(struct config_item *item)
182 {
183 	return container_of(to_config_group(item), struct f_uac_opts,
184 			    func_inst.group);
185 }
186 
f_uac_attr_release(struct config_item * item)187 static inline void f_uac_attr_release(struct config_item *item)
188 {
189 	struct f_uac_opts *opts = to_f_uac_opts(item);
190 
191 	usb_put_function_instance(&opts->func_inst);
192 }
193 
194 #endif /* __U_UAC_H */
195