zephyr/drivers/eeprom/eeprom_lpc11u6x.c
Maureen Helm 32b4950c61 drivers: eeprom: Refactor drivers to use shared init priority
Refactors all of the EEPROM drivers to use a shared driver class
initialization priority configuration, CONFIG_EEPROM_INIT_PRIORITY, to
allow configuring EEPROM drivers separately from other devices. This is
similar to other driver classes like I2C and SPI.

The default is set to CONFIG_KERNEL_INIT_PRIORITY_DEVICE to preserve the
existing default initialization priority for most drivers. The
exceptions are at2x and emul drivers which have dependencies on SPI,
I2C, or flash drivers and must therefore initialize later than the
default device priority.

Signed-off-by: Maureen Helm <maureen.helm@intel.com>
2021-11-04 07:33:01 -04:00

121 lines
2.5 KiB
C

/*
* Copyright (c) 2020 Seagate Technology LLC
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT nxp_lpc11u6x_eeprom
/**
* @file
* @brief EEPROM driver for NXP LPC11U6X MCUs
*
* This driver supports the on-chip EEPROM found on NXP LPC11U6x MCUs.
*
* @note This driver is only a wrapper for the IAP (In-Application Programming)
* EEPROM funcions.
*/
#include <drivers/eeprom.h>
#include <iap.h>
#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(eeprom_lpc11u6x);
struct eeprom_lpc11u6x_config {
size_t size;
};
static int eeprom_lpc11u6x_read(const struct device *dev,
off_t offset, void *data, size_t len)
{
const struct eeprom_lpc11u6x_config *config = dev->config;
uint32_t cmd[5];
int ret;
if (!len) {
return 0;
}
if ((offset + len) > config->size) {
LOG_WRN("attempt to read past device boundary");
return -EINVAL;
}
cmd[0] = IAP_CMD_EEPROM_READ;
cmd[1] = offset;
cmd[2] = (uint32_t) data;
cmd[3] = len;
cmd[4] = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000;
ret = iap_cmd(cmd);
if (ret != IAP_STATUS_CMD_SUCCESS) {
LOG_ERR("failed to read EEPROM (offset=%08x len=%d err=%d)",
(unsigned int) offset, len, ret);
return -EINVAL;
}
return 0;
}
static int eeprom_lpc11u6x_write(const struct device *dev,
off_t offset, const void *data, size_t len)
{
const struct eeprom_lpc11u6x_config *config = dev->config;
uint32_t cmd[5];
int ret;
if (!len) {
return 0;
}
if ((offset + len) > config->size) {
LOG_WRN("attempt to write past device boundary");
return -EINVAL;
}
cmd[0] = IAP_CMD_EEPROM_WRITE;
cmd[1] = offset;
cmd[2] = (uint32_t) data;
cmd[3] = len;
cmd[4] = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000;
ret = iap_cmd(cmd);
if (ret != IAP_STATUS_CMD_SUCCESS) {
LOG_ERR("failed to write EEPROM (offset=%08x len=%d err=%d)",
(unsigned int) offset, len, ret);
return -EINVAL;
}
return 0;
}
static size_t eeprom_lpc11u6x_size(const struct device *dev)
{
const struct eeprom_lpc11u6x_config *config = dev->config;
return config->size;
}
static int eeprom_lpc11u6x_init(const struct device *dev)
{
return 0;
}
static const struct eeprom_driver_api eeprom_lpc11u6x_api = {
.read = eeprom_lpc11u6x_read,
.write = eeprom_lpc11u6x_write,
.size = eeprom_lpc11u6x_size,
};
static const struct eeprom_lpc11u6x_config eeprom_config = {
.size = DT_INST_PROP(0, size),
};
DEVICE_DT_INST_DEFINE(0, &eeprom_lpc11u6x_init, NULL, NULL,
&eeprom_config, POST_KERNEL,
CONFIG_EEPROM_INIT_PRIORITY, &eeprom_lpc11u6x_api);