static int led_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct led_7seg_data *mdata = data; const struct sol_flow_node_type_led_7seg_led_options *opts = (const struct sol_flow_node_type_led_7seg_led_options *)options; struct sol_gpio_config gpio_conf = { 0 }; int i; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_LED_7SEG_LED_OPTIONS_API_VERSION, -EINVAL); gpio_conf.api_version = SOL_GPIO_CONFIG_API_VERSION; gpio_conf.dir = SOL_GPIO_DIR_OUT; OPEN_GPIO(0, dp); OPEN_GPIO(1, g); OPEN_GPIO(2, f); OPEN_GPIO(3, e); OPEN_GPIO(4, d); OPEN_GPIO(5, c); OPEN_GPIO(6, b); OPEN_GPIO(7, a); mdata->common_cathode = opts->common_cathode; return 0; port_error: for (i = 0; i < 8; i++) { if (mdata->gpio[i]) sol_gpio_close(mdata->gpio[i]); } return -EIO; }
static void gpio_close(struct sol_flow_node *node, void *data) { struct gpio_data *mdata = data; sol_gpio_close(mdata->gpio); }
static void led_close(struct sol_flow_node *node, void *data) { struct led_7seg_data *mdata = data; int i; for (i = 0; i < 8; i++) sol_gpio_close(mdata->gpio[i]); }
static void shutdown(void) { const char **itr; if (gpio) sol_gpio_close(gpio); sol_timeout_del(timeout); for (itr = services; *itr != NULL; itr++) sol_platform_del_service_monitor(on_service_change, *itr, NULL); sol_platform_del_state_monitor(on_platform_state_change, NULL); }
static int _set_gpio(int pin, enum sol_gpio_direction dir, int drive, bool val) { int ret = 0; int len; struct stat st; char path[PATH_MAX]; struct sol_gpio *gpio; const char *drive_str; struct sol_gpio_config gpio_config = { 0 }; gpio_config.dir = dir; gpio_config.out.value = val; gpio = sol_gpio_open_raw(pin, &gpio_config); if (!gpio) return -EINVAL; // Drive: // This is not standard interface in upstream Linux, so the // Linux implementation of sol-gpio doesn't handle it, thus the need // to set it here manually // // Not all platforms will have this (this will move in the future) // so its no problem to fail the if bellow len = snprintf(path, sizeof(path), BASE "/gpio%d/drive", pin); if (len < 0 || len > PATH_MAX || stat(path, &st) == -1) goto err; switch (drive) { case GPIO_DRIVE_PULLUP: drive_str = "pullup"; break; case GPIO_DRIVE_PULLDOWN: drive_str = "pulldown"; break; case GPIO_DRIVE_HIZ: drive_str = "hiz"; break; default: drive_str = "strong"; } ret = sol_util_write_file(path, "%s", drive_str); err: sol_gpio_close(gpio); return ret; }
SOL_API struct sol_gpio * sol_gpio_open(uint32_t pin, const struct sol_gpio_config *config) { struct sol_gpio *gpio; _log_init(); SOL_NULL_CHECK(config, NULL); gpio = sol_gpio_open_raw(pin, config); #ifdef USE_PIN_MUX if (gpio && sol_pin_mux_setup_gpio(pin, config)) { SOL_ERR("Pin Multiplexer Recipe for gpio=%d found, but couldn't be applied.", pin); sol_gpio_close(gpio); gpio = NULL; } #endif return gpio; }
static void shutdown(void) { SOL_WRN("shutdown\n"); sol_gpio_close(gpio); }