96 lines
3.6 KiB
C
96 lines
3.6 KiB
C
/*
|
|
* Copyright (c) 2024 Vogl Electronic GmbH
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#define DT_DRV_COMPAT mps_mpm54304
|
|
|
|
#include <errno.h>
|
|
|
|
#include <zephyr/device.h>
|
|
#include <zephyr/drivers/i2c.h>
|
|
#include <zephyr/drivers/regulator.h>
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(mps_mpm54304, CONFIG_REGULATOR_LOG_LEVEL);
|
|
|
|
#define MPM54304_REG_EN 0x0CU
|
|
#define MPM54304_REG_VENDOR_ID 0x13U
|
|
|
|
#define MPM54304_BUCK1_EN_MASK BIT(7)
|
|
#define MPM54304_BUCK2_EN_MASK BIT(6)
|
|
#define MPM54304_BUCK3_EN_MASK BIT(5)
|
|
#define MPM54304_BUCK4_EN_MASK BIT(4)
|
|
|
|
struct regulator_mpm54304_config {
|
|
struct regulator_common_config common;
|
|
struct i2c_dt_spec bus;
|
|
uint8_t enable_mask;
|
|
};
|
|
|
|
struct regulator_mpm54304_data {
|
|
struct regulator_common_data common;
|
|
};
|
|
|
|
static int regulator_mpm54304_enable(const struct device *dev)
|
|
{
|
|
const struct regulator_mpm54304_config *config = dev->config;
|
|
|
|
return i2c_reg_update_byte_dt(&config->bus, MPM54304_REG_EN, config->enable_mask,
|
|
config->enable_mask);
|
|
}
|
|
|
|
static int regulator_mpm54304_disable(const struct device *dev)
|
|
{
|
|
const struct regulator_mpm54304_config *config = dev->config;
|
|
|
|
return i2c_reg_update_byte_dt(&config->bus, MPM54304_REG_EN, config->enable_mask, 0x00);
|
|
}
|
|
|
|
static int regulator_mpm54304_init(const struct device *dev)
|
|
{
|
|
const struct regulator_mpm54304_config *config = dev->config;
|
|
uint8_t value;
|
|
|
|
if (!i2c_is_ready_dt(&config->bus)) {
|
|
LOG_ERR("I2C bus %s not ready", config->bus.bus->name);
|
|
return -ENODEV;
|
|
}
|
|
|
|
/* dummy read needed for chip to function properly */
|
|
(void)i2c_reg_read_byte_dt(&config->bus, MPM54304_REG_VENDOR_ID, &value);
|
|
LOG_DBG("vendor id: 0x%x", value >> 4);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct regulator_driver_api mpm54304_api = {
|
|
.enable = regulator_mpm54304_enable,
|
|
.disable = regulator_mpm54304_disable,
|
|
};
|
|
|
|
#define REGULATOR_MPM54304_DEFINE(node_id, id, child_name) \
|
|
static const struct regulator_mpm54304_config regulator_mpm54304_config_##id = { \
|
|
.common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \
|
|
.bus = I2C_DT_SPEC_GET(DT_PARENT(node_id)), \
|
|
.enable_mask = MPM54304_##child_name##_EN_MASK, \
|
|
}; \
|
|
\
|
|
static struct regulator_mpm54304_data regulator_mpm54304_data_##id; \
|
|
DEVICE_DT_DEFINE(node_id, regulator_mpm54304_init, NULL, ®ulator_mpm54304_data_##id, \
|
|
®ulator_mpm54304_config_##id, POST_KERNEL, \
|
|
CONFIG_REGULATOR_MPM54304_INIT_PRIORITY, &mpm54304_api);
|
|
|
|
#define REGULATOR_MPM54304_DEFINE_COND(inst, child, child_name) \
|
|
IF_ENABLED( \
|
|
DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \
|
|
(REGULATOR_MPM54304_DEFINE(DT_INST_CHILD(inst, child), child##inst, child_name)))
|
|
|
|
#define REGULATOR_MPM54304_DEFINE_ALL(inst) \
|
|
REGULATOR_MPM54304_DEFINE_COND(inst, buck1, BUCK1) \
|
|
REGULATOR_MPM54304_DEFINE_COND(inst, buck2, BUCK2) \
|
|
REGULATOR_MPM54304_DEFINE_COND(inst, buck3, BUCK3) \
|
|
REGULATOR_MPM54304_DEFINE_COND(inst, buck4, BUCK4)
|
|
|
|
DT_INST_FOREACH_STATUS_OKAY(REGULATOR_MPM54304_DEFINE_ALL)
|