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 bool ardu_breakout = false; static int _mux_init(void) { struct sol_gpio *tristate = NULL; struct sol_gpio_config config; //Try to detect the Arduino Breakout SOL_SET_API_VERSION(config.api_version = SOL_GPIO_CONFIG_API_VERSION; ) config.dir = SOL_GPIO_DIR_OUT; tristate = sol_gpio_open_raw(214, &config); if (tristate) { ardu_breakout = true; apply_mux_desc(init_board, MODE_GPIO); sol_gpio_close(tristate); } return 0; } static int _pin_map(const char *label, const enum sol_io_protocol prot, va_list args) { if (ardu_breakout) return mux_pin_map(pin_map, label, prot, args);