1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #define DT_DRV_COMPAT nordic_npm1300
7 
8 #include <errno.h>
9 
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/drivers/gpio/gpio_utils.h>
15 #include <zephyr/drivers/mfd/npm1300.h>
16 
17 #define TIME_BASE 0x07U
18 #define MAIN_BASE 0x00U
19 #define SHIP_BASE 0x0BU
20 #define GPIO_BASE 0x06U
21 
22 #define TIME_OFFSET_LOAD  0x03U
23 #define TIME_OFFSET_TIMER 0x08U
24 
25 #define MAIN_OFFSET_RESET    0x01U
26 #define MAIN_OFFSET_SET      0x00U
27 #define MAIN_OFFSET_CLR      0x01U
28 #define MAIN_OFFSET_INTENSET 0x02U
29 #define MAIN_OFFSET_INTENCLR 0x03U
30 
31 #define SHIP_OFFSET_HIBERNATE 0x00U
32 #define SHIP_OFFSET_CFGSTROBE 0x01U
33 #define SHIP_OFFSET_CONFIG    0x04U
34 #define SHIP_OFFSET_LPCONFIG  0x06U
35 
36 #define GPIO_OFFSET_MODE 0x00U
37 
38 #define TIMER_PRESCALER_MS 16U
39 #define TIMER_MAX          0xFFFFFFU
40 
41 #define MAIN_SIZE 0x26U
42 
43 #define GPIO_MODE_GPOIRQ 5
44 
45 struct mfd_npm1300_config {
46 	struct i2c_dt_spec i2c;
47 	struct gpio_dt_spec host_int_gpios;
48 	uint8_t pmic_int_pin;
49 	uint8_t active_time;
50 	uint8_t lp_reset;
51 };
52 
53 struct mfd_npm1300_data {
54 	struct k_mutex mutex;
55 	const struct device *dev;
56 	struct gpio_callback gpio_cb;
57 	struct k_work work;
58 	sys_slist_t callbacks;
59 };
60 
61 struct event_reg_t {
62 	uint8_t offset;
63 	uint8_t mask;
64 };
65 
66 static const struct event_reg_t event_reg[NPM1300_EVENT_MAX] = {
67 	[NPM1300_EVENT_CHG_COMPLETED] = {0x0AU, 0x10U},
68 	[NPM1300_EVENT_CHG_ERROR] = {0x0AU, 0x20U},
69 	[NPM1300_EVENT_BATTERY_DETECTED] = {0x0EU, 0x01U},
70 	[NPM1300_EVENT_BATTERY_REMOVED] = {0x0EU, 0x02U},
71 	[NPM1300_EVENT_SHIPHOLD_PRESS] = {0x12U, 0x01U},
72 	[NPM1300_EVENT_SHIPHOLD_RELEASE] = {0x12U, 0x02U},
73 	[NPM1300_EVENT_WATCHDOG_WARN] = {0x12U, 0x08U},
74 	[NPM1300_EVENT_VBUS_DETECTED] = {0x16U, 0x01U},
75 	[NPM1300_EVENT_VBUS_REMOVED] = {0x16U, 0x02U},
76 	[NPM1300_EVENT_GPIO0_EDGE] = {0x22U, 0x01U},
77 	[NPM1300_EVENT_GPIO1_EDGE] = {0x22U, 0x02U},
78 	[NPM1300_EVENT_GPIO2_EDGE] = {0x22U, 0x04U},
79 	[NPM1300_EVENT_GPIO3_EDGE] = {0x22U, 0x08U},
80 	[NPM1300_EVENT_GPIO4_EDGE] = {0x22U, 0x10U},
81 };
82 
gpio_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)83 static void gpio_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
84 {
85 	struct mfd_npm1300_data *data = CONTAINER_OF(cb, struct mfd_npm1300_data, gpio_cb);
86 
87 	k_work_submit(&data->work);
88 }
89 
work_callback(struct k_work * work)90 static void work_callback(struct k_work *work)
91 {
92 	struct mfd_npm1300_data *data = CONTAINER_OF(work, struct mfd_npm1300_data, work);
93 	const struct mfd_npm1300_config *config = data->dev->config;
94 	uint8_t buf[MAIN_SIZE];
95 	int ret;
96 
97 	/* Read all MAIN registers into temporary buffer */
98 	ret = mfd_npm1300_reg_read_burst(data->dev, MAIN_BASE, 0U, buf, sizeof(buf));
99 	if (ret < 0) {
100 		k_work_submit(&data->work);
101 		return;
102 	}
103 
104 	for (int i = 0; i < NPM1300_EVENT_MAX; i++) {
105 		int offset = event_reg[i].offset + MAIN_OFFSET_CLR;
106 
107 		if ((buf[offset] & event_reg[i].mask) != 0U) {
108 			gpio_fire_callbacks(&data->callbacks, data->dev, BIT(i));
109 
110 			ret = mfd_npm1300_reg_write(data->dev, MAIN_BASE, offset,
111 						    event_reg[i].mask);
112 			if (ret < 0) {
113 				k_work_submit(&data->work);
114 				return;
115 			}
116 		}
117 	}
118 
119 	/* Resubmit handler to queue if interrupt is still active */
120 	if (gpio_pin_get_dt(&config->host_int_gpios) != 0) {
121 		k_work_submit(&data->work);
122 	}
123 }
124 
mfd_npm1300_init(const struct device * dev)125 static int mfd_npm1300_init(const struct device *dev)
126 {
127 	const struct mfd_npm1300_config *config = dev->config;
128 	struct mfd_npm1300_data *mfd_data = dev->data;
129 	int ret;
130 
131 	if (!i2c_is_ready_dt(&config->i2c)) {
132 		return -ENODEV;
133 	}
134 
135 	k_mutex_init(&mfd_data->mutex);
136 
137 	mfd_data->dev = dev;
138 
139 	if (config->host_int_gpios.port != NULL) {
140 		/* Set specified PMIC pin to be interrupt output */
141 		ret = mfd_npm1300_reg_write(dev, GPIO_BASE, GPIO_OFFSET_MODE + config->pmic_int_pin,
142 					    GPIO_MODE_GPOIRQ);
143 		if (ret < 0) {
144 			return ret;
145 		}
146 
147 		/* Configure host interrupt GPIO */
148 		if (!gpio_is_ready_dt(&config->host_int_gpios)) {
149 			return -ENODEV;
150 		}
151 
152 		ret = gpio_pin_configure_dt(&config->host_int_gpios, GPIO_INPUT);
153 		if (ret < 0) {
154 			return ret;
155 		}
156 
157 		gpio_init_callback(&mfd_data->gpio_cb, gpio_callback,
158 				   BIT(config->host_int_gpios.pin));
159 
160 		ret = gpio_add_callback(config->host_int_gpios.port, &mfd_data->gpio_cb);
161 		if (ret < 0) {
162 			return ret;
163 		}
164 
165 		mfd_data->work.handler = work_callback;
166 
167 		ret = gpio_pin_interrupt_configure_dt(&config->host_int_gpios,
168 						      GPIO_INT_EDGE_TO_ACTIVE);
169 		if (ret < 0) {
170 			return ret;
171 		}
172 	}
173 
174 	ret = mfd_npm1300_reg_write(dev, SHIP_BASE, SHIP_OFFSET_CONFIG, config->active_time);
175 	if (ret < 0) {
176 		return ret;
177 	}
178 
179 	ret = mfd_npm1300_reg_write(dev, SHIP_BASE, SHIP_OFFSET_LPCONFIG, config->lp_reset);
180 	if (ret < 0) {
181 		return ret;
182 	}
183 
184 	return mfd_npm1300_reg_write(dev, SHIP_BASE, SHIP_OFFSET_CFGSTROBE, 1U);
185 }
186 
mfd_npm1300_reg_read_burst(const struct device * dev,uint8_t base,uint8_t offset,void * data,size_t len)187 int mfd_npm1300_reg_read_burst(const struct device *dev, uint8_t base, uint8_t offset, void *data,
188 			       size_t len)
189 {
190 	const struct mfd_npm1300_config *config = dev->config;
191 	uint8_t buff[] = {base, offset};
192 
193 	return i2c_write_read_dt(&config->i2c, buff, sizeof(buff), data, len);
194 }
195 
mfd_npm1300_reg_read(const struct device * dev,uint8_t base,uint8_t offset,uint8_t * data)196 int mfd_npm1300_reg_read(const struct device *dev, uint8_t base, uint8_t offset, uint8_t *data)
197 {
198 	return mfd_npm1300_reg_read_burst(dev, base, offset, data, 1U);
199 }
200 
mfd_npm1300_reg_write(const struct device * dev,uint8_t base,uint8_t offset,uint8_t data)201 int mfd_npm1300_reg_write(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data)
202 {
203 	const struct mfd_npm1300_config *config = dev->config;
204 	uint8_t buff[] = {base, offset, data};
205 
206 	return i2c_write_dt(&config->i2c, buff, sizeof(buff));
207 }
208 
mfd_npm1300_reg_write2(const struct device * dev,uint8_t base,uint8_t offset,uint8_t data1,uint8_t data2)209 int mfd_npm1300_reg_write2(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data1,
210 			   uint8_t data2)
211 {
212 	const struct mfd_npm1300_config *config = dev->config;
213 	uint8_t buff[] = {base, offset, data1, data2};
214 
215 	return i2c_write_dt(&config->i2c, buff, sizeof(buff));
216 }
217 
mfd_npm1300_reg_update(const struct device * dev,uint8_t base,uint8_t offset,uint8_t data,uint8_t mask)218 int mfd_npm1300_reg_update(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data,
219 			   uint8_t mask)
220 {
221 	struct mfd_npm1300_data *mfd_data = dev->data;
222 	uint8_t reg;
223 	int ret;
224 
225 	k_mutex_lock(&mfd_data->mutex, K_FOREVER);
226 
227 	ret = mfd_npm1300_reg_read(dev, base, offset, &reg);
228 
229 	if (ret == 0) {
230 		reg = (reg & ~mask) | (data & mask);
231 		ret = mfd_npm1300_reg_write(dev, base, offset, reg);
232 	}
233 
234 	k_mutex_unlock(&mfd_data->mutex);
235 
236 	return ret;
237 }
238 
mfd_npm1300_set_timer(const struct device * dev,uint32_t time_ms)239 int mfd_npm1300_set_timer(const struct device *dev, uint32_t time_ms)
240 {
241 	const struct mfd_npm1300_config *config = dev->config;
242 	uint8_t buff[5] = {TIME_BASE, TIME_OFFSET_TIMER};
243 	uint32_t ticks = time_ms / TIMER_PRESCALER_MS;
244 
245 	if (ticks > TIMER_MAX) {
246 		return -EINVAL;
247 	}
248 
249 	sys_put_be24(ticks, &buff[2]);
250 
251 	int ret = i2c_write_dt(&config->i2c, buff, sizeof(buff));
252 
253 	if (ret != 0) {
254 		return ret;
255 	}
256 
257 	return mfd_npm1300_reg_write(dev, TIME_BASE, TIME_OFFSET_LOAD, 1U);
258 }
259 
mfd_npm1300_reset(const struct device * dev)260 int mfd_npm1300_reset(const struct device *dev)
261 {
262 	return mfd_npm1300_reg_write(dev, MAIN_BASE, MAIN_OFFSET_RESET, 1U);
263 }
264 
mfd_npm1300_hibernate(const struct device * dev,uint32_t time_ms)265 int mfd_npm1300_hibernate(const struct device *dev, uint32_t time_ms)
266 {
267 	int ret = mfd_npm1300_set_timer(dev, time_ms);
268 
269 	if (ret != 0) {
270 		return ret;
271 	}
272 
273 	return mfd_npm1300_reg_write(dev, SHIP_BASE, SHIP_OFFSET_HIBERNATE, 1U);
274 }
275 
mfd_npm1300_add_callback(const struct device * dev,struct gpio_callback * callback)276 int mfd_npm1300_add_callback(const struct device *dev, struct gpio_callback *callback)
277 {
278 	struct mfd_npm1300_data *data = dev->data;
279 
280 	/* Enable interrupts for specified events */
281 	for (int i = 0; i < NPM1300_EVENT_MAX; i++) {
282 		if ((callback->pin_mask & BIT(i)) != 0U) {
283 			/* Clear pending interrupt */
284 			int ret = mfd_npm1300_reg_write(data->dev, MAIN_BASE,
285 							event_reg[i].offset + MAIN_OFFSET_CLR,
286 							event_reg[i].mask);
287 
288 			if (ret < 0) {
289 				return ret;
290 			}
291 
292 			ret = mfd_npm1300_reg_write(data->dev, MAIN_BASE,
293 						    event_reg[i].offset + MAIN_OFFSET_INTENSET,
294 						    event_reg[i].mask);
295 			if (ret < 0) {
296 				return ret;
297 			}
298 		}
299 	}
300 
301 	return gpio_manage_callback(&data->callbacks, callback, true);
302 }
303 
mfd_npm1300_remove_callback(const struct device * dev,struct gpio_callback * callback)304 int mfd_npm1300_remove_callback(const struct device *dev, struct gpio_callback *callback)
305 {
306 	struct mfd_npm1300_data *data = dev->data;
307 
308 	return gpio_manage_callback(&data->callbacks, callback, false);
309 }
310 
311 #define MFD_NPM1300_DEFINE(inst)                                                                   \
312 	static struct mfd_npm1300_data data_##inst;                                                \
313                                                                                                    \
314 	static const struct mfd_npm1300_config config##inst = {                                    \
315 		.i2c = I2C_DT_SPEC_INST_GET(inst),                                                 \
316 		.host_int_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, host_int_gpios, {0}),             \
317 		.pmic_int_pin = DT_INST_PROP_OR(inst, pmic_int_pin, 0),                            \
318 		.active_time = DT_INST_ENUM_IDX(inst, ship_to_active_time_ms),                     \
319 		.lp_reset = DT_INST_ENUM_IDX_OR(inst, long_press_reset, 0),                        \
320 	};                                                                                         \
321                                                                                                    \
322 	DEVICE_DT_INST_DEFINE(inst, mfd_npm1300_init, NULL, &data_##inst, &config##inst,           \
323 			      POST_KERNEL, CONFIG_MFD_NPM1300_INIT_PRIORITY, NULL);
324 
325 DT_INST_FOREACH_STATUS_OKAY(MFD_NPM1300_DEFINE)
326