diff --git a/src/hardware/baylibre-acme/api.c b/src/hardware/baylibre-acme/api.c index 201f9341..1fda2b24 100644 --- a/src/hardware/baylibre-acme/api.c +++ b/src/hardware/baylibre-acme/api.c @@ -28,6 +28,7 @@ static const uint32_t devopts[] = { SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET, SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST, SR_CONF_PROBE_FACTOR | SR_CONF_GET | SR_CONF_SET, + SR_CONF_POWER_OFF | SR_CONF_GET | SR_CONF_SET, }; #define MAX_SAMPLE_RATE 500 /* In Hz */ @@ -170,6 +171,7 @@ static int config_get(uint32_t key, GVariant **data, struct dev_context *devc; int ret; uint64_t shunt; + gboolean power_off; devc = sdi->priv; @@ -191,6 +193,13 @@ static int config_get(uint32_t key, GVariant **data, if (ret == SR_OK) *data = g_variant_new_uint64(shunt); break; + case SR_CONF_POWER_OFF: + if (!cg) + return SR_ERR_CHANNEL_GROUP; + ret = bl_acme_read_power_state(cg, &power_off); + if (ret == SR_OK) + *data = g_variant_new_boolean(power_off); + break; default: return SR_ERR_NA; } @@ -239,6 +248,11 @@ static int config_set(uint32_t key, GVariant *data, return SR_ERR_CHANNEL_GROUP; ret = bl_acme_set_shunt(cg, g_variant_get_uint64(data)); break; + case SR_CONF_POWER_OFF: + if (!cg) + return SR_ERR_CHANNEL_GROUP; + ret = bl_acme_set_power_off(cg, g_variant_get_boolean(data)); + break; default: ret = SR_ERR_NA; } diff --git a/src/hardware/baylibre-acme/protocol.c b/src/hardware/baylibre-acme/protocol.c index 22af9f97..419a9eba 100644 --- a/src/hardware/baylibre-acme/protocol.c +++ b/src/hardware/baylibre-acme/protocol.c @@ -23,10 +23,12 @@ #include /* open(), etc... */ #include #include "protocol.h" +#include "gpio.h" struct channel_group_priv { int hwmon_num; int probe_type; + int index; }; struct channel_priv { @@ -42,6 +44,14 @@ static const uint8_t temp_i2c_addrs[] = { 0x0, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x4f, 0x4b, }; +static const uint32_t pws_gpios[] = { + 486, 498, 502, 482, 478, 506, 510, 474 +}; + +static const uint32_t pws_info_gpios[] = { + 487, 499, 503, 483, 479, 507, 511, 475, +}; + #define MOHM_TO_UOHM(x) ((x) * 1000) #define UOHM_TO_MOHM(x) ((x) / 1000) @@ -218,6 +228,7 @@ SR_PRIV gboolean bl_acme_register_probe(struct sr_dev_inst *sdi, int type, cgp = g_malloc0(sizeof(struct channel_group_priv)); cgp->hwmon_num = hwmon; cgp->probe_type = type; + cgp->index = prb_num - 1; cg->name = g_strdup_printf("Probe_%d", prb_num); cg->priv = cgp; @@ -339,6 +350,45 @@ out: return ret; } +SR_PRIV int bl_acme_read_power_state(const struct sr_channel_group *cg, + gboolean *off) +{ + struct channel_group_priv *cgp; + int val; + + cgp = cg->priv; + + val = sr_gpio_getval_export(pws_info_gpios[cgp->index]); + if (val != 1) { + sr_err("Probe has no power-switch"); + return SR_ERR_ARG; + } + + val = sr_gpio_getval_export(pws_gpios[cgp->index]); + *off = val ? FALSE : TRUE; + + return SR_OK; +} + +SR_PRIV int bl_acme_set_power_off(const struct sr_channel_group *cg, + gboolean off) +{ + struct channel_group_priv *cgp; + int val; + + cgp = cg->priv; + + val = sr_gpio_getval_export(pws_info_gpios[cgp->index]); + if (val != 1) { + sr_err("Probe has no power-switch"); + return SR_ERR_ARG; + } + + val = sr_gpio_setval_export(pws_gpios[cgp->index], off ? 0 : 1); + + return SR_OK; +} + static int channel_to_mq(struct sr_channel *ch) { struct channel_priv *chp; diff --git a/src/hardware/baylibre-acme/protocol.h b/src/hardware/baylibre-acme/protocol.h index b70182c7..6e65772b 100644 --- a/src/hardware/baylibre-acme/protocol.h +++ b/src/hardware/baylibre-acme/protocol.h @@ -85,6 +85,10 @@ SR_PRIV int bl_acme_get_shunt(const struct sr_channel_group *cg, uint64_t *shunt); SR_PRIV int bl_acme_set_shunt(const struct sr_channel_group *cg, uint64_t shunt); +SR_PRIV int bl_acme_read_power_state(const struct sr_channel_group *cg, + gboolean *off); +SR_PRIV int bl_acme_set_power_off(const struct sr_channel_group *cg, + gboolean off); SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data);