2023-05-24 17:57:15 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define DT_DRV_COMPAT nordic_npm6001
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <zephyr/drivers/i2c.h>
|
|
|
|
#include <zephyr/sys/util.h>
|
|
|
|
|
|
|
|
/* nPM6001 registers */
|
2024-02-22 20:04:37 +08:00
|
|
|
#define NPM6001_SWREADY 0x01U
|
2023-05-24 17:57:15 +08:00
|
|
|
#define NPM6001_BUCK3SELDAC 0x44U
|
|
|
|
#define NPM6001_BUCKMODEPADCONF 0x4EU
|
|
|
|
#define NPM6001_PADDRIVESTRENGTH 0x53U
|
|
|
|
|
|
|
|
/* nPM6001 BUCKMODEPADCONF fields */
|
|
|
|
#define NPM6001_BUCKMODEPADCONF_BUCKMODE0PADTYPE_CMOS BIT(0)
|
|
|
|
#define NPM6001_BUCKMODEPADCONF_BUCKMODE1PADTYPE_CMOS BIT(1)
|
|
|
|
#define NPM6001_BUCKMODEPADCONF_BUCKMODE2PADTYPE_CMOS BIT(2)
|
|
|
|
#define NPM6001_BUCKMODEPADCONF_BUCKMODE0PULLD_ENABLED BIT(4)
|
|
|
|
#define NPM6001_BUCKMODEPADCONF_BUCKMODE1PULLD_ENABLED BIT(5)
|
|
|
|
#define NPM6001_BUCKMODEPADCONF_BUCKMODE2PULLD_ENABLED BIT(6)
|
|
|
|
|
|
|
|
/* nPM6001 PADDRIVESTRENGTH fields */
|
|
|
|
#define NPM6001_PADDRIVESTRENGTH_READY_HIGH BIT(2)
|
|
|
|
#define NPM6001_PADDRIVESTRENGTH_NINT_HIGH BIT(3)
|
|
|
|
#define NPM6001_PADDRIVESTRENGTH_SDA_HIGH BIT(5)
|
|
|
|
|
|
|
|
struct mfd_npm6001_config {
|
|
|
|
struct i2c_dt_spec i2c;
|
|
|
|
uint8_t buck_pad_val;
|
|
|
|
uint8_t pad_val;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int mfd_npm6001_init(const struct device *dev)
|
|
|
|
{
|
|
|
|
const struct mfd_npm6001_config *config = dev->config;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!i2c_is_ready_dt(&config->i2c)) {
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* always select BUCK3 DAC (does not increase power consumption) */
|
|
|
|
ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCK3SELDAC, 1U);
|
|
|
|
if (ret < 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* configure pad properties */
|
|
|
|
ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCKMODEPADCONF, config->buck_pad_val);
|
|
|
|
if (ret < 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_PADDRIVESTRENGTH, config->pad_val);
|
|
|
|
if (ret < 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-02-22 20:04:37 +08:00
|
|
|
/* Enable switching to hysteresis mode */
|
|
|
|
ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_SWREADY, 1U);
|
|
|
|
if (ret < 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2023-05-24 17:57:15 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MFD_NPM6001_DEFINE(inst) \
|
|
|
|
static const struct mfd_npm6001_config config##inst = { \
|
|
|
|
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
|
|
|
.buck_pad_val = ((DT_INST_ENUM_IDX(inst, nordic_buck_mode0_input_type) * \
|
|
|
|
NPM6001_BUCKMODEPADCONF_BUCKMODE0PADTYPE_CMOS) | \
|
|
|
|
(DT_INST_ENUM_IDX(inst, nordic_buck_mode1_input_type) * \
|
|
|
|
NPM6001_BUCKMODEPADCONF_BUCKMODE1PADTYPE_CMOS) | \
|
|
|
|
(DT_INST_ENUM_IDX(inst, nordic_buck_mode2_input_type) * \
|
|
|
|
NPM6001_BUCKMODEPADCONF_BUCKMODE2PADTYPE_CMOS) | \
|
|
|
|
(DT_INST_PROP(inst, nordic_buck_mode0_pull_down) * \
|
|
|
|
NPM6001_BUCKMODEPADCONF_BUCKMODE0PULLD_ENABLED) | \
|
|
|
|
(DT_INST_PROP(inst, nordic_buck_mode1_pull_down) * \
|
|
|
|
NPM6001_BUCKMODEPADCONF_BUCKMODE1PULLD_ENABLED) | \
|
|
|
|
(DT_INST_PROP(inst, nordic_buck_mode2_pull_down) * \
|
|
|
|
NPM6001_BUCKMODEPADCONF_BUCKMODE2PULLD_ENABLED)), \
|
|
|
|
.pad_val = ((DT_INST_PROP(inst, nordic_ready_high_drive) * \
|
|
|
|
NPM6001_PADDRIVESTRENGTH_READY_HIGH) | \
|
|
|
|
(DT_INST_PROP(inst, nordic_nint_high_drive) * \
|
|
|
|
NPM6001_PADDRIVESTRENGTH_NINT_HIGH) | \
|
|
|
|
(DT_INST_PROP(inst, nordic_sda_high_drive) * \
|
|
|
|
NPM6001_PADDRIVESTRENGTH_SDA_HIGH)), \
|
|
|
|
}; \
|
|
|
|
\
|
|
|
|
DEVICE_DT_INST_DEFINE(inst, mfd_npm6001_init, NULL, NULL, &config##inst, POST_KERNEL, \
|
2023-10-02 23:06:54 +08:00
|
|
|
CONFIG_MFD_NPM6001_INIT_PRIORITY, NULL);
|
2023-05-24 17:57:15 +08:00
|
|
|
|
|
|
|
DT_INST_FOREACH_STATUS_OKAY(MFD_NPM6001_DEFINE)
|