/* * Copyright (c) 2022 Meta * Copyright (c) 2024 SILA Embedded Solutions GmbH * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "fpga_ice40_common.h" LOG_MODULE_REGISTER(fpga_ice40); void fpga_ice40_crc_to_str(uint32_t crc, char *s) { char ch; uint8_t i; uint8_t nibble; const char *table = "0123456789abcdef"; for (i = 0; i < sizeof(crc) * NIBBLES_PER_BYTE; ++i, crc >>= BITS_PER_NIBBLE) { nibble = crc & GENMASK(BITS_PER_NIBBLE, 0); ch = table[nibble]; s[sizeof(crc) * NIBBLES_PER_BYTE - i - 1] = ch; } s[sizeof(crc) * NIBBLES_PER_BYTE] = '\0'; } enum FPGA_status fpga_ice40_get_status(const struct device *dev) { enum FPGA_status st; k_spinlock_key_t key; struct fpga_ice40_data *data = dev->data; key = k_spin_lock(&data->lock); if (data->loaded && data->on) { st = FPGA_STATUS_ACTIVE; } else { st = FPGA_STATUS_INACTIVE; } k_spin_unlock(&data->lock, key); return st; } static int fpga_ice40_on_off(const struct device *dev, bool on) { int ret; k_spinlock_key_t key; struct fpga_ice40_data *data = dev->data; const struct fpga_ice40_config *config = dev->config; key = k_spin_lock(&data->lock); ret = gpio_pin_configure_dt(&config->creset, on ? GPIO_OUTPUT_HIGH : GPIO_OUTPUT_LOW); if (ret < 0) { goto unlock; } data->on = on; ret = 0; unlock: k_spin_unlock(&data->lock, key); return ret; } int fpga_ice40_on(const struct device *dev) { return fpga_ice40_on_off(dev, true); } int fpga_ice40_off(const struct device *dev) { return fpga_ice40_on_off(dev, false); } int fpga_ice40_reset(const struct device *dev) { return fpga_ice40_off(dev) || fpga_ice40_on(dev); } const char *fpga_ice40_get_info(const struct device *dev) { struct fpga_ice40_data *data = dev->data; return data->info; } int fpga_ice40_init(const struct device *dev) { int ret; const struct fpga_ice40_config *config = dev->config; if (!device_is_ready(config->creset.port)) { LOG_ERR("%s: GPIO for creset is not ready", dev->name); return -ENODEV; } if (!device_is_ready(config->cdone.port)) { LOG_ERR("%s: GPIO for cdone is not ready", dev->name); return -ENODEV; } ret = gpio_pin_configure_dt(&config->creset, GPIO_OUTPUT_HIGH); if (ret < 0) { LOG_ERR("failed to configure CRESET: %d", ret); return ret; } ret = gpio_pin_configure_dt(&config->cdone, GPIO_INPUT); if (ret < 0) { LOG_ERR("Failed to initialize CDONE: %d", ret); return ret; } return 0; }