0001
0002
0003
0004
0005
0006
0007
0008 #include "./bebob.h"
0009
0010 int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
0011 unsigned int fb_id, unsigned int num)
0012 {
0013 u8 *buf;
0014 int err;
0015
0016 buf = kzalloc(12, GFP_KERNEL);
0017 if (buf == NULL)
0018 return -ENOMEM;
0019
0020 buf[0] = 0x00;
0021 buf[1] = 0x08 | (0x07 & subunit_id);
0022 buf[2] = 0xb8;
0023 buf[3] = 0x80;
0024 buf[4] = 0xff & fb_id;
0025 buf[5] = 0x10;
0026 buf[6] = 0x02;
0027 buf[7] = 0xff & num;
0028 buf[8] = 0x01;
0029
0030 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
0031 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0032 BIT(6) | BIT(7) | BIT(8));
0033 if (err < 0)
0034 ;
0035 else if (err < 9)
0036 err = -EIO;
0037 else if (buf[0] == 0x08)
0038 err = -ENOSYS;
0039 else if (buf[0] == 0x0a)
0040 err = -EINVAL;
0041 else
0042 err = 0;
0043
0044 kfree(buf);
0045 return err;
0046 }
0047
0048 int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
0049 unsigned int fb_id, unsigned int *num)
0050 {
0051 u8 *buf;
0052 int err;
0053
0054 buf = kzalloc(12, GFP_KERNEL);
0055 if (buf == NULL)
0056 return -ENOMEM;
0057
0058 buf[0] = 0x01;
0059 buf[1] = 0x08 | (0x07 & subunit_id);
0060 buf[2] = 0xb8;
0061 buf[3] = 0x80;
0062 buf[4] = 0xff & fb_id;
0063 buf[5] = 0x10;
0064 buf[6] = 0x02;
0065 buf[7] = 0xff;
0066 buf[8] = 0x01;
0067
0068 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
0069 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0070 BIT(6) | BIT(8));
0071 if (err < 0)
0072 ;
0073 else if (err < 9)
0074 err = -EIO;
0075 else if (buf[0] == 0x08)
0076 err = -ENOSYS;
0077 else if (buf[0] == 0x0a)
0078 err = -EINVAL;
0079 else if (buf[0] == 0x0b)
0080 err = -EAGAIN;
0081 if (err < 0)
0082 goto end;
0083
0084 *num = buf[7];
0085 err = 0;
0086 end:
0087 kfree(buf);
0088 return err;
0089 }
0090
0091 static inline void
0092 avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
0093 {
0094 buf[1] = addr[0];
0095 memcpy(buf + 4, addr + 1, 5);
0096 }
0097
0098 static inline void
0099 avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr,
0100 unsigned int itype)
0101 {
0102 buf[0] = 0x01;
0103 buf[2] = 0x02;
0104 buf[3] = 0xc0;
0105 avc_bridgeco_fill_extension_addr(buf, addr);
0106 buf[9] = itype;
0107 }
0108
0109 int avc_bridgeco_get_plug_type(struct fw_unit *unit,
0110 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
0111 enum avc_bridgeco_plug_type *type)
0112 {
0113 u8 *buf;
0114 int err;
0115
0116 buf = kzalloc(12, GFP_KERNEL);
0117 if (buf == NULL)
0118 return -ENOMEM;
0119
0120
0121 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00);
0122
0123 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
0124 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0125 BIT(6) | BIT(7) | BIT(9));
0126 if (err < 0)
0127 ;
0128 else if (err < 11)
0129 err = -EIO;
0130 else if (buf[0] == 0x08)
0131 err = -ENOSYS;
0132 else if (buf[0] == 0x0a)
0133 err = -EINVAL;
0134 else if (buf[0] == 0x0b)
0135 err = -EAGAIN;
0136 if (err < 0)
0137 goto end;
0138
0139 *type = buf[10];
0140 err = 0;
0141 end:
0142 kfree(buf);
0143 return err;
0144 }
0145
0146 int avc_bridgeco_get_plug_ch_count(struct fw_unit *unit, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
0147 unsigned int *ch_count)
0148 {
0149 u8 *buf;
0150 int err;
0151
0152 buf = kzalloc(12, GFP_KERNEL);
0153 if (buf == NULL)
0154 return -ENOMEM;
0155
0156
0157 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x02);
0158
0159 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
0160 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0161 BIT(6) | BIT(7) | BIT(9));
0162 if (err < 0)
0163 ;
0164 else if (err < 11)
0165 err = -EIO;
0166 else if (buf[0] == 0x08)
0167 err = -ENOSYS;
0168 else if (buf[0] == 0x0a)
0169 err = -EINVAL;
0170 else if (buf[0] == 0x0b)
0171 err = -EAGAIN;
0172 if (err < 0)
0173 goto end;
0174
0175 *ch_count = buf[10];
0176 err = 0;
0177 end:
0178 kfree(buf);
0179 return err;
0180 }
0181
0182 int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
0183 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
0184 u8 *buf, unsigned int len)
0185 {
0186 int err;
0187
0188
0189 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03);
0190
0191 err = fcp_avc_transaction(unit, buf, 12, buf, 256,
0192 BIT(1) | BIT(2) | BIT(3) | BIT(4) |
0193 BIT(5) | BIT(6) | BIT(7) | BIT(9));
0194 if (err < 0)
0195 ;
0196 else if (err < 11)
0197 err = -EIO;
0198 else if (buf[0] == 0x08)
0199 err = -ENOSYS;
0200 else if (buf[0] == 0x0a)
0201 err = -EINVAL;
0202 else if (buf[0] == 0x0b)
0203 err = -EAGAIN;
0204 if (err < 0)
0205 goto end;
0206
0207
0208 memmove(buf, buf + 10, err - 10);
0209 err = 0;
0210 end:
0211 return err;
0212 }
0213
0214 int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
0215 u8 addr[AVC_BRIDGECO_ADDR_BYTES],
0216 unsigned int id, u8 *type)
0217 {
0218 u8 *buf;
0219 int err;
0220
0221
0222 buf = kzalloc(12, GFP_KERNEL);
0223 if (buf == NULL)
0224 return -ENOMEM;
0225
0226
0227 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07);
0228 buf[10] = 0xff & ++id;
0229
0230 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
0231 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0232 BIT(6) | BIT(7) | BIT(9) | BIT(10));
0233 if (err < 0)
0234 ;
0235 else if (err < 12)
0236 err = -EIO;
0237 else if (buf[0] == 0x08)
0238 err = -ENOSYS;
0239 else if (buf[0] == 0x0a)
0240 err = -EINVAL;
0241 else if (buf[0] == 0x0b)
0242 err = -EAGAIN;
0243 if (err < 0)
0244 goto end;
0245
0246 *type = buf[11];
0247 err = 0;
0248 end:
0249 kfree(buf);
0250 return err;
0251 }
0252
0253 int avc_bridgeco_get_plug_input(struct fw_unit *unit,
0254 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7])
0255 {
0256 int err;
0257 u8 *buf;
0258
0259 buf = kzalloc(18, GFP_KERNEL);
0260 if (buf == NULL)
0261 return -ENOMEM;
0262
0263
0264 avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05);
0265
0266 err = fcp_avc_transaction(unit, buf, 16, buf, 16,
0267 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0268 BIT(6) | BIT(7));
0269 if (err < 0)
0270 ;
0271 else if (err < 16)
0272 err = -EIO;
0273 else if (buf[0] == 0x08)
0274 err = -ENOSYS;
0275 else if (buf[0] == 0x0a)
0276 err = -EINVAL;
0277 else if (buf[0] == 0x0b)
0278 err = -EAGAIN;
0279 if (err < 0)
0280 goto end;
0281
0282 memcpy(input, buf + 10, 5);
0283 err = 0;
0284 end:
0285 kfree(buf);
0286 return err;
0287 }
0288
0289 int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit,
0290 u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf,
0291 unsigned int *len, unsigned int eid)
0292 {
0293 int err;
0294
0295
0296 if ((buf == NULL) || (*len < 12)) {
0297 err = -EINVAL;
0298 goto end;
0299 }
0300
0301 buf[0] = 0x01;
0302 buf[2] = 0x2f;
0303 buf[3] = 0xc1;
0304 avc_bridgeco_fill_extension_addr(buf, addr);
0305 buf[10] = 0xff & eid;
0306
0307 err = fcp_avc_transaction(unit, buf, 12, buf, *len,
0308 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
0309 BIT(6) | BIT(7) | BIT(10));
0310 if (err < 0)
0311 ;
0312 else if (err < 12)
0313 err = -EIO;
0314 else if (buf[0] == 0x08)
0315 err = -ENOSYS;
0316 else if (buf[0] == 0x0a)
0317 err = -EINVAL;
0318 else if (buf[0] == 0x0b)
0319 err = -EAGAIN;
0320 else if (buf[10] != eid)
0321 err = -EIO;
0322 if (err < 0)
0323 goto end;
0324
0325
0326 memmove(buf, buf + 11, err - 11);
0327 *len = err - 11;
0328 err = 0;
0329 end:
0330 return err;
0331 }