Skip to content

Commit

Permalink
Merge branch 'bits/250-aop' into asahi-wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jannau committed Dec 11, 2024
2 parents 0f8915a + 407530e commit fce34c8
Show file tree
Hide file tree
Showing 28 changed files with 2,602 additions and 5 deletions.
1 change: 1 addition & 0 deletions drivers/iio/common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# IIO common modules
#

source "drivers/iio/common/aop_sensors/Kconfig"
source "drivers/iio/common/cros_ec_sensors/Kconfig"
source "drivers/iio/common/hid-sensors/Kconfig"
source "drivers/iio/common/inv_sensors/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions drivers/iio/common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#

# When adding new entries keep the list in alphabetical order
obj-y += aop_sensors/
obj-y += cros_ec_sensors/
obj-y += hid-sensors/
obj-y += inv_sensors/
Expand Down
23 changes: 23 additions & 0 deletions drivers/iio/common/aop_sensors/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# SPDX-License-Identifier: GPL-2.0-only OR MIT

config IIO_AOP_SENSOR_LAS
tristate "AOP Lid angle sensor"
depends on ARCH_APPLE || COMPILE_TEST
depends on RUST
depends on SYSFS
select APPLE_AOP
default m if ARCH_APPLE
help
Module to handle the lid angle sensor attached to the AOP
coprocessor on Apple laptops.

config IIO_AOP_SENSOR_ALS
tristate "AOP Ambient light sensor"
depends on ARCH_APPLE || COMPILE_TEST
depends on RUST
depends on SYSFS
select APPLE_AOP
default m if ARCH_APPLE
help
Module to handle the ambient light sensor attached to the AOP
coprocessor on Apple laptops.
4 changes: 4 additions & 0 deletions drivers/iio/common/aop_sensors/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only OR MIT

obj-$(CONFIG_IIO_AOP_SENSOR_LAS) += aop_las.o
obj-$(CONFIG_IIO_AOP_SENSOR_ALS) += aop_als.o
123 changes: 123 additions & 0 deletions drivers/iio/common/aop_sensors/aop_als.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT

//! Apple AOP ambient light sensor driver
//!
//! Copyright (C) The Asahi Linux Contributors
use kernel::{
bindings, c_str, device,
iio::common::aop_sensors::{AopSensorData, IIORegistration, MessageProcessor},
module_platform_driver,
of::{self, Node},
platform,
prelude::*,
soc::apple::aop::{EPICService, AOP},
sync::Arc,
types::{ARef, ForeignOwnable},
};

const EPIC_SUBTYPE_SET_ALS_PROPERTY: u16 = 0x4;

fn enable_als(
aop: &dyn AOP,
dev: &ARef<device::Device>,
of: &Node,
svc: &EPICService,
) -> Result<()> {
if let Some(prop) = of.find_property(c_str!("apple,als-calibration")) {
set_als_property(aop, svc, 0xb, prop.value())?;
set_als_property(aop, svc, 0, &200000u32.to_le_bytes())?;
} else {
dev_warn!(dev, "ALS Calibration not found, will not enable it");
}
Ok(())
}
fn set_als_property(aop: &dyn AOP, svc: &EPICService, tag: u32, data: &[u8]) -> Result<u32> {
let mut buf = KVec::new();
buf.resize(data.len() + 8, 0, GFP_KERNEL)?;
buf[8..].copy_from_slice(data);
buf[4..8].copy_from_slice(&tag.to_le_bytes());
aop.epic_call(svc, EPIC_SUBTYPE_SET_ALS_PROPERTY, &buf)
}

fn f32_to_u32(f: u32) -> u32 {
if f & 0x80000000 != 0 {
return 0;
}
let exp = ((f & 0x7f800000) >> 23) as i32 - 127;
if exp < 0 {
return 0;
}
if exp == 128 && f & 0x7fffff != 0 {
return 0;
}
let mant = f & 0x7fffff | 0x800000;
if exp <= 23 {
return mant >> (23 - exp);
}
if exp >= 32 {
return u32::MAX;
}
mant << (exp - 23)
}

struct MsgProc(usize);

impl MessageProcessor for MsgProc {
fn process(&self, message: &[u8]) -> u32 {
let offset = self.0;
let raw = u32::from_le_bytes(message[offset..offset + 4].try_into().unwrap());
f32_to_u32(raw)
}
}

#[repr(transparent)]
struct IIOAopAlsDriver(IIORegistration<MsgProc>);

kernel::of_device_table!(OF_TABLE, MODULE_OF_TABLE, (), [] as [(of::DeviceId, ()); 0]);

impl platform::Driver for IIOAopAlsDriver {
type IdInfo = ();

const ID_TABLE: platform::IdTable<()> = &OF_TABLE;

fn probe(
pdev: &mut platform::Device,
_info: Option<&()>,
) -> Result<Pin<KBox<IIOAopAlsDriver>>> {
let dev = pdev.get_device();
let parent = dev.parent().unwrap();
// SAFETY: our parent is AOP, and AopDriver is repr(transparent) for Arc<dyn Aop>
let adata_ptr = unsafe { Pin::<KBox<Arc<dyn AOP>>>::borrow(parent.get_drvdata()) };
let adata = (&*adata_ptr).clone();
// SAFETY: AOP sets the platform data correctly
let service = unsafe { *((*dev.as_raw()).platform_data as *const EPICService) };
let of = parent
.of_node()
.ok_or(EIO)?
.get_child_by_name(c_str!("als"))
.ok_or(EIO)?;
let ty = bindings::BINDINGS_IIO_LIGHT;
let data = AopSensorData::new(dev.clone(), ty, MsgProc(40))?;
adata.add_fakehid_listener(service, data.clone())?;
enable_als(adata.as_ref(), &dev, &of, &service)?;
let info_mask = 1 << bindings::BINDINGS_IIO_CHAN_INFO_PROCESSED;
Ok(KBox::pin(
IIOAopAlsDriver(IIORegistration::<MsgProc>::new(
data,
c_str!("aop-sensors-als"),
ty,
info_mask,
&THIS_MODULE,
)?),
GFP_KERNEL,
)?)
}
}

module_platform_driver! {
type: IIOAopAlsDriver,
name: "iio_aop_als",
license: "Dual MIT/GPL",
alias: ["platform:iio_aop_als"],
}
69 changes: 69 additions & 0 deletions drivers/iio/common/aop_sensors/aop_las.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0-only OR MIT

//! Apple AOP lid angle sensor driver
//!
//! Copyright (C) The Asahi Linux Contributors
use kernel::{
bindings, c_str,
iio::common::aop_sensors::{AopSensorData, IIORegistration, MessageProcessor},
module_platform_driver, of, platform,
prelude::*,
soc::apple::aop::{EPICService, AOP},
sync::Arc,
types::ForeignOwnable,
};

struct MsgProc;

impl MessageProcessor for MsgProc {
fn process(&self, message: &[u8]) -> u32 {
message[1] as u32
}
}

#[repr(transparent)]
struct IIOAopLasDriver(IIORegistration<MsgProc>);

kernel::of_device_table!(OF_TABLE, MODULE_OF_TABLE, (), [] as [(of::DeviceId, ()); 0]);

impl platform::Driver for IIOAopLasDriver {
type IdInfo = ();

const ID_TABLE: platform::IdTable<()> = &OF_TABLE;

fn probe(
pdev: &mut platform::Device,
_info: Option<&()>,
) -> Result<Pin<KBox<IIOAopLasDriver>>> {
let dev = pdev.get_device();
let parent = dev.parent().unwrap();
// SAFETY: our parent is AOP, and AopDriver is repr(transparent) for Arc<dyn Aop>
let adata_ptr = unsafe { Pin::<KBox<Arc<dyn AOP>>>::borrow(parent.get_drvdata()) };
let adata = (&*adata_ptr).clone();
// SAFETY: AOP sets the platform data correctly
let service = unsafe { *((*dev.as_raw()).platform_data as *const EPICService) };

let ty = bindings::BINDINGS_IIO_ANGL;
let data = AopSensorData::new(dev, ty, MsgProc)?;
adata.add_fakehid_listener(service, data.clone())?;
let info_mask = 1 << bindings::BINDINGS_IIO_CHAN_INFO_RAW;
Ok(KBox::pin(
IIOAopLasDriver(IIORegistration::<MsgProc>::new(
data,
c_str!("aop-sensors-las"),
ty,
info_mask,
&THIS_MODULE,
)?),
GFP_KERNEL,
)?)
}
}

module_platform_driver! {
type: IIOAopLasDriver,
name: "iio_aop_las",
license: "Dual MIT/GPL",
alias: ["platform:iio_aop_las"],
}
24 changes: 24 additions & 0 deletions drivers/soc/apple/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,30 @@ config RUST_APPLE_RTKIT
depends on RUST
depends on APPLE_RTKIT

config APPLE_AOP
tristate "Apple \"Always-on\" Processor"
depends on ARCH_APPLE || COMPILE_TEST
depends on RUST
select RUST_APPLE_RTKIT
default m if ARCH_APPLE
help
A co-processor persent on certain Apple SoCs controlling accelerometers,
gyros, ambient light sensors and microphones. Is not actually always on.

Say 'y' here if you have an Apple laptop.

config APPLE_SEP
tristate "Apple Secure Element Processor"
depends on ARCH_APPLE || COMPILE_TEST
depends on RUST
select RUST_APPLE_RTKIT
default y if ARCH_APPLE
help
A security co-processor persent on Apple SoCs, controlling transparent
disk encryption, secure boot, HDCP, biometric auth and probably more.

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

endmenu

endif
4 changes: 4 additions & 0 deletions drivers/soc/apple/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ apple-rtkit-helper-y = rtkit-helper.o

obj-$(CONFIG_APPLE_SART) += apple-sart.o
apple-sart-y = sart.o

obj-$(CONFIG_APPLE_AOP) += aop.o

obj-$(CONFIG_APPLE_SEP) += sep.o
Loading

0 comments on commit fce34c8

Please sign in to comment.