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));
34 if (err
> 0 && err
< 9)
36 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
38 else if (buf
[0] == 0x0a) /* REJECTED */
47 int avc_audio_get_selector(struct fw_unit
*unit
, unsigned int subunit_id
,
48 unsigned int fb_id
, unsigned int *num
)
53 buf
= kzalloc(12, GFP_KERNEL
);
57 buf
[0] = 0x01; /* AV/C STATUS */
58 buf
[1] = 0x08 | (0x07 & subunit_id
); /* AUDIO SUBUNIT ID */
59 buf
[2] = 0xb8; /* FUNCTION BLOCK */
60 buf
[3] = 0x80; /* type is 'selector'*/
61 buf
[4] = 0xff & fb_id
; /* function block id */
62 buf
[5] = 0x10; /* control attribute is CURRENT */
63 buf
[6] = 0x02; /* selector length is 2 */
64 buf
[7] = 0xff; /* input function block plug number */
65 buf
[8] = 0x01; /* control selector is SELECTOR_CONTROL */
67 err
= fcp_avc_transaction(unit
, buf
, 12, buf
, 12,
68 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
70 if (err
> 0 && err
< 9)
72 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
74 else if (buf
[0] == 0x0a) /* REJECTED */
76 else if (buf
[0] == 0x0b) /* IN TRANSITION */
89 avc_bridgeco_fill_extension_addr(u8
*buf
, u8
*addr
)
92 memcpy(buf
+ 4, addr
+ 1, 5);
96 avc_bridgeco_fill_plug_info_extension_command(u8
*buf
, u8
*addr
,
99 buf
[0] = 0x01; /* AV/C STATUS */
100 buf
[2] = 0x02; /* AV/C GENERAL PLUG INFO */
101 buf
[3] = 0xc0; /* BridgeCo extension */
102 avc_bridgeco_fill_extension_addr(buf
, addr
);
103 buf
[9] = itype
; /* info type */
106 int avc_bridgeco_get_plug_type(struct fw_unit
*unit
,
107 u8 addr
[AVC_BRIDGECO_ADDR_BYTES
],
108 enum avc_bridgeco_plug_type
*type
)
113 buf
= kzalloc(12, GFP_KERNEL
);
117 /* Info type is 'plug type'. */
118 avc_bridgeco_fill_plug_info_extension_command(buf
, addr
, 0x00);
120 err
= fcp_avc_transaction(unit
, buf
, 12, buf
, 12,
121 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
122 BIT(6) | BIT(7) | BIT(9));
123 if ((err
>= 0) && (err
< 8))
125 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
127 else if (buf
[0] == 0x0a) /* REJECTED */
129 else if (buf
[0] == 0x0b) /* IN TRANSITION */
141 int avc_bridgeco_get_plug_ch_pos(struct fw_unit
*unit
,
142 u8 addr
[AVC_BRIDGECO_ADDR_BYTES
],
143 u8
*buf
, unsigned int len
)
147 /* Info type is 'channel position'. */
148 avc_bridgeco_fill_plug_info_extension_command(buf
, addr
, 0x03);
150 err
= fcp_avc_transaction(unit
, buf
, 12, buf
, 256,
151 BIT(1) | BIT(2) | BIT(3) | BIT(4) |
152 BIT(5) | BIT(6) | BIT(7) | BIT(9));
153 if ((err
>= 0) && (err
< 8))
155 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
157 else if (buf
[0] == 0x0a) /* REJECTED */
159 else if (buf
[0] == 0x0b) /* IN TRANSITION */
164 /* Pick up specific data. */
165 memmove(buf
, buf
+ 10, err
- 10);
171 int avc_bridgeco_get_plug_section_type(struct fw_unit
*unit
,
172 u8 addr
[AVC_BRIDGECO_ADDR_BYTES
],
173 unsigned int id
, u8
*type
)
178 /* section info includes charactors but this module don't need it */
179 buf
= kzalloc(12, GFP_KERNEL
);
183 /* Info type is 'section info'. */
184 avc_bridgeco_fill_plug_info_extension_command(buf
, addr
, 0x07);
185 buf
[10] = 0xff & ++id
; /* section id */
187 err
= fcp_avc_transaction(unit
, buf
, 12, buf
, 12,
188 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
189 BIT(6) | BIT(7) | BIT(9) | BIT(10));
190 if ((err
>= 0) && (err
< 8))
192 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
194 else if (buf
[0] == 0x0a) /* REJECTED */
196 else if (buf
[0] == 0x0b) /* IN TRANSITION */
208 int avc_bridgeco_get_plug_input(struct fw_unit
*unit
,
209 u8 addr
[AVC_BRIDGECO_ADDR_BYTES
], u8 input
[7])
214 buf
= kzalloc(18, GFP_KERNEL
);
218 /* Info type is 'plug input'. */
219 avc_bridgeco_fill_plug_info_extension_command(buf
, addr
, 0x05);
221 err
= fcp_avc_transaction(unit
, buf
, 16, buf
, 16,
222 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
224 if ((err
>= 0) && (err
< 8))
226 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
228 else if (buf
[0] == 0x0a) /* REJECTED */
230 else if (buf
[0] == 0x0b) /* IN TRANSITION */
235 memcpy(input
, buf
+ 10, 5);
242 int avc_bridgeco_get_plug_strm_fmt(struct fw_unit
*unit
,
243 u8 addr
[AVC_BRIDGECO_ADDR_BYTES
], u8
*buf
,
244 unsigned int *len
, unsigned int eid
)
248 /* check given buffer */
249 if ((buf
== NULL
) || (*len
< 12)) {
254 buf
[0] = 0x01; /* AV/C STATUS */
255 buf
[2] = 0x2f; /* AV/C STREAM FORMAT SUPPORT */
256 buf
[3] = 0xc1; /* Bridgeco extension - List Request */
257 avc_bridgeco_fill_extension_addr(buf
, addr
);
258 buf
[10] = 0xff & eid
; /* Entry ID */
260 err
= fcp_avc_transaction(unit
, buf
, 12, buf
, *len
,
261 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
262 BIT(6) | BIT(7) | BIT(10));
263 if ((err
>= 0) && (err
< 12))
265 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
267 else if (buf
[0] == 0x0a) /* REJECTED */
269 else if (buf
[0] == 0x0b) /* IN TRANSITION */
271 else if (buf
[10] != eid
)
276 /* Pick up 'stream format info'. */
277 memmove(buf
, buf
+ 11, err
- 11);