|  | /* | 
|  | * 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 */ | 
|  | #define NPM6001_SWREADY          0x01U | 
|  | #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; | 
|  | } | 
|  |  | 
|  | /* Enable switching to hysteresis mode */ | 
|  | ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_SWREADY, 1U); | 
|  | if (ret < 0) { | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | 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,      \ | 
|  | CONFIG_MFD_NPM6001_INIT_PRIORITY, NULL); | 
|  |  | 
|  | DT_INST_FOREACH_STATUS_OKAY(MFD_NPM6001_DEFINE) |