1 // SPDX-License-Identifier: GPL-2.0-only
3 * bebob_command.c - driver for BeBoB based devices
5 * Copyright (c) 2013-2014 Takashi Sakamoto
10 int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
11 unsigned int fb_id, unsigned int num)
16 buf = kzalloc(12, GFP_KERNEL);
20 buf[0] = 0x00; /* AV/C CONTROL */
21 buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
22 buf[2] = 0xb8; /* FUNCTION BLOCK */
23 buf[3] = 0x80; /* type is 'selector'*/
24 buf[4] = 0xff & fb_id; /* function block id */
25 buf[5] = 0x10; /* control attribute is CURRENT */
26 buf[6] = 0x02; /* selector length is 2 */
27 buf[7] = 0xff & num; /* input function block plug number */
28 buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
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));
37 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
39 else if (buf[0] == 0x0a) /* REJECTED */
48 int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
49 unsigned int fb_id, unsigned int *num)
54 buf = kzalloc(12, GFP_KERNEL);
58 buf[0] = 0x01; /* AV/C STATUS */
59 buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
60 buf[2] = 0xb8; /* FUNCTION BLOCK */
61 buf[3] = 0x80; /* type is 'selector'*/
62 buf[4] = 0xff & fb_id; /* function block id */
63 buf[5] = 0x10; /* control attribute is CURRENT */
64 buf[6] = 0x02; /* selector length is 2 */
65 buf[7] = 0xff; /* input function block plug number */
66 buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
68 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
69 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
75 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
77 else if (buf[0] == 0x0a) /* REJECTED */
79 else if (buf[0] == 0x0b) /* IN TRANSITION */
92 avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
95 memcpy(buf + 4, addr + 1, 5);
99 avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr,
102 buf[0] = 0x01; /* AV/C STATUS */
103 buf[2] = 0x02; /* AV/C GENERAL PLUG INFO */
104 buf[3] = 0xc0; /* BridgeCo extension */
105 avc_bridgeco_fill_extension_addr(buf, addr);
106 buf[9] = itype; /* info type */
109 int avc_bridgeco_get_plug_type(struct fw_unit *unit,
110 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
111 enum avc_bridgeco_plug_type *type)
116 buf = kzalloc(12, GFP_KERNEL);
120 /* Info type is 'plug type'. */
121 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00);
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));
130 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
132 else if (buf[0] == 0x0a) /* REJECTED */
134 else if (buf[0] == 0x0b) /* IN TRANSITION */
146 int avc_bridgeco_get_plug_ch_count(struct fw_unit *unit, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
147 unsigned int *ch_count)
152 buf = kzalloc(12, GFP_KERNEL);
156 // Info type is 'plug type'.
157 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x02);
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));
166 else if (buf[0] == 0x08) // NOT IMPLEMENTED
168 else if (buf[0] == 0x0a) // REJECTED
170 else if (buf[0] == 0x0b) // IN TRANSITION
182 int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
183 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
184 u8 *buf, unsigned int len)
188 /* Info type is 'channel position'. */
189 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
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));
198 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
200 else if (buf[0] == 0x0a) /* REJECTED */
202 else if (buf[0] == 0x0b) /* IN TRANSITION */
207 /* Pick up specific data. */
208 memmove(buf, buf + 10, err - 10);
214 int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
215 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
216 unsigned int id, u8 *type)
221 /* section info includes charactors but this module don't need it */
222 buf = kzalloc(12, GFP_KERNEL);
226 /* Info type is 'section info'. */
227 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
228 buf[10] = 0xff & ++id; /* section id */
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));
237 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
239 else if (buf[0] == 0x0a) /* REJECTED */
241 else if (buf[0] == 0x0b) /* IN TRANSITION */
253 int avc_bridgeco_get_plug_input(struct fw_unit *unit,
254 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
259 buf = kzalloc(18, GFP_KERNEL);
263 /* Info type is 'plug input'. */
264 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
266 err = fcp_avc_transaction(unit, buf, 16, buf, 16,
267 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
273 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
275 else if (buf[0] == 0x0a) /* REJECTED */
277 else if (buf[0] == 0x0b) /* IN TRANSITION */
282 memcpy(input, buf + 10, 5);
289 int 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)
295 /* check given buffer */
296 if ((buf == NULL) || (*len < 12)) {
301 buf[0] = 0x01; /* AV/C STATUS */
302 buf[2] = 0x2f; /* AV/C STREAM FORMAT SUPPORT */
303 buf[3] = 0xc1; /* Bridgeco extension - List Request */
304 avc_bridgeco_fill_extension_addr(buf, addr);
305 buf[10] = 0xff & eid; /* Entry ID */
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));
314 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
316 else if (buf[0] == 0x0a) /* REJECTED */
318 else if (buf[0] == 0x0b) /* IN TRANSITION */
320 else if (buf[10] != eid)
325 /* Pick up 'stream format info'. */
326 memmove(buf, buf + 11, err - 11);