1
2
3
4
5
6
7
8#include "./bebob.h"
9
10int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
11 unsigned int fb_id, unsigned int num)
12{
13 u8 *buf;
14 int err;
15
16 buf = kzalloc(12, GFP_KERNEL);
17 if (buf == NULL)
18 return -ENOMEM;
19
20 buf[0] = 0x00;
21 buf[1] = 0x08 | (0x07 & subunit_id);
22 buf[2] = 0xb8;
23 buf[3] = 0x80;
24 buf[4] = 0xff & fb_id;
25 buf[5] = 0x10;
26 buf[6] = 0x02;
27 buf[7] = 0xff & num;
28 buf[8] = 0x01;
29
30 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
31 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
32 BIT(6) | BIT(7) | BIT(8));
33 if (err < 0)
34 ;
35 else if (err < 9)
36 err = -EIO;
37 else if (buf[0] == 0x08)
38 err = -ENOSYS;
39 else if (buf[0] == 0x0a)
40 err = -EINVAL;
41 else
42 err = 0;
43
44 kfree(buf);
45 return err;
46}
47
48int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
49 unsigned int fb_id, unsigned int *num)
50{
51 u8 *buf;
52 int err;
53
54 buf = kzalloc(12, GFP_KERNEL);
55 if (buf == NULL)
56 return -ENOMEM;
57
58 buf[0] = 0x01;
59 buf[1] = 0x08 | (0x07 & subunit_id);
60 buf[2] = 0xb8;
61 buf[3] = 0x80;
62 buf[4] = 0xff & fb_id;
63 buf[5] = 0x10;
64 buf[6] = 0x02;
65 buf[7] = 0xff;
66 buf[8] = 0x01;
67
68 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
69 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
70 BIT(6) | BIT(8));
71 if (err < 0)
72 ;
73 else if (err < 9)
74 err = -EIO;
75 else if (buf[0] == 0x08)
76 err = -ENOSYS;
77 else if (buf[0] == 0x0a)
78 err = -EINVAL;
79 else if (buf[0] == 0x0b)
80 err = -EAGAIN;
81 if (err < 0)
82 goto end;
83
84 *num = buf[7];
85 err = 0;
86end:
87 kfree(buf);
88 return err;
89}
90
91static inline void
92avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
93{
94 buf[1] = addr[0];
95 memcpy(buf + 4, addr + 1, 5);
96}
97
98static inline void
99avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr,
100 unsigned int itype)
101{
102 buf[0] = 0x01;
103 buf[2] = 0x02;
104 buf[3] = 0xc0;
105 avc_bridgeco_fill_extension_addr(buf, addr);
106 buf[9] = itype;
107}
108
109int avc_bridgeco_get_plug_type(struct fw_unit *unit,
110 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
111 enum avc_bridgeco_plug_type *type)
112{
113 u8 *buf;
114 int err;
115
116 buf = kzalloc(12, GFP_KERNEL);
117 if (buf == NULL)
118 return -ENOMEM;
119
120
121 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00);
122
123 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
124 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
125 BIT(6) | BIT(7) | BIT(9));
126 if (err < 0)
127 ;
128 else if (err < 11)
129 err = -EIO;
130 else if (buf[0] == 0x08)
131 err = -ENOSYS;
132 else if (buf[0] == 0x0a)
133 err = -EINVAL;
134 else if (buf[0] == 0x0b)
135 err = -EAGAIN;
136 if (err < 0)
137 goto end;
138
139 *type = buf[10];
140 err = 0;
141end:
142 kfree(buf);
143 return err;
144}
145
146int avc_bridgeco_get_plug_ch_count(struct fw_unit *unit, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
147 unsigned int *ch_count)
148{
149 u8 *buf;
150 int err;
151
152 buf = kzalloc(12, GFP_KERNEL);
153 if (buf == NULL)
154 return -ENOMEM;
155
156
157 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x02);
158
159 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
160 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
161 BIT(6) | BIT(7) | BIT(9));
162 if (err < 0)
163 ;
164 else if (err < 11)
165 err = -EIO;
166 else if (buf[0] == 0x08)
167 err = -ENOSYS;
168 else if (buf[0] == 0x0a)
169 err = -EINVAL;
170 else if (buf[0] == 0x0b)
171 err = -EAGAIN;
172 if (err < 0)
173 goto end;
174
175 *ch_count = buf[10];
176 err = 0;
177end:
178 kfree(buf);
179 return err;
180}
181
182int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
183 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
184 u8 *buf, unsigned int len)
185{
186 int err;
187
188
189 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
190
191 err = fcp_avc_transaction(unit, buf, 12, buf, 256,
192 BIT(1) | BIT(2) | BIT(3) | BIT(4) |
193 BIT(5) | BIT(6) | BIT(7) | BIT(9));
194 if (err < 0)
195 ;
196 else if (err < 11)
197 err = -EIO;
198 else if (buf[0] == 0x08)
199 err = -ENOSYS;
200 else if (buf[0] == 0x0a)
201 err = -EINVAL;
202 else if (buf[0] == 0x0b)
203 err = -EAGAIN;
204 if (err < 0)
205 goto end;
206
207
208 memmove(buf, buf + 10, err - 10);
209 err = 0;
210end:
211 return err;
212}
213
214int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
215 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
216 unsigned int id, u8 *type)
217{
218 u8 *buf;
219 int err;
220
221
222 buf = kzalloc(12, GFP_KERNEL);
223 if (buf == NULL)
224 return -ENOMEM;
225
226
227 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
228 buf[10] = 0xff & ++id;
229
230 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
231 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
232 BIT(6) | BIT(7) | BIT(9) | BIT(10));
233 if (err < 0)
234 ;
235 else if (err < 12)
236 err = -EIO;
237 else if (buf[0] == 0x08)
238 err = -ENOSYS;
239 else if (buf[0] == 0x0a)
240 err = -EINVAL;
241 else if (buf[0] == 0x0b)
242 err = -EAGAIN;
243 if (err < 0)
244 goto end;
245
246 *type = buf[11];
247 err = 0;
248end:
249 kfree(buf);
250 return err;
251}
252
253int avc_bridgeco_get_plug_input(struct fw_unit *unit,
254 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
255{
256 int err;
257 u8 *buf;
258
259 buf = kzalloc(18, GFP_KERNEL);
260 if (buf == NULL)
261 return -ENOMEM;
262
263
264 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
265
266 err = fcp_avc_transaction(unit, buf, 16, buf, 16,
267 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
268 BIT(6) | BIT(7));
269 if (err < 0)
270 ;
271 else if (err < 16)
272 err = -EIO;
273 else if (buf[0] == 0x08)
274 err = -ENOSYS;
275 else if (buf[0] == 0x0a)
276 err = -EINVAL;
277 else if (buf[0] == 0x0b)
278 err = -EAGAIN;
279 if (err < 0)
280 goto end;
281
282 memcpy(input, buf + 10, 5);
283 err = 0;
284end:
285 kfree(buf);
286 return err;
287}
288
289int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
290 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf,
291 unsigned int *len, unsigned int eid)
292{
293 int err;
294
295
296 if ((buf == NULL) || (*len < 12)) {
297 err = -EINVAL;
298 goto end;
299 }
300
301 buf[0] = 0x01;
302 buf[2] = 0x2f;
303 buf[3] = 0xc1;
304 avc_bridgeco_fill_extension_addr(buf, addr);
305 buf[10] = 0xff & eid;
306
307 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
308 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
309 BIT(6) | BIT(7) | BIT(10));
310 if (err < 0)
311 ;
312 else if (err < 12)
313 err = -EIO;
314 else if (buf[0] == 0x08)
315 err = -ENOSYS;
316 else if (buf[0] == 0x0a)
317 err = -EINVAL;
318 else if (buf[0] == 0x0b)
319 err = -EAGAIN;
320 else if (buf[10] != eid)
321 err = -EIO;
322 if (err < 0)
323 goto end;
324
325
326 memmove(buf, buf + 11, err - 11);
327 *len = err - 11;
328 err = 0;
329end:
330 return err;
331}
332