Skip to content

Commit

Permalink
Added code to deal with trackball with external power toggle
Browse files Browse the repository at this point in the history
Basic code mimics changes suggested by ddudek mentioned in zmkfirmware#674
Added extra code to deal with interrupt triggers
  • Loading branch information
petite2 committed May 13, 2022
1 parent cacd342 commit 241d047
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 3 deletions.
54 changes: 54 additions & 0 deletions app/drivers/sensor/pim447/pim447.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

LOG_MODULE_REGISTER(PIM447, CONFIG_SENSOR_LOG_LEVEL);

static int ext_power_status = true;

static int pim447_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
struct pim447_data *data = dev->data;
Expand Down Expand Up @@ -86,11 +88,16 @@ static int pim447_led_set(const struct device *dev,
return 0;
}

static int pim447_update_ext_power(const struct device *dev, bool ext_power_status_new_value);

int pim447_attr_set(const struct device *dev,
enum sensor_channel chan,
enum sensor_attribute attr,
const struct sensor_value *val)
{
if (attr == SENSOR_ATTR_CONFIGURATION) {
return pim447_update_ext_power(dev, (val->val1 == 1));
}
const struct device *i2c = pim447_i2c_device(dev);
uint8_t address = pim447_i2c_address(dev);
enum pim447_sensor_attribute pim447_attr = (enum pim447_sensor_attribute)attr;
Expand Down Expand Up @@ -195,6 +202,53 @@ static int pim447_init(const struct device *dev)
return 0;
}

static int pim447_update_ext_power(const struct device *dev, bool ext_power_status_new_value) {

// minimum sleep needed when waking up
if (ext_power_status_new_value == true) {
k_sleep(K_MSEC(30));
}
#ifdef CONFIG_PIM447_TRIGGER
if (ext_power_status && !ext_power_status_new_value) {
pim447_suspend_interrupt(dev);
k_sleep(K_MSEC(30));
}
#endif
// first update to I2C
if (dev->data != NULL) {
struct pim447_data *data = dev->data;
if (data->bus != NULL) {
if(i2c_update_ext_power(data->bus, ext_power_status_new_value)) {
LOG_ERR("Failed i2c_update_ext_power!");
return -EIO;
}
} else {
LOG_ERR("I2C bus is NULL");
}
} else {
LOG_ERR("trackball data is NULL");
}

if (ext_power_status != ext_power_status_new_value) {
if (ext_power_status_new_value == true)
{
// sleep after I2C reset
k_sleep(K_MSEC(30));

// re-init trackball, sends commands through i2c bus
pim447_init(dev);
#ifdef CONFIG_PIM447_TRIGGER
pim447_resume_interrupt(dev);
#endif
} else {
// no-op for now
}

ext_power_status = ext_power_status_new_value;
}
return 0;
}

#ifdef CONFIG_PIM447_TRIGGER
#define PIM447_INST(n)\
struct pim447_data pim447_data_##n;\
Expand Down
2 changes: 2 additions & 0 deletions app/drivers/sensor/pim447/pim447.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,6 @@ int pim447_trigger_set(const struct device *dev,
sensor_trigger_handler_t handler);

int pim447_init_interrupt(const struct device *dev);
void pim447_suspend_interrupt(const struct device *dev);
void pim447_resume_interrupt(const struct device *dev);
#endif
31 changes: 29 additions & 2 deletions app/drivers/sensor/pim447/pim447_trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ static void pim447_thread_cb(const struct device *dev)
static void pim447_thread(int dev_ptr, int unused)
{
struct device *dev = INT_TO_POINTER(dev_ptr);
struct pim447_data *data = dev->driver_data;
struct pim447_data *data = (struct pim447_data *)dev->data;

ARG_UNUSED(unused);

while (1) {
k_sem_take(&data->gpio_sem, K_FOREVER);
pim447_thread_cb(dev);
pim447_thread_cb(data->dev);
}
}
#endif
Expand Down Expand Up @@ -201,4 +201,31 @@ int pim447_init_interrupt(const struct device *dev)
#endif

return 0;
}

void pim447_suspend_interrupt(const struct device *dev) {
setup_alert(dev, false);
/* If ALERT is active we probably won't get the rising edge,
* so invoke the callback manually.
*/
struct pim447_data *data = (struct pim447_data *)dev->data;
const struct pim447_config *cfg =
(const struct pim447_config *)dev->config;
if (gpio_pin_get(data->alert_gpio, cfg->alert_pin)) {
LOG_DBG("Already got new alert, invoking callback manually.");
handle_alert(dev);
}
}
void pim447_resume_interrupt(const struct device *dev) {
setup_alert(dev, true);
/* If ALERT is active we probably won't get the rising edge,
* so invoke the callback manually.
*/
struct pim447_data *data = (struct pim447_data *)dev->data;
const struct pim447_config *cfg =
(const struct pim447_config *)dev->config;
if (gpio_pin_get(data->alert_gpio, cfg->alert_pin)) {
LOG_DBG("Already got new alert, invoking callback manually.");
handle_alert(dev);
}
}
26 changes: 25 additions & 1 deletion app/src/ext_power_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <settings/settings.h>
#include <drivers/gpio.h>
#include <drivers/ext_power.h>
#include <drivers/sensor.h>

#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)

Expand Down Expand Up @@ -57,6 +58,19 @@ int ext_power_save_state() {
#endif
}

static bool drivers_update_power_state(bool power) {
LOG_DBG("drivers_update_power_state: %s", power?"true":"false");
static const struct device *trackball;
trackball = device_get_binding("TRACKBALL");

if (trackball != NULL) {
struct sensor_value val;
val.val1 = power? 1 : 0;
sensor_attr_set(trackball, 0, SENSOR_ATTR_CONFIGURATION, &val);
}
return (trackball != NULL);
}

static int ext_power_generic_enable(const struct device *dev) {
struct ext_power_generic_data *data = dev->data;
const struct ext_power_generic_config *config = dev->config;
Expand All @@ -66,7 +80,12 @@ static int ext_power_generic_enable(const struct device *dev) {
return -EIO;
}
data->status = true;
drivers_update_power_state(true);
#if IS_ENABLED(CONFIG_PIM447_DEFAULT_EXT_POWER_OFF)
return 0;
#else
return ext_power_save_state();
#endif
}

static int ext_power_generic_disable(const struct device *dev) {
Expand All @@ -78,7 +97,12 @@ static int ext_power_generic_disable(const struct device *dev) {
return -EIO;
}
data->status = false;
drivers_update_power_state(false);
#if IS_ENABLED(CONFIG_PIM447_DEFAULT_EXT_POWER_OFF)
return 0;
#else
return ext_power_save_state();
#endif
}

static int ext_power_generic_get(const struct device *dev) {
Expand Down Expand Up @@ -141,7 +165,7 @@ static int ext_power_generic_init(const struct device *dev) {
return -EIO;
}

#if IS_ENABLED(CONFIG_SETTINGS)
#if IS_ENABLED(CONFIG_SETTINGS) && !IS_ENABLED(CONFIG_PIM447_DEFAULT_EXT_POWER_OFF)
settings_subsys_init();

int err = settings_register(&ext_power_conf);
Expand Down

0 comments on commit 241d047

Please sign in to comment.