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