summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Barnaś <mb@semihalf.com>2021-08-30 20:34:38 +0200
committerCommit Bot <commit-bot@chromium.org>2021-09-30 00:27:36 +0000
commit84aa3cb9dd0643e9fe0dd188163435d6d282aac9 (patch)
treee93a418bea9142c01b5362f6ac5c165e8a8d5073
parent78911f24fdfebf1fa2faf1fcfe2df1aeac897993 (diff)
downloadchrome-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.h17
-rw-r--r--zephyr/Kconfig.motionsense8
-rw-r--r--zephyr/dts/bindings/motionsense/motionsense-sensor-base.yaml6
-rw-r--r--zephyr/shim/include/motionsense_sensors.h8
-rw-r--r--zephyr/shim/src/motionsense_sensors.c94
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