struct gpio_pin *gpio_pin_by_name(const char *name) { struct gpio_pin *pin; for (pin = gpio_pins; *pin->name; pin++) { if (!strcmp(pin->name, name)) { return pin; } } log_error("pin named %s not found", name); return NULL; } // A GPIO pin number must only occur once. struct gpio_pin *gpio_pin_by_num(unsigned num) { int ipin = 0; while(*(gpio_pins[ipin].name)) { if (gpio_pins[ipin].pin.gpio == num) { return &(gpio_pins[ipin]); } ipin++; } log_error("pin numbered %u not found", num); return NULL; } struct gpio_pin *gpio_pin_by_attr_name(const char *name) { struct gpio_pin *pin; for (pin = gpio_pins; *pin->name; pin++) { if (!strcmp(pin->pin.label, name)) { return pin; } } log_error("pin with attr name %s not found", name); return NULL; } static ssize_t mts_attr_show_gpio_pin(struct device *dev, struct device_attribute *attr, char *buf) { int value; struct gpio_pin *pin = 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_gpio_pin(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; struct gpio_pin *pin = 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; } static int reset_gpio_pin(struct gpio_pin *pin, unsigned int delay_ms, unsigned int value) { if (!pin) { return -ENODEV; } gpio_set_value(pin->pin.gpio, value); mdelay(delay_ms); gpio_set_value(pin->pin.gpio, !value); return 0; }