/* * Copyright (c) 2022 BrainCo Inc. * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT gd_gd32_flash_controller #include "flash_gd32.h" #include #include #include #include #include LOG_MODULE_REGISTER(flash_gd32, CONFIG_FLASH_LOG_LEVEL); struct flash_gd32_data { struct k_sem mutex; }; static struct flash_gd32_data flash_data; static const struct flash_parameters flash_gd32_parameters = { .write_block_size = SOC_NV_FLASH_PRG_SIZE, .erase_value = 0xff, }; static int flash_gd32_read(const struct device *dev, off_t offset, void *data, size_t len) { if ((offset > SOC_NV_FLASH_SIZE) || ((offset + len) > SOC_NV_FLASH_SIZE)) { return -EINVAL; } if (len == 0U) { return 0; } memcpy(data, (uint8_t *)SOC_NV_FLASH_ADDR + offset, len); return 0; } static int flash_gd32_write(const struct device *dev, off_t offset, const void *data, size_t len) { struct flash_gd32_data *dev_data = dev->data; int ret = 0; if (!flash_gd32_valid_range(offset, len, true)) { return -EINVAL; } if (len == 0U) { return 0; } k_sem_take(&dev_data->mutex, K_FOREVER); ret = flash_gd32_write_range(offset, data, len); k_sem_give(&dev_data->mutex); return ret; } static int flash_gd32_erase(const struct device *dev, off_t offset, size_t size) { struct flash_gd32_data *data = dev->data; int ret = 0; if (size == 0U) { return 0; } if (!flash_gd32_valid_range(offset, size, false)) { return -EINVAL; } k_sem_take(&data->mutex, K_FOREVER); ret = flash_gd32_erase_block(offset, size); k_sem_give(&data->mutex); return ret; } static const struct flash_parameters* flash_gd32_get_parameters(const struct device *dev) { ARG_UNUSED(dev); return &flash_gd32_parameters; } static const struct flash_driver_api flash_gd32_driver_api = { .read = flash_gd32_read, .write = flash_gd32_write, .erase = flash_gd32_erase, .get_parameters = flash_gd32_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_gd32_pages_layout, #endif }; static int flash_gd32_init(const struct device *dev) { struct flash_gd32_data *data = dev->data; k_sem_init(&data->mutex, 1, 1); return 0; } DEVICE_DT_INST_DEFINE(0, flash_gd32_init, NULL, &flash_data, NULL, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, &flash_gd32_driver_api);