1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #define DT_DRV_COMPAT nordic_npm6001
7
8 #include <errno.h>
9
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/sys/util.h>
12
13 /* nPM6001 registers */
14 #define NPM6001_SWREADY 0x01U
15 #define NPM6001_BUCK3SELDAC 0x44U
16 #define NPM6001_BUCKMODEPADCONF 0x4EU
17 #define NPM6001_PADDRIVESTRENGTH 0x53U
18
19 /* nPM6001 BUCKMODEPADCONF fields */
20 #define NPM6001_BUCKMODEPADCONF_BUCKMODE0PADTYPE_CMOS BIT(0)
21 #define NPM6001_BUCKMODEPADCONF_BUCKMODE1PADTYPE_CMOS BIT(1)
22 #define NPM6001_BUCKMODEPADCONF_BUCKMODE2PADTYPE_CMOS BIT(2)
23 #define NPM6001_BUCKMODEPADCONF_BUCKMODE0PULLD_ENABLED BIT(4)
24 #define NPM6001_BUCKMODEPADCONF_BUCKMODE1PULLD_ENABLED BIT(5)
25 #define NPM6001_BUCKMODEPADCONF_BUCKMODE2PULLD_ENABLED BIT(6)
26
27 /* nPM6001 PADDRIVESTRENGTH fields */
28 #define NPM6001_PADDRIVESTRENGTH_READY_HIGH BIT(2)
29 #define NPM6001_PADDRIVESTRENGTH_NINT_HIGH BIT(3)
30 #define NPM6001_PADDRIVESTRENGTH_SDA_HIGH BIT(5)
31
32 struct mfd_npm6001_config {
33 struct i2c_dt_spec i2c;
34 uint8_t buck_pad_val;
35 uint8_t pad_val;
36 };
37
mfd_npm6001_init(const struct device * dev)38 static int mfd_npm6001_init(const struct device *dev)
39 {
40 const struct mfd_npm6001_config *config = dev->config;
41 int ret;
42
43 if (!i2c_is_ready_dt(&config->i2c)) {
44 return -ENODEV;
45 }
46
47 /* always select BUCK3 DAC (does not increase power consumption) */
48 ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCK3SELDAC, 1U);
49 if (ret < 0) {
50 return ret;
51 }
52
53 /* configure pad properties */
54 ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCKMODEPADCONF, config->buck_pad_val);
55 if (ret < 0) {
56 return ret;
57 }
58
59 ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_PADDRIVESTRENGTH, config->pad_val);
60 if (ret < 0) {
61 return ret;
62 }
63
64 /* Enable switching to hysteresis mode */
65 ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_SWREADY, 1U);
66 if (ret < 0) {
67 return ret;
68 }
69
70 return 0;
71 }
72
73 #define MFD_NPM6001_DEFINE(inst) \
74 static const struct mfd_npm6001_config config##inst = { \
75 .i2c = I2C_DT_SPEC_INST_GET(inst), \
76 .buck_pad_val = ((DT_INST_ENUM_IDX(inst, nordic_buck_mode0_input_type) * \
77 NPM6001_BUCKMODEPADCONF_BUCKMODE0PADTYPE_CMOS) | \
78 (DT_INST_ENUM_IDX(inst, nordic_buck_mode1_input_type) * \
79 NPM6001_BUCKMODEPADCONF_BUCKMODE1PADTYPE_CMOS) | \
80 (DT_INST_ENUM_IDX(inst, nordic_buck_mode2_input_type) * \
81 NPM6001_BUCKMODEPADCONF_BUCKMODE2PADTYPE_CMOS) | \
82 (DT_INST_PROP(inst, nordic_buck_mode0_pull_down) * \
83 NPM6001_BUCKMODEPADCONF_BUCKMODE0PULLD_ENABLED) | \
84 (DT_INST_PROP(inst, nordic_buck_mode1_pull_down) * \
85 NPM6001_BUCKMODEPADCONF_BUCKMODE1PULLD_ENABLED) | \
86 (DT_INST_PROP(inst, nordic_buck_mode2_pull_down) * \
87 NPM6001_BUCKMODEPADCONF_BUCKMODE2PULLD_ENABLED)), \
88 .pad_val = ((DT_INST_PROP(inst, nordic_ready_high_drive) * \
89 NPM6001_PADDRIVESTRENGTH_READY_HIGH) | \
90 (DT_INST_PROP(inst, nordic_nint_high_drive) * \
91 NPM6001_PADDRIVESTRENGTH_NINT_HIGH) | \
92 (DT_INST_PROP(inst, nordic_sda_high_drive) * \
93 NPM6001_PADDRIVESTRENGTH_SDA_HIGH)), \
94 }; \
95 \
96 DEVICE_DT_INST_DEFINE(inst, mfd_npm6001_init, NULL, NULL, &config##inst, POST_KERNEL, \
97 CONFIG_MFD_NPM6001_INIT_PRIORITY, NULL);
98
99 DT_INST_FOREACH_STATUS_OKAY(MFD_NPM6001_DEFINE)
100