Skip to content
29 changes: 23 additions & 6 deletions Documentation/devicetree/bindings/soc/apple/apple,t6041-aop.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/soc/apple/apple,t6041-aop.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Apple T604x Always-On Processor
title: Apple T604x and T8132 Always-On Processor

maintainers:
- Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com>
Expand All @@ -16,9 +16,15 @@ description:
reaches its services through the RTKit endpoints. The firmware's external
code and log segments live in DRAM, and the bootloader reserves them.

On T8132 the bootloader also programs the AOP DART's address filter (DAPF)
and reserves its windows, which the firmware reaches through its DART at
their physical addresses.

properties:
compatible:
const: apple,t6041-aop
enum:
- apple,t6041-aop
- apple,t8132-aop

reg:
minItems: 2
Expand Down Expand Up @@ -47,11 +53,12 @@ properties:

memory-region:
minItems: 1
maxItems: 4
maxItems: 18
description:
The firmware segments in DRAM (its external code and its log), filled in
by the bootloader from the ADT. The iommu-addresses property of each
region gives the address the firmware uses for it.
The firmware segments in DRAM (its external code and its log) and, on
T8132, the DAPF windows, filled in by the bootloader from the ADT. The
iommu-addresses property of each region gives the address the firmware
uses for it.

audio:
type: object
Expand Down Expand Up @@ -93,6 +100,16 @@ required:
- mbox-names
- iommus

allOf:
- if:
properties:
compatible:
const: apple,t6041-aop
then:
properties:
memory-region:
maxItems: 4

additionalProperties: false

examples:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ properties:
- apple,j616-macaudio
- apple,j616-macaudio-jack
- apple,j700-macaudio
- apple,j713-macaudio-jack
- const: apple,macaudio

"#address-cells":
Expand Down
61 changes: 40 additions & 21 deletions Documentation/devicetree/bindings/sound/apple,t6041-aop-audio.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
$id: http://devicetree.org/schemas/sound/apple,t6041-aop-audio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Apple T6041 AOP audio
title: Apple T6041 and T8132 AOP audio

maintainers:
- Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com>

description: |
The Always-On Processor on Apple T6041 SoCs runs the machine's audio
The Always-On Processor on Apple T6041 and T8132 SoCs runs the machine's audio
streams in its firmware: the microphone array, the internal speakers with
their voltage and current sense, and the 3.5 mm headset jack in both
directions. This node is a child of the AOP node and names the ADMAC
channels the host moves each stream's data over while the firmware runs
its serializer. The parent AOP binding describes the firmware transport.

The headset jack's channels are optional: a node without them has no jack
streams.
The speaker and headset jack channels are optional: a node without them has
no speaker or jack streams.

# Only select T6041 nodes: other AOP audio nodes carry the
# apple,t6030-aop-audio fallback too and have a different set of streams.
Expand All @@ -35,27 +35,46 @@ allOf:

properties:
compatible:
items:
- const: apple,t6041-aop-audio
- const: apple,t6030-aop-audio
oneOf:
- items:
- const: apple,t6041-aop-audio
- const: apple,t6030-aop-audio
- items:
- const: apple,t8132-aop-audio
- const: apple,t6041-aop-audio
- const: apple,t6030-aop-audio

dmas:
minItems: 3
items:
- description: Microphone array input
- description: Internal speaker output
- description: Speaker voltage and current sense input
- description: Headset jack output
- description: Headset microphone input
description:
The ADMAC channels named in dma-names, in that order. "dma" is the
microphone array input, "spkr" the internal speaker output, "sense" the
speakers' voltage and current sense input, "cout" the headset jack output
and "cin" the headset microphone input.
minItems: 1
maxItems: 5

dma-names:
minItems: 3
items:
- const: dma
- const: spkr
- const: sense
- const: cout
- const: cin
oneOf:
- description: The microphones only
items:
- const: dma
- description: The microphones and the headset jack
items:
- const: dma
- const: cout
- const: cin
- description: The microphones and the speakers
items:
- const: dma
- const: spkr
- const: sense
- description: The microphones, the speakers and the headset jack
items:
- const: dma
- const: spkr
- const: sense
- const: cout
- const: cin

"#sound-dai-cells":
const: 1
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/boot/dts/apple/t8132-j713-pmgr.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@
status = "disabled";
};

/* The CS42L84 headphone codec. */
&ps_i2c1 {
status = "disabled";
status = "okay";
};

&ps_i2c2 {
Expand Down
75 changes: 75 additions & 0 deletions arch/arm64/boot/dts/apple/t8132-j713.dts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,30 @@
wifi0 = &wifi0;
};

/*
* The headphone jack: the AOP audio component's jack back-end (DAI 4)
* to the CS42L84, as a card of its own.
*/
sound_jack: sound-jack {
compatible = "apple,j713-macaudio-jack", "apple,macaudio";
model = "MacBook Air J713 Jack";
#address-cells = <1>;
#size-cells = <0>;

dai-link@0 {
reg = <0>;
link-name = "Headphone Jack";

cpu {
sound-dai = <&aop_audio 4>;
};

codec {
sound-dai = <&jack_codec>;
};
};
};

chosen {
linux-enablement-mac,disk-boot;
linux-enablement-mac,dapf-handoff = "/arm-io/aop", "/arm-io/mtp",
Expand All @@ -56,6 +80,57 @@
};
};

/*
* m1n1 programs the AOP DART's DAPF and reserves the firmware segments and
* the DAPF windows in memory-region when /chosen asks for the AOP's handoff,
* or disables the AOP.
*/
&aop {
status = "okay";
};

&aop_audio {
/* The microphones on LEAP, the jack on base-ns TX2 and RX2. */
dmas = <&admac0 1>, <&admac1 4>, <&admac1 5>;
dma-names = "dma", "cout", "cin";
apple,chassis-name = "J713";
apple,machine-kind = "MacBook Air";
};

/*
* The CS42L84 headphone codec (ADT /arm-io/i2c1/audio-codec-output at 0x4b).
* Its reset line is nub GPIO 17, driven high to run the codec; its interrupt
* is AP GPIO 98, level low. The AOP firmware runs the jack's stream.
*/
&i2c1 {
status = "okay";

jack_codec: codec@4b {
compatible = "cirrus,cs42l84";
reg = <0x4b>;
reset-gpios = <&pinctrl_nub 17 GPIO_ACTIVE_HIGH>;
#sound-dai-cells = <0>;
interrupts-extended = <&pinctrl_ap 98 IRQ_TYPE_LEVEL_LOW>;
sound-name-prefix = "Jack";
};
};

&aop_dart {
status = "okay";
};

&aop_mbox {
status = "okay";
};

&admac0 {
status = "okay";
};

&admac1 {
status = "okay";
};

/* Enable DVFS only with the J713 board thermal owner. */
&cpufreq_e {
status = "okay";
Expand Down
78 changes: 78 additions & 0 deletions arch/arm64/boot/dts/apple/t8132.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,84 @@

/* Shared controller resources; board files select the qualified devices. */
&soc {
/*
* AOP (always-on processor). iBoot loads its RTKit firmware and leaves
* it halted; Linux starts it.
*/
aop: aop@390600000 {
compatible = "apple,t8132-aop";
reg = <0x3 0x90c00000 0x0 0x1e0000>,
<0x3 0x90600000 0x0 0x88000>,
<0x3 0x90050000 0x0 0x4000>,
<0x3 0x882a8000 0x0 0x8>;
reg-names = "firmware", "asc", "asc-aux", "config";
mboxes = <&aop_mbox>;
mbox-names = "mbox";
iommus = <&aop_dart 0>;
status = "disabled";

/*
* "dma" is the microphones' LEAP ADMAC channel (ADT audio-hp);
* the speaker and jack channels follow the T6041 map.
*/
aop_audio: audio {
compatible = "apple,t8132-aop-audio", "apple,t6041-aop-audio",
"apple,t6030-aop-audio";
dmas = <&admac0 1>;
dma-names = "dma";
#sound-dai-cells = <1>;
};
};

/* ADT lists the interrupts as 1, 0, 3, 2 of the block: send-empty is the lowest. */
aop_mbox: mailbox@390608000 {
compatible = "apple,t8132-asc-mailbox", "apple,asc-mailbox-v4";
reg = <0x3 0x90608000 0x0 0x4000>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 433 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 434 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 435 IRQ_TYPE_LEVEL_HIGH>,
<AIC_IRQ 436 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "send-empty", "send-not-empty",
"recv-empty", "recv-not-empty";
#mbox-cells = <0>;
status = "disabled";
};

aop_dart: iommu@390f00000 {
compatible = "apple,t8132-dart", "apple,t8110-dart";
reg = <0x3 0x90f00000 0x0 0xc000>;
#iommu-cells = <1>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 457 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};

/* The audio fabric's ADMACs: admac-leap-ns (DART stream 10) and admac-base-ns (stream 8) */
admac0: dma-controller@393300000 {
compatible = "apple,t8132-admac";
reg = <0x3 0x93300000 0x0 0x34000>;
#dma-cells = <1>;
dma-channels = <9>;
/* the ADT gives the first of the four outputs */
interrupts-extended = <&aic AIC_IRQ 478 IRQ_TYPE_LEVEL_HIGH>,
<0>, <0>, <0>;
iommus = <&aop_dart 10>;
status = "disabled";
};

admac1: dma-controller@393800000 {
compatible = "apple,t8132-admac";
reg = <0x3 0x93800000 0x0 0x34000>;
#dma-cells = <1>;
dma-channels = <13>;
/* the ADT gives the first of the four outputs */
interrupts-extended = <&aic AIC_IRQ 475 IRQ_TYPE_LEVEL_HIGH>,
<0>, <0>, <0>;
iommus = <&aop_dart 8>;
status = "disabled";
};

nub_spmi_a0: spmi@388908000 {
status = "disabled";
compatible = "apple,t8132-spmi", "apple,t8103-spmi";
Expand Down
5 changes: 5 additions & 0 deletions drivers/soc/apple/aop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,10 @@ const HW_CFG_T6040: AopHwConfig = AopHwConfig {
fw_regions: true,
halt_on_failed_start: true,
};
/// T8132 (J713): as T6040. The bootloader hands the AOP over the same way, with
/// the DART's DAPF programmed and its windows reserved alongside the firmware
/// segments.
const HW_CFG_T8132: AopHwConfig = HW_CFG_T6040;
/// T8140: the firmware is started with the boot arguments the bootloader
/// left, boots through the setup port and speaks EPIC version 4. Of the
/// advertised AFK endpoints, the application map is 0x20 misc, 0x21
Expand Down Expand Up @@ -2547,6 +2551,7 @@ kernel::of_device_table!(
(of::DeviceId::new(c_str!("apple,t6020-aop")), &HW_CFG_T6020),
(of::DeviceId::new(c_str!("apple,t8140-aop")), &HW_CFG_T8140),
(of::DeviceId::new(c_str!("apple,t6041-aop")), &HW_CFG_T6040),
(of::DeviceId::new(c_str!("apple,t8132-aop")), &HW_CFG_T8132),
]
);

Expand Down
14 changes: 8 additions & 6 deletions sound/soc/apple/aop_audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,12 +1092,14 @@ impl platform::Driver for SndSocAopDriver {
dev_warn!(data.dev, "decimator config refused, continuing\n");
}
let mut this = Self::new(data.clone())?;
// The speaker stream, where the node has its DMA channel.
if data
.fwnode
.property_match_string(c_str!("dma-names"), c_str!("spkr"))
.is_ok()
{
// The speaker and jack streams, where the node has their DMA
// channels: a machine may have the jack before its speakers.
let listed = |name: &CStr| {
data.fwnode
.property_match_string(c_str!("dma-names"), name)
.is_ok()
};
if listed(c_str!("spkr")) || (listed(c_str!("cout")) && listed(c_str!("cin"))) {
this.spkr = Some(aop_spkr::SpeakerComponent::register(data)?);
}
return Ok(this);
Expand Down
Loading