diff --git a/devices/d10/device.toml b/devices/d10/device.toml index 82a677cf..9c773e59 100644 --- a/devices/d10/device.toml +++ b/devices/d10/device.toml @@ -39,7 +39,7 @@ backlight = "untested" touch = "missing" buttons = "untested" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "untested" diff --git a/devices/d101/device.toml b/devices/d101/device.toml index 954d19bb..45cf05f6 100644 --- a/devices/d101/device.toml +++ b/devices/d101/device.toml @@ -39,7 +39,7 @@ backlight = "untested" touch = "missing" buttons = "untested" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "untested" diff --git a/devices/d11/device.toml b/devices/d11/device.toml index 8704efc0..01540275 100644 --- a/devices/d11/device.toml +++ b/devices/d11/device.toml @@ -36,7 +36,7 @@ backlight = "untested" touch = "untested" buttons = "untested" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "untested" diff --git a/devices/d111/device.toml b/devices/d111/device.toml index 0e48e5f2..b025d023 100644 --- a/devices/d111/device.toml +++ b/devices/d111/device.toml @@ -36,7 +36,7 @@ backlight = "untested" touch = "untested" buttons = "untested" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "untested" diff --git a/devices/j171/device.toml b/devices/j171/device.toml index 347f3a42..e1283022 100644 --- a/devices/j171/device.toml +++ b/devices/j171/device.toml @@ -36,7 +36,7 @@ backlight = "working" touch = "working" buttons = "working" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "working" diff --git a/devices/j171/firmware.json b/devices/j171/firmware.json index 30cb29ae..b41cf8ac 100644 --- a/devices/j171/firmware.json +++ b/devices/j171/firmware.json @@ -63,6 +63,12 @@ "zip": "Firmware/J171_Multitouch.im4p" }, "sha256": "159f75dbbbf694a47af0fa16d00f2cbf3cf9a3dd34bfdb8da5db1d167a3e9889" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad7caop.RELEASE.im4p" + }, + "sha256": "90daa7cd85aca3eb5f2b52967a5f9781a99fa72e5631b4c87c94da3a84061cae" } }, "outputs": [ @@ -180,6 +186,34 @@ "otp_preflight": true } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad7c.bin", + "sha256": "1d475fb6ac89cd9fb5abb942825371f1e2db225301832e3aca1a93722acbf34e", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad7c-ext.bin", + "sha256": "c5f01181d31ef64b409d350d5bac502bf395ef4814c855788a0f820ff9215606", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/j172/device.toml b/devices/j172/device.toml index 0c1aa351..c3e829ef 100644 --- a/devices/j172/device.toml +++ b/devices/j172/device.toml @@ -36,7 +36,7 @@ backlight = "untested" touch = "untested" buttons = "untested" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "untested" diff --git a/devices/j172/firmware.json b/devices/j172/firmware.json index 62514533..fe6020a6 100644 --- a/devices/j172/firmware.json +++ b/devices/j172/firmware.json @@ -63,6 +63,12 @@ "zip": "Firmware/J172_Multitouch.im4p" }, "sha256": "159f75dbbbf694a47af0fa16d00f2cbf3cf9a3dd34bfdb8da5db1d167a3e9889" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad7caop.RELEASE.im4p" + }, + "sha256": "90daa7cd85aca3eb5f2b52967a5f9781a99fa72e5631b4c87c94da3a84061cae" } }, "outputs": [ @@ -180,6 +186,34 @@ "otp_preflight": true } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad7c.bin", + "sha256": "1d475fb6ac89cd9fb5abb942825371f1e2db225301832e3aca1a93722acbf34e", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad7c-ext.bin", + "sha256": "c5f01181d31ef64b409d350d5bac502bf395ef4814c855788a0f820ff9215606", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/j71b/device.toml b/devices/j71b/device.toml index f9ec58f9..9b19418a 100644 --- a/devices/j71b/device.toml +++ b/devices/j71b/device.toml @@ -33,7 +33,7 @@ backlight = "working" touch = "working" buttons = "working" # Power, Home and volume keys in daily use on the desktop. accelerometer = "working" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "working" diff --git a/devices/j71s/device.toml b/devices/j71s/device.toml index 5f19b54e..6b3368ed 100644 --- a/devices/j71s/device.toml +++ b/devices/j71s/device.toml @@ -37,8 +37,8 @@ screen_off = "untested" backlight = "untested" touch = "untested" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "missing" diff --git a/devices/j71s/firmware.json b/devices/j71s/firmware.json index cf294ee9..8e3dfd25 100644 --- a/devices/j71s/firmware.json +++ b/devices/j71s/firmware.json @@ -113,6 +113,12 @@ }, "device": "/System/Library/DriverExtensions/com.apple.DriverKit-AppleBCMWLAN.dext/Firmware/C-4355__s-C0/feara.txcb", "sha256": "f67d8e62cbc876904c87ae0cd890b15f056bf6a4856e3f4ca4bdcb5689c3543b" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad6faop.im4p" + }, + "sha256": "5a4d8378bb83e175fc589cc1cf978430639d7ffcef07b2d94e9d6a4801124efa" } }, "outputs": [ @@ -279,6 +285,34 @@ "calibration_size": 1024 } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f.bin", + "sha256": "af5d51a368ceb89dc5c359e7c84e54cb6082e308956be742c17622eb4a6047c8", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f-ext.bin", + "sha256": "2528d2686ed1262de9910c2d60e45b68137e50aa601a0f8d54ea7d1347b9de22", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/j71t/device.toml b/devices/j71t/device.toml index 35e0420b..0808d450 100644 --- a/devices/j71t/device.toml +++ b/devices/j71t/device.toml @@ -34,9 +34,9 @@ screen_off = "untested" backlight = "untested" touch = "untested" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" -light_sensor = "untested" +accelerometer = "working" +gyroscope = "working" +light_sensor = "working" touch_id = "missing" storage_read = "untested" storage_write = "untested" diff --git a/devices/j71t/firmware.json b/devices/j71t/firmware.json index 3321e246..c03fb880 100644 --- a/devices/j71t/firmware.json +++ b/devices/j71t/firmware.json @@ -113,6 +113,12 @@ }, "device": "/usr/share/firmware/multitouch/J71t.mtprops", "sha256": "69f27fe207cc5810a748dac3dfe640b1c5a755709f49513b4b5125660784f0fc" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad6faop.im4p" + }, + "sha256": "5a4d8378bb83e175fc589cc1cf978430639d7ffcef07b2d94e9d6a4801124efa" } }, "outputs": [ @@ -279,6 +285,34 @@ "calibration_size": 1024 } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f.bin", + "sha256": "af5d51a368ceb89dc5c359e7c84e54cb6082e308956be742c17622eb4a6047c8", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f-ext.bin", + "sha256": "2528d2686ed1262de9910c2d60e45b68137e50aa601a0f8d54ea7d1347b9de22", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/j72b/device.toml b/devices/j72b/device.toml index c55ec4e2..2d05d5f8 100644 --- a/devices/j72b/device.toml +++ b/devices/j72b/device.toml @@ -36,7 +36,7 @@ backlight = "untested" touch = "untested" buttons = "untested" accelerometer = "untested" -gyroscope = "missing" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "untested" diff --git a/devices/j72b/firmware.json b/devices/j72b/firmware.json index f1e0886b..ba01c117 100644 --- a/devices/j72b/firmware.json +++ b/devices/j72b/firmware.json @@ -78,6 +78,12 @@ }, "device": "/usr/share/firmware/multitouch/J72b.mtprops", "sha256": "3b48de549088ad3310516cd05ce09b53eb2a0fb4e69e24624703bc6dcfa78dfa" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad7baop.RELEASE.im4p" + }, + "sha256": "58fb27cfcd42cab4f3154fb47d92cc7d51e4329caad9b2432ec5130a2423607e" } }, "outputs": [ @@ -214,6 +220,34 @@ "hbpp_version": 260 } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad7b.bin", + "sha256": "b9db3a9601b357d469ed79c2fa6b26c8e5fb4a3953ce289687f4ab434da338f1", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad7b-ext.bin", + "sha256": "25367930b9015e5c20d20a56d959a5e3e5fa713bc3b97aeef604c0ede9e74fc1", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/j72s/device.toml b/devices/j72s/device.toml index b15dbf38..97f9de0e 100644 --- a/devices/j72s/device.toml +++ b/devices/j72s/device.toml @@ -37,8 +37,8 @@ screen_off = "untested" backlight = "untested" touch = "untested" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "missing" diff --git a/devices/j72s/firmware.json b/devices/j72s/firmware.json index 7f82d04f..b538ac2a 100644 --- a/devices/j72s/firmware.json +++ b/devices/j72s/firmware.json @@ -113,6 +113,12 @@ }, "device": "/System/Library/DriverExtensions/com.apple.DriverKit-AppleBCMWLAN.dext/Firmware/C-4355__s-C0/fearb.txcb", "sha256": "7d036b6b063bcbf2643f689dd97f9949ebce06926dc5d05e4811e0f738c3aa1f" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad6faop.im4p" + }, + "sha256": "5a4d8378bb83e175fc589cc1cf978430639d7ffcef07b2d94e9d6a4801124efa" } }, "outputs": [ @@ -279,6 +285,34 @@ "calibration_size": 1024 } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f.bin", + "sha256": "af5d51a368ceb89dc5c359e7c84e54cb6082e308956be742c17622eb4a6047c8", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f-ext.bin", + "sha256": "2528d2686ed1262de9910c2d60e45b68137e50aa601a0f8d54ea7d1347b9de22", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/j72t/device.toml b/devices/j72t/device.toml index 6fa8ad18..c30c0854 100644 --- a/devices/j72t/device.toml +++ b/devices/j72t/device.toml @@ -34,8 +34,8 @@ screen_off = "untested" backlight = "untested" touch = "untested" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "untested" touch_id = "missing" storage_read = "untested" diff --git a/devices/j72t/firmware.json b/devices/j72t/firmware.json index ccf0cb64..0d25e450 100644 --- a/devices/j72t/firmware.json +++ b/devices/j72t/firmware.json @@ -113,6 +113,12 @@ }, "device": "/usr/share/firmware/multitouch/J72t.mtprops", "sha256": "69f27fe207cc5810a748dac3dfe640b1c5a755709f49513b4b5125660784f0fc" + }, + "aop.im4p": { + "ipsw": { + "zip": "Firmware/AOP/aopfw-ipad6faop.im4p" + }, + "sha256": "5a4d8378bb83e175fc589cc1cf978430639d7ffcef07b2d94e9d6a4801124efa" } }, "outputs": [ @@ -279,6 +285,34 @@ "calibration_size": 1024 } ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f.bin", + "sha256": "af5d51a368ceb89dc5c359e7c84e54cb6082e308956be742c17622eb4a6047c8", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP" + } + ] + }, + { + "destination": "lib/firmware/apple/aop-ipad6f-ext.bin", + "sha256": "2528d2686ed1262de9910c2d60e45b68137e50aa601a0f8d54ea7d1347b9de22", + "steps": [ + { + "step": "im4p-payload@1", + "input": "aop.im4p" + }, + { + "step": "aop-image@1", + "coprocessor": "AOP_ext" + } + ] } ] } diff --git a/devices/n66/device.toml b/devices/n66/device.toml index d2400599..52c91ccf 100644 --- a/devices/n66/device.toml +++ b/devices/n66/device.toml @@ -35,8 +35,8 @@ screen_off = "missing" backlight = "untested" touch = "missing" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "missing" diff --git a/devices/n66m/device.toml b/devices/n66m/device.toml index aa306b0d..53e3a7e5 100644 --- a/devices/n66m/device.toml +++ b/devices/n66m/device.toml @@ -35,8 +35,8 @@ screen_off = "missing" backlight = "untested" touch = "missing" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "missing" diff --git a/devices/n69/device.toml b/devices/n69/device.toml index 8c13faf9..0ff2e9e2 100644 --- a/devices/n69/device.toml +++ b/devices/n69/device.toml @@ -35,8 +35,8 @@ screen_off = "missing" backlight = "untested" touch = "missing" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "missing" diff --git a/devices/n69u/device.toml b/devices/n69u/device.toml index 2984e963..64859dbd 100644 --- a/devices/n69u/device.toml +++ b/devices/n69u/device.toml @@ -35,8 +35,8 @@ screen_off = "missing" backlight = "untested" touch = "missing" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "missing" diff --git a/devices/n71/device.toml b/devices/n71/device.toml index 0a541db0..b1e8ce21 100644 --- a/devices/n71/device.toml +++ b/devices/n71/device.toml @@ -35,8 +35,8 @@ screen_off = "missing" backlight = "untested" touch = "missing" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "missing" diff --git a/devices/n71m/device.toml b/devices/n71m/device.toml index 120c4ffe..1113bd86 100644 --- a/devices/n71m/device.toml +++ b/devices/n71m/device.toml @@ -35,8 +35,8 @@ screen_off = "missing" backlight = "untested" touch = "missing" buttons = "untested" -accelerometer = "missing" -gyroscope = "missing" +accelerometer = "untested" +gyroscope = "untested" light_sensor = "missing" touch_id = "missing" storage_read = "missing" diff --git a/docs/compatibility.md b/docs/compatibility.md index 9e53f9ac..bf0215ea 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -156,28 +156,28 @@ Boards Orchard builds for. States: working, untested, missing, none (no such har | `n61` | working | untested | untested | working | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | missing | missing | untested | untested | working | untested | missing | missing | missing | missing | | `j81` | working | untested | working | working | working | missing | missing | missing | missing | missing | missing | working | untested | untested | none | working | missing | missing | untested | untested | working | working | missing | missing | missing | missing | | `j82` | untested | untested | untested | untested | untested | missing | missing | missing | missing | missing | missing | untested | untested | untested | missing | untested | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `j71s` | untested | untested | untested | untested | untested | missing | missing | untested | missing | missing | missing | missing | untested | untested | none | untested | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | -| `j72s` | untested | untested | untested | untested | untested | missing | missing | untested | missing | missing | missing | missing | untested | untested | missing | untested | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | -| `n66` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `n69u` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `n71` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `j71t` | untested | untested | untested | untested | untested | missing | missing | untested | missing | untested | untested | untested | untested | untested | none | untested | untested | untested | untested | untested | working | working | working | untested | missing | working | -| `j72t` | untested | untested | untested | untested | untested | missing | missing | untested | missing | untested | untested | untested | untested | untested | missing | untested | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | -| `n66m` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `n69` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `n71m` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `j71s` | untested | untested | untested | untested | untested | untested | untested | untested | missing | missing | missing | missing | untested | untested | none | untested | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | +| `j72s` | untested | untested | untested | untested | untested | untested | untested | untested | missing | missing | missing | missing | untested | untested | missing | untested | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | +| `n66` | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `n69u` | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `n71` | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `j71t` | untested | untested | untested | untested | untested | working | working | working | missing | untested | untested | untested | untested | untested | none | untested | untested | untested | untested | untested | working | working | working | untested | missing | working | +| `j72t` | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | untested | untested | untested | untested | missing | untested | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | +| `n66m` | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `n69` | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `n71m` | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | | `j127` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | | `j128` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | | `j98a` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | | `j99a` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `d10` | untested | untested | untested | missing | untested | untested | missing | missing | missing | untested | untested | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `d101` | untested | untested | untested | missing | untested | untested | missing | missing | missing | untested | untested | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `d11` | untested | untested | untested | untested | untested | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | untested | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `d111` | untested | untested | untested | untested | untested | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | untested | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | -| `j171` | working | untested | working | working | working | untested | missing | untested | missing | working | working | working | missing | missing | none | working | untested | missing | untested | untested | untested | untested | working | missing | missing | untested | -| `j172` | untested | untested | untested | untested | untested | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | untested | untested | missing | untested | untested | untested | untested | untested | missing | missing | untested | -| `j71b` | working | working | working | working | working | working | missing | untested | missing | working | working | working | working | working | none | working | working | working | working | working | working | working | working | missing | missing | untested | -| `j72b` | untested | untested | untested | untested | untested | untested | missing | untested | missing | untested | untested | untested | missing | missing | missing | untested | untested | untested | untested | untested | untested | untested | untested | missing | missing | untested | +| `d10` | untested | untested | untested | missing | untested | untested | untested | missing | missing | untested | untested | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `d101` | untested | untested | untested | missing | untested | untested | untested | missing | missing | untested | untested | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `d11` | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | untested | untested | missing | missing | missing | untested | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `d111` | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | untested | untested | missing | missing | missing | untested | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | +| `j171` | working | untested | working | working | working | untested | untested | untested | missing | working | working | working | missing | missing | none | working | untested | missing | untested | untested | untested | untested | working | missing | missing | untested | +| `j172` | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | untested | untested | missing | missing | missing | untested | untested | missing | untested | untested | untested | untested | untested | missing | missing | untested | +| `j71b` | working | working | working | working | working | working | untested | untested | missing | working | working | working | working | working | none | working | working | working | working | working | working | working | working | missing | missing | untested | +| `j72b` | untested | untested | untested | untested | untested | untested | untested | untested | missing | untested | untested | untested | missing | missing | missing | untested | untested | untested | untested | untested | untested | untested | untested | missing | missing | untested | | `j120` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | | `j121` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | | `j207` | untested | missing | untested | missing | untested | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | missing | untested | untested | untested | untested | missing | missing | missing | missing | @@ -193,56 +193,56 @@ Boards Orchard builds for. States: working, untested, missing, none (no such har A yes means an enabled device tree node binds a driver in `7.3.0-rc1-orchard-apple-16k`, `7.3.0-rc1-orchard-apple-4k`. It does not mean the feature works. Read by `tools/catalog/generate kernel`. -| Board | Status | Backlight | Touchscreen | Buttons | Accelerometer | Light sensor | Internal storage read | Internal storage write | Wi-Fi | Bluetooth input devices | Bluetooth audio | Battery status | Charging | USB serial | USB network | Speakers | Hardware H.265 video decoding | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| `j71` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j73` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j85` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j85m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j86` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j86m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j87` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j87m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `n51` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `n53` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j96` | experimental | yes | yes | yes | – | – | – | – | yes | – | – | yes | – | yes | yes | – | – | -| `j97` | experimental | yes | yes | yes | – | – | – | – | yes | – | – | yes | – | yes | yes | – | – | -| `n56` | experimental | yes | – | yes | – | – | – | – | – | – | – | yes | – | yes | yes | – | – | -| `n61` | experimental | yes | yes | yes | – | – | – | – | – | – | – | yes | – | yes | yes | – | – | -| `j81` | experimental | yes | yes | yes | – | – | – | – | yes | yes | yes | yes | – | yes | yes | – | – | -| `j82` | experimental | yes | yes | yes | – | – | – | – | yes | yes | yes | yes | – | yes | yes | – | – | -| `j71s` | experimental | yes | yes | yes | – | yes | – | – | – | yes | yes | yes | yes | yes | yes | yes | yes | -| `j72s` | experimental | yes | yes | yes | – | yes | – | – | – | yes | yes | yes | yes | yes | yes | yes | yes | -| `n66` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `n69u` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `n71` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j71t` | experimental | yes | yes | yes | – | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | -| `j72t` | experimental | yes | yes | yes | – | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | -| `n66m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `n69` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `n71m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j127` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j128` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j98a` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j99a` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `d10` | experimental | yes | – | yes | yes | – | yes | yes | – | yes | yes | – | – | yes | yes | – | – | -| `d101` | experimental | yes | – | yes | yes | – | yes | yes | – | yes | yes | – | – | yes | yes | – | – | -| `d11` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | – | yes | yes | – | – | -| `d111` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | – | yes | yes | – | – | -| `j171` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | -| `j172` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | -| `j71b` | supported | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | -| `j72b` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | -| `j120` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j121` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j207` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `j208` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | yes | yes | – | – | -| `d20` | experimental | yes | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | -| `d201` | experimental | yes | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | -| `d21` | experimental | yes | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | -| `d211` | experimental | yes | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | -| `d22` | experimental | yes | yes | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | -| `d221` | experimental | yes | yes | – | – | – | yes | yes | yes | – | – | yes | – | yes | yes | – | – | +| Board | Status | Backlight | Touchscreen | Buttons | Accelerometer | Gyroscope | Light sensor | Internal storage read | Internal storage write | Wi-Fi | Bluetooth input devices | Bluetooth audio | Battery status | Charging | USB serial | USB network | Speakers | Hardware H.265 video decoding | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| `j71` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j73` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j85` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j85m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j86` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j86m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j87` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j87m` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `n51` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `n53` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j96` | experimental | yes | yes | yes | – | – | – | – | – | yes | – | – | yes | – | yes | yes | – | – | +| `j97` | experimental | yes | yes | yes | – | – | – | – | – | yes | – | – | yes | – | yes | yes | – | – | +| `n56` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | yes | – | yes | yes | – | – | +| `n61` | experimental | yes | yes | yes | – | – | – | – | – | – | – | – | yes | – | yes | yes | – | – | +| `j81` | experimental | yes | yes | yes | – | – | – | – | – | yes | yes | yes | yes | – | yes | yes | – | – | +| `j82` | experimental | yes | yes | yes | – | – | – | – | – | yes | yes | yes | yes | – | yes | yes | – | – | +| `j71s` | experimental | yes | yes | yes | yes | yes | yes | – | – | – | yes | yes | yes | yes | yes | yes | yes | yes | +| `j72s` | experimental | yes | yes | yes | yes | yes | yes | – | – | – | yes | yes | yes | yes | yes | yes | yes | yes | +| `n66` | experimental | yes | – | yes | yes | yes | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `n69u` | experimental | yes | – | yes | yes | yes | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `n71` | experimental | yes | – | yes | yes | yes | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j71t` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | +| `j72t` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | +| `n66m` | experimental | yes | – | yes | yes | yes | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `n69` | experimental | yes | – | yes | yes | yes | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `n71m` | experimental | yes | – | yes | yes | yes | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j127` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j128` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j98a` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j99a` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `d10` | experimental | yes | – | yes | yes | yes | – | yes | yes | – | yes | yes | – | – | yes | yes | – | – | +| `d101` | experimental | yes | – | yes | yes | yes | – | yes | yes | – | yes | yes | – | – | yes | yes | – | – | +| `d11` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | – | yes | yes | – | – | +| `d111` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | – | yes | yes | – | – | +| `j171` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | +| `j172` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | +| `j71b` | supported | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | +| `j72b` | experimental | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | +| `j120` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j121` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j207` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `j208` | experimental | yes | – | yes | – | – | – | – | – | – | – | – | – | – | yes | yes | – | – | +| `d20` | experimental | yes | – | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | +| `d201` | experimental | yes | – | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | +| `d21` | experimental | yes | – | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | +| `d211` | experimental | yes | – | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | +| `d22` | experimental | yes | yes | – | – | – | – | yes | yes | – | – | – | yes | – | yes | yes | – | – | +| `d221` | experimental | yes | yes | – | – | – | – | yes | yes | yes | – | – | yes | – | yes | yes | – | – | ### Where feature states and drivers disagree diff --git a/kernel/configs/apple-16k/config b/kernel/configs/apple-16k/config index 117dc426..f11529b5 100644 --- a/kernel/configs/apple-16k/config +++ b/kernel/configs/apple-16k/config @@ -5624,6 +5624,7 @@ CONFIG_APPLE_AOP_ACCEL=m # CONFIG_ADIS16260 is not set # CONFIG_ADXRS290 is not set # CONFIG_ADXRS450 is not set +CONFIG_APPLE_AOP_GYRO=m # CONFIG_BMG160 is not set # CONFIG_FXAS21002C is not set # CONFIG_MPU3050_I2C is not set @@ -5859,6 +5860,7 @@ CONFIG_TSL2583=m # CONFIG_HP206C is not set # CONFIG_ZPA2326 is not set # CONFIG_ADP810 is not set +CONFIG_APPLE_AOP_PRESSURE=m # end of Pressure sensors # diff --git a/kernel/patches/devices/s8000/0009-arm64-dts-apple-s800-0-3-Add-the-Always-On-Processor.patch b/kernel/patches/devices/s8000/0009-arm64-dts-apple-s800-0-3-Add-the-Always-On-Processor.patch new file mode 100644 index 00000000..f480da01 --- /dev/null +++ b/kernel/patches/devices/s8000/0009-arm64-dts-apple-s800-0-3-Add-the-Always-On-Processor.patch @@ -0,0 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] arm64: dts: apple: s800-0-3: Add the Always-On Processor + +Describe the A9's always-on processor and its A7 IOP mailbox, with the +accelerometer, gyroscope and pressure sensor that its firmware serves. +The register blocks and interrupts are the ones Apple's device tree +lists for /arm-io/aop; the SRAM is described up to the window the AOP +is given onto it. Boards enable the AOP together with their firmware. + +The bootloader finds the node through the aop alias to fill in the +ECID, the boot argument values and the sensors' factory calibration. + +[Orchard: from orchard PR #101, commit a54e2049; the SoC part of + devices/s8000/0007, unchanged] + +Assisted-by: LLM +--- + .../arm64/boot/dts/apple/s800-0-3-common.dtsi | 1 + + arch/arm64/boot/dts/apple/s800-0-3.dtsi | 37 +++++++++++++++++++ + 2 files changed, 38 insertions(+) + +diff --git a/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi b/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi +index 354533f..338182c 100644 +--- a/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi ++++ b/arch/arm64/boot/dts/apple/s800-0-3-common.dtsi +@@ -11,6 +11,7 @@ + + / { + aliases { ++ aop = &aop; /* Used by loader */ + ausbphy0 = &ausbphy0; + nvme-hmb = &nvme_hmb; /* Used by loader */ + serial0 = &serial0; +diff --git a/arch/arm64/boot/dts/apple/s800-0-3.dtsi b/arch/arm64/boot/dts/apple/s800-0-3.dtsi +index 779118f..8973c43 100644 +--- a/arch/arm64/boot/dts/apple/s800-0-3.dtsi ++++ b/arch/arm64/boot/dts/apple/s800-0-3.dtsi +@@ -421,6 +421,43 @@ + interrupt-parent = <&aic>; + interrupts = ; + }; ++ ++ aop: aop@210800000 { ++ compatible = "apple,s8000-aop"; ++ reg = <0x2 0x10800000 0x0 0x4000>, ++ <0x2 0x10000600 0x0 0x4>, ++ <0x2 0x10e00000 0x0 0x9b000>; ++ reg-names = "akf", "control", "sram"; ++ mboxes = <&aop_mbox>; ++ mbox-names = "mbox"; ++ status = "disabled"; ++ ++ aop_accel: accel { ++ compatible = "apple,s8000-aop-accel"; ++ }; ++ ++ aop_gyro: gyro { ++ compatible = "apple,s8000-aop-gyro"; ++ }; ++ ++ aop_pressure: pressure { ++ compatible = "apple,s8000-aop-pressure"; ++ }; ++ }; ++ ++ aop_mbox: mbox@210804000 { ++ compatible = "apple,s8000-a7iop-mailbox", "apple,t8010-a7iop-mailbox"; ++ reg = <0x2 0x10804000 0x0 0x1000>; ++ interrupt-parent = <&aic>; ++ interrupts = , ++ , ++ , ++ ; ++ interrupt-names = "send-empty", "send-not-empty", ++ "recv-empty", "recv-not-empty"; ++ #mbox-cells = <0>; ++ status = "disabled"; ++ }; + }; + + timer { +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/devices/s8000/0010-arm64-dts-apple-ipad5-Enable-the-AOP-sensors.patch b/kernel/patches/devices/s8000/0010-arm64-dts-apple-ipad5-Enable-the-AOP-sensors.patch new file mode 100644 index 00000000..ce6d467e --- /dev/null +++ b/kernel/patches/devices/s8000/0010-arm64-dts-apple-ipad5-Enable-the-AOP-sensors.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] arm64: dts: apple: ipad5: Enable the AOP sensors + +Enable the always-on processor and its mailbox on the iPad 5 with its +AOP firmware, which brings up the accelerometer, gyroscope and pressure +sensor. Apple's BuildManifest gives every iPad 5 model (J71s, J71t, +J72s, J72t) the same AOP firmware, aopfw-ipad6faop, so this goes in the +shared iPad 5 file. + +The A9's AOP firmware reports the accelerometer in its sensor frame: +the device frame negated, so that flat, screen up reads z = -1 g and +upright y = -1 g. Give the accelerometer the mount-matrix that maps it +for desktops in the shared iPad 5 file, so every iPad 5 model has it +once its AOP firmware is known. + +[Orchard: from orchard PR #101, commit a54e2049; the J71t part of + devices/s8000/0007 without the reserved shutdown page and the + apple,certified-reload, memory-region, apple,observe-domains and + apple,spi0-domain properties; the AOP enable and the mount-matrix moved + from the J71t board file to the shared iPad 5 file] + +Assisted-by: LLM +--- + arch/arm64/boot/dts/apple/s800x-ipad5.dtsi | 12 ++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi +index fc06d53..8015872 100644 +--- a/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi ++++ b/arch/arm64/boot/dts/apple/s800x-ipad5.dtsi +@@ -139,6 +139,28 @@ + }; + }; + ++/* All iPad 5 models use the same AOP firmware (ipad6faop). */ ++&aop { ++ firmware-name = "apple/aop-ipad6f.bin", "apple/aop-ipad6f-ext.bin"; ++ status = "okay"; ++}; ++ ++&aop_mbox { ++ status = "okay"; ++}; ++ ++/* ++ * The AOP reports the accelerometer in its sensor frame, which is the ++ * device frame (x right, y up, z out of the screen) negated: flat, screen up ++ * reads z = -1 g, upright y = -1 g. iio-sensor-proxy takes upright as ++ * negative y and needs z flipped. ++ */ ++&aop_accel { ++ mount-matrix = "1", "0", "0", ++ "0", "1", "0", ++ "0", "0", "-1"; ++}; ++ + &framebuffer0 { + power-domains = <&ps_disp0 &ps_dp>; + }; +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/devices/t8010/0024-arm64-dts-apple-ipad6-ipad7-Enable-the-AOP-sensors-on-every-model.patch b/kernel/patches/devices/t8010/0024-arm64-dts-apple-ipad6-ipad7-Enable-the-AOP-sensors-on-every-model.patch new file mode 100644 index 00000000..ba2c83d1 --- /dev/null +++ b/kernel/patches/devices/t8010/0024-arm64-dts-apple-ipad6-ipad7-Enable-the-AOP-sensors-on-every-model.patch @@ -0,0 +1,97 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Henrik Klee +Date: Fri, 13 Nov 2026 06:10:00 +0800 +Subject: [PATCH] arm64: dts: apple: ipad6, ipad7: Enable the AOP sensors on + every model + +Only the J71b enabled its always-on processor. Apple's BuildManifests +give both iPad 6 models (J71b, J72b) the AOP firmware aopfw-ipad7baop +and both iPad 7 models (J171, J172) aopfw-ipad7caop. Move the J71b's +AOP enable and accelerometer mount-matrix to the shared iPad 6 file and +name the iPad 7 firmware in the iPad 7 file, so all four get the +accelerometer, gyroscope and pressure sensor. Untested on J72b, J171 +and J172; the iPad 7 inherits the iPad 6 mount-matrix. + +Assisted-by: LLM +--- +diff --git a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi +index ed59564..fe76af1 100644 +--- a/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi ++++ b/arch/arm64/boot/dts/apple/t8010-ipad6.dtsi +@@ -249,6 +249,27 @@ + }; + }; + ++/* The iPad 6 models (J71b, J72b) use the same AOP firmware (ipad7baop). */ ++&aop { ++ firmware-name = "apple/aop-ipad7b.bin", "apple/aop-ipad7b-ext.bin"; ++ status = "okay"; ++}; ++ ++&aop_mbox { ++ status = "okay"; ++}; ++ ++/* ++ * The AOP reports the accelerometer in the device frame with y up when the ++ * iPad is upright; desktops (iio-sensor-proxy) take upright as y down and ++ * left/right accordingly, with z unchanged. ++ */ ++&aop_accel { ++ mount-matrix = "-1", "0", "0", ++ "0", "-1", "0", ++ "0", "0", "1"; ++}; ++ + &i2s_switch { + status = "okay"; + }; +diff --git a/arch/arm64/boot/dts/apple/t8010-ipad7.dtsi b/arch/arm64/boot/dts/apple/t8010-ipad7.dtsi +index 9a6899d..f493f50 100644 +--- a/arch/arm64/boot/dts/apple/t8010-ipad7.dtsi ++++ b/arch/arm64/boot/dts/apple/t8010-ipad7.dtsi +@@ -13,6 +13,11 @@ + */ + #include "t8010-ipad6.dtsi" + ++/* The iPad 7 has its own AOP firmware (ipad7caop). */ ++&aop { ++ firmware-name = "apple/aop-ipad7c.bin", "apple/aop-ipad7c-ext.bin"; ++}; ++ + /* The iPad 7 port controller is Bellatrix, with its own charger policy. */ + /delete-node/ &tristar_charger; + /delete-node/ &tristar; +diff --git a/arch/arm64/boot/dts/apple/t8010-j71b.dts b/arch/arm64/boot/dts/apple/t8010-j71b.dts +index f667e67..e6b9a30 100644 +--- a/arch/arm64/boot/dts/apple/t8010-j71b.dts ++++ b/arch/arm64/boot/dts/apple/t8010-j71b.dts +@@ -21,26 +21,6 @@ + brcm,board-type = "apple,j71b"; + }; + +-&aop { +- firmware-name = "apple/aop-ipad7b.bin", "apple/aop-ipad7b-ext.bin"; +- status = "okay"; +-}; +- +-&aop_mbox { +- status = "okay"; +-}; +- +-/* +- * The AOP reports the accelerometer in the device frame with y up when the +- * iPad is upright; desktops (iio-sensor-proxy) take upright as y down and +- * left/right accordingly, with z unchanged. +- */ +-&aop_accel { +- mount-matrix = "-1", "0", "0", +- "0", "-1", "0", +- "0", "0", "1"; +-}; +- + &touchscreen { + firmware-name = "apple/j71b-fwstart.z2fw"; + }; +-- +2.54.0 diff --git a/kernel/patches/drivers/iio/0005-iio-accel-apple_aop_accel-Support-the-S8000.patch b/kernel/patches/drivers/iio/0005-iio-accel-apple_aop_accel-Support-the-S8000.patch new file mode 100644 index 00000000..967a9063 --- /dev/null +++ b/kernel/patches/drivers/iio/0005-iio-accel-apple_aop_accel-Support-the-S8000.patch @@ -0,0 +1,174 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] iio: accel: apple_aop_accel: Support the S8000 + +The A9's AOP firmware serves the accelerometer like the A10's, with two +differences. It sends no motion reports until it has the unit's factory +calibration and has been told that the calibration is complete, and it +has no separate raw sample stream, so its raw interval has to be 0. + +Send the calibration blobs that the bootloader copies from the Apple +device tree into the sensor's node: the offset at low temperature, the +sensitivity (either of two forms) and the interrupt calibration. Select +the calibration table and the raw interval through match data, so that +the T8010 keeps its current behaviour. The S8000's firmware reports in +the sensor's frame, which the board's mount-matrix maps. + +Set the report properties through the AOP driver's +apple_aop_set_property() instead of a private copy of the request. + +[Orchard: from orchard PR #101, commit a54e2049; the accelerometer part + of drivers/iio/0005 without the warm-reload code, and the private + set-property request replaced by apple_aop_set_property()] + +Assisted-by: LLM +--- + drivers/iio/accel/Kconfig | 2 +- + drivers/iio/accel/apple_aop_accel.c | 59 +++++++++++++++++++++++------ + 2 files changed, 49 insertions(+), 12 deletions(-) + +diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig +index b015981..ed328a5 100644 +--- a/drivers/iio/accel/Kconfig ++++ b/drivers/iio/accel/Kconfig +@@ -213,7 +213,7 @@ config APPLE_AOP_ACCEL + select IIO_KFIFO_BUF + help + Say yes here to get support for the accelerometer that the Always-On +- Processor (AOP) of Apple A10 iPads and iPhones serves. ++ Processor (AOP) of Apple A9 and A10 iPads and iPhones serves. + + To compile this driver as a module, choose M here: the module will be + called apple_aop_accel. +diff --git a/drivers/iio/accel/apple_aop_accel.c b/drivers/iio/accel/apple_aop_accel.c +index 96c9013..f310af6 100644 +--- a/drivers/iio/accel/apple_aop_accel.c ++++ b/drivers/iio/accel/apple_aop_accel.c +@@ -9,9 +9,13 @@ + * + * 0 u32 sequence + * 4 u16 reserved +- * 6 s32 x, y, z in 1/65536 g, in the device frame (x right, y up, +- * z out of the screen; +1 g opposite to gravity) ++ * 6 s32 x, y, z in 1/65536 g + * 18 u32 timestamp ++ * ++ * The T8010's firmware reports in the device frame (x right, y up, z out of ++ * the screen; +1 g opposite to gravity). The S8000's firmware first needs the ++ * unit's factory calibration and reports in the sensor's frame; the board's ++ * mount-matrix maps it. + */ + + #include +@@ -21,11 +25,11 @@ + #include + #include + #include ++#include + #include + #include + #include + +-#define AOP_SET_PROPERTY 0x4 + #define AOP_PROP_REPORT_INTERVAL 0x00 + #define AOP_PROP_BATCH_INTERVAL 0x16 + #define AOP_PROP_RAW_INTERVAL 0x5c +@@ -41,8 +45,16 @@ + /* 9.80665 m/s^2 / 65536 */ + #define AOP_ACCEL_SCALE_NANO 149637 + ++struct apple_aop_accel_hw { ++ const struct apple_aop_calibration *calibration; ++ unsigned int num_calibration; ++ /* No separate raw sample stream (raw interval 0) */ ++ bool no_raw_stream; ++}; ++ + struct apple_aop_accel { + struct device *dev; ++ const struct apple_aop_accel_hw *hw; + const struct apple_aop_service *service; + struct iio_mount_matrix orientation; + +@@ -58,13 +70,9 @@ struct apple_aop_accel { + + static int apple_aop_accel_set_property(struct apple_aop_accel *accel, u32 tag, u32 value) + { +- __le32 buf[3] = { 0, cpu_to_le32(tag), cpu_to_le32(value) }; +- int ret; ++ __le32 le = cpu_to_le32(value); + +- ret = apple_aop_call(accel->service, AOP_SET_PROPERTY, buf, sizeof(buf), NULL, 0); +- if (ret > 0) +- ret = -EIO; +- return ret; ++ return apple_aop_set_property(accel->service, tag, &le, sizeof(le)); + } + + static int apple_aop_accel_set_interval(struct apple_aop_accel *accel, u32 interval_us) +@@ -75,7 +83,9 @@ static int apple_aop_accel_set_interval(struct apple_aop_accel *accel, u32 inter + int i, ret; + + for (i = 0; i < ARRAY_SIZE(tags); i++) { +- ret = apple_aop_accel_set_property(accel, tags[i], interval_us); ++ ret = apple_aop_accel_set_property(accel, tags[i], ++ tags[i] == AOP_PROP_RAW_INTERVAL && ++ accel->hw->no_raw_stream ? 0 : interval_us); + if (ret) + return ret; + } +@@ -230,6 +240,7 @@ static int apple_aop_accel_probe(struct platform_device *pdev) + return -ENOMEM; + accel = iio_priv(indio_dev); + accel->dev = dev; ++ accel->hw = device_get_match_data(dev); + accel->service = service; + mutex_init(&accel->lock); + spin_lock_init(&accel->sample_lock); +@@ -252,6 +263,15 @@ static int apple_aop_accel_probe(struct platform_device *pdev) + if (ret) + return ret; + ++ if (accel->hw->num_calibration) { ++ ret = apple_aop_calibrate(service, dev, accel->hw->calibration, ++ accel->hw->num_calibration); ++ if (ret) { ++ apple_aop_unlisten(service); ++ return dev_err_probe(dev, ret, "failed to calibrate\n"); ++ } ++ } ++ + ret = apple_aop_accel_set_interval(accel, AOP_ACCEL_DEFAULT_US); + if (ret) { + apple_aop_unlisten(service); +@@ -265,8 +285,25 @@ static int apple_aop_accel_probe(struct platform_device *pdev) + return devm_iio_device_register(dev, indio_dev); + } + ++/* Offset at low temperature, sensitivity (either), interrupt calibration */ ++static const struct apple_aop_calibration apple_aop_accel_s8000_calibration[] = { ++ { "apple,low-temp-accel-offset", 0x1a, 1 }, ++ { "apple,accel-sensitivity-calibration", 0x0b, 2 }, ++ { "apple,accel-range-sensitivity-cal", 0x27, 2 }, ++ { "apple,accel-interrupt-calibration", 0x19, 3 }, ++}; ++ ++static const struct apple_aop_accel_hw apple_aop_accel_s8000 = { ++ .calibration = apple_aop_accel_s8000_calibration, ++ .num_calibration = ARRAY_SIZE(apple_aop_accel_s8000_calibration), ++ .no_raw_stream = true, ++}; ++ ++static const struct apple_aop_accel_hw apple_aop_accel_t8010 = { }; ++ + static const struct of_device_id apple_aop_accel_of_match[] = { +- { .compatible = "apple,t8010-aop-accel" }, ++ { .compatible = "apple,s8000-aop-accel", .data = &apple_aop_accel_s8000 }, ++ { .compatible = "apple,t8010-aop-accel", .data = &apple_aop_accel_t8010 }, + { } + }; + MODULE_DEVICE_TABLE(of, apple_aop_accel_of_match); +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/iio/0006-iio-gyro-Add-the-Apple-AOP-gyroscope.patch b/kernel/patches/drivers/iio/0006-iio-gyro-Add-the-Apple-AOP-gyroscope.patch new file mode 100644 index 00000000..7918d66f --- /dev/null +++ b/kernel/patches/drivers/iio/0006-iio-gyro-Add-the-Apple-AOP-gyroscope.patch @@ -0,0 +1,365 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] iio: gyro: Add the Apple AOP gyroscope + +The Always-On Processor of Apple A9 devices samples the gyroscope and, +once it has the unit's factory calibration and its batch, raw and +report intervals (EPIC set-property tags 0x16, 0x5c and 0), sends one +motion report (EPIC subtype 0xc1) per report interval. The report is +laid out like the accelerometer's and carries x, y and z in 1/65536 +degree per second. + +Expose them as an IIO angular velocity sensor: raw values, scale in +rad/s, sampling frequency (the report interval), a software buffer +with timestamps and the standard mount-matrix. The calibration is +complete once the sensitivity and the interrupt calibration are +applied; the range sensitivity and trim calibration are sent when the +bootloader provides them. + +[Orchard: from orchard PR #101, commit a54e2049; the gyroscope part of + drivers/iio/0005, unchanged] + +Assisted-by: LLM +--- + drivers/iio/gyro/Kconfig | 12 ++ + drivers/iio/gyro/Makefile | 1 + + drivers/iio/gyro/apple_aop_gyro.c | 291 ++++++++++++++++++++++++++++++ + 3 files changed, 304 insertions(+) + create mode 100644 drivers/iio/gyro/apple_aop_gyro.c + +diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig +index 3e193ee..8f506a6 100644 +--- a/drivers/iio/gyro/Kconfig ++++ b/drivers/iio/gyro/Kconfig +@@ -63,6 +63,18 @@ config ADXRS450 + This driver can also be built as a module. If so, the module + will be called adxrs450. + ++config APPLE_AOP_GYRO ++ tristate "Apple AOP gyroscope" ++ depends on APPLE_AOP_T8010 ++ select IIO_BUFFER ++ select IIO_KFIFO_BUF ++ help ++ Say yes here to get support for the gyroscope that the Always-On ++ Processor (AOP) of Apple A9 iPads and iPhones serves. ++ ++ To compile this driver as a module, choose M here: the module will be ++ called apple_aop_gyro. ++ + config BMG160 + tristate "BOSCH BMG160 Gyro Sensor" + depends on (I2C || SPI_MASTER) +diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile +index 0319b39..212bbb8 100644 +--- a/drivers/iio/gyro/Makefile ++++ b/drivers/iio/gyro/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_ADIS16136) += adis16136.o + obj-$(CONFIG_ADIS16260) += adis16260.o + obj-$(CONFIG_ADXRS290) += adxrs290.o + obj-$(CONFIG_ADXRS450) += adxrs450.o ++obj-$(CONFIG_APPLE_AOP_GYRO) += apple_aop_gyro.o + obj-$(CONFIG_BMG160) += bmg160_core.o + obj-$(CONFIG_BMG160_I2C) += bmg160_i2c.o + obj-$(CONFIG_BMG160_SPI) += bmg160_spi.o +diff --git a/drivers/iio/gyro/apple_aop_gyro.c b/drivers/iio/gyro/apple_aop_gyro.c +new file mode 100644 +index 0000000..edbda1f +--- /dev/null ++++ b/drivers/iio/gyro/apple_aop_gyro.c +@@ -0,0 +1,291 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR MIT ++/* ++ * Gyroscope served by the Apple Always-On Processor (AOP) ++ * ++ * The AOP firmware samples the gyroscope itself. Once it has the unit's ++ * factory calibration and its batch, raw and report intervals (EPIC ++ * set-property tags 0x16, 0x5c and 0), it sends one motion report (EPIC ++ * subtype 0xc1) per report interval, laid out like the accelerometer's: ++ * ++ * 0 u16 sequence ++ * 2 u32 status ++ * 6 s32 x, y, z in 1/65536 degree per second ++ * 18 s32 temperature (unit unknown, not exported) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define AOP_PROP_REPORT_INTERVAL 0x00 ++#define AOP_PROP_BATCH_INTERVAL 0x16 ++#define AOP_PROP_RAW_INTERVAL 0x5c ++ ++#define AOP_REPORT_GYRO 0xc1 ++#define AOP_GYRO_LEN 22 ++#define AOP_GYRO_XYZ 6 ++ ++#define AOP_GYRO_DEFAULT_US 100000 /* 10 Hz */ ++#define AOP_GYRO_MIN_US 10000 /* 100 Hz */ ++#define AOP_GYRO_MAX_US 1000000 /* 1 Hz */ ++ ++/* pi / 180 rad/s / 65536 = 1171270 / 2^42 rad/s */ ++#define AOP_GYRO_SCALE 1171270 ++#define AOP_GYRO_SCALE_LOG2 42 ++ ++struct apple_aop_gyro { ++ struct device *dev; ++ const struct apple_aop_service *service; ++ struct iio_mount_matrix orientation; ++ ++ struct mutex lock; /* interval */ ++ u32 interval_us; ++ ++ spinlock_t sample_lock; /* sample, have_sample */ ++ s32 sample[3]; ++ bool have_sample; ++ ++ IIO_DECLARE_BUFFER_WITH_TS(s32, scan, 3); ++}; ++ ++static int apple_aop_gyro_set_u32(struct apple_aop_gyro *gyro, u32 key, u32 value) ++{ ++ __le32 le = cpu_to_le32(value); ++ ++ return apple_aop_set_property(gyro->service, key, &le, sizeof(le)); ++} ++ ++/* No separate raw sample stream: raw interval 0. */ ++static int apple_aop_gyro_set_interval(struct apple_aop_gyro *gyro, u32 interval_us) ++{ ++ int ret; ++ ++ ret = apple_aop_gyro_set_u32(gyro, AOP_PROP_BATCH_INTERVAL, interval_us); ++ if (!ret) ++ ret = apple_aop_gyro_set_u32(gyro, AOP_PROP_RAW_INTERVAL, 0); ++ if (!ret) ++ ret = apple_aop_gyro_set_u32(gyro, AOP_PROP_REPORT_INTERVAL, interval_us); ++ if (!ret) ++ gyro->interval_us = interval_us; ++ return ret; ++} ++ ++static void apple_aop_gyro_report(void *cookie, u16 subtype, const void *data, size_t len) ++{ ++ struct iio_dev *indio_dev = cookie; ++ struct apple_aop_gyro *gyro = iio_priv(indio_dev); ++ unsigned long flags; ++ int i; ++ ++ if (subtype != AOP_REPORT_GYRO || len < AOP_GYRO_LEN) ++ return; ++ ++ spin_lock_irqsave(&gyro->sample_lock, flags); ++ for (i = 0; i < 3; i++) ++ gyro->sample[i] = get_unaligned_le32(data + AOP_GYRO_XYZ + 4 * i); ++ gyro->have_sample = true; ++ spin_unlock_irqrestore(&gyro->sample_lock, flags); ++ ++ if (iio_buffer_enabled(indio_dev)) { ++ memcpy(gyro->scan, gyro->sample, sizeof(gyro->sample)); ++ iio_push_to_buffers_with_ts(indio_dev, gyro->scan, sizeof(gyro->scan), ++ iio_get_time_ns(indio_dev)); ++ } ++} ++ ++static int apple_aop_gyro_read_raw(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ int *val, int *val2, long mask) ++{ ++ struct apple_aop_gyro *gyro = iio_priv(indio_dev); ++ unsigned long flags; ++ int ret; ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_RAW: ++ spin_lock_irqsave(&gyro->sample_lock, flags); ++ *val = gyro->sample[chan->scan_index]; ++ ret = gyro->have_sample ? IIO_VAL_INT : -EAGAIN; ++ spin_unlock_irqrestore(&gyro->sample_lock, flags); ++ return ret; ++ case IIO_CHAN_INFO_SCALE: ++ *val = AOP_GYRO_SCALE; ++ *val2 = AOP_GYRO_SCALE_LOG2; ++ return IIO_VAL_FRACTIONAL_LOG2; ++ case IIO_CHAN_INFO_SAMP_FREQ: ++ mutex_lock(&gyro->lock); ++ *val = USEC_PER_SEC / gyro->interval_us; ++ *val2 = (u64)(USEC_PER_SEC % gyro->interval_us) * USEC_PER_SEC / ++ gyro->interval_us; ++ mutex_unlock(&gyro->lock); ++ return IIO_VAL_INT_PLUS_MICRO; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int apple_aop_gyro_write_raw(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ int val, int val2, long mask) ++{ ++ struct apple_aop_gyro *gyro = iio_priv(indio_dev); ++ u64 micro_hz; ++ u32 interval; ++ int ret; ++ ++ if (mask != IIO_CHAN_INFO_SAMP_FREQ) ++ return -EINVAL; ++ if (val < 0 || val2 < 0) ++ return -EINVAL; ++ ++ micro_hz = (u64)val * USEC_PER_SEC + val2; ++ if (!micro_hz) ++ return -EINVAL; ++ interval = clamp_t(u64, div64_u64((u64)USEC_PER_SEC * USEC_PER_SEC, micro_hz), ++ AOP_GYRO_MIN_US, AOP_GYRO_MAX_US); ++ ++ mutex_lock(&gyro->lock); ++ ret = apple_aop_gyro_set_interval(gyro, interval); ++ mutex_unlock(&gyro->lock); ++ return ret; ++} ++ ++static const struct iio_mount_matrix * ++apple_aop_gyro_get_mount_matrix(const struct iio_dev *indio_dev, ++ const struct iio_chan_spec *chan) ++{ ++ struct apple_aop_gyro *gyro = iio_priv(indio_dev); ++ ++ return &gyro->orientation; ++} ++ ++static const struct iio_chan_spec_ext_info apple_aop_gyro_ext_info[] = { ++ IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, apple_aop_gyro_get_mount_matrix), ++ { } ++}; ++ ++#define APPLE_AOP_GYRO_CHANNEL(axis, index) { \ ++ .type = IIO_ANGL_VEL, \ ++ .modified = 1, \ ++ .channel2 = IIO_MOD_##axis, \ ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ ++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ ++ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ ++ .scan_index = index, \ ++ .scan_type = { \ ++ .sign = 's', \ ++ .realbits = 32, \ ++ .storagebits = 32, \ ++ .endianness = IIO_CPU, \ ++ }, \ ++ .ext_info = apple_aop_gyro_ext_info, \ ++} ++ ++static const struct iio_chan_spec apple_aop_gyro_channels[] = { ++ APPLE_AOP_GYRO_CHANNEL(X, 0), ++ APPLE_AOP_GYRO_CHANNEL(Y, 1), ++ APPLE_AOP_GYRO_CHANNEL(Z, 2), ++ IIO_CHAN_SOFT_TIMESTAMP(3), ++}; ++ ++static const struct iio_info apple_aop_gyro_info = { ++ .read_raw = apple_aop_gyro_read_raw, ++ .write_raw = apple_aop_gyro_write_raw, ++}; ++ ++/* Sensitivity and interrupt calibration make it complete */ ++static const struct apple_aop_calibration apple_aop_gyro_calibration[] = { ++ { "apple,gyro-sensitivity-calibration", 0x0b, 1 }, ++ { "apple,gyro-interrupt-calibration", 0x19, 2 }, ++ { "apple,gyro-range-sensitivity-cal", 0x27, 0 }, ++ { "apple,gyro-trim-calibration", 0x20, 0 }, ++}; ++ ++static void apple_aop_gyro_stop(void *data) ++{ ++ struct apple_aop_gyro *gyro = data; ++ ++ apple_aop_gyro_set_u32(gyro, AOP_PROP_REPORT_INTERVAL, 0); ++ apple_aop_unlisten(gyro->service); ++} ++ ++static int apple_aop_gyro_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct apple_aop_service *service = dev_get_platdata(dev); ++ struct apple_aop_gyro *gyro; ++ struct iio_dev *indio_dev; ++ int ret; ++ ++ if (!service) ++ return -ENODEV; ++ ++ indio_dev = devm_iio_device_alloc(dev, sizeof(*gyro)); ++ if (!indio_dev) ++ return -ENOMEM; ++ gyro = iio_priv(indio_dev); ++ gyro->dev = dev; ++ gyro->service = service; ++ mutex_init(&gyro->lock); ++ spin_lock_init(&gyro->sample_lock); ++ ++ ret = iio_read_mount_matrix(dev, &gyro->orientation); ++ if (ret) ++ return ret; ++ ++ indio_dev->name = "apple-aop-gyro"; ++ indio_dev->info = &apple_aop_gyro_info; ++ indio_dev->channels = apple_aop_gyro_channels; ++ indio_dev->num_channels = ARRAY_SIZE(apple_aop_gyro_channels); ++ indio_dev->modes = INDIO_DIRECT_MODE; ++ ++ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, NULL); ++ if (ret) ++ return ret; ++ ++ ret = apple_aop_listen(service, apple_aop_gyro_report, indio_dev); ++ if (ret) ++ return ret; ++ ++ ret = apple_aop_calibrate(service, dev, apple_aop_gyro_calibration, ++ ARRAY_SIZE(apple_aop_gyro_calibration)); ++ if (!ret) ++ ret = apple_aop_gyro_set_interval(gyro, AOP_GYRO_DEFAULT_US); ++ if (ret) { ++ apple_aop_unlisten(service); ++ return dev_err_probe(dev, ret, "failed to start reports\n"); ++ } ++ ++ ret = devm_add_action_or_reset(dev, apple_aop_gyro_stop, gyro); ++ if (ret) ++ return ret; ++ ++ return devm_iio_device_register(dev, indio_dev); ++} ++ ++static const struct of_device_id apple_aop_gyro_of_match[] = { ++ { .compatible = "apple,s8000-aop-gyro" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, apple_aop_gyro_of_match); ++ ++static struct platform_driver apple_aop_gyro_driver = { ++ .driver = { ++ .name = "apple-aop-gyro", ++ .of_match_table = apple_aop_gyro_of_match, ++ }, ++ .probe = apple_aop_gyro_probe, ++}; ++module_platform_driver(apple_aop_gyro_driver); ++ ++MODULE_AUTHOR("Berkay Kösebay "); ++MODULE_DESCRIPTION("Apple AOP gyroscope driver"); ++MODULE_LICENSE("Dual MIT/GPL"); +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/iio/0007-iio-pressure-Add-the-Apple-AOP-barometric-pressure-s.patch b/kernel/patches/drivers/iio/0007-iio-pressure-Add-the-Apple-AOP-barometric-pressure-s.patch new file mode 100644 index 00000000..2f01f4e7 --- /dev/null +++ b/kernel/patches/drivers/iio/0007-iio-pressure-Add-the-Apple-AOP-barometric-pressure-s.patch @@ -0,0 +1,327 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] iio: pressure: Add the Apple AOP barometric pressure sensor + +The Always-On Processor of Apple A9 devices samples the barometric +pressure sensor and, once it has the unit's factory calibration and its +batch, raw and report intervals (EPIC set-property tags 0x16, 0x5c and +0), sends one report (EPIC subtype 0xc4) per report interval with the +pressure in 1/65536 kPa. + +Expose it as an IIO pressure sensor: raw value, scale in kPa, sampling +frequency (the report interval) and a software buffer with timestamps. +The calibration is complete once the offset or the acceleration +sensitivity is applied; the heater resistance is sent when the +bootloader provides it. + +[Orchard: from orchard PR #101, commit a54e2049; the pressure part of + drivers/iio/0005, unchanged] + +Assisted-by: LLM +--- + drivers/iio/pressure/Kconfig | 12 + + drivers/iio/pressure/Makefile | 1 + + drivers/iio/pressure/apple_aop_pressure.c | 257 ++++++++++++++++++++++ + 3 files changed, 270 insertions(+) + create mode 100644 drivers/iio/pressure/apple_aop_pressure.c + +diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig +index 838a834..18535ad 100644 +--- a/drivers/iio/pressure/Kconfig ++++ b/drivers/iio/pressure/Kconfig +@@ -384,4 +384,16 @@ config ADP810 + To compile this driver as a module, choose M here: the module will + be called adp810 + ++config APPLE_AOP_PRESSURE ++ tristate "Apple AOP barometric pressure sensor" ++ depends on APPLE_AOP_T8010 ++ select IIO_BUFFER ++ select IIO_KFIFO_BUF ++ help ++ Say yes here to get support for the barometric pressure sensor that ++ the Always-On Processor (AOP) of Apple A9 iPads and iPhones serves. ++ ++ To compile this driver as a module, choose M here: the module will be ++ called apple_aop_pressure. ++ + endmenu +diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile +index bc0d11a..bf3e27b 100644 +--- a/drivers/iio/pressure/Makefile ++++ b/drivers/iio/pressure/Makefile +@@ -9,6 +9,7 @@ obj-$(CONFIG_ABP2030PA) += abp2030pa.o + obj-$(CONFIG_ABP2030PA_I2C) += abp2030pa_i2c.o + obj-$(CONFIG_ABP2030PA_SPI) += abp2030pa_spi.o + obj-$(CONFIG_ADP810) += adp810.o ++obj-$(CONFIG_APPLE_AOP_PRESSURE) += apple_aop_pressure.o + obj-$(CONFIG_ROHM_BM1390) += rohm-bm1390.o + obj-$(CONFIG_BMP280) += bmp280.o + bmp280-objs := bmp280-core.o bmp280-regmap.o +diff --git a/drivers/iio/pressure/apple_aop_pressure.c b/drivers/iio/pressure/apple_aop_pressure.c +new file mode 100644 +index 0000000..8cd983c +--- /dev/null ++++ b/drivers/iio/pressure/apple_aop_pressure.c +@@ -0,0 +1,257 @@ ++// SPDX-License-Identifier: GPL-2.0-only OR MIT ++/* ++ * Barometric pressure sensor served by the Apple Always-On Processor (AOP) ++ * ++ * The AOP firmware samples the pressure sensor itself. Once it has the unit's ++ * factory calibration and its batch, raw and report intervals (EPIC ++ * set-property tags 0x16, 0x5c and 0), it sends one report (EPIC subtype ++ * 0xc4) per report interval: ++ * ++ * 0 u16 sequence ++ * 2 u32 pressure in 1/65536 kPa ++ * 6 s32 temperature (unit unknown, not exported) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define AOP_PROP_REPORT_INTERVAL 0x00 ++#define AOP_PROP_BATCH_INTERVAL 0x16 ++#define AOP_PROP_RAW_INTERVAL 0x5c ++ ++#define AOP_REPORT_PRESSURE 0xc4 ++#define AOP_PRESSURE_LEN 10 ++#define AOP_PRESSURE_VALUE 2 ++ ++#define AOP_PRESSURE_DEFAULT_US 100000 /* 10 Hz */ ++#define AOP_PRESSURE_MIN_US 10000 /* 100 Hz */ ++#define AOP_PRESSURE_MAX_US 1000000 /* 1 Hz */ ++ ++struct apple_aop_pressure { ++ struct device *dev; ++ const struct apple_aop_service *service; ++ ++ struct mutex lock; /* interval */ ++ u32 interval_us; ++ ++ spinlock_t sample_lock; /* sample, have_sample */ ++ u32 sample; ++ bool have_sample; ++ ++ IIO_DECLARE_BUFFER_WITH_TS(u32, scan, 1); ++}; ++ ++static int apple_aop_pressure_set_u32(struct apple_aop_pressure *pressure, u32 key, u32 value) ++{ ++ __le32 le = cpu_to_le32(value); ++ ++ return apple_aop_set_property(pressure->service, key, &le, sizeof(le)); ++} ++ ++/* No separate raw sample stream: raw interval 0. */ ++static int apple_aop_pressure_set_interval(struct apple_aop_pressure *pressure, u32 interval_us) ++{ ++ int ret; ++ ++ ret = apple_aop_pressure_set_u32(pressure, AOP_PROP_BATCH_INTERVAL, interval_us); ++ if (!ret) ++ ret = apple_aop_pressure_set_u32(pressure, AOP_PROP_RAW_INTERVAL, 0); ++ if (!ret) ++ ret = apple_aop_pressure_set_u32(pressure, AOP_PROP_REPORT_INTERVAL, interval_us); ++ if (!ret) ++ pressure->interval_us = interval_us; ++ return ret; ++} ++ ++static void apple_aop_pressure_report(void *cookie, u16 subtype, const void *data, size_t len) ++{ ++ struct iio_dev *indio_dev = cookie; ++ struct apple_aop_pressure *pressure = iio_priv(indio_dev); ++ unsigned long flags; ++ ++ if (subtype != AOP_REPORT_PRESSURE || len < AOP_PRESSURE_LEN) ++ return; ++ ++ spin_lock_irqsave(&pressure->sample_lock, flags); ++ pressure->sample = get_unaligned_le32(data + AOP_PRESSURE_VALUE); ++ pressure->have_sample = true; ++ spin_unlock_irqrestore(&pressure->sample_lock, flags); ++ ++ if (iio_buffer_enabled(indio_dev)) { ++ pressure->scan[0] = pressure->sample; ++ iio_push_to_buffers_with_ts(indio_dev, pressure->scan, sizeof(pressure->scan), ++ iio_get_time_ns(indio_dev)); ++ } ++} ++ ++static int apple_aop_pressure_read_raw(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ int *val, int *val2, long mask) ++{ ++ struct apple_aop_pressure *pressure = iio_priv(indio_dev); ++ unsigned long flags; ++ int ret; ++ ++ switch (mask) { ++ case IIO_CHAN_INFO_RAW: ++ spin_lock_irqsave(&pressure->sample_lock, flags); ++ *val = pressure->sample; ++ ret = pressure->have_sample ? IIO_VAL_INT : -EAGAIN; ++ spin_unlock_irqrestore(&pressure->sample_lock, flags); ++ return ret; ++ case IIO_CHAN_INFO_SCALE: ++ /* kPa */ ++ *val = 1; ++ *val2 = 16; ++ return IIO_VAL_FRACTIONAL_LOG2; ++ case IIO_CHAN_INFO_SAMP_FREQ: ++ mutex_lock(&pressure->lock); ++ *val = USEC_PER_SEC / pressure->interval_us; ++ *val2 = (u64)(USEC_PER_SEC % pressure->interval_us) * USEC_PER_SEC / ++ pressure->interval_us; ++ mutex_unlock(&pressure->lock); ++ return IIO_VAL_INT_PLUS_MICRO; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static int apple_aop_pressure_write_raw(struct iio_dev *indio_dev, ++ struct iio_chan_spec const *chan, ++ int val, int val2, long mask) ++{ ++ struct apple_aop_pressure *pressure = iio_priv(indio_dev); ++ u64 micro_hz; ++ u32 interval; ++ int ret; ++ ++ if (mask != IIO_CHAN_INFO_SAMP_FREQ) ++ return -EINVAL; ++ if (val < 0 || val2 < 0) ++ return -EINVAL; ++ ++ micro_hz = (u64)val * USEC_PER_SEC + val2; ++ if (!micro_hz) ++ return -EINVAL; ++ interval = clamp_t(u64, div64_u64((u64)USEC_PER_SEC * USEC_PER_SEC, micro_hz), ++ AOP_PRESSURE_MIN_US, AOP_PRESSURE_MAX_US); ++ ++ mutex_lock(&pressure->lock); ++ ret = apple_aop_pressure_set_interval(pressure, interval); ++ mutex_unlock(&pressure->lock); ++ return ret; ++} ++ ++static const struct iio_chan_spec apple_aop_pressure_channels[] = { ++ { ++ .type = IIO_PRESSURE, ++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), ++ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), ++ .scan_index = 0, ++ .scan_type = { ++ .sign = 'u', ++ .realbits = 32, ++ .storagebits = 32, ++ .endianness = IIO_CPU, ++ }, ++ }, ++ IIO_CHAN_SOFT_TIMESTAMP(1), ++}; ++ ++static const struct iio_info apple_aop_pressure_info = { ++ .read_raw = apple_aop_pressure_read_raw, ++ .write_raw = apple_aop_pressure_write_raw, ++}; ++ ++/* The offset or the acceleration sensitivity makes it complete */ ++static const struct apple_aop_calibration apple_aop_pressure_calibration[] = { ++ { "apple,pressure-offset-calibration", 0x0b, 1 }, ++ { "apple,pressure-accel-sensitivity", 0xd3, 1 }, ++ { "apple,pressure-heater-resistance", 0xd4, 0 }, ++}; ++ ++static void apple_aop_pressure_stop(void *data) ++{ ++ struct apple_aop_pressure *pressure = data; ++ ++ apple_aop_pressure_set_u32(pressure, AOP_PROP_REPORT_INTERVAL, 0); ++ apple_aop_unlisten(pressure->service); ++} ++ ++static int apple_aop_pressure_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct apple_aop_service *service = dev_get_platdata(dev); ++ struct apple_aop_pressure *pressure; ++ struct iio_dev *indio_dev; ++ int ret; ++ ++ if (!service) ++ return -ENODEV; ++ ++ indio_dev = devm_iio_device_alloc(dev, sizeof(*pressure)); ++ if (!indio_dev) ++ return -ENOMEM; ++ pressure = iio_priv(indio_dev); ++ pressure->dev = dev; ++ pressure->service = service; ++ mutex_init(&pressure->lock); ++ spin_lock_init(&pressure->sample_lock); ++ ++ indio_dev->name = "apple-aop-pressure"; ++ indio_dev->info = &apple_aop_pressure_info; ++ indio_dev->channels = apple_aop_pressure_channels; ++ indio_dev->num_channels = ARRAY_SIZE(apple_aop_pressure_channels); ++ indio_dev->modes = INDIO_DIRECT_MODE; ++ ++ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, NULL); ++ if (ret) ++ return ret; ++ ++ ret = apple_aop_listen(service, apple_aop_pressure_report, indio_dev); ++ if (ret) ++ return ret; ++ ++ ret = apple_aop_calibrate(service, dev, apple_aop_pressure_calibration, ++ ARRAY_SIZE(apple_aop_pressure_calibration)); ++ if (!ret) ++ ret = apple_aop_pressure_set_interval(pressure, AOP_PRESSURE_DEFAULT_US); ++ if (ret) { ++ apple_aop_unlisten(service); ++ return dev_err_probe(dev, ret, "failed to start reports\n"); ++ } ++ ++ ret = devm_add_action_or_reset(dev, apple_aop_pressure_stop, pressure); ++ if (ret) ++ return ret; ++ ++ return devm_iio_device_register(dev, indio_dev); ++} ++ ++static const struct of_device_id apple_aop_pressure_of_match[] = { ++ { .compatible = "apple,s8000-aop-pressure" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, apple_aop_pressure_of_match); ++ ++static struct platform_driver apple_aop_pressure_driver = { ++ .driver = { ++ .name = "apple-aop-pressure", ++ .of_match_table = apple_aop_pressure_of_match, ++ }, ++ .probe = apple_aop_pressure_probe, ++}; ++module_platform_driver(apple_aop_pressure_driver); ++ ++MODULE_AUTHOR("Berkay Kösebay "); ++MODULE_DESCRIPTION("Apple AOP barometric pressure sensor driver"); ++MODULE_LICENSE("Dual MIT/GPL"); +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/iio/0008-iio-apple-aop-Serve-the-T8010-s-gyroscope-and-pressu.patch b/kernel/patches/drivers/iio/0008-iio-apple-aop-Serve-the-T8010-s-gyroscope-and-pressu.patch new file mode 100644 index 00000000..34783b9a --- /dev/null +++ b/kernel/patches/drivers/iio/0008-iio-apple-aop-Serve-the-T8010-s-gyroscope-and-pressu.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Henrik Klee +Date: Fri, 13 Nov 2026 12:00:00 +0100 +Subject: [PATCH] iio: apple-aop: Serve the T8010's gyroscope and pressure + sensor + +The A10's AOP firmware announces the same gyroscope and pressure +services as the A9's, and Apple's device trees for the iPad 5 (S8003) +and iPad 6 (T8010) describe both sensors with the same calibration +properties; the A10's AOP node is even compatible with the A9's +("iop,t8010", "iop,s8000"). The gyroscope and pressure drivers use only +the AOP service protocol: set-property requests, the calibration state +and the service's reports. + +Bind them to the T8010's sensor nodes, which the T8010 device tree +already describes. + +Assisted-by: LLM +--- + drivers/iio/gyro/Kconfig | 2 +- + drivers/iio/gyro/apple_aop_gyro.c | 7 ++++--- + drivers/iio/pressure/Kconfig | 3 ++- + drivers/iio/pressure/apple_aop_pressure.c | 9 +++++---- + 4 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig +index 8f506a6..77f2180 100644 +--- a/drivers/iio/gyro/Kconfig ++++ b/drivers/iio/gyro/Kconfig +@@ -70,7 +70,7 @@ config APPLE_AOP_GYRO + select IIO_KFIFO_BUF + help + Say yes here to get support for the gyroscope that the Always-On +- Processor (AOP) of Apple A9 iPads and iPhones serves. ++ Processor (AOP) of Apple A9 and A10 iPads and iPhones serves. + + To compile this driver as a module, choose M here: the module will be + called apple_aop_gyro. +diff --git a/drivers/iio/gyro/apple_aop_gyro.c b/drivers/iio/gyro/apple_aop_gyro.c +index edbda1f..3341164 100644 +--- a/drivers/iio/gyro/apple_aop_gyro.c ++++ b/drivers/iio/gyro/apple_aop_gyro.c +@@ -2,9 +2,9 @@ + /* + * Gyroscope served by the Apple Always-On Processor (AOP) + * +- * The AOP firmware samples the gyroscope itself. Once it has the unit's +- * factory calibration and its batch, raw and report intervals (EPIC +- * set-property tags 0x16, 0x5c and 0), it sends one motion report (EPIC ++ * The AOP firmware of the A9 and A10 samples the gyroscope itself. Once it ++ * has the unit's factory calibration and its batch, raw and report intervals ++ * (EPIC set-property tags 0x16, 0x5c and 0), it sends one motion report (EPIC + * subtype 0xc1) per report interval, laid out like the accelerometer's: + * + * 0 u16 sequence +@@ -273,6 +273,7 @@ static int apple_aop_gyro_probe(struct platform_device *pdev) + + static const struct of_device_id apple_aop_gyro_of_match[] = { + { .compatible = "apple,s8000-aop-gyro" }, ++ { .compatible = "apple,t8010-aop-gyro" }, + { } + }; + MODULE_DEVICE_TABLE(of, apple_aop_gyro_of_match); +diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig +index 18535ad..fcdb9e1 100644 +--- a/drivers/iio/pressure/Kconfig ++++ b/drivers/iio/pressure/Kconfig +@@ -391,7 +391,8 @@ config APPLE_AOP_PRESSURE + select IIO_KFIFO_BUF + help + Say yes here to get support for the barometric pressure sensor that +- the Always-On Processor (AOP) of Apple A9 iPads and iPhones serves. ++ the Always-On Processor (AOP) of Apple A9 and A10 iPads and iPhones ++ serves. + + To compile this driver as a module, choose M here: the module will be + called apple_aop_pressure. +diff --git a/drivers/iio/pressure/apple_aop_pressure.c b/drivers/iio/pressure/apple_aop_pressure.c +index 8cd983c..70b1257 100644 +--- a/drivers/iio/pressure/apple_aop_pressure.c ++++ b/drivers/iio/pressure/apple_aop_pressure.c +@@ -2,10 +2,10 @@ + /* + * Barometric pressure sensor served by the Apple Always-On Processor (AOP) + * +- * The AOP firmware samples the pressure sensor itself. Once it has the unit's +- * factory calibration and its batch, raw and report intervals (EPIC +- * set-property tags 0x16, 0x5c and 0), it sends one report (EPIC subtype +- * 0xc4) per report interval: ++ * The AOP firmware of the A9 and A10 samples the pressure sensor itself. Once ++ * it has the unit's factory calibration and its batch, raw and report ++ * intervals (EPIC set-property tags 0x16, 0x5c and 0), it sends one report ++ * (EPIC subtype 0xc4) per report interval: + * + * 0 u16 sequence + * 2 u32 pressure in 1/65536 kPa +@@ -239,6 +239,7 @@ static int apple_aop_pressure_probe(struct platform_device *pdev) + + static const struct of_device_id apple_aop_pressure_of_match[] = { + { .compatible = "apple,s8000-aop-pressure" }, ++ { .compatible = "apple,t8010-aop-pressure" }, + { } + }; + MODULE_DEVICE_TABLE(of, apple_aop_pressure_of_match); +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/iio/0009-iio-accel-apple_aop_accel-Calibrate-the-T8010-s-acce.patch b/kernel/patches/drivers/iio/0009-iio-accel-apple_aop_accel-Calibrate-the-T8010-s-acce.patch new file mode 100644 index 00000000..5f88f1f2 --- /dev/null +++ b/kernel/patches/drivers/iio/0009-iio-accel-apple_aop_accel-Calibrate-the-T8010-s-acce.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Henrik Klee +Date: Fri, 13 Nov 2026 12:00:00 +0100 +Subject: [PATCH] iio: accel: apple_aop_accel: Calibrate the T8010's + accelerometer too + +Apple's device trees for the iPad 5 (S8003) and the iPad 6 (T8010) +give the accelerometer the same factory calibration properties, filled +from the unit's syscfg, and the bootloader copies them into the sensor +node on both. The T8010's firmware reports without them; with them it +gets the unit's offset and sensitivity like the S8000's. + +Send the calibration on every SoC. A failure to set the calibration +state is no longer fatal: the T8010's firmware reports either way, and +the accelerometer must not disappear on a firmware that does not know +the property. + +Assisted-by: LLM +--- + drivers/iio/accel/apple_aop_accel.c | 44 +++++++++++++---------------- + 1 file changed, 20 insertions(+), 24 deletions(-) + +diff --git a/drivers/iio/accel/apple_aop_accel.c b/drivers/iio/accel/apple_aop_accel.c +index f310af6..a6447e8 100644 +--- a/drivers/iio/accel/apple_aop_accel.c ++++ b/drivers/iio/accel/apple_aop_accel.c +@@ -12,10 +12,10 @@ + * 6 s32 x, y, z in 1/65536 g + * 18 u32 timestamp + * +- * The T8010's firmware reports in the device frame (x right, y up, z out of +- * the screen; +1 g opposite to gravity). The S8000's firmware first needs the +- * unit's factory calibration and reports in the sensor's frame; the board's +- * mount-matrix maps it. ++ * Both take the unit's factory calibration first; the S8000's firmware sends ++ * no reports without it. The T8010's firmware reports in the device frame ++ * (x right, y up, z out of the screen; +1 g opposite to gravity), the S8000's ++ * in the sensor's frame; the board's mount-matrix maps it. + */ + + #include +@@ -46,8 +46,6 @@ + #define AOP_ACCEL_SCALE_NANO 149637 + + struct apple_aop_accel_hw { +- const struct apple_aop_calibration *calibration; +- unsigned int num_calibration; + /* No separate raw sample stream (raw interval 0) */ + bool no_raw_stream; + }; +@@ -216,6 +214,14 @@ static const struct iio_info apple_aop_accel_info = { + .write_raw = apple_aop_accel_write_raw, + }; + ++/* Offset at low temperature, sensitivity (either), interrupt calibration */ ++static const struct apple_aop_calibration apple_aop_accel_calibration[] = { ++ { "apple,low-temp-accel-offset", 0x1a, 1 }, ++ { "apple,accel-sensitivity-calibration", 0x0b, 2 }, ++ { "apple,accel-range-sensitivity-cal", 0x27, 2 }, ++ { "apple,accel-interrupt-calibration", 0x19, 3 }, ++}; ++ + static void apple_aop_accel_stop(void *data) + { + struct apple_aop_accel *accel = data; +@@ -263,14 +269,14 @@ static int apple_aop_accel_probe(struct platform_device *pdev) + if (ret) + return ret; + +- if (accel->hw->num_calibration) { +- ret = apple_aop_calibrate(service, dev, accel->hw->calibration, +- accel->hw->num_calibration); +- if (ret) { +- apple_aop_unlisten(service); +- return dev_err_probe(dev, ret, "failed to calibrate\n"); +- } +- } ++ /* ++ * Without the calibration state the S8000's firmware stays silent; the ++ * T8010's reports anyway, so carry on either way. ++ */ ++ ret = apple_aop_calibrate(service, dev, apple_aop_accel_calibration, ++ ARRAY_SIZE(apple_aop_accel_calibration)); ++ if (ret) ++ dev_warn(dev, "calibration state not set: %d\n", ret); + + ret = apple_aop_accel_set_interval(accel, AOP_ACCEL_DEFAULT_US); + if (ret) { +@@ -285,17 +291,7 @@ static int apple_aop_accel_probe(struct platform_device *pdev) + return devm_iio_device_register(dev, indio_dev); + } + +-/* Offset at low temperature, sensitivity (either), interrupt calibration */ +-static const struct apple_aop_calibration apple_aop_accel_s8000_calibration[] = { +- { "apple,low-temp-accel-offset", 0x1a, 1 }, +- { "apple,accel-sensitivity-calibration", 0x0b, 2 }, +- { "apple,accel-range-sensitivity-cal", 0x27, 2 }, +- { "apple,accel-interrupt-calibration", 0x19, 3 }, +-}; +- + static const struct apple_aop_accel_hw apple_aop_accel_s8000 = { +- .calibration = apple_aop_accel_s8000_calibration, +- .num_calibration = ARRAY_SIZE(apple_aop_accel_s8000_calibration), + .no_raw_stream = true, + }; + +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/soc-apple/0016-dt-bindings-mailbox-apple-mailbox-Add-the-S8000-A7-I.patch b/kernel/patches/drivers/soc-apple/0016-dt-bindings-mailbox-apple-mailbox-Add-the-S8000-A7-I.patch new file mode 100644 index 00000000..929193b0 --- /dev/null +++ b/kernel/patches/drivers/soc-apple/0016-dt-bindings-mailbox-apple-mailbox-Add-the-S8000-A7-I.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] dt-bindings: mailbox: apple,mailbox: Add the S8000 A7 IOP + mailbox + +The A9's always-on processor talks to the application processor +through the same A7 IOP mailbox as the A10's. Add its compatible, with +the T8010's as the fallback. + +[Orchard: from orchard PR #101, commit a54e2049; drivers/mailbox/0001 + without the reload wording, the entry placed after the T8010's] + +Assisted-by: LLM +--- + .../devicetree/bindings/mailbox/apple,mailbox.yaml | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml +index ba035ff..ea414a8 100644 +--- a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml ++++ b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml +@@ -59,6 +59,12 @@ properties: + items: + - const: apple,t8010-a7iop-mailbox + ++ - description: ++ The same A7 IOP mailbox on the A9. ++ items: ++ - const: apple,s8000-a7iop-mailbox ++ - const: apple,t8010-a7iop-mailbox ++ + reg: + maxItems: 1 + +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/soc-apple/0017-dt-bindings-soc-apple-apple-t8010-aop-Add-the-S8000.patch b/kernel/patches/drivers/soc-apple/0017-dt-bindings-soc-apple-apple-t8010-aop-Add-the-S8000.patch new file mode 100644 index 00000000..3fe5fe19 --- /dev/null +++ b/kernel/patches/drivers/soc-apple/0017-dt-bindings-soc-apple-apple-t8010-aop-Add-the-S8000.patch @@ -0,0 +1,113 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] dt-bindings: soc: apple: apple,t8010-aop: Add the S8000 + +The A9 (S8000, S8003) has the same always-on processor as the A10, with +the same register blocks and sensors. Its firmware takes three more +boot arguments that the bootloader fills in from the Apple device tree: +the AOP target number, the chip ID and the chip revision. + +Add the S8000 compatibles for the AOP and its accelerometer, gyroscope +and pressure sensor, and the three bootloader properties. Describe the +per-unit factory calibration blobs that the bootloader copies into the +sensor nodes, which the sensor drivers hand to the firmware. + +[Orchard: from orchard PR #101, commit a54e2049; soc-apple/0014 without + apple,certified-reload, memory-region, apple,observe-domains and + apple,spi0-domain, and the calibration text not limited to the S8000] + +Assisted-by: LLM +--- + .../bindings/soc/apple/apple,t8010-aop.yaml | 42 +++++++++++++++++-- + 1 file changed, 38 insertions(+), 4 deletions(-) + +diff --git a/Documentation/devicetree/bindings/soc/apple/apple,t8010-aop.yaml b/Documentation/devicetree/bindings/soc/apple/apple,t8010-aop.yaml +index 14726af..32788d1 100644 +--- a/Documentation/devicetree/bindings/soc/apple/apple,t8010-aop.yaml ++++ b/Documentation/devicetree/bindings/soc/apple/apple,t8010-aop.yaml +@@ -4,14 +4,14 @@ + $id: http://devicetree.org/schemas/soc/apple/apple,t8010-aop.yaml# + $schema: http://devicetree.org/meta-schemas/core.yaml# + +-title: Apple T8010 Always-On Processor ++title: Apple S8000 and T8010 Always-On Processor + + maintainers: + - Dalton Alexandre + + description: +- The Always-On Processor (AOP) of the A10 is an ARMv7 coprocessor that +- runs RTKit firmware and serves the motion sensors (accelerometer, ++ The Always-On Processor (AOP) of the A9 and A10 is an ARMv7 coprocessor ++ that runs RTKit firmware and serves the motion sensors (accelerometer, + gyroscope, compass, pressure) and the always-on microphones. It runs from + local SRAM, with a further firmware segment in system memory, and talks + to the application processor through an A7 IOP mailbox. Its firmware is +@@ -19,7 +19,9 @@ description: + + properties: + compatible: +- const: apple,t8010-aop ++ enum: ++ - apple,s8000-aop ++ - apple,t8010-aop + + reg: + items: +@@ -50,6 +52,24 @@ properties: + The chip's unique ID (ECID), filled in by the bootloader. The + firmware's boot arguments carry it. + ++ apple,aop-target: ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ description: ++ The AOP target number from the Apple device tree, filled in by the ++ bootloader. The S8000 firmware's boot arguments carry it. ++ ++ apple,chip-id: ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ description: ++ The SoC's chip ID (e.g. 0x8003), filled in by the bootloader. The S8000 ++ firmware's boot arguments carry it. ++ ++ apple,chip-revision: ++ $ref: /schemas/types.yaml#/definitions/uint32 ++ description: ++ The SoC's chip revision, filled in by the bootloader. The S8000 ++ firmware's boot arguments carry it. ++ + patternProperties: + "^(accel|gyro|compass|pressure)$": + type: object +@@ -58,6 +78,9 @@ patternProperties: + properties: + compatible: + enum: ++ - apple,s8000-aop-accel ++ - apple,s8000-aop-gyro ++ - apple,s8000-aop-pressure + - apple,t8010-aop-accel + - apple,t8010-aop-gyro + - apple,t8010-aop-compass +@@ -65,6 +88,17 @@ patternProperties: + + mount-matrix: + description: The sensor's mounting rotation in the device. ++ ++ patternProperties: ++ "^apple,(low-temp-accel-offset|(accel|gyro)-(sensitivity|interrupt)-calibration|(accel|gyro)-range-sensitivity-cal|gyro-trim-calibration|pressure-(offset-calibration|accel-sensitivity|heater-resistance))$": ++ $ref: /schemas/types.yaml#/definitions/uint8-array ++ maxItems: 64 ++ description: ++ The unit's factory calibration of the sensor, copied by the ++ bootloader from the property of the same name (without the ++ prefix) in the Apple device tree. The driver hands it to the ++ firmware as a property of the sensor's service. ++ + required: + - compatible + additionalProperties: false +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/soc-apple/0018-soc-apple-aop-Add-the-S8000.patch b/kernel/patches/drivers/soc-apple/0018-soc-apple-aop-Add-the-S8000.patch new file mode 100644 index 00000000..8993b663 --- /dev/null +++ b/kernel/patches/drivers/soc-apple/0018-soc-apple-aop-Add-the-S8000.patch @@ -0,0 +1,371 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] soc: apple: aop: Add the S8000 + +The A9's always-on processor runs the same kind of RTKit firmware as +the A10's and is started the same way, with three differences: + +- The AOP sees its SRAM through a window in its wrapper (base, size and + enable registers at 0x08 to 0x38) that has to point at the SRAM + before the AOP runs. +- Its firmware takes the AOP target number, the SoC's chip ID and + revision, the wrapper's address, a stack guard and a calibration flag + as boot arguments (AOPt, SOC_, SOCR, WrAd, STKG, nCal), and no NONC. +- Its service announcements end after the channel, shorter than the + A10's; only the name and the channel are used. + +Describe the differences in per-SoC match data, so that the T8010's +start sequence stays as it is, and take the three new values from the +properties the bootloader fills in. The S8000 loader writes the SRAM +32 bits at a time, as Apple's loader does; the T8010 keeps +memcpy_toio(). + +As on the A10, the AOP starts once per boot and the driver cannot be +unbound after that. + +[Orchard: from orchard PR #101, commit a54e2049; the S8000 start path of + soc-apple/0015 only: without the warm reload, kexec and shutdown + certification code, the pmgr observer, the SHA-256 checks, the + shutdown log, the warm_state attribute and the AFK shutdown opcode + changes; the 32-bit SRAM writes limited to the S8000 through match + data, with a byte tail for SRAM sizes that are not a multiple of 4] + +Assisted-by: LLM +--- + drivers/soc/apple/Kconfig | 12 +-- + drivers/soc/apple/aop.c | 173 ++++++++++++++++++++++++++++++++------ + 2 files changed, 152 insertions(+), 33 deletions(-) + +diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig +index ade72a5..3042c2d 100644 +--- a/drivers/soc/apple/Kconfig ++++ b/drivers/soc/apple/Kconfig +@@ -39,16 +39,16 @@ config APPLE_RTKIT + Say 'y' here if you have an Apple SoC. + + config APPLE_AOP_T8010 +- tristate "Apple T8010 Always-On Processor" ++ tristate "Apple S8000 and T8010 Always-On Processor" + depends on APPLE_RTKIT + depends on ARCH_APPLE || COMPILE_TEST + help +- The Always-On Processor (AOP) of the Apple A10 runs the firmware for +- the motion sensors and the always-on microphones. This driver loads +- and starts that firmware and provides its services to the sensor +- drivers. ++ The Always-On Processor (AOP) of the Apple A9 and A10 runs the ++ firmware for the motion sensors and the always-on microphones. This ++ driver loads and starts that firmware and provides its services to ++ the sensor drivers. + +- Say 'y' or 'm' here if you have an A10-based iPad or iPhone. ++ Say 'y' or 'm' here if you have an A9- or A10-based iPad or iPhone. + + config APPLE_PMP_T8015_V1 + tristate "Apple T8015 PMP" +diff --git a/drivers/soc/apple/aop.c b/drivers/soc/apple/aop.c +index e8ae900..ffd48d6 100644 +--- a/drivers/soc/apple/aop.c ++++ b/drivers/soc/apple/aop.c +@@ -1,11 +1,13 @@ + // SPDX-License-Identifier: GPL-2.0-only OR MIT + /* +- * Apple T8010 Always-On Processor (AOP) ++ * Apple S8000 and T8010 Always-On Processor (AOP) + * + * The AOP runs RTKit firmware that the operating system loads: a main image + * into the AOP's SRAM and an external segment into system memory, with boot +- * arguments filled in. Its services talk AFK/EPIC over shared ring buffers on +- * the RTKit application endpoints, as on later SoCs (see the Asahi Linux AOP ++ * arguments filled in. On the S8000 (A9) the AOP sees its SRAM through a window ++ * that has to be set up first, and its firmware takes more boot arguments. ++ * Its services talk AFK/EPIC over shared ring buffers on the RTKit ++ * application endpoints, as on later SoCs (see the Asahi Linux AOP + * driver). Each service with a device tree child node of the same name gets a + * child platform device; its driver receives the service's reports through + * apple_aop_listen() and sends requests with apple_aop_call(). +@@ -41,6 +43,14 @@ + #define APPLE_AOP_IRQ_MASK_ALL 0x1111 + #define APPLE_AOP_IRQ_INBOX BIT(0) + #define APPLE_AOP_IRQ_OUTBOX BIT(12) ++/* S8000: the window through which the AOP sees its SRAM */ ++#define APPLE_AOP_REMAP_PA_LO 0x08 ++#define APPLE_AOP_REMAP_PA_HI 0x10 ++#define APPLE_AOP_REMAP_IOVA_LO 0x18 ++#define APPLE_AOP_REMAP_IOVA_HI 0x20 ++#define APPLE_AOP_REMAP_SIZE 0x28 ++#define APPLE_AOP_REMAP_RESERVED 0x30 ++#define APPLE_AOP_REMAP_ENABLE 0x38 + + #define APPLE_AOP_CONTROL_AUTO_BOOT 0x0 + +@@ -54,6 +64,13 @@ + #define APPLE_AOP_BOOTARG_ECID APPLE_AOP_FOURCC('E', 'C', 'I', 'D') + #define APPLE_AOP_BOOTARG_NONC APPLE_AOP_FOURCC('N', 'O', 'N', 'C') + #define APPLE_AOP_BOOTARG_EC0P APPLE_AOP_FOURCC('E', 'C', '0', 'p') ++#define APPLE_AOP_BOOTARG_AOPT APPLE_AOP_FOURCC('A', 'O', 'P', 't') ++#define APPLE_AOP_BOOTARG_NCAL APPLE_AOP_FOURCC('n', 'C', 'a', 'l') ++#define APPLE_AOP_BOOTARG_WRAD APPLE_AOP_FOURCC('W', 'r', 'A', 'd') ++#define APPLE_AOP_BOOTARG_SOC APPLE_AOP_FOURCC('S', 'O', 'C', '_') ++#define APPLE_AOP_BOOTARG_SOCR APPLE_AOP_FOURCC('S', 'O', 'C', 'R') ++#define APPLE_AOP_BOOTARG_STKG APPLE_AOP_FOURCC('S', 'T', 'K', 'G') ++#define APPLE_AOP_MAX_BOOTARGS 10 + + #define APPLE_AOP_HALT_TIMEOUT_US 10000 + +@@ -182,12 +199,27 @@ struct apple_aop_register_work { + struct apple_aop_service service; + }; + ++struct apple_aop_hw { ++ /* Set up the AOP's window onto its SRAM before starting it */ ++ bool sram_window; ++ /* Write the SRAM 32 bits at a time, as Apple's loader does */ ++ bool sram_32bit; ++ /* A fresh NONC boot argument */ ++ bool nonce; ++ /* AOPt, SOC_, SOCR, WrAd, STKG and nCal boot arguments */ ++ bool soc_bootargs; ++}; ++ + struct apple_aop { + struct device *dev; ++ const struct apple_aop_hw *hw; + void __iomem *akf; + void __iomem *control; + void __iomem *sram; ++ resource_size_t akf_base; ++ resource_size_t sram_base; + resource_size_t sram_size; ++ u32 target, chip_id, chip_revision; + struct apple_rtkit *rtk; + + void *ext; +@@ -232,11 +264,19 @@ struct apple_aop_bootarg { + bool found; + }; + ++static void apple_aop_add_bootarg(struct apple_aop_bootarg *args, unsigned int *count, ++ u32 key, const void *value, u32 size) ++{ ++ if (WARN_ON(*count >= APPLE_AOP_MAX_BOOTARGS)) ++ return; ++ args[(*count)++] = (struct apple_aop_bootarg){ .key = key, .value = value, .size = size }; ++} ++ + static int apple_aop_patch_bootargs(struct apple_aop *aop, u8 *image, size_t size, +- struct apple_aop_bootarg *args, int count) ++ struct apple_aop_bootarg *args, unsigned int count) + { + size_t offset, end, pos; +- int i; ++ unsigned int i; + + offset = get_unaligned_le32(image + APPLE_AOP_IMAGE_BOOTARGS_OFFSET); + end = get_unaligned_le32(image + APPLE_AOP_IMAGE_BOOTARGS_SIZE); +@@ -269,13 +309,47 @@ static int apple_aop_patch_bootargs(struct apple_aop *aop, u8 *image, size_t siz + return 0; + } + ++/* Copy the main image into the SRAM and clear the rest of it. */ ++static void apple_aop_write_sram(struct apple_aop *aop, const u8 *image, size_t size) ++{ ++ size_t offset; ++ ++ if (!aop->hw->sram_32bit) { ++ memcpy_toio(aop->sram, image, size); ++ memset_io(aop->sram + size, 0, aop->sram_size - size); ++ return; ++ } ++ ++ /* The image size is a multiple of 4, checked by the caller. */ ++ __iowrite32_copy(aop->sram, image, size / 4); ++ for (offset = size; offset + 4 <= aop->sram_size; offset += 4) ++ writel_relaxed(0, aop->sram + offset); ++ for (; offset < aop->sram_size; offset++) ++ writeb_relaxed(0, aop->sram + offset); ++} ++ ++/* S8000: point the AOP's window at its SRAM; the firmware runs from there. */ ++static void apple_aop_map_sram(struct apple_aop *aop) ++{ ++ writel(0, aop->akf + APPLE_AOP_REMAP_IOVA_LO); ++ writel(0, aop->akf + APPLE_AOP_REMAP_IOVA_HI); ++ writel(aop->sram_size & ~0xfffULL, aop->akf + APPLE_AOP_REMAP_SIZE); ++ writel(0, aop->akf + APPLE_AOP_REMAP_RESERVED); ++ writel(lower_32_bits(aop->sram_base), aop->akf + APPLE_AOP_REMAP_PA_LO); ++ writel(upper_32_bits(aop->sram_base), aop->akf + APPLE_AOP_REMAP_PA_HI); ++ writel(1, aop->akf + APPLE_AOP_REMAP_ENABLE); ++} ++ + static int apple_aop_load(struct apple_aop *aop, u64 ecid) + { ++ struct apple_aop_bootarg args[APPLE_AOP_MAX_BOOTARGS]; + const struct firmware *main_fw, *ext_fw; + const char *main_name, *ext_name; + struct device_node *np = aop->dev->of_node; +- u8 prng[32], nonce[8]; +- __le64 ecid_le = cpu_to_le64(ecid), ext_le; ++ u8 prng[32], nonce[8], guard[4], ncal = 0; ++ __le64 ecid_le = cpu_to_le64(ecid), ext_le, wrapper_le; ++ __le32 target_le, chip_le, revision_le; ++ unsigned int count = 0; + u8 *image; + int ret; + +@@ -316,28 +390,43 @@ static int apple_aop_load(struct apple_aop *aop, u64 ecid) + } + + get_random_bytes(prng, sizeof(prng)); +- get_random_bytes(nonce, sizeof(nonce)); +- { +- struct apple_aop_bootarg args[] = { +- { APPLE_AOP_BOOTARG_PRNG, prng, sizeof(prng) }, +- { APPLE_AOP_BOOTARG_ECID, &ecid_le, sizeof(ecid_le) }, +- { APPLE_AOP_BOOTARG_NONC, nonce, sizeof(nonce) }, +- { APPLE_AOP_BOOTARG_EC0P, &ext_le, sizeof(ext_le) }, +- }; +- +- ret = apple_aop_patch_bootargs(aop, image, main_fw->size, args, +- ARRAY_SIZE(args)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_PRNG, prng, sizeof(prng)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_ECID, &ecid_le, sizeof(ecid_le)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_EC0P, &ext_le, sizeof(ext_le)); ++ if (aop->hw->nonce) { ++ get_random_bytes(nonce, sizeof(nonce)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_NONC, nonce, sizeof(nonce)); + } +- if (ret) { +- dev_err(aop->dev, "unexpected boot arguments in %s: %d\n", main_name, ret); +- } else { +- memcpy_toio(aop->sram, image, main_fw->size); +- memset_io(aop->sram + main_fw->size, 0, aop->sram_size - main_fw->size); ++ if (aop->hw->soc_bootargs) { ++ /* A random stack guard with one zero byte */ ++ get_random_bytes(guard, sizeof(guard)); ++ guard[get_random_u32_below(sizeof(guard))] = 0; ++ target_le = cpu_to_le32(aop->target); ++ chip_le = cpu_to_le32(aop->chip_id); ++ revision_le = cpu_to_le32(aop->chip_revision); ++ wrapper_le = cpu_to_le64(aop->akf_base); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_AOPT, ++ &target_le, sizeof(target_le)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_NCAL, &ncal, sizeof(ncal)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_WRAD, ++ &wrapper_le, sizeof(wrapper_le)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_SOC, ++ &chip_le, sizeof(chip_le)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_SOCR, ++ &revision_le, sizeof(revision_le)); ++ apple_aop_add_bootarg(args, &count, APPLE_AOP_BOOTARG_STKG, guard, sizeof(guard)); + } + ++ ret = apple_aop_patch_bootargs(aop, image, main_fw->size, args, count); ++ if (ret) ++ dev_err(aop->dev, "unexpected boot arguments in %s: %d\n", main_name, ret); ++ else ++ apple_aop_write_sram(aop, image, main_fw->size); ++ + kfree_sensitive(image); + memzero_explicit(prng, sizeof(prng)); + memzero_explicit(nonce, sizeof(nonce)); ++ memzero_explicit(guard, sizeof(guard)); + memzero_explicit(&ecid_le, sizeof(ecid_le)); + out_ext: + release_firmware(ext_fw); +@@ -448,7 +537,8 @@ static void apple_aop_announce(struct apple_aop_ep *ep, u32 channel, const void + const struct epic_service_announce *announce = data; + struct apple_aop_register_work *rw; + +- if (len < sizeof(*announce)) ++ /* Only the name and channel are used; the S8000's announcements are shorter. */ ++ if (len < offsetofend(struct epic_service_announce, channel)) + return; + + rw = kzalloc_obj(*rw); +@@ -825,20 +915,24 @@ static int apple_aop_probe(struct platform_device *pdev) + if (!aop) + return -ENOMEM; + aop->dev = dev; ++ aop->hw = of_device_get_match_data(dev); + mutex_init(&aop->listeners_lock); + INIT_LIST_HEAD(&aop->listeners); + mutex_init(&aop->children_lock); + INIT_LIST_HEAD(&aop->children); + +- aop->akf = devm_platform_ioremap_resource_byname(pdev, "akf"); ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "akf"); ++ aop->akf = devm_ioremap_resource(dev, res); + if (IS_ERR(aop->akf)) + return PTR_ERR(aop->akf); ++ aop->akf_base = res->start; + aop->control = devm_platform_ioremap_resource_byname(pdev, "control"); + if (IS_ERR(aop->control)) + return PTR_ERR(aop->control); + aop->sram = devm_platform_get_and_ioremap_resource(pdev, 2, &res); + if (IS_ERR(aop->sram)) + return PTR_ERR(aop->sram); ++ aop->sram_base = res->start; + aop->sram_size = resource_size(res); + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(44)); +@@ -853,6 +947,17 @@ static int apple_aop_probe(struct platform_device *pdev) + if (ret) + return dev_err_probe(dev, ret, "no apple,ecid from the bootloader\n"); + ++ if (aop->hw->soc_bootargs) { ++ ret = of_property_read_u32(np, "apple,aop-target", &aop->target); ++ if (!ret) ++ ret = of_property_read_u32(np, "apple,chip-id", &aop->chip_id); ++ if (!ret) ++ ret = of_property_read_u32(np, "apple,chip-revision", &aop->chip_revision); ++ if (ret) ++ return dev_err_probe(dev, ret, ++ "no AOP target or chip ID from the bootloader\n"); ++ } ++ + aop->eps = devm_kcalloc(dev, AFK_ENDPOINT_COUNT, sizeof(*aop->eps), GFP_KERNEL); + if (!aop->eps) + return -ENOMEM; +@@ -867,6 +972,9 @@ static int apple_aop_probe(struct platform_device *pdev) + if (ret) + goto err_free; + ++ if (aop->hw->sram_window) ++ apple_aop_map_sram(aop); ++ + aop->rtk = apple_rtkit_init(dev, aop, "mbox", 0, &apple_aop_rtkit_ops); + if (IS_ERR(aop->rtk)) { + ret = dev_err_probe(dev, PTR_ERR(aop->rtk), "failed to init RTKit\n"); +@@ -939,8 +1047,19 @@ static void apple_aop_shutdown(struct platform_device *pdev) + dev_err(aop->dev, "failed to halt\n"); + } + ++static const struct apple_aop_hw apple_aop_s8000_hw = { ++ .sram_window = true, ++ .sram_32bit = true, ++ .soc_bootargs = true, ++}; ++ ++static const struct apple_aop_hw apple_aop_t8010_hw = { ++ .nonce = true, ++}; ++ + static const struct of_device_id apple_aop_of_match[] = { +- { .compatible = "apple,t8010-aop" }, ++ { .compatible = "apple,s8000-aop", .data = &apple_aop_s8000_hw }, ++ { .compatible = "apple,t8010-aop", .data = &apple_aop_t8010_hw }, + {} + }; + MODULE_DEVICE_TABLE(of, apple_aop_of_match); +@@ -957,5 +1076,5 @@ static struct platform_driver apple_aop_driver = { + module_platform_driver(apple_aop_driver); + + MODULE_AUTHOR("Dalton Alexandre "); +-MODULE_DESCRIPTION("Apple T8010 Always-On Processor driver"); ++MODULE_DESCRIPTION("Apple S8000 and T8010 Always-On Processor driver"); + MODULE_LICENSE("Dual MIT/GPL"); +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/soc-apple/0019-soc-apple-aop-Add-service-properties-and-factory-cal.patch b/kernel/patches/drivers/soc-apple/0019-soc-apple-aop-Add-service-properties-and-factory-cal.patch new file mode 100644 index 00000000..e8753b0f --- /dev/null +++ b/kernel/patches/drivers/soc-apple/0019-soc-apple-aop-Add-service-properties-and-factory-cal.patch @@ -0,0 +1,151 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] soc: apple: aop: Add service properties and factory + calibration + +The sensor services of the AOP firmware are configured through EPIC +set-property requests (subtype 0x4): the report intervals, and the +unit's factory calibration, which the bootloader copies from the Apple +device tree into the sensor's node. Once the calibration is sent, the +firmware is told whether it is complete (property 0x3d: 2 complete, +1 partial); the S8000's firmware sends no reports before that. + +Add apple_aop_set_property() for a property of up to 64 bytes, and +apple_aop_calibrate(), which sends a sensor driver's table of +calibration properties that are present in its node and then the +calibration state. A table entry belongs to a group; the calibration +is complete once one entry of every group was applied. + +[Orchard: from orchard PR #101, commit a54e2049; the property and + calibration API of soc-apple/0015, unchanged] + +Assisted-by: LLM +--- + drivers/soc/apple/aop.c | 58 +++++++++++++++++++++++++++++++++++ + include/linux/soc/apple/aop.h | 28 +++++++++++++++++ + 2 files changed, 86 insertions(+) + +diff --git a/drivers/soc/apple/aop.c b/drivers/soc/apple/aop.c +index ffd48d6..6d94720 100644 +--- a/drivers/soc/apple/aop.c ++++ b/drivers/soc/apple/aop.c +@@ -117,6 +117,12 @@ + #define APPLE_AOP_MAX_CALLS 8 + #define APPLE_AOP_CALL_TIMEOUT msecs_to_jiffies(1000) + ++/* Service properties */ ++#define APPLE_AOP_PROPERTY_MAX 64 ++#define APPLE_AOP_PROP_CALIBRATION 0x3d ++#define APPLE_AOP_CALIBRATION_PARTIAL 1 ++#define APPLE_AOP_CALIBRATION_COMPLETE 2 ++ + struct afk_qe_header { + __le32 magic; + __le32 size; +@@ -887,6 +893,58 @@ int apple_aop_call(const struct apple_aop_service *service, u16 subtype, const v + } + EXPORT_SYMBOL_GPL(apple_aop_call); + ++int apple_aop_set_property(const struct apple_aop_service *service, u32 key, ++ const void *value, size_t len) ++{ ++ u8 buf[8 + APPLE_AOP_PROPERTY_MAX]; ++ int ret; ++ ++ if (len > APPLE_AOP_PROPERTY_MAX) ++ return -EINVAL; ++ put_unaligned_le32(0, buf); ++ put_unaligned_le32(key, buf + 4); ++ memcpy(buf + 8, value, len); ++ ++ ret = apple_aop_call(service, APPLE_AOP_SET_PROPERTY, buf, 8 + len, NULL, 0); ++ return ret > 0 ? -EIO : ret; ++} ++EXPORT_SYMBOL_GPL(apple_aop_set_property); ++ ++int apple_aop_calibrate(const struct apple_aop_service *service, struct device *dev, ++ const struct apple_aop_calibration *cal, unsigned int count) ++{ ++ unsigned long needed = 0, applied = 0; ++ __le32 state; ++ unsigned int i; ++ int len, ret; ++ ++ for (i = 0; i < count; i++) { ++ const void *blob; ++ ++ if (cal[i].group) ++ needed |= BIT(cal[i].group); ++ blob = of_get_property(dev->of_node, cal[i].property, &len); ++ if (!blob) ++ continue; ++ ret = apple_aop_set_property(service, cal[i].key, blob, len); ++ if (ret) { ++ dev_warn(dev, "%s not applied: %d\n", cal[i].property, ret); ++ continue; ++ } ++ if (cal[i].group) ++ applied |= BIT(cal[i].group); ++ } ++ ++ if (needed && applied == needed) { ++ state = cpu_to_le32(APPLE_AOP_CALIBRATION_COMPLETE); ++ } else { ++ dev_warn(dev, "factory calibration incomplete\n"); ++ state = cpu_to_le32(APPLE_AOP_CALIBRATION_PARTIAL); ++ } ++ return apple_aop_set_property(service, APPLE_AOP_PROP_CALIBRATION, &state, sizeof(state)); ++} ++EXPORT_SYMBOL_GPL(apple_aop_calibrate); ++ + /* Driver */ + + static void apple_aop_free_buffers(struct apple_aop *aop) +diff --git a/include/linux/soc/apple/aop.h b/include/linux/soc/apple/aop.h +index 8c8bc71..b5188a0 100644 +--- a/include/linux/soc/apple/aop.h ++++ b/include/linux/soc/apple/aop.h +@@ -7,6 +7,8 @@ + + #include + ++struct device; ++ + struct apple_aop; + + /* +@@ -40,4 +42,30 @@ void apple_aop_unlisten(const struct apple_aop_service *service); + int apple_aop_call(const struct apple_aop_service *service, u16 subtype, + const void *data, size_t len, void *reply, size_t reply_len); + ++/* The EPIC notification subtype that sets a service property */ ++#define APPLE_AOP_SET_PROPERTY 0x4 ++ ++/* Set property @key of a service to @len (at most 64) bytes at @value. */ ++int apple_aop_set_property(const struct apple_aop_service *service, u32 key, ++ const void *value, size_t len); ++ ++/* ++ * A factory calibration blob of a sensor: the bootloader copies it from the ++ * Apple device tree into the sensor's node as @property, and the firmware ++ * takes it as property @key. The calibration is complete once a blob of each ++ * @group (1 to 31) was applied; group 0 blobs are not needed for that. ++ */ ++struct apple_aop_calibration { ++ const char *property; ++ u32 key; ++ u8 group; ++}; ++ ++/* ++ * Send the factory calibration found in @dev's node, then tell the firmware ++ * whether it is complete. Some firmware (S8000) sends no reports before. ++ */ ++int apple_aop_calibrate(const struct apple_aop_service *service, struct device *dev, ++ const struct apple_aop_calibration *cal, unsigned int count); ++ + #endif /* _LINUX_SOC_APPLE_AOP_H_ */ +-- +2.54.0 (Apple Git-157) + diff --git a/kernel/patches/drivers/soc-apple/0020-MAINTAINERS-Add-the-Apple-AOP-gyroscope-and-pressure.patch b/kernel/patches/drivers/soc-apple/0020-MAINTAINERS-Add-the-Apple-AOP-gyroscope-and-pressure.patch new file mode 100644 index 00000000..8496b6ff --- /dev/null +++ b/kernel/patches/drivers/soc-apple/0020-MAINTAINERS-Add-the-Apple-AOP-gyroscope-and-pressure.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Berkay=20K=C3=B6sebay?= +Date: Thu, 12 Nov 2026 09:00:00 +0100 +Subject: [PATCH] MAINTAINERS: Add the Apple AOP gyroscope and pressure drivers + +List the AOP's gyroscope and pressure sensor drivers with the AOP +driver they are built on. + +[Orchard: from orchard PR #101, commit a54e2049; the MAINTAINERS part of + soc-apple/0015, split out because drivers/iio applies before + drivers/soc-apple, where the AOP entry is added] + +Assisted-by: LLM +--- + MAINTAINERS | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/MAINTAINERS b/MAINTAINERS +index a4a6964..12c2928 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2068,6 +2068,8 @@ APPLE T8010 ALWAYS-ON PROCESSOR + M: Dalton Alexandre + S: Maintained + F: Documentation/devicetree/bindings/soc/apple/apple,t8010-aop.yaml ++F: drivers/iio/gyro/apple_aop_gyro.c ++F: drivers/iio/pressure/apple_aop_pressure.c + F: drivers/soc/apple/aop.c + F: include/linux/soc/apple/aop.h + +-- +2.54.0 (Apple Git-157) + diff --git a/tests/test_t8010_device_data.py b/tests/test_t8010_device_data.py index 4e8c9e6e..ee20c739 100644 --- a/tests/test_t8010_device_data.py +++ b/tests/test_t8010_device_data.py @@ -24,7 +24,7 @@ # Recipe steps implemented by the Orchard CLI (docs/firmware-recipes.md). STEPS = {'copy@1', 'bluetool-hcd@1', 'smartio-from-kernelcache@1', 'im4p-payload@1', 'z2fw-from-mtprops@1', 'z2fw-from-mtprops@2', 'z2fw-from-mtfw@1', 'vxd-firmware-from-kernelcache@1', - 'agx-g9p-firmware-from-kernelcache@1'} + 'agx-g9p-firmware-from-kernelcache@1', 'aop-image@1'} # Touch firmware the device tree requests (firmware-name); J171 shares the iPad 7 DT with J172. TOUCH = {'d11': 'dfrmtfw-d11-c1f5e-2.bin', 'd111': 'dfrmtfw-d111-c1f5e-2.bin', 'j171': 'dfrmtfw-j172-k1f19-6.bin', 'j172': 'dfrmtfw-j172-k1f19-6.bin'} @@ -85,7 +85,8 @@ def test_kernel_request_names(self): names = [PurePosixPath(o['destination']).name for o in self.load(profile)[1]['outputs']] for name in names: self.assertTrue(name.startswith(('brcmfmac4355', 'BCM.apple,', 't8010-smartio.bin', - 'vxd-deva.bin', 'gfx-t8010.bin', profile + '-fwstart')) or name == TOUCH.get(profile), name) + 'vxd-deva.bin', 'gfx-t8010.bin', 'aop-ipad7', + profile + '-fwstart')) or name == TOUCH.get(profile), name) def test_touch_is_claimed_exactly_where_firmware_is_built(self): for profile in BOARDS: diff --git a/tools/catalog/drivers.json b/tools/catalog/drivers.json index 0aedc420..0af8941c 100644 --- a/tools/catalog/drivers.json +++ b/tools/catalog/drivers.json @@ -6,6 +6,7 @@ "bluetooth_audio", "bluetooth_input", "buttons", + "gyroscope", "storage_read", "storage_write", "usb_network", @@ -17,6 +18,7 @@ "bluetooth_audio", "bluetooth_input", "buttons", + "gyroscope", "storage_read", "storage_write", "usb_network", @@ -29,6 +31,7 @@ "bluetooth_audio", "bluetooth_input", "buttons", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -44,6 +47,7 @@ "bluetooth_audio", "bluetooth_input", "buttons", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -136,6 +140,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -154,6 +159,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -190,6 +196,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -200,6 +207,7 @@ "wifi" ], "j71s": [ + "accelerometer", "audio_output", "backlight", "battery", @@ -207,6 +215,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "touch", "usb_network", @@ -214,6 +223,7 @@ "video_decode_hevc" ], "j71t": [ + "accelerometer", "audio_output", "backlight", "battery", @@ -221,6 +231,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -239,6 +250,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -249,6 +261,7 @@ "wifi" ], "j72s": [ + "accelerometer", "audio_output", "backlight", "battery", @@ -256,6 +269,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "touch", "usb_network", @@ -263,6 +277,7 @@ "video_decode_hevc" ], "j72t": [ + "accelerometer", "audio_output", "backlight", "battery", @@ -270,6 +285,7 @@ "bluetooth_input", "buttons", "charging", + "gyroscope", "light_sensor", "storage_read", "storage_write", @@ -401,38 +417,50 @@ "usb_serial" ], "n66": [ + "accelerometer", "backlight", "buttons", + "gyroscope", "usb_network", "usb_serial" ], "n66m": [ + "accelerometer", "backlight", "buttons", + "gyroscope", "usb_network", "usb_serial" ], "n69": [ + "accelerometer", "backlight", "buttons", + "gyroscope", "usb_network", "usb_serial" ], "n69u": [ + "accelerometer", "backlight", "buttons", + "gyroscope", "usb_network", "usb_serial" ], "n71": [ + "accelerometer", "backlight", "buttons", + "gyroscope", "usb_network", "usb_serial" ], "n71m": [ + "accelerometer", "backlight", "buttons", + "gyroscope", "usb_network", "usb_serial" ] diff --git a/tools/catalog/feature-drivers.toml b/tools/catalog/feature-drivers.toml index e8cb9f07..4ed8524b 100644 --- a/tools/catalog/feature-drivers.toml +++ b/tools/catalog/feature-drivers.toml @@ -6,6 +6,7 @@ touch = ["apple_z2", "apple_hidspi_ts"] buttons = ["gpio_keys"] backlight = ["apple_dwi_bl", "apple_pmic_bl", "apple_dsi_bl"] accelerometer = ["apple_aop_accel"] +gyroscope = ["apple_aop_gyro"] light_sensor = ["tsl2583"] storage_read = ["nvme_apple", "pcie_apple_h9p:apple,nvme-hmb"] storage_write = ["nvme_apple", "pcie_apple_h9p:apple,nvme-hmb"]