diff options
Diffstat (limited to 'io-module/mtac.c')
-rw-r--r-- | io-module/mtac.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/io-module/mtac.c b/io-module/mtac.c index 99e2ce7..1c88b40 100644 --- a/io-module/mtac.c +++ b/io-module/mtac.c @@ -111,3 +111,89 @@ static bool ap_add_product_info_attributes(int port, int type) { return true; } + +struct gpio_pin *ap_gpio_pin_by_attr_name(const char *name) { + struct gpio_pin *pin; + char *pin_attr_name; + long port; + int port_index; + char *colon; + + colon = strstr(name, ":"); + if (colon && ++colon) { + if (kstrtol(colon, 10, &port)) { + log_error("kstrtol failed on [%s]", colon); + return NULL; + } + } else { + log_error("could not read port from attr name [%s]", name); + return NULL; + } + port_index = port - 1; + + pin_attr_name = port_info[port_index]->gpio_pin_name_by_attr_name(name); + + for (pin = gpio_pins; *pin->name; pin++) { + if (!strcmp(pin->pin.label, pin_attr_name)) { + return pin; + } + } + + log_error("pin with attr name [%s] not found", name); + return NULL; +} + +static ssize_t mts_attr_show_ap_gpio_pin(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int value; + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + mutex_lock(&mts_io_mutex); + + value = gpio_get_value(pin->pin.gpio); + + mutex_unlock(&mts_io_mutex); + + if (value < 0) { + return value; + } + + if (pin->active_low) { + value = !value; + } + + return sprintf(buf, "%d\n", value); +} + +static ssize_t mts_attr_store_ap_gpio_pin(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + int value; + struct gpio_pin *pin = ap_gpio_pin_by_attr_name(attr->attr.name); + + if (!pin) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + if (pin->active_low) { + value = !value; + } + + mutex_lock(&mts_io_mutex); + + gpio_set_value(pin->pin.gpio, value); + + mutex_unlock(&mts_io_mutex); + + return count; +} |