aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/firewire/fwdv.h
blob: f4c2c3dfc56142648cf2bcc1cf0cb47d3722f931 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
 * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#ifndef _DEV_FIREWIRE_FWDV_H_
#define _DEV_FIREWIRE_FWDV_H_

/* FCP (Function Control Protocol) register addresses (IEC 61883-1 9.2) */
#define FCP_COMMAND_ADDR	0xfffff0000b00ULL
#define FCP_RESPONSE_ADDR	0xfffff0000d00ULL
#define FCP_MAX_FRAME_LEN	512

/* AV/C command/response type codes (ctype / response, 4-bit) */
#define AVC_CTYPE_CONTROL	0x0
#define AVC_CTYPE_STATUS	0x1
#define AVC_CTYPE_NOTIFY	0x3

#define AVC_RESP_NOT_IMPL	0x8
#define AVC_RESP_ACCEPTED	0x9
#define AVC_RESP_REJECTED	0xa
#define AVC_RESP_IN_TRANSITION	0xb
#define AVC_RESP_STABLE		0xc
#define AVC_RESP_INTERIM	0xf

/* AV/C subunit types (5-bit) */
#define AVC_SUBUNIT_TAPE	0x04
#define AVC_SUBUNIT_UNIT	0x1f

/* AV/C subunit ID (3-bit) */
#define AVC_SUBUNIT_ID_0	0x00
#define AVC_SUBUNIT_ID_IGNORE	0x07

/* AV/C address byte: subunit_type(5) | subunit_id(3) */
#define AVC_ADDR(type, id)	(((type) << 3) | ((id) & 0x07))
#define AVC_ADDR_UNIT		AVC_ADDR(AVC_SUBUNIT_UNIT, AVC_SUBUNIT_ID_IGNORE)
#define AVC_ADDR_TAPE0		AVC_ADDR(AVC_SUBUNIT_TAPE, AVC_SUBUNIT_ID_0)

/* AV/C unit commands (opcode) */
#define AVC_OP_UNIT_INFO	0x30
#define AVC_OP_SUBUNIT_INFO	0x31
#define AVC_OP_VENDOR_DEP	0x00
#define AVC_OP_POWER		0xb2

/* AV/C tape subunit opcodes */
#define AVC_OP_PLAY		0xc3
#define AVC_OP_RECORD		0xc2
#define AVC_OP_WIND		0xc4
#define AVC_OP_TRANSPORT_STATE	0xd0

/* PLAY operand[0] values */
#define AVC_PLAY_FWD		0x75
#define AVC_PLAY_STOP		0x60

/* WIND operand[0] values */
#define AVC_WIND_FFWD		0x75
#define AVC_WIND_REW		0x65
#define AVC_WIND_STOP		0x60

/* TRANSPORT_STATE operand[0] values */
#define AVC_XPORT_PLAY		0x01
#define AVC_XPORT_RECORD	0x02
#define AVC_XPORT_WIND_FF	0x03
#define AVC_XPORT_WIND_REW	0x04
#define AVC_XPORT_NO_INFO	0x7f

/* POWER operand[0] */
#define AVC_POWER_ON		0x70
#define AVC_POWER_OFF		0x60

/* IEEE 1394 CSR register space */
#define CSR_BASE_HI		0xffff
#define CSR_BASE_LO		0xf0000000

/* ISO channel limits */
#define ISO_CHANNEL_MASK	0x3f
#define ISO_CHANNEL_MAX		64

/* IEC 61883 plug control registers (CSR offsets) */
#define PCR_oMPR		0x900
#define PCR_oPCR(n)		(0x904 + (n) * 4)
#define PCR_iMPR		0x980
#define PCR_iPCR(n)		(0x984 + (n) * 4)

/*
 * oPCR register fields (IEC 61883-1 7.5)
 *
 * 31    30    29:24       23:16      15:14  13:10       9:0
 * online bcast n_p2p_conn channel    speed  overhead_id payload
 */
#define OPCR_ONLINE		(1U << 31)
#define OPCR_BCAST		(1U << 30)
#define OPCR_N_P2P_MASK		0x3f000000
#define OPCR_N_P2P_SHIFT	24
#define OPCR_CHANNEL_MASK	0x003f0000
#define OPCR_CHANNEL_SHIFT	16
#define OPCR_SPEED_MASK		0x0000c000
#define OPCR_SPEED_SHIFT	14
#define OPCR_OVERHEAD_MASK	0x00003c00
#define OPCR_OVERHEAD_SHIFT	10
#define OPCR_PAYLOAD_MASK	0x000003ff

/* DV frame sizes */
#define DV_SD_NTSC_FRAME	(10 * 150 * 80)	/* 120,000 bytes */
#define DV_SD_PAL_FRAME		(12 * 150 * 80)	/* 144,000 bytes */
#define DV_DVCPRO_HD_FRAME	(10 * 250 * 80)	/* 200,000 bytes */

/*
 * ioctl interface
 */
struct fwdv_info {
	uint8_t		state;
	uint8_t		iso_channel;
	uint8_t		dv_system;	/* 0=NTSC, 1=PAL, 0xff=unknown */
	uint8_t		_pad;
	uint32_t	frame_size;
	uint32_t	frame_count;
	uint32_t	frame_dropped;
	uint32_t	eui_hi;		/* device EUI-64 high */
	uint32_t	eui_lo;		/* device EUI-64 low */
	char		vendor[32];	/* from config ROM */
	char		model[32];	/* from config ROM */
};

#define FWDV_GINFO	_IOR('D', 1, struct fwdv_info)
#define FWDV_PLAY	_IO('D', 2)
#define FWDV_STOP	_IO('D', 3)
#define FWDV_FFWD	_IO('D', 4)
#define FWDV_REW	_IO('D', 5)

/* fwdv state values */
#define FWDV_STATE_IDLE		0	/* no AV/C device found */
#define FWDV_STATE_PROBED	1	/* device found, not streaming */
#define FWDV_STATE_STARTING	2	/* iso_start in progress */
#define FWDV_STATE_STREAMING	3	/* iso receive active */
#define FWDV_STATE_DETACHING	4

#define DV_DIF_BLOCK_SIZE	80
#define FWDV_MAX_FRAME_SIZE	DV_DVCPRO_HD_FRAME
#define FWDV_ISO_NCHUNK		256
#define FWDV_ISO_PKTSIZE	2048
#define FWDV_DEFAULT_ISO_CH	63
#define FWDV_FCP_XFERS		4

#ifdef _KERNEL

struct fwdv_softc {
	struct firewire_dev_comm fd;
	struct mtx		mtx;
	struct cdev		*cdev;

	struct fw_device	*fwdev;
	uint32_t		eui_hi;
	uint32_t		eui_lo;

	struct fw_bind		fcp_bind;
	uint8_t			fcp_resp[FCP_MAX_FRAME_LEN];
	int			fcp_resp_len;
	int			fcp_resp_ready;
	int			avc_busy;

	int			iso_active;

	char			vendor[32];
	char			model[32];

	struct task		probe_task;

	int			dma_ch;
	uint8_t			iso_channel;

	uint8_t			*frame_buf;
	uint8_t			*read_buf;
	uint32_t		frame_size;
	uint32_t		frame_offset;
	int			frame_ready;
	int			read_in_progress;
	uint32_t		frame_count;
	uint32_t		frame_dropped;
	int			open_count;
	struct selinfo		rsel;

	uint8_t			dv_system;
	int			dv_detected;

	int			state;
};

#define FWDV_LOCK(sc)		mtx_lock(&(sc)->mtx)
#define FWDV_UNLOCK(sc)		mtx_unlock(&(sc)->mtx)

#endif /* _KERNEL */

#endif /* _DEV_FIREWIRE_FWDV_H_ */