Commit 0742c2a6 authored by Patrick Rudolph's avatar Patrick Rudolph Committed by Lee Jones

mfd: max597x: Add support for MAX5970 and MAX5978

Implement a regulator driver with IRQ support for fault management.
Written against documentation [1] and [2] and tested on real hardware.

Every channel has it's own regulator supply nammed 'vss1-supply' and
'vss2-supply'. The regulator supply is used to determine the output
voltage, as the smart switch provides no output regulation.
The driver requires the 'shunt-resistor-micro-ohms' to be present in
the devicetree to properly calculate current related values.

You must specify compatible devictree layout:

regulator@3a {
        reg = <0x3a>;
        vss1-supply = <&p3v3>;
        compatible = "maxim,max5978";

        ...

        regulators {
                sw0_ref: SW0 {
                        regulator-compatible = "SW0";
                        shunt-resistor-micro-ohms = <12000>;
                        ...
                }
        }
}

1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf
2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf

...
Changes in V12:
- Use simple_mfd_i2c driver and remove previous implementation.
- Remove newline
- Use _MFD_MAX597X_H in header file
- Successfull build need following patch from regulator:
https://lore.kernel.org/r/20230216075302.68935-1-Naresh.Solanki@9elements.com
https://lore.kernel.org/r/20230210163225.1208035-1-Naresh.Solanki@9elements.comSigned-off-by: default avatarPatrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: default avatarMarcello Sylvester Bauer <sylv@sylv.io>
Signed-off-by: default avatarNaresh Solanki <Naresh.Solanki@9elements.com>
Signed-off-by: default avatarLee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230307121246.127425-2-Naresh.Solanki@9elements.com
parent ba2b13df
...@@ -266,6 +266,16 @@ config MFD_MADERA_SPI ...@@ -266,6 +266,16 @@ config MFD_MADERA_SPI
Support for the Cirrus Logic Madera platform audio SoC Support for the Cirrus Logic Madera platform audio SoC
core functionality controlled via SPI. core functionality controlled via SPI.
config MFD_MAX597X
tristate "Maxim 597x power switch and monitor"
depends on (I2C && OF)
select MFD_SIMPLE_MFD_I2C
help
This driver controls a Maxim 5970/5978 switch via I2C bus.
The MAX5970/5978 is a smart switch with no output regulation, but
fault protection and voltage and current monitoring capabilities.
Also it supports upto 4 indication leds.
config MFD_CS47L15 config MFD_CS47L15
bool "Cirrus Logic CS47L15" bool "Cirrus Logic CS47L15"
select PINCTRL_CS47L15 select PINCTRL_CS47L15
......
...@@ -72,9 +72,22 @@ static const struct simple_mfd_data silergy_sy7636a = { ...@@ -72,9 +72,22 @@ static const struct simple_mfd_data silergy_sy7636a = {
.mfd_cell_size = ARRAY_SIZE(sy7636a_cells), .mfd_cell_size = ARRAY_SIZE(sy7636a_cells),
}; };
static const struct mfd_cell max597x_cells[] = {
{ .name = "max597x-regulator", },
{ .name = "max597x-iio", },
{ .name = "max597x-led", },
};
static const struct simple_mfd_data maxim_max597x = {
.mfd_cell = max597x_cells,
.mfd_cell_size = ARRAY_SIZE(max597x_cells),
};
static const struct of_device_id simple_mfd_i2c_of_match[] = { static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "kontron,sl28cpld" }, { .compatible = "kontron,sl28cpld" },
{ .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
{ .compatible = "maxim,max5970", .data = &maxim_max597x},
{ .compatible = "maxim,max5978", .data = &maxim_max597x},
{} {}
}; };
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Device driver for regulators in MAX5970 and MAX5978 IC
*
* Copyright (c) 2022 9elements GmbH
*
* Author: Patrick Rudolph <patrick.rudolph@9elements.com>
*/
#ifndef _MFD_MAX597X_H
#define _MFD_MAX597X_H
#include <linux/regmap.h>
#define MAX5970_NUM_SWITCHES 2
#define MAX5978_NUM_SWITCHES 1
#define MAX597X_NUM_LEDS 4
struct max597x_data {
int num_switches;
u32 irng[MAX5970_NUM_SWITCHES];
u32 mon_rng[MAX5970_NUM_SWITCHES];
u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES];
};
enum max597x_chip_type {
MAX597x_TYPE_MAX5978 = 1,
MAX597x_TYPE_MAX5970,
};
#define MAX5970_REG_CURRENT_L(ch) (0x01 + (ch) * 4)
#define MAX5970_REG_CURRENT_H(ch) (0x00 + (ch) * 4)
#define MAX5970_REG_VOLTAGE_L(ch) (0x03 + (ch) * 4)
#define MAX5970_REG_VOLTAGE_H(ch) (0x02 + (ch) * 4)
#define MAX5970_REG_MON_RANGE 0x18
#define MAX5970_MON_MASK 0x3
#define MAX5970_MON(reg, ch) (((reg) >> ((ch) * 2)) & MAX5970_MON_MASK)
#define MAX5970_MON_MAX_RANGE_UV 16000000
#define MAX5970_REG_CH_UV_WARN_H(ch) (0x1A + (ch) * 10)
#define MAX5970_REG_CH_UV_WARN_L(ch) (0x1B + (ch) * 10)
#define MAX5970_REG_CH_UV_CRIT_H(ch) (0x1C + (ch) * 10)
#define MAX5970_REG_CH_UV_CRIT_L(ch) (0x1D + (ch) * 10)
#define MAX5970_REG_CH_OV_WARN_H(ch) (0x1E + (ch) * 10)
#define MAX5970_REG_CH_OV_WARN_L(ch) (0x1F + (ch) * 10)
#define MAX5970_REG_CH_OV_CRIT_H(ch) (0x20 + (ch) * 10)
#define MAX5970_REG_CH_OV_CRIT_L(ch) (0x21 + (ch) * 10)
#define MAX5970_VAL2REG_H(x) (((x) >> 2) & 0xFF)
#define MAX5970_VAL2REG_L(x) ((x) & 0x3)
#define MAX5970_REG_DAC_FAST(ch) (0x2E + (ch))
#define MAX5970_FAST2SLOW_RATIO 200
#define MAX5970_REG_STATUS0 0x31
#define MAX5970_CB_IFAULTF(ch) (1 << (ch))
#define MAX5970_CB_IFAULTS(ch) (1 << ((ch) + 4))
#define MAX5970_REG_STATUS1 0x32
#define STATUS1_PROT_MASK 0x3
#define STATUS1_PROT(reg) \
(((reg) >> 6) & STATUS1_PROT_MASK)
#define STATUS1_PROT_SHUTDOWN 0
#define STATUS1_PROT_CLEAR_PG 1
#define STATUS1_PROT_ALERT_ONLY 2
#define MAX5970_REG_STATUS2 0x33
#define MAX5970_IRNG_MASK 0x3
#define MAX5970_IRNG(reg, ch) \
(((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK)
#define MAX5970_REG_STATUS3 0x34
#define MAX5970_STATUS3_ALERT BIT(4)
#define MAX5970_STATUS3_PG(ch) BIT(ch)
#define MAX5970_REG_FAULT0 0x35
#define UV_STATUS_WARN(ch) (1 << (ch))
#define UV_STATUS_CRIT(ch) (1 << ((ch) + 4))
#define MAX5970_REG_FAULT1 0x36
#define OV_STATUS_WARN(ch) (1 << (ch))
#define OV_STATUS_CRIT(ch) (1 << ((ch) + 4))
#define MAX5970_REG_FAULT2 0x37
#define OC_STATUS_WARN(ch) (1 << (ch))
#define MAX5970_REG_CHXEN 0x3b
#define CHXEN(ch) (3 << ((ch) * 2))
#define MAX5970_REG_LED_FLASH 0x43
#define MAX_REGISTERS 0x49
#define ADC_MASK 0x3FF
#endif /* _MFD_MAX597X_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment