~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/firewire/bebob/bebob_command.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 
 10 int 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 
 48 int 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;
 86 end:
 87         kfree(buf);
 88         return err;
 89 }
 90 
 91 static inline void
 92 avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
 93 {
 94         buf[1] = addr[0];
 95         memcpy(buf + 4, addr + 1, 5);
 96 }
 97 
 98 static inline void
 99 avc_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 
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)
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;
141 end:
142         kfree(buf);
143         return err;
144 }
145 
146 int 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;
177 end:
178         kfree(buf);
179         return err;
180 }
181 
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)
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;
210 end:
211         return err;
212 }
213 
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)
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;
248 end:
249         kfree(buf);
250         return err;
251 }
252 
253 int 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;
284 end:
285         kfree(buf);
286         return err;
287 }
288 
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)
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;
329 end:
330         return err;
331 }
332 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php