Skip to content

Commit f2d7de8

Browse files
committed
regulator: add ti tps55287
add ti tps55287 regulator Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
1 parent 7acc119 commit f2d7de8

File tree

6 files changed

+222
-0
lines changed

6 files changed

+222
-0
lines changed

drivers/regulator/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9420 regulator_pca9420.c)
2020
zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9422 regulator_pca9422.c)
2121
zephyr_library_sources_ifdef(CONFIG_REGULATOR_PF1550 regulator_pf1550.c)
2222
zephyr_library_sources_ifdef(CONFIG_REGULATOR_SHELL regulator_shell.c)
23+
zephyr_library_sources_ifdef(CONFIG_REGULATOR_TPS55287 regulator_tps55287.c)
2324
zephyr_library_sources_ifdef(CONFIG_REGULATOR_RPI_PICO regulator_rpi_pico.c)
2425
zephyr_library_sources_ifdef(CONFIG_REGULATOR_NXP_VREF regulator_nxp_vref.c)
2526
zephyr_library_sources_ifdef(CONFIG_REGULATOR_NXP_VREFV1 regulator_nxp_vrefv1.c)

drivers/regulator/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ source "drivers/regulator/Kconfig.pca9420"
4242
source "drivers/regulator/Kconfig.pca9422"
4343
source "drivers/regulator/Kconfig.pf1550"
4444
source "drivers/regulator/Kconfig.rpi_pico"
45+
source "drivers/regulator/Kconfig.tps55287"
4546
source "drivers/regulator/Kconfig.nxp_vref"
4647
source "drivers/regulator/Kconfig.nxp_vrefv1"
4748
source "drivers/regulator/Kconfig.mpm54304"

drivers/regulator/Kconfig.tps55287

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config REGULATOR_TPS55287
5+
bool "TPS55287 regulator driver"
6+
default y
7+
depends on DT_HAS_TI_TPS55287_ENABLED
8+
select I2C
9+
help
10+
Enable support for the TPS55287 regulator.
11+
12+
if REGULATOR_TPS55287
13+
14+
config REGULATOR_TPS55287_INIT_PRIORITY
15+
int "TPS55287 regulator driver init priority"
16+
default 51
17+
help
18+
Init priority for the TPS55287 regulator driver. This must be higher
19+
than the parent I2C bus init priority.
20+
21+
endif
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#define DT_DRV_COMPAT ti_tps55287
7+
8+
#include <zephyr/drivers/i2c.h>
9+
#include <zephyr/drivers/regulator.h>
10+
#include <zephyr/logging/log.h>
11+
#include <zephyr/sys/byteorder.h>
12+
#include <zephyr/sys/linear_range.h>
13+
#include <zephyr/sys/util.h>
14+
15+
LOG_MODULE_REGISTER(tps55287, CONFIG_REGULATOR_LOG_LEVEL);
16+
17+
#define TPS55287_REG_REF 0x00U
18+
#define TPS55287_REG_VOUT_FS 0x04U
19+
#define TPS55287_REG_MODE 0x06U
20+
21+
#define TPS55287_REG_VOUT_FS_INTFB_MASK BIT_MASK(2)
22+
#define TPS55287_REG_MODE_OE BIT(7)
23+
24+
/* The order of the voltage ranges is important, as it maps to the VOUT_FS register */
25+
static const struct linear_range core_ranges[] = {
26+
LINEAR_RANGE_INIT(800000u, 2500u, 0xf0, BIT_MASK(11)),
27+
LINEAR_RANGE_INIT(800000u, 5000u, 0x50, BIT_MASK(11)),
28+
LINEAR_RANGE_INIT(800000u, 7500u, 0x1a, BIT_MASK(11)),
29+
LINEAR_RANGE_INIT(800000u, 10000u, 0x00, BIT_MASK(11)),
30+
};
31+
32+
struct regulator_tps55287_config {
33+
struct regulator_common_config common;
34+
struct i2c_dt_spec i2c;
35+
};
36+
37+
struct regulator_tps55287_data {
38+
struct regulator_common_data data;
39+
};
40+
41+
static unsigned int regulator_tps55287_count_voltages(const struct device *dev)
42+
{
43+
return linear_range_group_values_count(core_ranges, ARRAY_SIZE(core_ranges));
44+
}
45+
46+
static int regulator_tps55287_list_voltage(const struct device *dev, unsigned int idx,
47+
int32_t *volt_uv)
48+
{
49+
for (uint8_t i = 0U; i < ARRAY_SIZE(core_ranges); i++) {
50+
if (linear_range_get_value(&core_ranges[i], idx, volt_uv) == 0) {
51+
return 0;
52+
}
53+
idx -= linear_range_values_count(&core_ranges[i]);
54+
}
55+
56+
return -EINVAL;
57+
}
58+
59+
static int regulator_tps55287_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv)
60+
{
61+
const struct regulator_tps55287_config *config = dev->config;
62+
uint8_t buf[3] = {0};
63+
uint16_t idx;
64+
uint8_t vout_fs_reg;
65+
int ret;
66+
67+
ret = i2c_reg_read_byte_dt(&config->i2c, TPS55287_REG_VOUT_FS, &vout_fs_reg);
68+
if (ret < 0) {
69+
return ret;
70+
}
71+
72+
vout_fs_reg &= TPS55287_REG_VOUT_FS_INTFB_MASK;
73+
74+
ret = linear_range_get_win_index(&core_ranges[vout_fs_reg], min_uv, max_uv, &idx);
75+
76+
/* If we couldn't find a matching voltage in the current range, check the other ranges */
77+
if (ret < 0) {
78+
vout_fs_reg = ARRAY_SIZE(core_ranges);
79+
/* We start with the highest voltage range and work our way down */
80+
do {
81+
vout_fs_reg--;
82+
83+
ret = linear_range_get_win_index(&core_ranges[vout_fs_reg], min_uv, max_uv,
84+
&idx);
85+
} while ((ret < 0) && (vout_fs_reg > 0U));
86+
87+
if (ret < 0) {
88+
return ret;
89+
}
90+
91+
ret = i2c_reg_write_byte_dt(&config->i2c, TPS55287_REG_VOUT_FS, vout_fs_reg);
92+
if (ret < 0) {
93+
return ret;
94+
}
95+
}
96+
97+
LOG_DBG("%s: Setting voltage to range %u, index %u", dev->name, vout_fs_reg, idx);
98+
99+
buf[0] = TPS55287_REG_REF;
100+
101+
sys_put_be16(idx, &buf[1]);
102+
103+
return i2c_write_dt(&config->i2c, buf, sizeof(buf));
104+
}
105+
106+
static int regulator_tps55287_get_voltage(const struct device *dev, int32_t *volt_uv)
107+
{
108+
const struct regulator_tps55287_config *config = dev->config;
109+
uint8_t vout_fs_reg = 0;
110+
uint8_t buf[2] = {0};
111+
uint16_t idx;
112+
int ret;
113+
114+
ret = i2c_reg_read_byte_dt(&config->i2c, TPS55287_REG_VOUT_FS, &vout_fs_reg);
115+
if (ret < 0) {
116+
return ret;
117+
}
118+
119+
ret = i2c_burst_read_dt(&config->i2c, TPS55287_REG_REF, buf, sizeof(buf));
120+
if (ret < 0) {
121+
return ret;
122+
}
123+
124+
vout_fs_reg &= TPS55287_REG_VOUT_FS_INTFB_MASK;
125+
idx = sys_get_be16(buf);
126+
127+
ret = linear_range_get_value(&core_ranges[vout_fs_reg], idx, volt_uv);
128+
129+
LOG_DBG("%s: Got voltage: %d uV (range %u, index %u)", dev->name, *volt_uv, vout_fs_reg,
130+
idx);
131+
132+
return ret;
133+
}
134+
135+
static int regulator_tps55287_enable(const struct device *dev)
136+
{
137+
const struct regulator_tps55287_config *config = dev->config;
138+
139+
return i2c_reg_update_byte_dt(&config->i2c, TPS55287_REG_MODE, TPS55287_REG_MODE_OE,
140+
TPS55287_REG_MODE_OE);
141+
}
142+
143+
static int regulator_tps55287_disable(const struct device *dev)
144+
{
145+
const struct regulator_tps55287_config *config = dev->config;
146+
147+
return i2c_reg_update_byte_dt(&config->i2c, TPS55287_REG_MODE, TPS55287_REG_MODE_OE, 0);
148+
}
149+
150+
static int regulator_tps55287_init(const struct device *dev)
151+
{
152+
int ret;
153+
154+
regulator_common_data_init(dev);
155+
156+
ret = regulator_common_init(dev, false);
157+
if (ret < 0) {
158+
LOG_ERR("%s: Failed to initialize regulator: %d", dev->name, ret);
159+
}
160+
return ret;
161+
}
162+
163+
static DEVICE_API(regulator, api) = {
164+
.enable = regulator_tps55287_enable,
165+
.disable = regulator_tps55287_disable,
166+
.count_voltages = regulator_tps55287_count_voltages,
167+
.list_voltage = regulator_tps55287_list_voltage,
168+
.set_voltage = regulator_tps55287_set_voltage,
169+
.get_voltage = regulator_tps55287_get_voltage,
170+
};
171+
172+
#define REGULATOR_TPS55287_DEFINE_ALL(inst) \
173+
static struct regulator_tps55287_data data_##inst; \
174+
\
175+
static const struct regulator_tps55287_config config_##inst = { \
176+
.common = REGULATOR_DT_INST_COMMON_CONFIG_INIT(inst), \
177+
.i2c = I2C_DT_SPEC_INST_GET(inst), \
178+
}; \
179+
\
180+
DEVICE_DT_INST_DEFINE(inst, regulator_tps55287_init, NULL, &data_##inst, &config_##inst, \
181+
POST_KERNEL, CONFIG_REGULATOR_TPS55287_INIT_PRIORITY, &api);
182+
183+
DT_INST_FOREACH_STATUS_OKAY(REGULATOR_TPS55287_DEFINE_ALL)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
TPS55287 core supply regulator
6+
7+
compatible: "ti,tps55287"
8+
9+
include:
10+
- name: i2c-device.yaml
11+
- name: regulator.yaml

tests/drivers/build_all/regulator/i2c.dtsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,8 @@ npm1304@9 {
200200
LDO2 {};
201201
};
202202
};
203+
204+
tps55287@a {
205+
compatible = "ti,tps55287";
206+
reg = <0xa>;
207+
};

0 commit comments

Comments
 (0)