1 // SPDX-License-Identifier: GPL-2.0-only
3 * oxfw_command.c - a part of driver for OXFW970/971 based devices
5 * Copyright (c) 2014 Takashi Sakamoto
10 int avc_stream_set_format(struct fw_unit
*unit
, enum avc_general_plug_dir dir
,
11 unsigned int pid
, u8
*format
, unsigned int len
)
16 buf
= kmalloc(len
+ 10, GFP_KERNEL
);
20 buf
[0] = 0x00; /* CONTROL */
21 buf
[1] = 0xff; /* UNIT */
22 buf
[2] = 0xbf; /* EXTENDED STREAM FORMAT INFORMATION */
23 buf
[3] = 0xc0; /* SINGLE subfunction */
24 buf
[4] = dir
; /* Plug Direction */
25 buf
[5] = 0x00; /* UNIT */
26 buf
[6] = 0x00; /* PCR (Isochronous Plug) */
27 buf
[7] = 0xff & pid
; /* Plug ID */
28 buf
[8] = 0xff; /* Padding */
29 buf
[9] = 0xff; /* Support status in response */
30 memcpy(buf
+ 10, format
, len
);
32 /* do transaction and check buf[1-8] are the same against command */
33 err
= fcp_avc_transaction(unit
, buf
, len
+ 10, buf
, len
+ 10,
34 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
35 BIT(6) | BIT(7) | BIT(8));
38 else if (err
< len
+ 10)
40 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
42 else if (buf
[0] == 0x0a) /* REJECTED */
52 int avc_stream_get_format(struct fw_unit
*unit
,
53 enum avc_general_plug_dir dir
, unsigned int pid
,
54 u8
*buf
, unsigned int *len
, unsigned int eid
)
60 subfunc
= 0xc0; /* SINGLE */
62 subfunc
= 0xc1; /* LIST */
64 buf
[0] = 0x01; /* STATUS */
65 buf
[1] = 0xff; /* UNIT */
66 buf
[2] = 0xbf; /* EXTENDED STREAM FORMAT INFORMATION */
67 buf
[3] = subfunc
; /* SINGLE or LIST */
68 buf
[4] = dir
; /* Plug Direction */
69 buf
[5] = 0x00; /* Unit */
70 buf
[6] = 0x00; /* PCR (Isochronous Plug) */
71 buf
[7] = 0xff & pid
; /* Plug ID */
72 buf
[8] = 0xff; /* Padding */
73 buf
[9] = 0xff; /* support status in response */
74 buf
[10] = 0xff & eid
; /* entry ID for LIST subfunction */
75 buf
[11] = 0xff; /* padding */
77 /* do transaction and check buf[1-7] are the same against command */
78 err
= fcp_avc_transaction(unit
, buf
, 12, buf
, *len
,
79 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
85 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */
87 else if (buf
[0] == 0x0a) /* REJECTED */
89 else if (buf
[0] == 0x0b) /* IN TRANSITION */
91 /* LIST subfunction has entry ID */
92 else if ((subfunc
== 0xc1) && (buf
[10] != eid
))
97 /* keep just stream format information */
98 if (subfunc
== 0xc0) {
99 memmove(buf
, buf
+ 10, err
- 10);
102 memmove(buf
, buf
+ 11, err
- 11);
111 int avc_general_inquiry_sig_fmt(struct fw_unit
*unit
, unsigned int rate
,
112 enum avc_general_plug_dir dir
,
119 for (sfc
= 0; sfc
< CIP_SFC_COUNT
; sfc
++) {
120 if (amdtp_rate_table
[sfc
] == rate
)
123 if (sfc
== CIP_SFC_COUNT
)
126 buf
= kzalloc(8, GFP_KERNEL
);
130 buf
[0] = 0x02; /* SPECIFIC INQUIRY */
131 buf
[1] = 0xff; /* UNIT */
132 if (dir
== AVC_GENERAL_PLUG_DIR_IN
)
133 buf
[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */
135 buf
[2] = 0x18; /* OUTPUT PLUG SIGNAL FORMAT */
136 buf
[3] = 0xff & pid
; /* plug id */
137 buf
[4] = 0x90; /* EOH_1, Form_1, FMT. AM824 */
138 buf
[5] = 0x07 & sfc
; /* FDF-hi. AM824, frequency */
139 buf
[6] = 0xff; /* FDF-mid. AM824, SYT hi (not used) */
140 buf
[7] = 0xff; /* FDF-low. AM824, SYT lo (not used) */
142 /* do transaction and check buf[1-5] are the same against command */
143 err
= fcp_avc_transaction(unit
, buf
, 8, buf
, 8,
144 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
149 else if (buf
[0] == 0x08) /* NOT IMPLEMENTED */