diff options
author | Michał Barnaś <mb@semihalf.com> | 2021-08-30 20:34:38 +0200 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-30 00:27:36 +0000 |
commit | 84aa3cb9dd0643e9fe0dd188163435d6d282aac9 (patch) | |
tree | e93a418bea9142c01b5362f6ac5c165e8a8d5073 | |
parent | 78911f24fdfebf1fa2faf1fcfe2df1aeac897993 (diff) | |
download | chrome-ec-84aa3cb9dd0643e9fe0dd188163435d6d282aac9.tar.gz |
zephyr: motion: add support for runtime probing of motion sensors
Add possibility to define alternative motion sensors that
will be probed on EC boot.
This will allow to easily specify different variants of boards with
different motion sensors.
BRANCH=main
BUG=b:194424288
TEST=This commit shouldn't change anything.
Build, flash EC and motion sensors should work correctly,
detecting tablet mode and orientation changes.
Change-Id: Ia2f864854699416abdd188a6bc36e6356e86f6f5
Signed-off-by: Michał Barnaś <mb@semihalf.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3129962
Reviewed-by: Yuval Peress <peress@google.com>
Reviewed-by: Keith Short <keithshort@chromium.org>
Commit-Queue: Keith Short <keithshort@chromium.org>
-rw-r--r-- | include/accelgyro.h | 17 | ||||
-rw-r--r-- | zephyr/Kconfig.motionsense | 8 | ||||
-rw-r--r-- | zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml | 6 | ||||
-rw-r--r-- | zephyr/shim/include/motionsense_sensors.h | 8 | ||||
-rw-r--r-- | zephyr/shim/src/motionsense_sensors.c | 94 |
5 files changed, 126 insertions, 7 deletions
diff --git a/include/accelgyro.h b/include/accelgyro.h index 5d755b7eaa..be6b8061c3 100644 --- a/include/accelgyro.h +++ b/include/accelgyro.h @@ -125,6 +125,23 @@ struct accelgyro_drv { */ int (*perform_calib)(struct motion_sensor_t *s, int enable); + + /** + * Function that probes if supported chip is present. + * This pointer can be NULL if driver doesn't implement probing. + * + * @s Pointer to sensor data. + * @return EC_SUCCESS if the probe was successful, non-zero otherwise. + */ + int (*probe)(const struct motion_sensor_t *s); + + /** + * Interrupt handler for GPIO pin. + * + * @signal Signal which caused interrupt. + */ + void (*interrupt)(enum gpio_signal signal); + /** * handler for interrupts triggered by the sensor: it runs in task and * process the events that triggered an interrupt. diff --git a/zephyr/Kconfig.motionsense b/zephyr/Kconfig.motionsense index daf2bbcdf8..69980f33da 100644 --- a/zephyr/Kconfig.motionsense +++ b/zephyr/Kconfig.motionsense @@ -187,4 +187,12 @@ config PLATFORM_EC_CONSOLE_CMD_ACCEL_SPOOF endif # PLATFORM_EC_ACCEL_SPOOF_MODE +config PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL + bool "Disable deferred call that probes motion sensors on boot-up" + help + Disables deferred call that probes motion sensors on boot-up. + If this option is enabled, board logic code must call + board_detect_motionsensor manually. This is useful if board needs + manual control of sensors probing. + rsource "Kconfig.sensor_devices" diff --git a/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml b/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml index 6948ce6997..6adaa22ee5 100644 --- a/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml +++ b/zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml @@ -62,6 +62,12 @@ properties: type: phandle description: phandle to CBI SSGC value indicating that the sensor should be used + runtime-probe: + type: boolean + description: runtime probing of sensor will be executed if true + int-signal: + type: phandle + description: pin which triggers interrupt for sensor # # examples: diff --git a/zephyr/shim/include/motionsense_sensors.h b/zephyr/shim/include/motionsense_sensors.h index bdec8e79bd..bfa9aea050 100644 --- a/zephyr/shim/include/motionsense_sensors.h +++ b/zephyr/shim/include/motionsense_sensors.h @@ -100,4 +100,12 @@ enum sensor_alt_id { SENSOR_INFO_NODE)) #endif +/** + * If CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL is enabled, + * this function must be called to perform probing of alternative sensors. + */ +#ifdef CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL +void motion_sense_probe_sensors(void); +#endif + #endif /* __CROS_EC_MOTIONSENSE_SENSORS_H */ diff --git a/zephyr/shim/src/motionsense_sensors.c b/zephyr/shim/src/motionsense_sensors.c index 0c54160e2e..b884f890b2 100644 --- a/zephyr/shim/src/motionsense_sensors.c +++ b/zephyr/shim/src/motionsense_sensors.c @@ -3,11 +3,14 @@ * found in the LICENSE file. */ +#include <logging/log.h> #include "common.h" #include "accelgyro.h" #include "hooks.h" #include "drivers/cros_cbi.h" +LOG_MODULE_REGISTER(shim_cros_motionsense_sensors); + #define SENSOR_MUTEX_NODE DT_PATH(motionsense_mutex) #define SENSOR_MUTEX_NAME(id) DT_CAT(MUTEX_, id) @@ -121,6 +124,22 @@ DT_FOREACH_CHILD(SENSOR_ROT_REF_NODE, DECLARE_SENSOR_ROT_REF) (.mutex = &SENSOR_MUTEX_NAME(DT_PHANDLE(id, mutex)),)) /* + * Set the interrupt pin which is referred by the phandle. + */ +#define SENSOR_INT_SIGNAL(id) \ + IF_ENABLED(DT_NODE_HAS_PROP(id, int_signal), \ + (.int_signal = GPIO_SIGNAL(DT_PHANDLE(id, int_signal)),)) + +/* + * Set flags based on values defined in the node. + */ +#define SENSOR_FLAGS(id) \ + .flags = 0 \ + IF_ENABLED(DT_NODE_HAS_PROP(id, int_signal), \ + (|MOTIONSENSE_FLAG_INT_SIGNAL)) \ + , + +/* * Get I2C port number which is referred by phandle. * See motionsense-sensor-base.yaml for DT example and details. */ @@ -196,7 +215,9 @@ DT_FOREACH_CHILD(SENSOR_ROT_REF_NODE, DECLARE_SENSOR_ROT_REF) SENSOR_I2C_PORT(id) \ SENSOR_ROT_STD_REF(id) \ SENSOR_DRV_DATA(id) \ - SENSOR_CONFIG(id) + SENSOR_CONFIG(id) \ + SENSOR_INT_SIGNAL(id) \ + SENSOR_FLAGS(id) /* Create motion sensor node with node ID */ #define DO_MK_SENSOR_ENTRY( \ @@ -388,16 +409,75 @@ DECLARE_HOOK(HOOK_INIT, sensor_enable_irqs, HOOK_PRIO_DEFAULT); DT_NODE_HAS_PROP(id, alternate_indicator)), \ (CHECK_AND_REPLACE_ALT_MOTION_SENSOR(id)), ()) -void motion_sensors_init_alt(void) -{ - const struct device *dev = device_get_binding("cros_cbi"); +#define PROBE_SENSOR(id) \ +{ \ + int res; \ + \ + LOG_INF("Probing \"%s\" chip %d type %d loc %d", \ + motion_sensors_alt[SENSOR_ID(id)].name, \ + motion_sensors_alt[SENSOR_ID(id)].chip, \ + motion_sensors_alt[SENSOR_ID(id)].type, \ + motion_sensors_alt[SENSOR_ID(id)].location); \ + \ + __ASSERT(motion_sensors_alt[SENSOR_ID(id)].drv->probe != NULL, \ + "No probing function for alt sensor: %d", SENSOR_ID(id)); \ + res = motion_sensors_alt[SENSOR_ID(id)].drv->probe( \ + &motion_sensors_alt[SENSOR_ID(id)]); \ + LOG_INF("%sfound\n", (res != EC_SUCCESS ? "not " : "")); \ + \ + if (res == EC_SUCCESS) { \ + REPLACE_ALT_MOTION_SENSOR(id, \ + DT_PHANDLE(id, alternate_for)); \ + } \ +} - if (dev == NULL) - return; +#define PROBE_IF_NEEDED(id) \ + COND_CODE_1(DT_PROP(id, runtime_probe), \ + (PROBE_SENSOR(id)), \ + ()) #if DT_NODE_EXISTS(SENSOR_ALT_NODE) - DT_FOREACH_CHILD(SENSOR_ALT_NODE, ALT_MOTION_SENSOR_INIT_ID) +#ifndef CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL +static void motion_sense_probe_sensors(void) +#else +void motion_sense_probe_sensors(void) #endif +{ + DT_FOREACH_CHILD(SENSOR_ALT_NODE, PROBE_IF_NEEDED); } +static void motion_sensors_init_alt(void) +{ + const struct device *dev = device_get_binding("cros_cbi"); + + if (dev != NULL) { + DT_FOREACH_CHILD(SENSOR_ALT_NODE, ALT_MOTION_SENSOR_INIT_ID) + } + + if (!IS_ENABLED( + CONFIG_PLATFORM_EC_MOTION_SENSE_RUNTIME_PROBE_CUSTOM_CALL)) + motion_sense_probe_sensors(); +} DECLARE_HOOK(HOOK_INIT, motion_sensors_init_alt, HOOK_PRIO_INIT_I2C + 1); +#endif /* DT_NODE_EXISTS(SENSOR_ALT_NODE) */ + +#define DEF_MOTION_ISR_NAME_ENUM(id) \ + DT_STRING_UPPER_TOKEN(DT_PHANDLE(id, int_signal), enum_name) +#define DEF_MOTION_ISR_NAME_ENUM_WITH_SUFFIX(name) DT_CAT(name, _ISR) +#define DEF_MOTION_ISR_NAME(id) \ + DEF_MOTION_ISR_NAME_ENUM_WITH_SUFFIX(DEF_MOTION_ISR_NAME_ENUM(id)) + +#define DEF_MOTION_ISR(id) \ +void DEF_MOTION_ISR_NAME(id)(enum gpio_signal signal) \ +{ \ + __ASSERT(motion_sensors[SENSOR_ID(id)].drv->interrupt, \ + "No interrupt handler for signal: %x", signal); \ + motion_sensors[SENSOR_ID(id)].drv->interrupt(signal); \ +} + +#define DEF_MOTION_CHECK_ISR(id) \ + COND_CODE_1(DT_NODE_HAS_PROP(id, int_signal), (DEF_MOTION_ISR(id)), ()) + +#if DT_NODE_EXISTS(SENSOR_NODE) +DT_FOREACH_CHILD(SENSOR_NODE, DEF_MOTION_CHECK_ISR) +#endif |