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