Skip to content

Commit 48eeb90

Browse files
committed
Merge branch 'bits/250-aop' into asahi-wip
2 parents 2b15f68 + 6e085aa commit 48eeb90

File tree

30 files changed

+2681
-5
lines changed

30 files changed

+2681
-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: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
default m if ARCH_APPLE
10+
help
11+
Module to handle the lid angle sensor attached to the AOP
12+
coprocessor on Apple laptops.
13+
14+
config IIO_AOP_SENSOR_ALS
15+
tristate "AOP Ambient light sensor"
16+
depends on ARCH_APPLE || COMPILE_TEST
17+
depends on RUST
18+
depends on SYSFS
19+
select APPLE_AOP
20+
default m if ARCH_APPLE
21+
help
22+
Module to handle the ambient light sensor attached to the AOP
23+
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: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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+
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+
const EPIC_SUBTYPE_SET_ALS_PROPERTY: u16 = 0x4;
19+
20+
fn enable_als(aop: &dyn AOP, dev: &platform::Device, svc: &EPICService) -> Result<()> {
21+
let fwnode = dev.as_ref().fwnode().ok_or(ENODEV)?;
22+
let prop_name = c_str!("apple,als-calibration");
23+
if !fwnode.property_present(prop_name) {
24+
dev_warn!(
25+
dev.as_ref(),
26+
"ALS Calibration not found, will not enable it"
27+
);
28+
return Ok(());
29+
}
30+
let calib_len = fwnode.property_count_elem::<u8>(prop_name)?;
31+
let prop = fwnode
32+
.property_read_array_vec::<u8>(prop_name, calib_len)?
33+
.required_by(dev.as_ref())?;
34+
35+
set_als_property(aop, svc, 0xb, &prop)?;
36+
set_als_property(aop, svc, 0, &200000u32.to_le_bytes())?;
37+
38+
Ok(())
39+
}
40+
fn set_als_property(aop: &dyn AOP, svc: &EPICService, tag: u32, data: &[u8]) -> Result<u32> {
41+
let mut buf = KVec::new();
42+
buf.resize(data.len() + 8, 0, GFP_KERNEL)?;
43+
buf[8..].copy_from_slice(data);
44+
buf[4..8].copy_from_slice(&tag.to_le_bytes());
45+
aop.epic_call(svc, EPIC_SUBTYPE_SET_ALS_PROPERTY, &buf)
46+
}
47+
48+
fn f32_to_u32(f: u32) -> u32 {
49+
if f & 0x80000000 != 0 {
50+
return 0;
51+
}
52+
let exp = ((f & 0x7f800000) >> 23) as i32 - 127;
53+
if exp < 0 {
54+
return 0;
55+
}
56+
if exp == 128 && f & 0x7fffff != 0 {
57+
return 0;
58+
}
59+
let mant = f & 0x7fffff | 0x800000;
60+
if exp <= 23 {
61+
return mant >> (23 - exp);
62+
}
63+
if exp >= 32 {
64+
return u32::MAX;
65+
}
66+
mant << (exp - 23)
67+
}
68+
69+
struct MsgProc(usize);
70+
71+
impl MessageProcessor for MsgProc {
72+
fn process(&self, message: &[u8]) -> u32 {
73+
let offset = self.0;
74+
let raw = u32::from_le_bytes(message[offset..offset + 4].try_into().unwrap());
75+
f32_to_u32(raw)
76+
}
77+
}
78+
79+
#[repr(transparent)]
80+
struct IIOAopAlsDriver(IIORegistration<MsgProc>);
81+
82+
kernel::of_device_table!(
83+
OF_TABLE,
84+
MODULE_OF_TABLE,
85+
(),
86+
[(of::DeviceId::new(c_str!("apple,aop-als")), ())]
87+
);
88+
89+
impl platform::Driver for IIOAopAlsDriver {
90+
type IdInfo = ();
91+
92+
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
93+
94+
fn probe(
95+
pdev: &platform::Device<Core>,
96+
_info: Option<&()>,
97+
) -> Result<Pin<KBox<IIOAopAlsDriver>>> {
98+
let dev = pdev.as_ref();
99+
let parent = dev.parent().unwrap();
100+
// SAFETY: our parent is AOP, and AopDriver is repr(transparent) for Arc<dyn Aop>
101+
let adata_ptr = unsafe { Pin::<KBox<Arc<dyn AOP>>>::borrow(parent.get_drvdata()) };
102+
let adata = (&*adata_ptr).clone();
103+
// SAFETY: AOP sets the platform data correctly
104+
let service = unsafe { *((*dev.as_raw()).platform_data as *const EPICService) };
105+
let ty = bindings::BINDINGS_IIO_LIGHT;
106+
let data = AopSensorData::new(dev.into(), ty, MsgProc(40))?;
107+
adata.add_fakehid_listener(service, data.clone())?;
108+
enable_als(adata.as_ref(), pdev, &service)?;
109+
let info_mask = 1 << bindings::BINDINGS_IIO_CHAN_INFO_PROCESSED;
110+
Ok(KBox::pin(
111+
IIOAopAlsDriver(IIORegistration::<MsgProc>::new(
112+
data,
113+
c_str!("aop-sensors-als"),
114+
ty,
115+
info_mask,
116+
&THIS_MODULE,
117+
)?),
118+
GFP_KERNEL,
119+
)?)
120+
}
121+
}
122+
123+
module_platform_driver! {
124+
type: IIOAopAlsDriver,
125+
name: "iio_aop_als",
126+
description: "AOP ambient light sensor driver",
127+
license: "Dual MIT/GPL",
128+
alias: ["platform:iio_aop_als"],
129+
}
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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,30 @@ config RUST_APPLE_RTKIT
7979
depends on RUST
8080
depends on APPLE_RTKIT
8181

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

84108
endif

drivers/soc/apple/Makefile

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

1717
obj-$(CONFIG_APPLE_SART) += apple-sart.o
1818
apple-sart-y = sart.o
19+
20+
obj-$(CONFIG_APPLE_AOP) += aop.o
21+
22+
obj-$(CONFIG_APPLE_SEP) += sep.o

0 commit comments

Comments
 (0)