root/sound/firewire/bebob/bebob_command.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. avc_audio_set_selector
  2. avc_audio_get_selector
  3. avc_bridgeco_fill_extension_addr
  4. avc_bridgeco_fill_plug_info_extension_command
  5. avc_bridgeco_get_plug_type
  6. avc_bridgeco_get_plug_ch_pos
  7. avc_bridgeco_get_plug_section_type
  8. avc_bridgeco_get_plug_input
  9. avc_bridgeco_get_plug_strm_fmt

   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_pos(struct fw_unit *unit,
 147                                  u8 addr[AVC_BRIDGECO_ADDR_BYTES],
 148                                  u8 *buf, unsigned int len)
 149 {
 150         int err;
 151 
 152         /* Info type is 'channel position'. */
 153         avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
 154 
 155         err = fcp_avc_transaction(unit, buf, 12, buf, 256,
 156                                   BIT(1) | BIT(2) | BIT(3) | BIT(4) |
 157                                   BIT(5) | BIT(6) | BIT(7) | BIT(9));
 158         if (err < 0)
 159                 ;
 160         else if (err < 11)
 161                 err = -EIO;
 162         else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
 163                 err = -ENOSYS;
 164         else if (buf[0] == 0x0a) /* REJECTED */
 165                 err = -EINVAL;
 166         else if (buf[0] == 0x0b) /* IN TRANSITION */
 167                 err = -EAGAIN;
 168         if (err < 0)
 169                 goto end;
 170 
 171         /* Pick up specific data. */
 172         memmove(buf, buf + 10, err - 10);
 173         err = 0;
 174 end:
 175         return err;
 176 }
 177 
 178 int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
 179                                        u8 addr[AVC_BRIDGECO_ADDR_BYTES],
 180                                        unsigned int id, u8 *type)
 181 {
 182         u8 *buf;
 183         int err;
 184 
 185         /* section info includes charactors but this module don't need it */
 186         buf = kzalloc(12, GFP_KERNEL);
 187         if (buf == NULL)
 188                 return -ENOMEM;
 189 
 190         /* Info type is 'section info'. */
 191         avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
 192         buf[10] = 0xff & ++id;  /* section id */
 193 
 194         err = fcp_avc_transaction(unit, buf, 12, buf, 12,
 195                                   BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
 196                                   BIT(6) | BIT(7) | BIT(9) | BIT(10));
 197         if (err < 0)
 198                 ;
 199         else if (err < 12)
 200                 err = -EIO;
 201         else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
 202                 err = -ENOSYS;
 203         else if (buf[0] == 0x0a) /* REJECTED */
 204                 err = -EINVAL;
 205         else if (buf[0] == 0x0b) /* IN TRANSITION */
 206                 err = -EAGAIN;
 207         if (err < 0)
 208                 goto end;
 209 
 210         *type = buf[11];
 211         err = 0;
 212 end:
 213         kfree(buf);
 214         return err;
 215 }
 216 
 217 int avc_bridgeco_get_plug_input(struct fw_unit *unit,
 218                                 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
 219 {
 220         int err;
 221         u8 *buf;
 222 
 223         buf = kzalloc(18, GFP_KERNEL);
 224         if (buf == NULL)
 225                 return -ENOMEM;
 226 
 227         /* Info type is 'plug input'. */
 228         avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
 229 
 230         err = fcp_avc_transaction(unit, buf, 16, buf, 16,
 231                                   BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
 232                                   BIT(6) | BIT(7));
 233         if (err < 0)
 234                 ;
 235         else if (err < 16)
 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         memcpy(input, buf + 10, 5);
 247         err = 0;
 248 end:
 249         kfree(buf);
 250         return err;
 251 }
 252 
 253 int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
 254                                    u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf,
 255                                    unsigned int *len, unsigned int eid)
 256 {
 257         int err;
 258 
 259         /* check given buffer */
 260         if ((buf == NULL) || (*len < 12)) {
 261                 err = -EINVAL;
 262                 goto end;
 263         }
 264 
 265         buf[0] = 0x01;  /* AV/C STATUS */
 266         buf[2] = 0x2f;  /* AV/C STREAM FORMAT SUPPORT */
 267         buf[3] = 0xc1;  /* Bridgeco extension - List Request */
 268         avc_bridgeco_fill_extension_addr(buf, addr);
 269         buf[10] = 0xff & eid;   /* Entry ID */
 270 
 271         err = fcp_avc_transaction(unit, buf, 12, buf, *len,
 272                                   BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
 273                                   BIT(6) | BIT(7) | BIT(10));
 274         if (err < 0)
 275                 ;
 276         else if (err < 12)
 277                 err = -EIO;
 278         else if (buf[0] == 0x08)        /* NOT IMPLEMENTED */
 279                 err = -ENOSYS;
 280         else if (buf[0] == 0x0a)        /* REJECTED */
 281                 err = -EINVAL;
 282         else if (buf[0] == 0x0b)        /* IN TRANSITION */
 283                 err = -EAGAIN;
 284         else if (buf[10] != eid)
 285                 err = -EIO;
 286         if (err < 0)
 287                 goto end;
 288 
 289         /* Pick up 'stream format info'. */
 290         memmove(buf, buf + 11, err - 11);
 291         *len = err - 11;
 292         err = 0;
 293 end:
 294         return err;
 295 }

/* [<][>][^][v][top][bottom][index][help] */