Skip to content

Commit fad6f24

Browse files
committed
Merge branch 'bits/250-aop' into asahi-wip
2 parents 3504b9b + cfe7ddb commit fad6f24

File tree

29 files changed

+2758
-5
lines changed

29 files changed

+2758
-5
lines changed

drivers/iio/common/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# IIO common modules
44
#
55

6+
source "drivers/iio/common/aop_sensors/Kconfig"
67
source "drivers/iio/common/cros_ec_sensors/Kconfig"
78
source "drivers/iio/common/hid-sensors/Kconfig"
89
source "drivers/iio/common/inv_sensors/Kconfig"

drivers/iio/common/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#
99

1010
# When adding new entries keep the list in alphabetical order
11+
obj-y += aop_sensors/
1112
obj-y += cros_ec_sensors/
1213
obj-y += hid-sensors/
1314
obj-y += inv_sensors/
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
3+
config IIO_AOP_SENSOR_LAS
4+
tristate "AOP Lid angle sensor"
5+
depends on ARCH_APPLE || COMPILE_TEST
6+
depends on RUST
7+
depends on SYSFS
8+
select APPLE_AOP
9+
help
10+
Module to handle the lid angle sensor attached to the AOP
11+
coprocessor on Apple laptops.
12+
13+
config IIO_AOP_SENSOR_ALS
14+
tristate "AOP Ambient light sensor"
15+
depends on ARCH_APPLE || COMPILE_TEST
16+
depends on RUST
17+
depends on SYSFS
18+
select APPLE_AOP
19+
help
20+
Module to handle the ambient light sensor attached to the AOP
21+
coprocessor on Apple laptops.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
3+
obj-$(CONFIG_IIO_AOP_SENSOR_LAS) += aop_las.o
4+
obj-$(CONFIG_IIO_AOP_SENSOR_ALS) += aop_als.o
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
3+
//! Apple AOP ambient light sensor driver
4+
//!
5+
//! Copyright (C) The Asahi Linux Contributors
6+
7+
use kernel::{
8+
bindings, c_str,
9+
device::Core,
10+
firmware::Firmware,
11+
iio::common::aop_sensors::{AopSensorData, IIORegistration, MessageProcessor},
12+
module_platform_driver, of, platform,
13+
prelude::*,
14+
soc::apple::aop::{EPICService, AOP},
15+
sync::Arc,
16+
types::ForeignOwnable,
17+
};
18+
19+
const EPIC_SUBTYPE_GET_AOP_PROPERTY: u16 = 0xa;
20+
const EPIC_SUBTYPE_SET_ALS_PROPERTY: u16 = 0x4;
21+
const LUX_OFFSET_CT720: usize = 0x1d;
22+
const LUX_OFFSET_VD6286: usize = 0x28;
23+
24+
fn get_lux_offset(aop: &dyn AOP, dev: &platform::Device, svc: &EPICService) -> Result<usize> {
25+
let name = get_aop_property(aop, svc, 0xf, 16)?.1;
26+
match name.as_slice() {
27+
b"Redbird\0" => Ok(LUX_OFFSET_VD6286),
28+
b"FireFish2\0" => Ok(LUX_OFFSET_CT720),
29+
_ => {
30+
dev_warn!(
31+
dev.as_ref(),
32+
"Unknown sensor type {:?}",
33+
str::from_utf8(&name)
34+
);
35+
Err(EIO)
36+
}
37+
}
38+
}
39+
40+
fn enable_als(aop: &dyn AOP, dev: &platform::Device, svc: &EPICService) -> Result<()> {
41+
let fw = Firmware::request(c_str!("apple/aop-als-cal.bin"), dev.as_ref())?;
42+
set_als_property(aop, svc, 0xb, fw.data())?;
43+
set_als_property(aop, svc, 0, &200000u32.to_le_bytes())?;
44+
45+
Ok(())
46+
}
47+
48+
fn get_aop_property(
49+
aop: &dyn AOP,
50+
svc: &EPICService,
51+
tag: u32,
52+
data_len: usize,
53+
) -> Result<(u32, KVec<u8>)> {
54+
let mut buf = KVec::new();
55+
buf.resize(8, 0, GFP_KERNEL)?;
56+
buf[4..8].copy_from_slice(&tag.to_le_bytes());
57+
aop.epic_call_ret(svc, EPIC_SUBTYPE_GET_AOP_PROPERTY, &buf, data_len)
58+
}
59+
60+
fn set_als_property(aop: &dyn AOP, svc: &EPICService, tag: u32, data: &[u8]) -> Result<u32> {
61+
let mut buf = KVec::new();
62+
buf.resize(data.len() + 8, 0, GFP_KERNEL)?;
63+
buf[8..].copy_from_slice(data);
64+
buf[4..8].copy_from_slice(&tag.to_le_bytes());
65+
aop.epic_call(svc, EPIC_SUBTYPE_SET_ALS_PROPERTY, &buf)
66+
}
67+
68+
fn f32_to_u32(f: u32) -> u32 {
69+
if f & 0x80000000 != 0 {
70+
return 0;
71+
}
72+
let exp = ((f & 0x7f800000) >> 23) as i32 - 127;
73+
if exp < 0 {
74+
return 0;
75+
}
76+
if exp == 128 && f & 0x7fffff != 0 {
77+
return 0;
78+
}
79+
let mant = f & 0x7fffff | 0x800000;
80+
if exp <= 23 {
81+
return mant >> (23 - exp);
82+
}
83+
if exp >= 32 {
84+
return u32::MAX;
85+
}
86+
mant << (exp - 23)
87+
}
88+
89+
struct MsgProc(usize);
90+
91+
impl MessageProcessor for MsgProc {
92+
fn process(&self, message: &[u8]) -> u32 {
93+
let offset = self.0;
94+
let raw = u32::from_le_bytes(message[offset..offset + 4].try_into().unwrap());
95+
f32_to_u32(raw)
96+
}
97+
}
98+
99+
#[repr(transparent)]
100+
struct IIOAopAlsDriver(IIORegistration<MsgProc>);
101+
102+
kernel::of_device_table!(
103+
OF_TABLE,
104+
MODULE_OF_TABLE,
105+
(),
106+
[(of::DeviceId::new(c_str!("apple,aop-als")), ())]
107+
);
108+
109+
impl platform::Driver for IIOAopAlsDriver {
110+
type IdInfo = ();
111+
112+
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
113+
114+
fn probe(
115+
pdev: &platform::Device<Core>,
116+
_info: Option<&()>,
117+
) -> Result<Pin<KBox<IIOAopAlsDriver>>> {
118+
let dev = pdev.as_ref();
119+
let parent = dev.parent().unwrap();
120+
// SAFETY: our parent is AOP, and AopDriver is repr(transparent) for Arc<dyn Aop>
121+
let adata_ptr = unsafe { Pin::<KBox<Arc<dyn AOP>>>::borrow(parent.get_drvdata()) };
122+
let adata = (&*adata_ptr).clone();
123+
// SAFETY: AOP sets the platform data correctly
124+
let service = unsafe { *((*dev.as_raw()).platform_data as *const EPICService) };
125+
let ty = bindings::BINDINGS_IIO_LIGHT;
126+
let offset = get_lux_offset(adata.as_ref(), pdev, &service)?;
127+
let data = AopSensorData::new(dev.into(), ty, MsgProc(offset))?;
128+
adata.add_fakehid_listener(service, data.clone())?;
129+
enable_als(adata.as_ref(), pdev, &service)?;
130+
let info_mask = 1 << bindings::BINDINGS_IIO_CHAN_INFO_PROCESSED;
131+
Ok(KBox::pin(
132+
IIOAopAlsDriver(IIORegistration::<MsgProc>::new(
133+
data,
134+
c_str!("aop-sensors-als"),
135+
ty,
136+
info_mask,
137+
&THIS_MODULE,
138+
)?),
139+
GFP_KERNEL,
140+
)?)
141+
}
142+
}
143+
144+
module_platform_driver! {
145+
type: IIOAopAlsDriver,
146+
name: "iio_aop_als",
147+
description: "AOP ambient light sensor driver",
148+
license: "Dual MIT/GPL",
149+
alias: ["platform:iio_aop_als"],
150+
firmware: ["apple/aop-als-cal.bin"],
151+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
3+
//! Apple AOP lid angle sensor driver
4+
//!
5+
//! Copyright (C) The Asahi Linux Contributors
6+
7+
use kernel::{
8+
bindings, c_str,
9+
device::Core,
10+
iio::common::aop_sensors::{AopSensorData, IIORegistration, MessageProcessor},
11+
module_platform_driver, of, platform,
12+
prelude::*,
13+
soc::apple::aop::{EPICService, AOP},
14+
sync::Arc,
15+
types::ForeignOwnable,
16+
};
17+
18+
struct MsgProc;
19+
20+
impl MessageProcessor for MsgProc {
21+
fn process(&self, message: &[u8]) -> u32 {
22+
message[1] as u32
23+
}
24+
}
25+
26+
#[repr(transparent)]
27+
struct IIOAopLasDriver(IIORegistration<MsgProc>);
28+
29+
kernel::of_device_table!(
30+
OF_TABLE,
31+
MODULE_OF_TABLE,
32+
(),
33+
[(of::DeviceId::new(c_str!("apple,aop-las")), ())]
34+
);
35+
36+
impl platform::Driver for IIOAopLasDriver {
37+
type IdInfo = ();
38+
39+
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
40+
41+
fn probe(
42+
pdev: &platform::Device<Core>,
43+
_info: Option<&()>,
44+
) -> Result<Pin<KBox<IIOAopLasDriver>>> {
45+
let dev = pdev.as_ref();
46+
let parent = dev.parent().unwrap();
47+
// SAFETY: our parent is AOP, and AopDriver is repr(transparent) for Arc<dyn Aop>
48+
let adata_ptr = unsafe { Pin::<KBox<Arc<dyn AOP>>>::borrow(parent.get_drvdata()) };
49+
let adata = (&*adata_ptr).clone();
50+
// SAFETY: AOP sets the platform data correctly
51+
let service = unsafe { *((*dev.as_raw()).platform_data as *const EPICService) };
52+
53+
let ty = bindings::BINDINGS_IIO_ANGL;
54+
let data = AopSensorData::new(dev.into(), ty, MsgProc)?;
55+
adata.add_fakehid_listener(service, data.clone())?;
56+
let info_mask = 1 << bindings::BINDINGS_IIO_CHAN_INFO_RAW;
57+
Ok(KBox::pin(
58+
IIOAopLasDriver(IIORegistration::<MsgProc>::new(
59+
data,
60+
c_str!("aop-sensors-las"),
61+
ty,
62+
info_mask,
63+
&THIS_MODULE,
64+
)?),
65+
GFP_KERNEL,
66+
)?)
67+
}
68+
}
69+
70+
module_platform_driver! {
71+
type: IIOAopLasDriver,
72+
name: "iio_aop_las",
73+
description: "AOP lid angle sensor driver",
74+
license: "Dual MIT/GPL",
75+
alias: ["platform:iio_aop_las"],
76+
}

drivers/soc/apple/Kconfig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,43 @@ config APPLE_SART
7272

7373
Say 'y' here if you have an Apple SoC.
7474

75+
config RUST_APPLE_MAILBOX
76+
bool
77+
depends on PM
78+
depends on RUST
79+
select APPLE_MAILBOX
80+
7581
config RUST_APPLE_RTKIT
7682
bool
7783
depends on PM
7884
depends on RUST
7985
select APPLE_RTKIT
8086

87+
config APPLE_AOP
88+
tristate "Apple \"Always-on\" Processor"
89+
depends on ARCH_APPLE || COMPILE_TEST
90+
depends on PM
91+
depends on RUST
92+
select RUST_APPLE_RTKIT
93+
help
94+
A co-processor persent on certain Apple SoCs controlling accelerometers,
95+
gyros, ambient light sensors and microphones. Is not actually always on.
96+
97+
Say 'y' here if you have an Apple laptop.
98+
99+
config APPLE_SEP
100+
tristate "Apple Secure Element Processor"
101+
depends on ARCH_APPLE || COMPILE_TEST
102+
depends on PM
103+
depends on RUST
104+
select RUST_APPLE_RTKIT
105+
select RUST_APPLE_MAILBOX
106+
help
107+
A security co-processor persent on Apple SoCs, controlling transparent
108+
disk encryption, secure boot, HDCP, biometric auth and probably more.
109+
110+
Say 'y' here if you have an Apple SoC.
111+
81112
endmenu
82113

83114
endif

drivers/soc/apple/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ apple-rtkit-helper-y = rtkit-helper.o
1919

2020
obj-$(CONFIG_APPLE_SART) += apple-sart.o
2121
apple-sart-y = sart.o
22+
23+
obj-$(CONFIG_APPLE_AOP) += aop.o
24+
25+
obj-$(CONFIG_APPLE_SEP) += sep.o

0 commit comments

Comments
 (0)