drivers: pwm: split up driver for MAX31790 into a MFD
Split up the driver for the PWM controller MAX31790 into a multi function device driver. Signed-off-by: Benedikt Schmidt <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
parent
68eb97ea05
commit
961c985ee4
|
@ -9,5 +9,6 @@ zephyr_library_sources_ifdef(CONFIG_MFD_NPM1300 mfd_npm1300.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_MFD_NPM6001 mfd_npm6001.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_AXP192 mfd_axp192.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_AD5592 mfd_ad5592.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_MAX31790 mfd_max31790.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NXP_LP_FLEXCOMM mfd_nxp_lp_flexcomm.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MFD_BD8LB600FS mfd_bd8lb600fs.c)
|
||||
|
|
|
@ -22,6 +22,7 @@ source "drivers/mfd/Kconfig.ad5592"
|
|||
source "drivers/mfd/Kconfig.axp192"
|
||||
source "drivers/mfd/Kconfig.bd8lb600fs"
|
||||
source "drivers/mfd/Kconfig.max20335"
|
||||
source "drivers/mfd/Kconfig.max31790"
|
||||
source "drivers/mfd/Kconfig.nct38xx"
|
||||
source "drivers/mfd/Kconfig.npm1300"
|
||||
source "drivers/mfd/Kconfig.npm6001"
|
||||
|
|
10
drivers/mfd/Kconfig.max31790
Normal file
10
drivers/mfd/Kconfig.max31790
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
# SPDX -License-Identifier: Apache-2.0
|
||||
|
||||
config MFD_MAX31790
|
||||
bool "Maxim Integrated MAX31790 I2C configurable PWM controller"
|
||||
default y
|
||||
depends on DT_HAS_MAXIM_MAX31790_ENABLED
|
||||
select I2C
|
||||
help
|
||||
Enable driver for Maxim Integrated MAX31790.
|
81
drivers/mfd/mfd_max31790.c
Normal file
81
drivers/mfd/mfd_max31790.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT maxim_max31790
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/mfd/max31790.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
|
||||
LOG_MODULE_REGISTER(max_max31790, CONFIG_MFD_LOG_LEVEL);
|
||||
|
||||
struct max31790_config {
|
||||
struct i2c_dt_spec i2c;
|
||||
};
|
||||
|
||||
static void max31790_set_globalconfiguration_i2cwatchdog(uint8_t *destination, uint8_t value)
|
||||
{
|
||||
uint8_t length = MAX37190_GLOBALCONFIGURATION_I2CWATCHDOG_LENGTH;
|
||||
uint8_t pos = MAX37190_GLOBALCONFIGURATION_I2CWATCHDOG_POS;
|
||||
|
||||
*destination &= ~GENMASK(pos + length - 1, pos);
|
||||
*destination |= FIELD_PREP(GENMASK(pos + length - 1, pos), value);
|
||||
}
|
||||
|
||||
static int max31790_init(const struct device *dev)
|
||||
{
|
||||
const struct max31790_config *config = dev->config;
|
||||
int result;
|
||||
uint8_t reg_value;
|
||||
|
||||
if (!i2c_is_ready_dt(&config->i2c)) {
|
||||
LOG_ERR("I2C device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
reg_value = 0;
|
||||
reg_value &= ~MAX37190_GLOBALCONFIGURATION_STANDBY_BIT;
|
||||
reg_value |= MAX37190_GLOBALCONFIGURATION_RESET_BIT;
|
||||
reg_value |= MAX37190_GLOBALCONFIGURATION_BUSTIMEOUT_BIT;
|
||||
reg_value &= ~MAX37190_GLOBALCONFIGURATION_OSCILLATORSELECTION_BIT;
|
||||
max31790_set_globalconfiguration_i2cwatchdog(®_value, 0);
|
||||
reg_value &= ~MAX37190_GLOBALCONFIGURATION_I2CWATCHDOGSTATUS_BIT;
|
||||
|
||||
result = i2c_reg_write_byte_dt(&config->i2c, MAX37190_REGISTER_GLOBALCONFIGURATION,
|
||||
reg_value);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
k_sleep(K_USEC(MAX31790_RESET_TIMEOUT_IN_US));
|
||||
|
||||
result = i2c_reg_read_byte_dt(&config->i2c, MAX37190_REGISTER_GLOBALCONFIGURATION,
|
||||
®_value);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((reg_value & MAX37190_GLOBALCONFIGURATION_STANDBY_BIT) != 0) {
|
||||
LOG_ERR("PWM controller is still in standby");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX31790_INIT(inst) \
|
||||
static const struct max31790_config max31790_##inst##_config = { \
|
||||
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, max31790_init, NULL, NULL, &max31790_##inst##_config, \
|
||||
POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(MAX31790_INIT);
|
|
@ -7,7 +7,7 @@
|
|||
config PWM_MAX31790
|
||||
bool "MAX31790 6-channel I2C-bus PWM controller"
|
||||
default y
|
||||
depends on DT_HAS_MAXIM_MAX31790_ENABLED
|
||||
select I2C
|
||||
depends on DT_HAS_MAXIM_MAX31790_PWM_ENABLED
|
||||
select MFD
|
||||
help
|
||||
Enable driver for MAX31790 6-channel I2C-bus PWM controller.
|
||||
|
|
|
@ -4,68 +4,28 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT maxim_max31790
|
||||
#define DT_DRV_COMPAT maxim_max31790_pwm
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/mfd/max31790.h>
|
||||
#include <zephyr/drivers/pwm.h>
|
||||
#include <zephyr/drivers/pwm/max31790.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(pwm_max31790, CONFIG_PWM_LOG_LEVEL);
|
||||
|
||||
#define MAX31790_OSCILLATOR_FREQUENCY_IN_HZ 32768
|
||||
#define MAX31790_PWMTARGETDUTYCYCLE_MAXIMUM ((1 << 9) - 1)
|
||||
#define MAX31790_CHANNEL_COUNT 6
|
||||
|
||||
struct max31790_config {
|
||||
struct max31790_pwm_config {
|
||||
struct i2c_dt_spec i2c;
|
||||
};
|
||||
|
||||
struct max31790_data {
|
||||
struct max31790_pwm_data {
|
||||
struct k_mutex lock;
|
||||
};
|
||||
|
||||
#define MAX37190_REGISTER_GLOBALCONFIGURATION 0x00
|
||||
#define MAX37190_REGISTER_PWMFREQUENCY 0x01
|
||||
#define MAX37190_REGISTER_FANCONFIGURATION(channel) (0x02 + channel)
|
||||
#define MAX31790_REGISTER_PWMOUTTARGETDUTYCYCLEMSB(channel) (0x40 + 2 * channel)
|
||||
#define MAX31790_REGISTER_FANDYNAMICS(channel) (0x08 + channel)
|
||||
#define MAX31790_REGISTER_TACHTARGETCOUNTMSB(channel) (0x50 + 2 * channel)
|
||||
|
||||
#define MAX37190_GLOBALCONFIGURATION_STANDBY_BIT BIT(7)
|
||||
#define MAX37190_FANXCONFIGURATION_MONITOR_BIT BIT(4)
|
||||
#define MAX37190_FANXCONFIGURATION_TACHINPUTENABLED_BIT BIT(3)
|
||||
#define MAX37190_FANXCONFIGURATION_LOCKEDROTOR_BIT BIT(2)
|
||||
#define MAX37190_FANXCONFIGURATION_LOCKEDROTORPOLARITY_BIT BIT(1)
|
||||
#define MAX37190_FANXCONFIGURATION_TACH_BIT BIT(0)
|
||||
#define MAX37190_FANXCONFIGURATION_MODE_BIT BIT(7)
|
||||
#define MAX37190_FANXDYNAMICS_ASYMMETRICRATEOFCHANGE_BIT BIT(1)
|
||||
|
||||
#define MAX37190_FANXDYNAMICS_SPEEDRANGE_LENGTH 3
|
||||
#define MAX37190_FANXDYNAMICS_SPEEDRANGE_POS 5
|
||||
#define MAX37190_FANXDYNAMICS_PWMRATEOFCHANGE_LENGTH 3
|
||||
#define MAX37190_FANXDYNAMICS_PWMRATEOFCHANGE_POS 2
|
||||
#define MAX37190_PWMFREQUENCY_PWM_LENGTH 4
|
||||
#define MAX37190_PWMFREQUENCY_PWM4TO6_POS 4
|
||||
#define MAX37190_PWMFREQUENCY_PWM1TO3_LENGTH 4
|
||||
#define MAX37190_PWMFREQUENCY_PWM1TO3_POS 0
|
||||
#define MAX37190_FANXCONFIGURATION_SPINUP_LENGTH 2
|
||||
#define MAX37190_FANXCONFIGURATION_SPINUP_POS 5
|
||||
|
||||
#define PWM_MAX31790_FLAG_SPEED_RANGE_GET(flags) \
|
||||
FIELD_GET(GENMASK(MAX37190_FANXDYNAMICS_SPEEDRANGE_LENGTH + \
|
||||
PWM_MAX31790_FLAG_SPEED_RANGE_POS - 1, \
|
||||
PWM_MAX31790_FLAG_SPEED_RANGE_POS), \
|
||||
flags)
|
||||
#define PWM_MAX31790_FLAG_PWM_RATE_OF_CHANGE_GET(flags) \
|
||||
FIELD_GET(GENMASK(MAX37190_FANXDYNAMICS_PWMRATEOFCHANGE_LENGTH + \
|
||||
PWM_MAX31790_FLAG_PWM_RATE_OF_CHANGE_POS - 1, \
|
||||
PWM_MAX31790_FLAG_PWM_RATE_OF_CHANGE_POS), \
|
||||
flags)
|
||||
|
||||
static void max31790_set_fandynamics_speedrange(uint8_t *destination, uint8_t value)
|
||||
{
|
||||
uint8_t length = MAX37190_FANXDYNAMICS_SPEEDRANGE_LENGTH;
|
||||
|
@ -110,54 +70,6 @@ static void max31790_set_fanconfiguration_spinup(uint8_t *destination, uint8_t v
|
|||
*destination |= FIELD_PREP(GENMASK(pos + length - 1, pos), value);
|
||||
}
|
||||
|
||||
static int max31790_read_register(const struct device *dev, uint8_t address, uint8_t *value)
|
||||
{
|
||||
const struct max31790_config *config = dev->config;
|
||||
int result;
|
||||
|
||||
result = i2c_reg_read_byte_dt(&config->i2c, address, value);
|
||||
if (result != 0) {
|
||||
LOG_ERR("unable to read register 0x%02X, error %i", address, result);
|
||||
}
|
||||
|
||||
LOG_DBG("read value 0x%02X from register 0x%02X", *value, address);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int max31790_write_register_uint8(const struct device *dev, uint8_t address, uint8_t value)
|
||||
{
|
||||
const struct max31790_config *config = dev->config;
|
||||
int result;
|
||||
|
||||
LOG_DBG("writing value 0x%02X to register 0x%02X", value, address);
|
||||
result = i2c_reg_write_byte_dt(&config->i2c, address, value);
|
||||
if (result != 0) {
|
||||
LOG_ERR("unable to write register 0x%02X, error %i", address, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int max31790_write_register_uint16(const struct device *dev, uint8_t address, uint16_t value)
|
||||
{
|
||||
const struct max31790_config *config = dev->config;
|
||||
int result;
|
||||
uint8_t buffer[] = {
|
||||
address,
|
||||
value >> 8,
|
||||
value,
|
||||
};
|
||||
|
||||
LOG_DBG("writing value 0x%04X to address 0x%02X", value, address);
|
||||
result = i2c_write_dt(&config->i2c, buffer, sizeof(buffer));
|
||||
if (result != 0) {
|
||||
LOG_ERR("unable to write to address 0x%02X, error %i", address, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool max31790_convert_pwm_frequency_into_hz(uint16_t *result, uint8_t pwm_frequency)
|
||||
{
|
||||
switch (pwm_frequency) {
|
||||
|
@ -252,28 +164,31 @@ static int max31790_set_cycles_internal(const struct device *dev, uint32_t chann
|
|||
uint32_t period_count, uint32_t pulse_count,
|
||||
pwm_flags_t flags)
|
||||
{
|
||||
const struct max31790_pwm_config *config = dev->config;
|
||||
int result;
|
||||
uint8_t pwm_frequency_channel_value;
|
||||
uint8_t value_pwm_frequency;
|
||||
uint8_t value_fan_configuration;
|
||||
uint8_t value_fan_dynamics;
|
||||
uint8_t value_speed_range = PWM_MAX31790_FLAG_SPEED_RANGE_GET(flags);
|
||||
uint8_t value_pwm_rate_of_change = PWM_MAX31790_FLAG_PWM_RATE_OF_CHANGE_GET(flags);
|
||||
uint8_t value_speed_range = MAX31790_FLAG_SPEED_RANGE_GET(flags);
|
||||
uint8_t value_pwm_rate_of_change = MAX31790_FLAG_PWM_RATE_OF_CHANGE_GET(flags);
|
||||
uint8_t buffer[3];
|
||||
|
||||
if (!max31790_convert_pwm_frequency_into_register(&pwm_frequency_channel_value,
|
||||
period_count)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
result = max31790_read_register(dev, MAX37190_REGISTER_PWMFREQUENCY, &value_pwm_frequency);
|
||||
result = i2c_reg_read_byte_dt(&config->i2c, MAX37190_REGISTER_PWMFREQUENCY,
|
||||
&value_pwm_frequency);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
max31790_set_pwmfrequency(&value_pwm_frequency, channel, pwm_frequency_channel_value);
|
||||
|
||||
result = max31790_write_register_uint8(dev, MAX37190_REGISTER_PWMFREQUENCY,
|
||||
value_pwm_frequency);
|
||||
result = i2c_reg_write_byte_dt(&config->i2c, MAX37190_REGISTER_PWMFREQUENCY,
|
||||
value_pwm_frequency);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
@ -299,46 +214,56 @@ static int max31790_set_cycles_internal(const struct device *dev, uint32_t chann
|
|||
|
||||
if ((flags & PWM_MAX31790_FLAG_RPM_MODE) == 0) {
|
||||
LOG_DBG("PWM mode");
|
||||
uint16_t pwm_target_duty_cycle =
|
||||
pulse_count * MAX31790_PWMTARGETDUTYCYCLE_MAXIMUM / period_count;
|
||||
uint16_t tach_target_count = MAX31790_TACHTARGETCOUNT_MAXIMUM;
|
||||
value_fan_configuration &= ~MAX37190_FANXCONFIGURATION_MODE_BIT;
|
||||
buffer[0] = MAX31790_REGISTER_TACHTARGETCOUNTMSB(channel);
|
||||
sys_put_be16(tach_target_count << 5, buffer + 1);
|
||||
|
||||
result = max31790_write_register_uint16(
|
||||
dev, MAX31790_REGISTER_PWMOUTTARGETDUTYCYCLEMSB(channel),
|
||||
pwm_target_duty_cycle);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
result = i2c_write_dt(&config->i2c, buffer, sizeof(buffer));
|
||||
} else {
|
||||
LOG_DBG("RPM mode");
|
||||
value_fan_configuration |= MAX37190_FANXCONFIGURATION_MODE_BIT;
|
||||
buffer[0] = MAX31790_REGISTER_TACHTARGETCOUNTMSB(channel);
|
||||
sys_put_be16(pulse_count << 5, buffer + 1);
|
||||
|
||||
result = max31790_write_register_uint16(
|
||||
dev, MAX31790_REGISTER_TACHTARGETCOUNTMSB(channel), pulse_count);
|
||||
result = i2c_write_dt(&config->i2c, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = i2c_reg_write_byte_dt(&config->i2c, MAX37190_REGISTER_FANCONFIGURATION(channel),
|
||||
value_fan_configuration);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = i2c_reg_write_byte_dt(&config->i2c, MAX31790_REGISTER_FANDYNAMICS(channel),
|
||||
value_fan_dynamics);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((flags & PWM_MAX31790_FLAG_RPM_MODE) == 0) {
|
||||
uint16_t pwm_target_duty_cycle =
|
||||
pulse_count * MAX31790_PWMTARGETDUTYCYCLE_MAXIMUM / period_count;
|
||||
buffer[0] = MAX31790_REGISTER_PWMOUTTARGETDUTYCYCLEMSB(channel);
|
||||
sys_put_be16(pwm_target_duty_cycle << 7, buffer + 1);
|
||||
|
||||
result = i2c_write_dt(&config->i2c, buffer, sizeof(buffer));
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = max31790_write_register_uint8(dev, MAX37190_REGISTER_FANCONFIGURATION(channel),
|
||||
value_fan_configuration);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = max31790_write_register_uint8(dev, MAX31790_REGISTER_FANDYNAMICS(channel),
|
||||
value_fan_dynamics);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max31790_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_count,
|
||||
uint32_t pulse_count, pwm_flags_t flags)
|
||||
{
|
||||
struct max31790_data *data = dev->data;
|
||||
struct max31790_pwm_data *data = dev->data;
|
||||
int result;
|
||||
|
||||
LOG_DBG("set period %i with pulse %i for channel %i and flags 0x%04X", period_count,
|
||||
|
@ -362,7 +287,8 @@ static int max31790_set_cycles(const struct device *dev, uint32_t channel, uint3
|
|||
|
||||
static int max31790_get_cycles_per_sec(const struct device *dev, uint32_t channel, uint64_t *cycles)
|
||||
{
|
||||
struct max31790_data *data = dev->data;
|
||||
const struct max31790_pwm_config *config = dev->config;
|
||||
struct max31790_pwm_data *data = dev->data;
|
||||
int result;
|
||||
bool success;
|
||||
uint8_t pwm_frequency_register;
|
||||
|
@ -375,9 +301,8 @@ static int max31790_get_cycles_per_sec(const struct device *dev, uint32_t channe
|
|||
}
|
||||
|
||||
k_mutex_lock(&data->lock, K_FOREVER);
|
||||
result = max31790_read_register(dev, MAX37190_REGISTER_GLOBALCONFIGURATION,
|
||||
&pwm_frequency_register);
|
||||
|
||||
result = i2c_reg_read_byte_dt(&config->i2c, MAX37190_REGISTER_GLOBALCONFIGURATION,
|
||||
&pwm_frequency_register);
|
||||
if (result != 0) {
|
||||
k_mutex_unlock(&data->lock);
|
||||
return result;
|
||||
|
@ -385,7 +310,6 @@ static int max31790_get_cycles_per_sec(const struct device *dev, uint32_t channe
|
|||
|
||||
pwm_frequency = max31790_get_pwmfrequency(pwm_frequency_register, channel);
|
||||
success = max31790_convert_pwm_frequency_into_hz(&pwm_frequency_in_hz, pwm_frequency);
|
||||
|
||||
if (!success) {
|
||||
k_mutex_unlock(&data->lock);
|
||||
return -EINVAL;
|
||||
|
@ -397,17 +321,15 @@ static int max31790_get_cycles_per_sec(const struct device *dev, uint32_t channe
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct pwm_driver_api max31790_api = {
|
||||
static const struct pwm_driver_api max31790_pwm_api = {
|
||||
.set_cycles = max31790_set_cycles,
|
||||
.get_cycles_per_sec = max31790_get_cycles_per_sec,
|
||||
};
|
||||
|
||||
static int max31790_init(const struct device *dev)
|
||||
static int max31790_pwm_init(const struct device *dev)
|
||||
{
|
||||
const struct max31790_config *config = dev->config;
|
||||
struct max31790_data *data = dev->data;
|
||||
int result;
|
||||
uint8_t reg_value;
|
||||
const struct max31790_pwm_config *config = dev->config;
|
||||
struct max31790_pwm_data *data = dev->data;
|
||||
|
||||
k_mutex_init(&data->lock);
|
||||
|
||||
|
@ -416,45 +338,18 @@ static int max31790_init(const struct device *dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
result = max31790_read_register(dev, MAX37190_REGISTER_GLOBALCONFIGURATION, ®_value);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((reg_value & MAX37190_GLOBALCONFIGURATION_STANDBY_BIT) != 0) {
|
||||
LOG_DBG("taking PWM controller out of standby");
|
||||
|
||||
reg_value &= ~MAX37190_GLOBALCONFIGURATION_STANDBY_BIT;
|
||||
result = max31790_write_register_uint8(dev, MAX37190_REGISTER_GLOBALCONFIGURATION,
|
||||
reg_value);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = max31790_read_register(dev, MAX37190_REGISTER_GLOBALCONFIGURATION,
|
||||
®_value);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((reg_value & MAX37190_GLOBALCONFIGURATION_STANDBY_BIT) != 0) {
|
||||
LOG_ERR("unable to take PWM controller out of standby");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX31790_INIT(inst) \
|
||||
static const struct max31790_config max31790_##inst##_config = { \
|
||||
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
||||
#define MAX31790_PWM_INIT(inst) \
|
||||
static const struct max31790_pwm_config max31790_pwm_##inst##_config = { \
|
||||
.i2c = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)), \
|
||||
}; \
|
||||
\
|
||||
static struct max31790_data max31790_##inst##_data; \
|
||||
static struct max31790_pwm_data max31790_pwm_##inst##_data; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, max31790_init, NULL, &max31790_##inst##_data, \
|
||||
&max31790_##inst##_config, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY, \
|
||||
&max31790_api);
|
||||
DEVICE_DT_INST_DEFINE(inst, max31790_pwm_init, NULL, &max31790_pwm_##inst##_data, \
|
||||
&max31790_pwm_##inst##_config, POST_KERNEL, \
|
||||
CONFIG_PWM_INIT_PRIORITY, &max31790_pwm_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(MAX31790_INIT);
|
||||
DT_INST_FOREACH_STATUS_OKAY(MAX31790_PWM_INIT);
|
||||
|
|
14
dts/bindings/mfd/maxim,max31790.yaml
Normal file
14
dts/bindings/mfd/maxim,max31790.yaml
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Maxim MAX31790 6-channel I2C-bus PWM controller, MFD device
|
||||
|
||||
compatible: "maxim,max31790"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
bus: max31790
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
|
@ -3,14 +3,13 @@
|
|||
|
||||
description: Maxim MAX31790 6-channel I2C-bus PWM controller
|
||||
|
||||
compatible: "maxim,max31790"
|
||||
compatible: "maxim,max31790-pwm"
|
||||
|
||||
include: [pwm-controller.yaml, i2c-device.yaml, base.yaml]
|
||||
include: [pwm-controller.yaml, base.yaml]
|
||||
|
||||
on-bus: max31790
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
"#pwm-cells":
|
||||
const: 2
|
||||
|
70
include/zephyr/drivers/mfd/max31790.h
Normal file
70
include/zephyr/drivers/mfd/max31790.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2024 SILA Embedded Solutions GmbH
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_MFD_MAX31790_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_MFD_MAX31790_H_
|
||||
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
|
||||
#define MAX31790_OSCILLATOR_FREQUENCY_IN_HZ 32768
|
||||
#define MAX31790_PWMTARGETDUTYCYCLE_MAXIMUM ((1 << 9) - 1)
|
||||
#define MAX31790_TACHTARGETCOUNT_MAXIMUM ((1 << 11) - 1)
|
||||
#define MAX31790_CHANNEL_COUNT 6
|
||||
#define MAX31790_RESET_TIMEOUT_IN_US 1000
|
||||
|
||||
#define MAX37190_REGISTER_GLOBALCONFIGURATION 0x00
|
||||
#define MAX37190_REGISTER_PWMFREQUENCY 0x01
|
||||
#define MAX37190_REGISTER_FANCONFIGURATION(channel) (0x02 + channel)
|
||||
#define MAX31790_REGISTER_FANDYNAMICS(channel) (0x08 + channel)
|
||||
#define MAX37190_REGISTER_FANFAULTSTATUS1 0x11
|
||||
#define MAX37190_REGISTER_TACHCOUNTMSB(channel) (0x18 + 2 * channel)
|
||||
#define MAX31790_REGISTER_PWMOUTTARGETDUTYCYCLEMSB(channel) (0x40 + 2 * channel)
|
||||
#define MAX31790_REGISTER_TACHTARGETCOUNTMSB(channel) (0x50 + 2 * channel)
|
||||
|
||||
#define MAX37190_GLOBALCONFIGURATION_STANDBY_BIT BIT(7)
|
||||
#define MAX37190_GLOBALCONFIGURATION_RESET_BIT BIT(6)
|
||||
#define MAX37190_GLOBALCONFIGURATION_BUSTIMEOUT_BIT BIT(5)
|
||||
#define MAX37190_GLOBALCONFIGURATION_OSCILLATORSELECTION_BIT BIT(3)
|
||||
#define MAX37190_GLOBALCONFIGURATION_I2CWATCHDOGSTATUS_BIT BIT(0)
|
||||
#define MAX37190_FANXCONFIGURATION_MONITOR_BIT BIT(4)
|
||||
#define MAX37190_FANXCONFIGURATION_TACHINPUTENABLED_BIT BIT(3)
|
||||
#define MAX37190_FANXCONFIGURATION_LOCKEDROTOR_BIT BIT(2)
|
||||
#define MAX37190_FANXCONFIGURATION_LOCKEDROTORPOLARITY_BIT BIT(1)
|
||||
#define MAX37190_FANXCONFIGURATION_TACH_BIT BIT(0)
|
||||
#define MAX37190_FANXCONFIGURATION_MODE_BIT BIT(7)
|
||||
#define MAX37190_FANXDYNAMICS_ASYMMETRICRATEOFCHANGE_BIT BIT(1)
|
||||
|
||||
#define MAX37190_GLOBALCONFIGURATION_I2CWATCHDOG_LENGTH 2
|
||||
#define MAX37190_GLOBALCONFIGURATION_I2CWATCHDOG_POS 1
|
||||
#define MAX37190_FANXDYNAMICS_SPEEDRANGE_LENGTH 3
|
||||
#define MAX37190_FANXDYNAMICS_SPEEDRANGE_POS 5
|
||||
#define MAX37190_FANXDYNAMICS_PWMRATEOFCHANGE_LENGTH 3
|
||||
#define MAX37190_FANXDYNAMICS_PWMRATEOFCHANGE_POS 2
|
||||
#define MAX37190_PWMFREQUENCY_PWM_LENGTH 4
|
||||
#define MAX37190_PWMFREQUENCY_PWM4TO6_POS 4
|
||||
#define MAX37190_PWMFREQUENCY_PWM1TO3_LENGTH 4
|
||||
#define MAX37190_PWMFREQUENCY_PWM1TO3_POS 0
|
||||
#define MAX37190_FANXCONFIGURATION_SPINUP_LENGTH 2
|
||||
#define MAX37190_FANXCONFIGURATION_SPINUP_POS 5
|
||||
|
||||
#define MAX31790_FANXDYNAMCIS_SPEED_RANGE_GET(value) \
|
||||
FIELD_GET(GENMASK(MAX37190_FANXDYNAMICS_SPEEDRANGE_LENGTH + \
|
||||
MAX37190_FANXDYNAMICS_SPEEDRANGE_POS - 1, \
|
||||
MAX37190_FANXDYNAMICS_SPEEDRANGE_POS), \
|
||||
value)
|
||||
|
||||
#define MAX31790_FLAG_SPEED_RANGE_GET(flags) \
|
||||
FIELD_GET(GENMASK(MAX37190_FANXDYNAMICS_SPEEDRANGE_LENGTH + \
|
||||
PWM_MAX31790_FLAG_SPEED_RANGE_POS - 1, \
|
||||
PWM_MAX31790_FLAG_SPEED_RANGE_POS), \
|
||||
flags)
|
||||
#define MAX31790_FLAG_PWM_RATE_OF_CHANGE_GET(flags) \
|
||||
FIELD_GET(GENMASK(MAX37190_FANXDYNAMICS_PWMRATEOFCHANGE_LENGTH + \
|
||||
PWM_MAX31790_FLAG_PWM_RATE_OF_CHANGE_POS - 1, \
|
||||
PWM_MAX31790_FLAG_PWM_RATE_OF_CHANGE_POS), \
|
||||
flags)
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_MFD_MAX31790_H_ */
|
|
@ -11,7 +11,12 @@
|
|||
compatible = "maxim,max31790";
|
||||
status = "okay";
|
||||
reg = <0x20>;
|
||||
pwm-controller;
|
||||
#pwm-cells = <2>;
|
||||
|
||||
max31790_max31790_pwm: max31790_max31790_pwm {
|
||||
compatible = "maxim,max31790-pwm";
|
||||
status = "okay";
|
||||
pwm-controller;
|
||||
#pwm-cells = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
CONFIG_PWM=y
|
||||
CONFIG_MFD_INIT_PRIORITY=80
|
||||
CONFIG_PWM_INIT_PRIORITY=81
|
||||
|
|
Loading…
Reference in a new issue