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