drivers: regulator: add support for RaspberryPi Pico regulator.
Add support for rpi_pico regulator. Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
This commit is contained in:
parent
e75b72234c
commit
47f52bba42
7 changed files with 248 additions and 0 deletions
|
@ -10,3 +10,4 @@ zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1100 regulator_npm1100.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM6001 regulator_npm6001.c)
|
zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM6001 regulator_npm6001.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9420 regulator_pca9420.c)
|
zephyr_library_sources_ifdef(CONFIG_REGULATOR_PCA9420 regulator_pca9420.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_REGULATOR_SHELL regulator_shell.c)
|
zephyr_library_sources_ifdef(CONFIG_REGULATOR_SHELL regulator_shell.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_REGULATOR_RPI_PICO regulator_rpi_pico.c)
|
||||||
|
|
|
@ -25,5 +25,6 @@ source "drivers/regulator/Kconfig.fixed"
|
||||||
source "drivers/regulator/Kconfig.npm1100"
|
source "drivers/regulator/Kconfig.npm1100"
|
||||||
source "drivers/regulator/Kconfig.npm6001"
|
source "drivers/regulator/Kconfig.npm6001"
|
||||||
source "drivers/regulator/Kconfig.pca9420"
|
source "drivers/regulator/Kconfig.pca9420"
|
||||||
|
source "drivers/regulator/Kconfig.rpi_pico"
|
||||||
|
|
||||||
endif # REGULATOR
|
endif # REGULATOR
|
||||||
|
|
19
drivers/regulator/Kconfig.rpi_pico
Normal file
19
drivers/regulator/Kconfig.rpi_pico
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (c) 2023 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config REGULATOR_RPI_PICO
|
||||||
|
bool "RaspberryPi Pico regulator driver"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_RASPBERRYPI_CORE_SUPPLY_REGULATOR_ENABLED
|
||||||
|
help
|
||||||
|
Enable support for the RaspberryPi Pico regulator.
|
||||||
|
|
||||||
|
if REGULATOR_RPI_PICO
|
||||||
|
|
||||||
|
config REGULATOR_RPI_PICO_INIT_PRIORITY
|
||||||
|
int "RaspberryPi Pico regulator driver init priority"
|
||||||
|
default KERNEL_INIT_PRIORITY_DEVICE
|
||||||
|
help
|
||||||
|
Init priority for the RaspberryPi Pico regulator driver.
|
||||||
|
|
||||||
|
endif
|
158
drivers/regulator/regulator_rpi_pico.c
Normal file
158
drivers/regulator/regulator_rpi_pico.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT raspberrypi_core_supply_regulator
|
||||||
|
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
|
#include <zephyr/drivers/regulator.h>
|
||||||
|
#include <zephyr/dt-bindings/regulator/rpi_pico.h>
|
||||||
|
#include <zephyr/sys/linear_range.h>
|
||||||
|
#include <zephyr/toolchain.h>
|
||||||
|
#include <hardware/regs/vreg_and_chip_reset.h>
|
||||||
|
#include <hardware/structs/vreg_and_chip_reset.h>
|
||||||
|
|
||||||
|
static const struct linear_range core_ranges[] = {
|
||||||
|
LINEAR_RANGE_INIT(800000u, 0u, 0u, 5u),
|
||||||
|
LINEAR_RANGE_INIT(850000u, 50000u, 6u, 15u),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const size_t num_core_ranges = ARRAY_SIZE(core_ranges);
|
||||||
|
|
||||||
|
struct regulator_rpi_pico_config {
|
||||||
|
struct regulator_common_config common;
|
||||||
|
vreg_and_chip_reset_hw_t * const reg;
|
||||||
|
const bool brown_out_detection;
|
||||||
|
const uint32_t brown_out_threshold;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regulator_rpi_pico_data {
|
||||||
|
struct regulator_common_data data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* APIs
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned int regulator_rpi_pico_count_voltages(const struct device *dev)
|
||||||
|
{
|
||||||
|
return linear_range_group_values_count(core_ranges, num_core_ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_list_voltage(const struct device *dev, unsigned int idx,
|
||||||
|
int32_t *volt_uv)
|
||||||
|
{
|
||||||
|
return linear_range_group_get_value(core_ranges, num_core_ranges, idx, volt_uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
uint16_t idx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = linear_range_group_get_win_index(core_ranges, num_core_ranges, min_uv, max_uv, &idx);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->reg->vreg = ((config->reg->vreg & ~VREG_AND_CHIP_RESET_VREG_VSEL_BITS) |
|
||||||
|
(idx << VREG_AND_CHIP_RESET_VREG_VSEL_LSB));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_get_voltage(const struct device *dev, int32_t *volt_uv)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
|
||||||
|
return linear_range_group_get_value(
|
||||||
|
core_ranges, num_core_ranges,
|
||||||
|
((config->reg->vreg & VREG_AND_CHIP_RESET_VREG_VSEL_BITS) >>
|
||||||
|
VREG_AND_CHIP_RESET_VREG_VSEL_LSB),
|
||||||
|
volt_uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_enable(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
|
||||||
|
config->reg->vreg |= BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_disable(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
|
||||||
|
config->reg->vreg &= ~BIT(VREG_AND_CHIP_RESET_VREG_EN_LSB);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_set_mode(const struct device *dev, regulator_mode_t mode)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
|
||||||
|
if (mode & REGULATOR_RPI_PICO_MODE_HI_Z) {
|
||||||
|
config->reg->vreg |= REGULATOR_RPI_PICO_MODE_HI_Z;
|
||||||
|
} else {
|
||||||
|
config->reg->vreg &= (~REGULATOR_RPI_PICO_MODE_HI_Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_get_mode(const struct device *dev, regulator_mode_t *mode)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
|
||||||
|
*mode = (config->reg->vreg & REGULATOR_RPI_PICO_MODE_HI_Z);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int regulator_rpi_pico_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct regulator_rpi_pico_config *config = dev->config;
|
||||||
|
|
||||||
|
if (config->brown_out_detection) {
|
||||||
|
config->reg->bod =
|
||||||
|
(BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB) |
|
||||||
|
(config->brown_out_threshold << VREG_AND_CHIP_RESET_BOD_VSEL_LSB));
|
||||||
|
} else {
|
||||||
|
config->reg->bod &= ~BIT(VREG_AND_CHIP_RESET_BOD_EN_LSB);
|
||||||
|
}
|
||||||
|
|
||||||
|
regulator_common_data_init(dev);
|
||||||
|
|
||||||
|
return regulator_common_init(dev, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct regulator_driver_api api = {
|
||||||
|
.enable = regulator_rpi_pico_enable,
|
||||||
|
.disable = regulator_rpi_pico_disable,
|
||||||
|
.count_voltages = regulator_rpi_pico_count_voltages,
|
||||||
|
.list_voltage = regulator_rpi_pico_list_voltage,
|
||||||
|
.set_voltage = regulator_rpi_pico_set_voltage,
|
||||||
|
.get_voltage = regulator_rpi_pico_get_voltage,
|
||||||
|
.set_mode = regulator_rpi_pico_set_mode,
|
||||||
|
.get_mode = regulator_rpi_pico_get_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REGULATOR_RPI_PICO_DEFINE_ALL(inst) \
|
||||||
|
static struct regulator_rpi_pico_data data_##inst; \
|
||||||
|
\
|
||||||
|
static const struct regulator_rpi_pico_config config_##inst = { \
|
||||||
|
.common = REGULATOR_DT_COMMON_CONFIG_INIT(inst), \
|
||||||
|
.reg = (vreg_and_chip_reset_hw_t * const)DT_INST_REG_ADDR(inst), \
|
||||||
|
.brown_out_detection = DT_INST_PROP(inst, raspberrypi_brown_out_detection), \
|
||||||
|
.brown_out_threshold = DT_INST_ENUM_IDX(inst, raspberrypi_brown_out_threshold), \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
DEVICE_DT_INST_DEFINE(inst, regulator_rpi_pico_init, NULL, &data_##inst, &config_##inst, \
|
||||||
|
POST_KERNEL, CONFIG_REGULATOR_RPI_PICO_INIT_PRIORITY, &api);
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(REGULATOR_RPI_PICO_DEFINE_ALL)
|
|
@ -7,6 +7,7 @@
|
||||||
#include <arm/armv6-m.dtsi>
|
#include <arm/armv6-m.dtsi>
|
||||||
#include <zephyr/dt-bindings/gpio/gpio.h>
|
#include <zephyr/dt-bindings/gpio/gpio.h>
|
||||||
#include <zephyr/dt-bindings/i2c/i2c.h>
|
#include <zephyr/dt-bindings/i2c/i2c.h>
|
||||||
|
#include <zephyr/dt-bindings/regulator/rpi_pico.h>
|
||||||
#include <mem.h>
|
#include <mem.h>
|
||||||
|
|
||||||
#include "rpi_pico_common.dtsi"
|
#include "rpi_pico_common.dtsi"
|
||||||
|
@ -184,6 +185,14 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
#pwm-cells = <3>;
|
#pwm-cells = <3>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
vreg: vreg@40064000 {
|
||||||
|
compatible = "raspberrypi,core-supply-regulator";
|
||||||
|
reg = <0x40064000 1>;
|
||||||
|
status = "okay";
|
||||||
|
raspberrypi,brown-out-detection;
|
||||||
|
raspberrypi,brown-out-threshold = <860000>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pinctrl: pin-controller {
|
pinctrl: pin-controller {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Copyright (c), 2023 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
|
||||||
|
# SPDX -License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: |
|
||||||
|
RaspberryPi Pico core supply regurator
|
||||||
|
|
||||||
|
compatible: "raspberrypi,core-supply-regulator"
|
||||||
|
|
||||||
|
include:
|
||||||
|
- name: base.yaml
|
||||||
|
- name: regulator.yaml
|
||||||
|
property-allowlist:
|
||||||
|
- regulator-always-on
|
||||||
|
- regulator-boot-on
|
||||||
|
- regulator-min-microvolt
|
||||||
|
- regulator-max-microvolt
|
||||||
|
- regulator-allowed-modes
|
||||||
|
- regulator-initial-mode
|
||||||
|
|
||||||
|
properties:
|
||||||
|
raspberrypi,brown-out-detection:
|
||||||
|
type: boolean
|
||||||
|
description:
|
||||||
|
Enable brown-out detection
|
||||||
|
|
||||||
|
raspberrypi,brown-out-threshold:
|
||||||
|
type: int
|
||||||
|
default: 860000
|
||||||
|
enum:
|
||||||
|
- 473000
|
||||||
|
- 516000
|
||||||
|
- 559000
|
||||||
|
- 602000
|
||||||
|
- 645000
|
||||||
|
- 688000
|
||||||
|
- 731000
|
||||||
|
- 774000
|
||||||
|
- 817000
|
||||||
|
- 860000
|
||||||
|
- 903000
|
||||||
|
- 946000
|
||||||
|
- 989000
|
||||||
|
- 1032000
|
||||||
|
- 1075000
|
||||||
|
- 1118000
|
||||||
|
description: |
|
||||||
|
Reset if the core voltage drops below this threshold for a particular time
|
||||||
|
(determined by the 'brown-out detection assertion delay').
|
12
include/zephyr/dt-bindings/regulator/rpi_pico.h
Normal file
12
include/zephyr/dt-bindings/regulator/rpi_pico.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_RPI_PICO_H_
|
||||||
|
#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_RPI_PICO_H_
|
||||||
|
|
||||||
|
#define REGULATOR_RPI_PICO_MODE_NORMAL 0x0
|
||||||
|
#define REGULATOR_RPI_PICO_MODE_HI_Z 0x2
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_RPI_PICO_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue