xref: /freebsd/sys/dev/firewire/fwisound.h (revision dd56711e83533ffe40f3f54b01565537f85381cc)
1 /*
2  * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #ifndef _DEV_FIREWIRE_FWISOUND_H_
8 #define _DEV_FIREWIRE_FWISOUND_H_
9 
10 #include <dev/firewire/fwcam.h>
11 
12 /* Protocol reverse-engineered by Clemens Ladisch (Linux isight-firmware). */
13 #define FWISOUND_SPEC_ID	APPLE_FW_OUI
14 #define FWISOUND_VERSION	0x000010	/* SW_ISIGHT_AUDIO */
15 
16 #define APPLE_FW_OUI		0x000a27
17 
18 /* Audio register offsets from audio_base */
19 #define FWISOUND_REG_AUDIO_ENABLE	0x000	/* bit31 = enable streaming */
20 #define FWISOUND_REG_DEF_AUDIO_GAIN	0x204
21 #define FWISOUND_REG_GAIN_RAW_START	0x210
22 #define FWISOUND_REG_GAIN_RAW_END	0x214
23 #define FWISOUND_REG_GAIN_DB_START	0x218
24 #define FWISOUND_REG_GAIN_DB_END	0x21c
25 #define FWISOUND_REG_SAMPLE_RATE_INQ	0x280
26 #define FWISOUND_REG_ISO_TX_CONFIG	0x300	/* bits[19:16]=speed, [3:0]=ch*/
27 #define FWISOUND_REG_SAMPLE_RATE	0x400	/* bit31 = 1 → 48000 Hz */
28 #define FWISOUND_REG_GAIN		0x500
29 #define FWISOUND_REG_MUTE		0x504
30 
31 /* REG_AUDIO_ENABLE / REG_SAMPLE_RATE bit */
32 #define FWISOUND_AUDIO_ENABLE		(1u << 31)
33 #define FWISOUND_RATE_48000		(1u << 31)
34 
35 #define FWISOUND_MAX_SAMPLES	475		/* max samples per ISO packet */
36 #define FWISOUND_SIGNATURE	0x73676874u	/* "sght" */
37 
38 /* Apple FireWire audio ISO payload. */
39 struct fwisound_payload {
40 	uint32_t	sample_count;		/* samples in this packet */
41 	uint32_t	signature;		/* 0x73676874 = "sght" */
42 	uint32_t	sample_total;		/* running total (drop detect)*/
43 	uint32_t	reserved;
44 	int16_t		samples[2 * FWISOUND_MAX_SAMPLES]; /* stereo S16BE */
45 };
46 
47 /* ISO DMA parameters */
48 #define FWISOUND_ISO_CHANNEL	1
49 #define FWISOUND_ISO_NCHUNK	64
50 #define FWISOUND_ISO_PKTSIZE	2048		/* MCLBYTES */
51 
52 /* Driver states */
53 #define FWISOUND_STATE_IDLE	0
54 #define FWISOUND_STATE_PROBED	1
55 #define FWISOUND_STATE_STREAMING 2
56 #define FWISOUND_STATE_DETACHING 3
57 
58 #ifdef _KERNEL
59 
60 #include <dev/sound/pcm/sound.h>
61 
62 struct fwisound_chan {
63 	struct fwisound_softc	*sc;
64 	struct pcm_channel	*pcm_chan;
65 	struct snd_dbuf		*buf;
66 	struct pcmchan_caps	 caps;
67 	uint32_t		 fmts[2];
68 	uint32_t		 hw_ptr;	/* ring write offset (bytes) */
69 	int			 running;
70 };
71 
72 struct fwisound_softc {
73 	struct firewire_dev_comm fd;	/* MUST BE FIRST */
74 	struct mtx		 mtx;
75 	device_t		 dev;
76 	device_t		 pcm_dev;
77 
78 	struct fw_device	*fwdev;
79 	uint16_t		 cmd_hi;	/* always 0xffff */
80 	uint32_t		 cmd_lo;	/* 0xf0000000|(audio_base<<2) */
81 
82 	struct task		 probe_task;
83 	struct task		 start_task;	/* deferred iso_start */
84 	struct task		 stop_task;	/* deferred iso_stop */
85 
86 	/* ISO streaming */
87 	int			 dma_ch;	/* -1 = not open */
88 	int			 iso_active;	/* iso_input running */
89 	uint8_t			 iso_channel;
90 
91 	/* PCM channel back-reference */
92 	struct fwisound_chan	*chan;
93 
94 	/* Sample drop detection */
95 	uint32_t		 sample_total;
96 
97 	/* Gain range (read from camera during probe) */
98 	int32_t			 gain_raw_min;
99 	int32_t			 gain_raw_max;
100 
101 	int			 state;
102 	int			 dropped;
103 };
104 
105 #define FWISOUND_LOCK(sc)	mtx_lock(&(sc)->mtx)
106 #define FWISOUND_UNLOCK(sc)	mtx_unlock(&(sc)->mtx)
107 
108 int	fwisound_iso_start(struct fwisound_softc *);
109 void	fwisound_iso_stop(struct fwisound_softc *);
110 
111 #endif /* _KERNEL */
112 
113 #endif /* _DEV_FIREWIRE_FWISOUND_H_ */
114