Linux Audio

Check our new training course

Loading...
v4.10.11
 
  1/*
  2 * bebob_command.c - driver for BeBoB based devices
  3 *
  4 * Copyright (c) 2013-2014 Takashi Sakamoto
  5 *
  6 * Licensed under the terms of the GNU General Public License, version 2.
  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;		/* 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 */
 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 && err < 9)
 
 
 35		err = -EIO;
 36	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
 37		err = -ENOSYS;
 38	else if (buf[0] == 0x0a) /* REJECTED */
 39		err = -EINVAL;
 40	else if (err > 0)
 41		err = 0;
 42
 43	kfree(buf);
 44	return err;
 45}
 46
 47int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
 48			   unsigned int fb_id, unsigned int *num)
 49{
 50	u8 *buf;
 51	int err;
 52
 53	buf = kzalloc(12, GFP_KERNEL);
 54	if (buf == NULL)
 55		return -ENOMEM;
 56
 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 */
 66
 67	err = fcp_avc_transaction(unit, buf, 12, buf, 12,
 68				  BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
 69				  BIT(6) | BIT(8));
 70	if (err > 0 && err < 9)
 
 
 71		err = -EIO;
 72	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
 73		err = -ENOSYS;
 74	else if (buf[0] == 0x0a) /* REJECTED */
 75		err = -EINVAL;
 76	else if (buf[0] == 0x0b) /* IN TRANSITION */
 77		err = -EAGAIN;
 78	if (err < 0)
 79		goto end;
 80
 81	*num = buf[7];
 82	err = 0;
 83end:
 84	kfree(buf);
 85	return err;
 86}
 87
 88static inline void
 89avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
 90{
 91	buf[1] = addr[0];
 92	memcpy(buf + 4, addr + 1, 5);
 93}
 94
 95static inline void
 96avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr,
 97					      unsigned int itype)
 98{
 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 */
104}
105
106int avc_bridgeco_get_plug_type(struct fw_unit *unit,
107			       u8 addr[AVC_BRIDGECO_ADDR_BYTES],
108			       enum avc_bridgeco_plug_type *type)
109{
110	u8 *buf;
111	int err;
112
113	buf = kzalloc(12, GFP_KERNEL);
114	if (buf == NULL)
115		return -ENOMEM;
116
117	/* Info type is 'plug type'. */
118	avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00);
119
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))
 
 
124		err = -EIO;
125	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
126		err = -ENOSYS;
127	else if (buf[0] == 0x0a) /* REJECTED */
128		err = -EINVAL;
129	else if (buf[0] == 0x0b) /* IN TRANSITION */
130		err = -EAGAIN;
131	if (err < 0)
132		goto end;
133
134	*type = buf[10];
135	err = 0;
136end:
137	kfree(buf);
138	return err;
139}
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
142				 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
143				 u8 *buf, unsigned int len)
144{
145	int err;
146
147	/* Info type is 'channel position'. */
148	avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
149
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))
 
 
154		err = -EIO;
155	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
156		err = -ENOSYS;
157	else if (buf[0] == 0x0a) /* REJECTED */
158		err = -EINVAL;
159	else if (buf[0] == 0x0b) /* IN TRANSITION */
160		err = -EAGAIN;
161	if (err < 0)
162		goto end;
163
164	/* Pick up specific data. */
165	memmove(buf, buf + 10, err - 10);
166	err = 0;
167end:
168	return err;
169}
170
171int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
172				       u8 addr[AVC_BRIDGECO_ADDR_BYTES],
173				       unsigned int id, u8 *type)
174{
175	u8 *buf;
176	int err;
177
178	/* section info includes charactors but this module don't need it */
179	buf = kzalloc(12, GFP_KERNEL);
180	if (buf == NULL)
181		return -ENOMEM;
182
183	/* Info type is 'section info'. */
184	avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
185	buf[10] = 0xff & ++id;	/* section id */
186
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))
 
 
191		err = -EIO;
192	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
193		err = -ENOSYS;
194	else if (buf[0] == 0x0a) /* REJECTED */
195		err = -EINVAL;
196	else if (buf[0] == 0x0b) /* IN TRANSITION */
197		err = -EAGAIN;
198	if (err < 0)
199		goto end;
200
201	*type = buf[11];
202	err = 0;
203end:
204	kfree(buf);
205	return err;
206}
207
208int avc_bridgeco_get_plug_input(struct fw_unit *unit,
209				u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
210{
211	int err;
212	u8 *buf;
213
214	buf = kzalloc(18, GFP_KERNEL);
215	if (buf == NULL)
216		return -ENOMEM;
217
218	/* Info type is 'plug input'. */
219	avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
220
221	err = fcp_avc_transaction(unit, buf, 16, buf, 16,
222				  BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
223				  BIT(6) | BIT(7));
224	if ((err >= 0) && (err < 8))
 
 
225		err = -EIO;
226	else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
227		err = -ENOSYS;
228	else if (buf[0] == 0x0a) /* REJECTED */
229		err = -EINVAL;
230	else if (buf[0] == 0x0b) /* IN TRANSITION */
231		err = -EAGAIN;
232	if (err < 0)
233		goto end;
234
235	memcpy(input, buf + 10, 5);
236	err = 0;
237end:
238	kfree(buf);
239	return err;
240}
241
242int 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)
245{
246	int err;
247
248	/* check given buffer */
249	if ((buf == NULL) || (*len < 12)) {
250		err = -EINVAL;
251		goto end;
252	}
253
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 */
259
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))
 
 
264		err = -EIO;
265	else if (buf[0] == 0x08)        /* NOT IMPLEMENTED */
266		err = -ENOSYS;
267	else if (buf[0] == 0x0a)        /* REJECTED */
268		err = -EINVAL;
269	else if (buf[0] == 0x0b)        /* IN TRANSITION */
270		err = -EAGAIN;
271	else if (buf[10] != eid)
272		err = -EIO;
273	if (err < 0)
274		goto end;
275
276	/* Pick up 'stream format info'. */
277	memmove(buf, buf + 11, err - 11);
278	*len = err - 11;
279	err = 0;
280end:
281	return err;
282}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * bebob_command.c - driver for BeBoB based devices
  4 *
  5 * Copyright (c) 2013-2014 Takashi Sakamoto
 
 
  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;		/* 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 */
 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) /* NOT IMPLEMENTED */
 38		err = -ENOSYS;
 39	else if (buf[0] == 0x0a) /* REJECTED */
 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;		/* 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 */
 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) /* NOT IMPLEMENTED */
 76		err = -ENOSYS;
 77	else if (buf[0] == 0x0a) /* REJECTED */
 78		err = -EINVAL;
 79	else if (buf[0] == 0x0b) /* IN TRANSITION */
 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;	/* 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 */
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	/* Info type is 'plug type'. */
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) /* NOT IMPLEMENTED */
131		err = -ENOSYS;
132	else if (buf[0] == 0x0a) /* REJECTED */
133		err = -EINVAL;
134	else if (buf[0] == 0x0b) /* IN TRANSITION */
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	// Info type is 'plug type'.
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) // NOT IMPLEMENTED
167		err = -ENOSYS;
168	else if (buf[0] == 0x0a) // REJECTED
169		err = -EINVAL;
170	else if (buf[0] == 0x0b) // IN TRANSITION
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	/* Info type is 'channel position'. */
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) /* NOT IMPLEMENTED */
199		err = -ENOSYS;
200	else if (buf[0] == 0x0a) /* REJECTED */
201		err = -EINVAL;
202	else if (buf[0] == 0x0b) /* IN TRANSITION */
203		err = -EAGAIN;
204	if (err < 0)
205		goto end;
206
207	/* Pick up specific data. */
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	/* section info includes charactors but this module don't need it */
222	buf = kzalloc(12, GFP_KERNEL);
223	if (buf == NULL)
224		return -ENOMEM;
225
226	/* Info type is 'section info'. */
227	avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
228	buf[10] = 0xff & ++id;	/* section 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) /* NOT IMPLEMENTED */
238		err = -ENOSYS;
239	else if (buf[0] == 0x0a) /* REJECTED */
240		err = -EINVAL;
241	else if (buf[0] == 0x0b) /* IN TRANSITION */
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	/* Info type is 'plug input'. */
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) /* NOT IMPLEMENTED */
274		err = -ENOSYS;
275	else if (buf[0] == 0x0a) /* REJECTED */
276		err = -EINVAL;
277	else if (buf[0] == 0x0b) /* IN TRANSITION */
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	/* check given buffer */
296	if ((buf == NULL) || (*len < 12)) {
297		err = -EINVAL;
298		goto end;
299	}
300
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 */
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)        /* NOT IMPLEMENTED */
315		err = -ENOSYS;
316	else if (buf[0] == 0x0a)        /* REJECTED */
317		err = -EINVAL;
318	else if (buf[0] == 0x0b)        /* IN TRANSITION */
319		err = -EAGAIN;
320	else if (buf[10] != eid)
321		err = -EIO;
322	if (err < 0)
323		goto end;
324
325	/* Pick up 'stream format info'. */
326	memmove(buf, buf + 11, err - 11);
327	*len = err - 11;
328	err = 0;
329end:
330	return err;
331}