Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9afc945
dt-bindings: sound: apple,macaudio: Add J813 and J873
sithglan Oct 25, 2026
7e364bb
soc: apple: aop: support T8152
sithglan Oct 25, 2026
bb9ad0e
dt-bindings: sound: ti,tas27xx: add ti,bclk-ratio
sithglan Oct 25, 2026
9b5dafe
ASoC: tas2764: support a fixed BCLK/FS ratio
sithglan Oct 25, 2026
e4d92b3
ASoC: cs42l84: Route SDOUT1 from the ASP input
sithglan Nov 1, 2026
a0d23fb
ASoC: apple: add the T8152 AOP audio driver
sithglan Oct 25, 2026
7bcebdc
ASoC: apple: macaudio: add J873
sithglan Oct 25, 2026
39934b9
soc: apple: aop: Boot the T8142 (M5) AOP through its setup port
sithglan Oct 31, 2026
a5ab733
dmaengine: apple-admac: Restart a paused capture at a frame boundary
sithglan Oct 31, 2026
e115f85
ASoC: apple: t8152-aop-audio: Add T8142 (MacBook Air J813)
sithglan Oct 31, 2026
e526f2b
ASoC: apple: macaudio: Add J813
sithglan Oct 31, 2026
bd7da28
ASoC: apple: t8152-aop-audio: Add the J813 microphone array
sithglan Oct 31, 2026
ea81c57
arm64: configs: asahi: build the T8152 AOP audio driver
sithglan Nov 10, 2026
c531d1c
ASoC: tas2764: test the BCLK/FS ratio with and without ti,bclk-ratio
sithglan Nov 10, 2026
35ef6d5
dmaengine: apple-admac: test that only a configured capture realigns
sithglan Nov 10, 2026
114ebfd
ASoC: apple: macaudio: test the J813 and J873 speaker tables
sithglan Nov 10, 2026
8579c33
ASoC: apple: t8152-aop-audio: Describe T8142 and the microphones
DjDeveloperr Nov 11, 2026
de172b9
ASoC: tas2764: Keep the IRQZ_CLR bit next to INT_CLK_CFG
DjDeveloperr Nov 11, 2026
713c8a2
ASoC: apple: Synchronize T8152 microphone capture shutdown
DjDeveloperr Nov 11, 2026
2b671f4
ASoC: apple: Synchronize T8152 front-end PCM shutdown
DjDeveloperr Nov 11, 2026
375393a
Merge current integration while preserving J813 AOP audio synchroniza…
DjDeveloperr Nov 11, 2026
18fa06f
Merge integration/aurora; keep its policy-window test
DjDeveloperr Nov 11, 2026
d4e7bf0
soc: apple: aop: Add T6050
DjDeveloperr Nov 11, 2026
76b99d5
dt-bindings: mailbox: apple: Add the T6050 and T8142 AOP setup ports
DjDeveloperr Nov 11, 2026
f62705c
arm64: dts: apple: t6050: Put the AOP setup port at its real address
DjDeveloperr Nov 11, 2026
3c16dac
arm64: dts: apple: t6050-j714s: Enable the AOP
DjDeveloperr Nov 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ properties:
AOP setup-port mailbox with a separate register layout.
const: apple,t8140-aop-setup-mailbox

- description:
Later AOP setup-port mailboxes with the T8140 register layout.
items:
- enum:
- apple,t6050-aop-setup-mailbox
- apple,t8142-aop-setup-mailbox
- const: apple,t8140-aop-setup-mailbox

- description:
An older ASC mailbox interface found on T2 and A11 that is also
used for the NVMe coprocessor and the system management
Expand Down
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/sound/apple,macaudio.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ properties:
- apple,j715-macaudio-jack
- apple,j773-macaudio
- apple,j773-macaudio-jack
- apple,j813-macaudio
- apple,j873-macaudio
- const: apple,macaudio
- description:
Machines that share the speaker and jack layout of an earlier
Expand Down
8 changes: 8 additions & 0 deletions Documentation/devicetree/bindings/sound/ti,tas27xx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ properties:
$ref: /schemas/types.yaml#/definitions/uint32
description: TDM TX voltage sense time slot.

ti,bclk-ratio:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [250]
description:
Fixed BCLK/FS ratio of the TDM frame, for a frame the amplifier's ratio
auto-detection does not accept (250 BCLKs on the Mac mini (M6, J873)
speaker).

'#sound-dai-cells':
# The codec has a single DAI, the #sound-dai-cells=<1>; case is left in for backward
# compatibility but is deprecated.
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/boot/dts/apple/adt-coverage/t6050-j716s.txt
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@
/arm-io/dart-aop/mapper-admac-leap-s - -> /soc@200000000/iommu@290fc0000
/arm-io/dart-aop/mapper-admac-base-s - -> /soc@200000000/iommu@290fc0000
/arm-io/dart-aop/mapper-scm - -> /soc@200000000/iommu@290fc0000
/arm-io/aop-exclave-mailbox 0x4d067c000 -> /soc/mailbox@4d067c000
/arm-io/aop-exclave-mailbox 0x2d067c000 -> /soc/mailbox@2d067c000
/arm-io/aop-exclave-ioreporting - -> MISSING
/arm-io/aop2 0x291600000 -> /soc/aop@291600000
/arm-io/aop2/iop-aop2-nub - -> /soc/aop@291600000
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/boot/dts/apple/adt-coverage/t6050-j873s.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@
/arm-io/dart-aop/mapper-admac-leap-s - -> /soc@200000000/iommu@290fc0000
/arm-io/dart-aop/mapper-admac-base-s - -> /soc@200000000/iommu@290fc0000
/arm-io/dart-aop/mapper-scm - -> /soc@200000000/iommu@290fc0000
/arm-io/aop-exclave-mailbox 0x4d067c000 -> /soc/mailbox@4d067c000
/arm-io/aop-exclave-mailbox 0x2d067c000 -> /soc/mailbox@2d067c000
/arm-io/aop-exclave-ioreporting - -> MISSING
/arm-io/aop2 0x291600000 -> /soc/aop@291600000
/arm-io/aop2/iop-aop2-nub - -> /soc/aop@291600000
Expand Down
14 changes: 6 additions & 8 deletions arch/arm64/boot/dts/apple/t6050-die0.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,9 @@
/*
* The AOP's audio path: the AP GPIO block, the I2C1/I2C2 buses and their power states (in
* pmgr1, below), and the AOP with its mailbox, dart-aop and the ADMAC its audio streams use.
* From the ADT (arm-io ranges +0x200000000). The AOP, its mailbox, dart-aop and the ADMAC are disabled:
* iBoot leaves the AOP halted on locked dart-aop tables, and Aura enables them only when its
* checks of that state pass (chosen.aurora,t6050-aop=1).
* From the ADT (arm-io ranges +0x200000000). The AOP, its mailboxes, dart-aop and the ADMAC are
* disabled here: iBoot leaves the AOP halted on locked dart-aop tables, and the boards that
* boot it enable them.
*/
pinctrl_ap: pinctrl@29c000000 {
compatible = "apple,t6050-pinctrl", "apple,t8103-pinctrl";
Expand Down Expand Up @@ -790,17 +790,15 @@

/*
* The AOP: its SRAM window (ADT reg[2]) and its ASC (reg[0]). Its firmware is loaded and
* left halted by iBoot. Booted as on T8152, over the RTKit mailbox alone: the ADT's
* aop-exclave-mailbox (the setup port T8140 and T8142 boot through) is exclave-assigned
* here and takes an SError from the AP.
* left halted by iBoot. Booted as on T8142, over the RTKit mailbox and the setup port.
*/
aop: aop@290c00000 {
compatible = "apple,t6050-aop", "apple,t8152-aop";
reg = <0x2 0x90c00000 0x0 0x1e0000>,
<0x2 0x90600000 0x0 0x4000>;
reg-names = "mmio", "asc";
mboxes = <&aop_mbox>;
mbox-names = "mbox";
mboxes = <&aop_mbox>, <&aop_setup_mbox>;
mbox-names = "mbox", "setup";
iommus = <&aop_dart 0>;
apple,dma-range = <0x110 0x0 0x10 0x0>;
status = "disabled";
Expand Down
17 changes: 17 additions & 0 deletions arch/arm64/boot/dts/apple/t6050-j714s.dts
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,20 @@
&i2c2 {
status = "disabled";
};

/* The AOP, booted through its setup port, with its sensor and audio services. */
&aop_mbox {
status = "okay";
};

&aop_setup_mbox {
status = "okay";
};

&aop_dart {
status = "okay";
};

&aop {
status = "okay";
};
18 changes: 13 additions & 5 deletions arch/arm64/boot/dts/apple/t6050-peripherals.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -1965,12 +1965,20 @@
status = "disabled";
};

aop_exclave_mailbox: mailbox@4d067c000 {
compatible = "apple,t6050-secure-mailbox", "apple,secure-mailbox";
reg = <0x4 0xd067c000 0x0 0x4000>;
interrupts = <AIC_IRQ 0 585 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 0 582 IRQ_TYPE_LEVEL_HIGH>;
/*
* The AOP setup port, ADT aop-exclave-mailbox. Its ADT reg is not behind the arm-io
* translation: AOP ASC + 0x4007c000, as on T8140 and T8142. ADT interrupts [585, 582].
* dart-aop stream 1: ADT vm-base-1 0x20000000000, vm-size-1 0x2000000000.
*/
aop_setup_mbox: mailbox@2d067c000 {
compatible = "apple,t6050-aop-setup-mailbox", "apple,t8140-aop-setup-mailbox";
reg = <0x2 0xd067c000 0x0 0x4000>;
interrupts = <AIC_IRQ 0 582 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 0 585 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "send-empty", "recv-not-empty";
iommus = <&aop_dart 1>;
apple,dma-range = <0x200 0x0 0x20 0x0>;
#mbox-cells = <0>;
status = "disabled";
};

Expand Down
1 change: 1 addition & 0 deletions arch/arm64/configs/asahi.config
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ CONFIG_DRM_ACCEL_ANE=m
CONFIG_DRM_SIMPLEDRM=y
CONFIG_SYSFB_SIMPLEFB=y
CONFIG_SND_SOC_APPLE_AOP_AUDIO=m
CONFIG_SND_SOC_APPLE_T8152_AOP_AUDIO=m
CONFIG_SND_SOC_APPLE_MCA=m
CONFIG_SND_SOC_APPLE_MACAUDIO=m
CONFIG_SND_SOC_CS42L83=m
Expand Down
61 changes: 61 additions & 0 deletions drivers/dma/apple-admac-test.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,64 @@ static struct kunit_suite admac_pos_suite = {
};

kunit_test_suite(admac_pos_suite);

/*
* The paused-capture realignment (admac_cyclic_realign()) is the AOP audio
* driver's alone: it passes the frame size in the peripheral config, for its
* speaker sense capture. The MCA's PCM zeroes its slave config, so every MCA
* channel, and every playback channel, resumes where it paused.
*/
static void admac_realign_needs_a_frame_size(struct kunit *test)
{
struct dma_slave_config config = {};
u32 frame = 16;
u64 wrong = 16;

/* As mca_hw_params() configures a channel */
config.direction = DMA_DEV_TO_MEM;
config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
config.src_port_window_size = 4;
KUNIT_EXPECT_EQ(test, admac_config_realign_bytes(&config), 0);

config.peripheral_config = &wrong;
config.peripheral_size = sizeof(wrong);
KUNIT_EXPECT_EQ(test, admac_config_realign_bytes(&config), 0);

config.peripheral_config = &frame;
config.peripheral_size = sizeof(frame);
KUNIT_EXPECT_EQ(test, admac_config_realign_bytes(&config), 16);
}

static void admac_realign_only_a_configured_capture(struct kunit *test)
{
struct admac_tx tx = admac_test_tx(0, 0);
struct admac_chan adchan = { .current_tx = &tx };

/* Playback (even channels): never, frame size or not */
adchan.no = 0;
KUNIT_EXPECT_FALSE(test, admac_resume_realigns(&adchan));
adchan.realign_bytes = 16;
KUNIT_EXPECT_FALSE(test, admac_resume_realigns(&adchan));

/* Capture (odd channels): only with a frame size and a transfer */
adchan.no = 1;
adchan.realign_bytes = 0;
KUNIT_EXPECT_FALSE(test, admac_resume_realigns(&adchan));
adchan.realign_bytes = 16;
KUNIT_EXPECT_TRUE(test, admac_resume_realigns(&adchan));
adchan.current_tx = NULL;
KUNIT_EXPECT_FALSE(test, admac_resume_realigns(&adchan));
}

static struct kunit_case admac_realign_cases[] = {
KUNIT_CASE(admac_realign_needs_a_frame_size),
KUNIT_CASE(admac_realign_only_a_configured_capture),
{}
};

static struct kunit_suite admac_realign_suite = {
.name = "apple-admac-realign",
.test_cases = admac_realign_cases,
};

kunit_test_suite(admac_realign_suite);
108 changes: 101 additions & 7 deletions drivers/dma/apple-admac.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ struct admac_chan {
spinlock_t lock;
struct admac_tx *current_tx;
int nperiod_acks;
/* frame size a paused capture restarts aligned to on resume, or 0 */
u32 realign_bytes;

/*
* We maintain a 'submitted' and 'issued' list mainly for interface
Expand Down Expand Up @@ -340,6 +342,21 @@ static struct dma_async_tx_descriptor *admac_prep_dma_cyclic(
return &adtx->tx;
}

/*
* Write one hardware descriptor.
*/
static void admac_write_hw_desc(struct admac_data *ad, int channo,
dma_addr_t addr, size_t len)
{
dev_dbg(ad->dev, "ch%d descriptor: addr=0x%pad len=0x%zx flags=0x%lx\n",
channo, &addr, len, FLAG_DESC_NOTIFY);

writel_relaxed(lower_32_bits(addr), ad->base + REG_DESC_WRITE(channo));
writel_relaxed(upper_32_bits(addr), ad->base + REG_DESC_WRITE(channo));
writel_relaxed(len, ad->base + REG_DESC_WRITE(channo));
writel_relaxed(FLAG_DESC_NOTIFY, ad->base + REG_DESC_WRITE(channo));
}

/*
* Write one hardware descriptor for a dmaengine cyclic transaction.
*/
Expand All @@ -356,13 +373,7 @@ static bool admac_cyclic_write_one_desc(struct admac_data *ad, int channo,
/* If happens means we have buggy code */
WARN_ON_ONCE(addr + tx->period_len > tx->buf_end);

dev_dbg(ad->dev, "ch%d descriptor: addr=0x%pad len=0x%zx flags=0x%lx\n",
channo, &addr, tx->period_len, FLAG_DESC_NOTIFY);

writel_relaxed(lower_32_bits(addr), ad->base + REG_DESC_WRITE(channo));
writel_relaxed(upper_32_bits(addr), ad->base + REG_DESC_WRITE(channo));
writel_relaxed(tx->period_len, ad->base + REG_DESC_WRITE(channo));
writel_relaxed(FLAG_DESC_NOTIFY, ad->base + REG_DESC_WRITE(channo));
admac_write_hw_desc(ad, channo, addr, tx->period_len);
/* Include a descriptor already consumed while the ring is refilled. */
tx->nperiods_outstanding++;

Expand Down Expand Up @@ -679,6 +690,73 @@ static int admac_pause(struct dma_chan *chan)
return 0;
}

static int admac_drain_reports(struct admac_data *ad, int channo);

/*
* Restart a paused cyclic capture at the next frame boundary of the current
* period. A source that stopped in the middle of a frame (a serializer that
* firmware stops whenever it likes) leaves a partial frame in the buffer, and
* without this every later frame would be off by its words. Called with the
* channel stopped and the lock held.
*/
static void admac_cyclic_realign(struct admac_chan *adchan)
{
struct admac_data *ad = adchan->host;
struct admac_tx *tx = adchan->current_tx;
int ch = adchan->no;
size_t done, aligned;
int nreports;

/* Periods completed before the pause */
nreports = admac_drain_reports(ad, ch);
tx->nperiods_outstanding -= min_t(unsigned int, nreports, tx->nperiods_outstanding);
adchan->nperiod_acks += nreports;
tx->reclaimed_pos += nreports * tx->period_len;
tx->reclaimed_pos %= 2 * tx->buf_len;

done = tx->period_len -
min_t(size_t, readl_relaxed(ad->base + REG_RESIDUE(ad, ch)), tx->period_len);
aligned = roundup(done, adchan->realign_bytes);
if (aligned >= tx->period_len) {
adchan->nperiod_acks++;
tx->reclaimed_pos += tx->period_len;
tx->reclaimed_pos %= 2 * tx->buf_len;
aligned = 0;
}
if (adchan->nperiod_acks)
tasklet_schedule(&adchan->tasklet);

dev_dbg(ad->dev, "ch%d realign: %zu bytes into the period, restart at %zu\n",
ch, done, aligned);

admac_reset_rings(adchan);
writel_relaxed(0, ad->base + REG_CHAN_CTL(ad, ch));
/* The reset dropped every descriptor still in the ring. */
tx->nperiods_outstanding = 0;

/* The rest of the current period, then whole periods as before */
tx->submitted_pos = tx->reclaimed_pos;
admac_write_hw_desc(ad, ch, tx->buf_addr + (tx->submitted_pos % tx->buf_len) + aligned,
tx->period_len - aligned);
tx->nperiods_outstanding++;
tx->submitted_pos += tx->period_len;
tx->submitted_pos %= 2 * tx->buf_len;

admac_start_chan(adchan);
admac_cyclic_write_desc(ad, ch, tx);
}

/*
* Whether a resume restarts the channel aligned (admac_cyclic_realign()): only a
* capture whose client gave a frame size, with a transfer to restart. Every
* other channel, and every playback one, starts again where it paused.
*/
static bool admac_resume_realigns(const struct admac_chan *adchan)
{
return adchan->realign_bytes && adchan->current_tx &&
admac_chan_direction(adchan->no) == DMA_DEV_TO_MEM;
}

static int admac_resume(struct dma_chan *chan)
{
struct admac_chan *adchan = to_admac_chan(chan);
Expand All @@ -688,6 +766,8 @@ static int admac_resume(struct dma_chan *chan)
spin_lock_irqsave(&adchan->lock, flags);
if (adchan->current_tx && adchan->current_tx->error)
ret = -EIO;
else if (admac_resume_realigns(adchan))
admac_cyclic_realign(adchan);
else
admac_start_chan(adchan);
spin_unlock_irqrestore(&adchan->lock, flags);
Expand Down Expand Up @@ -987,6 +1067,18 @@ static void admac_chan_tasklet(struct tasklet_struct *t)
}
}

/*
* The frame size a paused capture is restarted aligned to on resume (see
* admac_cyclic_realign()): an optional u32 in bytes in the peripheral config.
* A client that passes none, as the MCA's PCM does, gets 0: no realignment.
*/
static u32 admac_config_realign_bytes(const struct dma_slave_config *config)
{
if (config->peripheral_config && config->peripheral_size == sizeof(u32))
return *(const u32 *)config->peripheral_config;
return 0;
}

static int admac_device_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
Expand Down Expand Up @@ -1041,6 +1133,8 @@ static int admac_device_config(struct dma_chan *chan,

writel_relaxed(bus_width, ad->base + REG_BUS_WIDTH(ad, adchan->no));

adchan->realign_bytes = admac_config_realign_bytes(config);

/*
* By FIFOCTL_LIMIT we seem to set the maximal number of bytes allowed to be
* held in controller's per-channel FIFO. Transfers seem to be triggered
Expand Down
Loading
Loading