1 /*
2  * Copyright 2019-2020 Peter Bigot Consulting, LLC
3  * Copyright 2022 Nordic Semiconductor ASA
4  * Copyright 2023 EPAM Systems
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT regulator_fixed
9 
10 #include <stdint.h>
11 
12 #include <zephyr/drivers/regulator.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/logging/log.h>
15 
16 LOG_MODULE_REGISTER(regulator_fixed, CONFIG_REGULATOR_LOG_LEVEL);
17 
18 struct regulator_fixed_config {
19 	struct regulator_common_config common;
20 	struct gpio_dt_spec enable;
21 };
22 
23 struct regulator_fixed_data {
24 	struct regulator_common_data common;
25 };
26 
regulator_fixed_enable(const struct device * dev)27 static int regulator_fixed_enable(const struct device *dev)
28 {
29 	const struct regulator_fixed_config *cfg = dev->config;
30 	int ret;
31 
32 	if (!cfg->enable.port) {
33 		return -ENOTSUP;
34 	}
35 
36 	ret = gpio_pin_set_dt(&cfg->enable, 1);
37 	if (ret < 0) {
38 		return ret;
39 	}
40 
41 	return 0;
42 }
43 
regulator_fixed_disable(const struct device * dev)44 static int regulator_fixed_disable(const struct device *dev)
45 {
46 	const struct regulator_fixed_config *cfg = dev->config;
47 
48 	if (!cfg->enable.port) {
49 		return -ENOTSUP;
50 	}
51 
52 	return gpio_pin_set_dt(&cfg->enable, 0);
53 }
54 
regulator_fixed_count_voltages(const struct device * dev)55 static unsigned int regulator_fixed_count_voltages(const struct device *dev)
56 {
57 	int32_t min_uv;
58 
59 	return (regulator_common_get_min_voltage(dev, &min_uv) < 0) ? 0U : 1U;
60 }
61 
regulator_fixed_list_voltage(const struct device * dev,unsigned int idx,int32_t * volt_uv)62 static int regulator_fixed_list_voltage(const struct device *dev,
63 					unsigned int idx,
64 					int32_t *volt_uv)
65 {
66 	if (idx != 0) {
67 		return -EINVAL;
68 	}
69 
70 	if (regulator_common_get_min_voltage(dev, volt_uv) < 0) {
71 		return -EINVAL;
72 	}
73 
74 	return 0;
75 }
76 
77 static const struct regulator_driver_api regulator_fixed_api = {
78 	.enable = regulator_fixed_enable,
79 	.disable = regulator_fixed_disable,
80 	.count_voltages = regulator_fixed_count_voltages,
81 	.list_voltage = regulator_fixed_list_voltage,
82 };
83 
regulator_fixed_init(const struct device * dev)84 static int regulator_fixed_init(const struct device *dev)
85 {
86 	const struct regulator_fixed_config *cfg = dev->config;
87 
88 	regulator_common_data_init(dev);
89 
90 	if (cfg->enable.port != NULL) {
91 		if (!gpio_is_ready_dt(&cfg->enable)) {
92 			LOG_ERR("GPIO port: %s not ready", cfg->enable.port->name);
93 			return -ENODEV;
94 		}
95 
96 		int ret = gpio_pin_configure_dt(&cfg->enable, GPIO_OUTPUT);
97 
98 		if (ret < 0) {
99 			return ret;
100 		}
101 	}
102 
103 	return regulator_common_init(dev, false);
104 }
105 
106 #define REGULATOR_FIXED_DEFINE(inst)                                              \
107 	BUILD_ASSERT(DT_INST_PROP_OR(inst, regulator_min_microvolt, 0) ==         \
108 		     DT_INST_PROP_OR(inst, regulator_max_microvolt, 0),           \
109 		     "Regulator requires fixed voltages");                        \
110 	static struct regulator_fixed_data data##inst;                            \
111                                                                                   \
112 	static const struct regulator_fixed_config config##inst = {               \
113 		.common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst),             \
114 		.enable = GPIO_DT_SPEC_INST_GET_OR(inst, enable_gpios, {0}),      \
115 	};                                                                        \
116                                                                                   \
117 	DEVICE_DT_INST_DEFINE(inst, regulator_fixed_init, NULL, &data##inst,      \
118 			      &config##inst, POST_KERNEL,                         \
119 			      CONFIG_REGULATOR_FIXED_INIT_PRIORITY,               \
120 			      &regulator_fixed_api);
121 
122 DT_INST_FOREACH_STATUS_OKAY(REGULATOR_FIXED_DEFINE)
123