2 * bebob_command.c - driver for BeBoB based devices
4 * Copyright (c) 2013-2014 Takashi Sakamoto
6 * Licensed under the terms of the GNU General Public License, version 2.
11 int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
12 unsigned int fb_id, unsigned int num)
17 buf = kzalloc(12, GFP_KERNEL);
21 buf[0] = 0x00; /* AV/C CONTROL */
22 buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
23 buf[2] = 0xb8; /* FUNCTION BLOCK */
24 buf[3] = 0x80; /* type is 'selector'*/
25 buf[4] = 0xff & fb_id; /* function block id */
26 buf[5] = 0x10; /* control attribute is CURRENT */
27 buf[6] = 0x02; /* selector length is 2 */
28 buf[7] = 0xff & num; /* input function block plug number */
29 buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
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));
38 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
40 else if (buf[0] == 0x0a) /* REJECTED */
49 int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
50 unsigned int fb_id, unsigned int *num)
55 buf = kzalloc(12, GFP_KERNEL);
59 buf[0] = 0x01; /* AV/C STATUS */
60 buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
61 buf[2] = 0xb8; /* FUNCTION BLOCK */
62 buf[3] = 0x80; /* type is 'selector'*/
63 buf[4] = 0xff & fb_id; /* function block id */
64 buf[5] = 0x10; /* control attribute is CURRENT */
65 buf[6] = 0x02; /* selector length is 2 */
66 buf[7] = 0xff; /* input function block plug number */
67 buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
69 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
70 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
76 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
78 else if (buf[0] == 0x0a) /* REJECTED */
80 else if (buf[0] == 0x0b) /* IN TRANSITION */
93 avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
96 memcpy(buf + 4, addr + 1, 5);
100 avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr,
103 buf[0] = 0x01; /* AV/C STATUS */
104 buf[2] = 0x02; /* AV/C GENERAL PLUG INFO */
105 buf[3] = 0xc0; /* BridgeCo extension */
106 avc_bridgeco_fill_extension_addr(buf, addr);
107 buf[9] = itype; /* info type */
110 int avc_bridgeco_get_plug_type(struct fw_unit *unit,
111 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
112 enum avc_bridgeco_plug_type *type)
117 buf = kzalloc(12, GFP_KERNEL);
121 /* Info type is 'plug type'. */
122 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00);
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));
131 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
133 else if (buf[0] == 0x0a) /* REJECTED */
135 else if (buf[0] == 0x0b) /* IN TRANSITION */
147 int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
148 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
149 u8 *buf, unsigned int len)
153 /* Info type is 'channel position'. */
154 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
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));
163 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
165 else if (buf[0] == 0x0a) /* REJECTED */
167 else if (buf[0] == 0x0b) /* IN TRANSITION */
172 /* Pick up specific data. */
173 memmove(buf, buf + 10, err - 10);
179 int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
180 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
181 unsigned int id, u8 *type)
186 /* section info includes charactors but this module don't need it */
187 buf = kzalloc(12, GFP_KERNEL);
191 /* Info type is 'section info'. */
192 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
193 buf[10] = 0xff & ++id; /* section id */
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));
202 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
204 else if (buf[0] == 0x0a) /* REJECTED */
206 else if (buf[0] == 0x0b) /* IN TRANSITION */
218 int avc_bridgeco_get_plug_input(struct fw_unit *unit,
219 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
224 buf = kzalloc(18, GFP_KERNEL);
228 /* Info type is 'plug input'. */
229 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
231 err = fcp_avc_transaction(unit, buf, 16, buf, 16,
232 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
238 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
240 else if (buf[0] == 0x0a) /* REJECTED */
242 else if (buf[0] == 0x0b) /* IN TRANSITION */
247 memcpy(input, buf + 10, 5);
254 int 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)
260 /* check given buffer */
261 if ((buf == NULL) || (*len < 12)) {
266 buf[0] = 0x01; /* AV/C STATUS */
267 buf[2] = 0x2f; /* AV/C STREAM FORMAT SUPPORT */
268 buf[3] = 0xc1; /* Bridgeco extension - List Request */
269 avc_bridgeco_fill_extension_addr(buf, addr);
270 buf[10] = 0xff & eid; /* Entry ID */
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));
279 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
281 else if (buf[0] == 0x0a) /* REJECTED */
283 else if (buf[0] == 0x0b) /* IN TRANSITION */
285 else if (buf[10] != eid)
290 /* Pick up 'stream format info'. */
291 memmove(buf, buf + 11, err - 11);