1 /*
2  * Copyright (c) 2024 ITE Corporation. All Rights Reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ite_it8801_gpio
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/gpio/gpio_utils.h>
12 #include <zephyr/drivers/i2c.h>
13 #include <zephyr/drivers/mfd/mfd_ite_it8801.h>
14 #include <zephyr/spinlock.h>
15 
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(gpio_ite_it8801, CONFIG_GPIO_LOG_LEVEL);
18 
19 struct gpio_it8801_config {
20 	/* gpio_driver_config needs to be first */
21 	struct gpio_driver_config common;
22 	/* IT8801 controller dev */
23 	const struct device *mfd;
24 	/* I2C device for the MFD parent */
25 	const struct i2c_dt_spec i2c_dev;
26 	/* GPIO input pin status register */
27 	uint8_t reg_ipsr;
28 	/* GPIO set output value register */
29 	uint8_t reg_sovr;
30 	/* GPIO control register */
31 	uint8_t reg_gpcr;
32 	/* GPIO interrupt status register */
33 	uint8_t reg_gpisr;
34 	/* GPIO interrupt enable register */
35 	uint8_t reg_gpier;
36 	uint8_t pin_mask;
37 };
38 
39 struct gpio_it8801_data {
40 	struct gpio_driver_data common;
41 	struct it8801_mfd_callback it8801_gpio_callback;
42 	sys_slist_t callbacks;
43 };
44 
ioex_check_is_not_valid(const struct device * dev,gpio_pin_t pin)45 static int ioex_check_is_not_valid(const struct device *dev, gpio_pin_t pin)
46 {
47 	const struct gpio_it8801_config *config = dev->config;
48 
49 	if (BIT(pin) & ~(config->pin_mask)) {
50 		LOG_ERR("GPIO  port%d-%d is not support", config->reg_ipsr, pin);
51 		return -ENOTSUP;
52 	}
53 
54 	return 0;
55 }
56 
gpio_it8801_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)57 static int gpio_it8801_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
58 {
59 	const struct gpio_it8801_config *config = dev->config;
60 	int ret;
61 	uint8_t reg_gpcr = config->reg_gpcr + pin;
62 	uint8_t mask = BIT(pin);
63 	uint8_t new_value, control;
64 
65 	/* Don't support "open source" mode */
66 	if (((flags & GPIO_SINGLE_ENDED) != 0) && ((flags & GPIO_LINE_OPEN_DRAIN) == 0)) {
67 		return -ENOTSUP;
68 	}
69 
70 	if (ioex_check_is_not_valid(dev, pin)) {
71 		return -ENOTSUP;
72 	}
73 
74 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, reg_gpcr, &control);
75 	if (ret) {
76 		LOG_ERR("Failed to read control value (ret %d)", ret);
77 		return ret;
78 	}
79 
80 	if (flags == GPIO_DISCONNECTED) {
81 		control &= ~(IT8801_GPIODIR | IT8801_GPIOPDE | IT8801_GPIOPUE);
82 
83 		goto write_and_return;
84 	}
85 
86 	/* If output, set level before changing type to an output. */
87 	if (flags & GPIO_OUTPUT) {
88 		if (flags & GPIO_OUTPUT_INIT_HIGH) {
89 			new_value = mask;
90 		} else if (flags & GPIO_OUTPUT_INIT_LOW) {
91 			new_value = 0;
92 		} else {
93 			new_value = 0;
94 		}
95 		ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_sovr, mask, new_value);
96 		if (ret) {
97 			LOG_ERR("Failed to set output value (ret %d)", ret);
98 			return ret;
99 		}
100 		/* Set output */
101 		control |= IT8801_GPIODIR;
102 		/* Select open drain 0:push-pull 1:open-drain */
103 		if (flags & GPIO_OPEN_DRAIN) {
104 			control |= IT8801_GPIOIOT_OD;
105 		} else {
106 			control &= ~IT8801_GPIOIOT_OD;
107 		}
108 	} else {
109 		/* Set input */
110 		control &= ~IT8801_GPIODIR;
111 	}
112 
113 	/* Handle pullup / pulldown */
114 	if (flags & GPIO_PULL_UP) {
115 		control = (control | IT8801_GPIOPUE) & ~IT8801_GPIOPDE;
116 	} else if (flags & GPIO_PULL_DOWN) {
117 		control = (control | IT8801_GPIOPDE) & ~IT8801_GPIOPUE;
118 	} else {
119 		/* No pull up/down */
120 		control &= ~(IT8801_GPIOPUE | IT8801_GPIOPDE);
121 	}
122 
123 write_and_return:
124 	/* Set GPIO control */
125 	ret = i2c_reg_write_byte_dt(&config->i2c_dev, reg_gpcr, control);
126 	if (ret) {
127 		LOG_ERR("Failed to set control value (ret %d)", ret);
128 		return ret;
129 	}
130 
131 	return 0;
132 }
133 
134 #ifdef CONFIG_GPIO_GET_CONFIG
gpio_it8801_get_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t * out_flags)135 static int gpio_it8801_get_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t *out_flags)
136 {
137 	const struct gpio_it8801_config *config = dev->config;
138 	gpio_flags_t flags = 0;
139 	int ret;
140 	uint8_t reg_gpcr = config->reg_gpcr + pin;
141 	uint8_t mask = BIT(pin);
142 	uint8_t control, value;
143 
144 	if (ioex_check_is_not_valid(dev, pin)) {
145 		return -ENOTSUP;
146 	}
147 
148 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, reg_gpcr, &control);
149 	if (ret) {
150 		LOG_ERR("Failed to read control value (ret %d)", ret);
151 		return ret;
152 	}
153 
154 	/* Get GPIO direction */
155 	if (control & IT8801_GPIODIR) {
156 		flags |= GPIO_OUTPUT;
157 
158 		/* Get GPIO type, 0:push-pull 1:open-drain */
159 		if (control & IT8801_GPIOIOT_OD) {
160 			flags |= GPIO_OPEN_DRAIN;
161 		}
162 
163 		ret = i2c_reg_read_byte_dt(&config->i2c_dev, config->reg_ipsr, &value);
164 		if (ret) {
165 			LOG_ERR("Failed to read pin status (ret %d)", ret);
166 			return ret;
167 		}
168 
169 		/* Get GPIO output level */
170 		if (value & mask) {
171 			flags |= GPIO_OUTPUT_HIGH;
172 		} else {
173 			flags |= GPIO_OUTPUT_LOW;
174 		}
175 	} else {
176 		flags |= GPIO_INPUT;
177 	}
178 
179 	/* pullup / pulldown */
180 	if (control & IT8801_GPIOPUE) {
181 		flags |= GPIO_PULL_UP;
182 	} else if (control & IT8801_GPIOPDE) {
183 		flags |= GPIO_PULL_DOWN;
184 	}
185 
186 	*out_flags = flags;
187 
188 	return 0;
189 }
190 #endif
191 
gpio_it8801_port_get_raw(const struct device * dev,gpio_port_value_t * value)192 static int gpio_it8801_port_get_raw(const struct device *dev, gpio_port_value_t *value)
193 {
194 	const struct gpio_it8801_config *config = dev->config;
195 	int ret;
196 	uint8_t val;
197 
198 	/* Get raw bits of GPIO mirror register */
199 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, config->reg_ipsr, &val);
200 	if (ret) {
201 		LOG_ERR("Failed to get port mask (ret %d)", ret);
202 		return ret;
203 	}
204 
205 	*value = val;
206 
207 	return 0;
208 }
209 
gpio_it8801_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)210 static int gpio_it8801_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
211 					   gpio_port_value_t value)
212 {
213 	const struct gpio_it8801_config *config = dev->config;
214 	int ret;
215 
216 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_sovr, mask, value);
217 	if (ret) {
218 		LOG_ERR("Failed to set port mask (ret %d)", ret);
219 		return ret;
220 	}
221 
222 	return 0;
223 }
224 
gpio_it8801_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)225 static int gpio_it8801_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
226 {
227 	const struct gpio_it8801_config *config = dev->config;
228 	int ret;
229 
230 	/* Set raw bits of GPIO data register */
231 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_sovr, pins, pins);
232 	if (ret) {
233 		LOG_ERR("Failed to set bits raw (ret %d)", ret);
234 		return ret;
235 	}
236 
237 	return 0;
238 }
239 
gpio_it8801_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)240 static int gpio_it8801_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
241 {
242 	const struct gpio_it8801_config *config = dev->config;
243 	int ret;
244 
245 	/* Clear raw bits of GPIO data register */
246 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_sovr, pins, 0);
247 	if (ret) {
248 		LOG_ERR("Failed to clear bits raw (ret %d)", ret);
249 		return ret;
250 	}
251 
252 	return 0;
253 }
254 
gpio_it8801_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)255 static int gpio_it8801_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
256 {
257 	const struct gpio_it8801_config *config = dev->config;
258 	int ret;
259 	uint8_t val, new_val;
260 
261 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, config->reg_sovr, &val);
262 	if (ret) {
263 		return ret;
264 	}
265 	/* Toggle raw bits of GPIO data register */
266 	new_val = val ^ pins;
267 	if (new_val != val) {
268 		ret = i2c_reg_write_byte_dt(&config->i2c_dev, config->reg_sovr, new_val);
269 		if (ret) {
270 			LOG_ERR("Failed to write toggle value (ret %d)", ret);
271 			return ret;
272 		}
273 	}
274 
275 	return 0;
276 }
277 
gpio_it8801_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)278 static int gpio_it8801_manage_callback(const struct device *dev, struct gpio_callback *callback,
279 				       bool set)
280 {
281 	struct gpio_it8801_data *data = dev->data;
282 	int ret;
283 
284 	ret = gpio_manage_callback(&data->callbacks, callback, set);
285 
286 	return ret;
287 }
288 
it8801_gpio_alert_handler(const struct device * dev)289 static void it8801_gpio_alert_handler(const struct device *dev)
290 {
291 	const struct gpio_it8801_config *config = dev->config;
292 	struct gpio_it8801_data *data = dev->data;
293 	int ret;
294 	uint8_t isr_val, ier_val;
295 
296 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, config->reg_gpisr, &isr_val);
297 	if (ret) {
298 		LOG_ERR("Failed to read GPIO interrupt status (ret %d)", ret);
299 		return;
300 	}
301 
302 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, config->reg_gpier, &ier_val);
303 	if (ret) {
304 		LOG_ERR("Failed to read GPIO interrupt pin set (ret %d)", ret);
305 		return;
306 	}
307 
308 	if (isr_val & ier_val) {
309 		/* Clear pending interrupt */
310 		ret = i2c_reg_write_byte_dt(&config->i2c_dev, config->reg_gpisr, isr_val);
311 		if (ret) {
312 			LOG_ERR("Failed to clear GPIO interrupt (ret %d)", ret);
313 			return;
314 		}
315 
316 		gpio_fire_callbacks(&data->callbacks, dev, isr_val);
317 	}
318 }
319 
gpio_it8801_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)320 static int gpio_it8801_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
321 					       enum gpio_int_mode mode, enum gpio_int_trig trig)
322 {
323 	const struct gpio_it8801_config *config = dev->config;
324 	struct gpio_it8801_data *data = dev->data;
325 	int ret;
326 	uint8_t reg_gpcr = config->reg_gpcr + pin;
327 	uint8_t control;
328 	uint8_t mask = BIT(pin);
329 
330 	if (ioex_check_is_not_valid(dev, pin)) {
331 		return -ENOTSUP;
332 	}
333 
334 	/* Disable irq before configuring it  */
335 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_gpier, mask, 0);
336 	if (ret) {
337 		LOG_ERR("Failed to disable irq (ret %d)", ret);
338 		return ret;
339 	}
340 
341 	if (mode == GPIO_INT_MODE_DISABLED) {
342 		return ret;
343 	}
344 
345 	/* Set input pin */
346 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, reg_gpcr, IT8801_GPIODIR, 0);
347 	if (ret) {
348 		LOG_ERR("Failed to set input pin (ret %d)", ret);
349 		return ret;
350 	}
351 
352 	/* Clear trigger type */
353 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, reg_gpcr, GENMASK(4, 3), 0);
354 	if (ret) {
355 		LOG_ERR("Failed to clear trigger type (ret %d)", ret);
356 		return ret;
357 	}
358 
359 	ret = i2c_reg_read_byte_dt(&config->i2c_dev, reg_gpcr, &control);
360 	if (ret) {
361 		LOG_ERR("Failed to read gpio control (ret %d)", ret);
362 		return ret;
363 	}
364 
365 	if (mode == GPIO_INT_MODE_EDGE) {
366 		/* Set edge trigger */
367 		if ((trig & GPIO_INT_TRIG_BOTH) == GPIO_INT_TRIG_BOTH) {
368 			control |= IT8801_GPIOIOT_INT_FALL | IT8801_GPIOIOT_INT_RISE;
369 		} else if (trig & GPIO_INT_TRIG_LOW) {
370 			control |= IT8801_GPIOIOT_INT_FALL;
371 		} else if (trig & GPIO_INT_TRIG_HIGH) {
372 			control |= IT8801_GPIOIOT_INT_RISE;
373 		} else {
374 			LOG_ERR("Invalid interrupt trigger type %d", trig);
375 			return -EINVAL;
376 		}
377 	} else if (mode == GPIO_INT_MODE_LEVEL) {
378 		/* Set level trigger */
379 		if (trig & GPIO_INT_TRIG_LOW) {
380 			control &= ~IT8801_GPIOPOL;
381 		} else {
382 			control |= IT8801_GPIOPOL;
383 		}
384 	}
385 
386 	/* Set control value */
387 	ret = i2c_reg_write_byte_dt(&config->i2c_dev, reg_gpcr, control);
388 	if (ret) {
389 		LOG_ERR("Failed to write trigger state (ret %d)", ret);
390 		return ret;
391 	}
392 
393 	/* Clear pending interrupt */
394 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_gpisr, mask, mask);
395 	if (ret) {
396 		LOG_ERR("Failed to clear pending interrupt (ret %d)", ret);
397 		return ret;
398 	}
399 
400 	/* Enable GPIO interrupt */
401 	ret = i2c_reg_update_byte_dt(&config->i2c_dev, config->reg_gpier, mask, mask);
402 	if (ret) {
403 		LOG_ERR("Failed to enable interrupt (ret %d)", ret);
404 		return ret;
405 	}
406 
407 	/* Gather GPIO interrupt enable */
408 	ret = i2c_reg_write_byte_dt(&config->i2c_dev, IT8801_REG_GIECR, IT8801_REG_MASK_GGPIOIE);
409 
410 	/* Register the interrupt of IT8801 MFD callback function */
411 	data->it8801_gpio_callback.cb = it8801_gpio_alert_handler;
412 	data->it8801_gpio_callback.dev = dev;
413 	mfd_it8801_register_interrupt_callback(config->mfd, &data->it8801_gpio_callback);
414 
415 	return ret;
416 }
417 
418 static DEVICE_API(gpio, gpio_it8801_driver_api) = {
419 	.pin_configure = gpio_it8801_configure,
420 #ifdef CONFIG_GPIO_GET_CONFIG
421 	.pin_get_config = gpio_it8801_get_config,
422 #endif
423 	.port_get_raw = gpio_it8801_port_get_raw,
424 	.port_set_masked_raw = gpio_it8801_port_set_masked_raw,
425 	.port_set_bits_raw = gpio_it8801_port_set_bits_raw,
426 	.port_clear_bits_raw = gpio_it8801_port_clear_bits_raw,
427 	.port_toggle_bits = gpio_it8801_port_toggle_bits,
428 	.pin_interrupt_configure = gpio_it8801_pin_interrupt_configure,
429 	.manage_callback = gpio_it8801_manage_callback,
430 };
431 
gpio_it8801_init(const struct device * dev)432 static int gpio_it8801_init(const struct device *dev)
433 {
434 	const struct gpio_it8801_config *config = dev->config;
435 
436 	/* Verify multi-function parent is ready */
437 	if (!device_is_ready(config->mfd)) {
438 		LOG_ERR("(gpio)%s is not ready", config->mfd->name);
439 		return -ENODEV;
440 	}
441 
442 	return 0;
443 }
444 
445 #define GPIO_IT8801_DEVICE_INST(inst)                                                              \
446 	static struct gpio_it8801_data gpio_it8801_data_##inst;                                    \
447 	static const struct gpio_it8801_config gpio_it8801_cfg_##inst = {                          \
448 		.common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)},                \
449 		.mfd = DEVICE_DT_GET(DT_INST_PARENT(inst)),                                        \
450 		.i2c_dev = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)),                                  \
451 		.reg_ipsr = DT_INST_REG_ADDR_BY_IDX(inst, 0),                                      \
452 		.reg_sovr = DT_INST_REG_ADDR_BY_IDX(inst, 1),                                      \
453 		.reg_gpcr = DT_INST_REG_ADDR_BY_IDX(inst, 2),                                      \
454 		.reg_gpisr = DT_INST_REG_ADDR_BY_IDX(inst, 3),                                     \
455 		.reg_gpier = DT_INST_REG_ADDR_BY_IDX(inst, 4),                                     \
456 		.pin_mask = DT_INST_PROP(inst, pin_mask),                                          \
457 	};                                                                                         \
458 	DEVICE_DT_INST_DEFINE(inst, gpio_it8801_init, NULL, &gpio_it8801_data_##inst,              \
459 			      &gpio_it8801_cfg_##inst, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY,      \
460 			      &gpio_it8801_driver_api);
461 
462 DT_INST_FOREACH_STATUS_OKAY(GPIO_IT8801_DEVICE_INST)
463