// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2020 ROHM Semiconductors
// ROHM BD9576MUF/BD9573MUF regulator driver
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd957x.h>
#include <linux/mfd/rohm-generic.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#define BD957X_VOUTS1_VOLT 3300000
#define BD957X_VOUTS4_BASE_VOLT 1030000
#define BD957X_VOUTS34_NUM_VOLT 32
#define BD9576_THERM_IRQ_MASK_TW BIT(5)
#define BD9576_xVD_IRQ_MASK_VOUTL1 BIT(5)
#define BD9576_UVD_IRQ_MASK_VOUTS1_OCW BIT(6)
#define BD9576_xVD_IRQ_MASK_VOUT1TO4 0x0F
static const unsigned int vout1_volt_table[] = {
5000000, 4900000, 4800000, 4700000, 4600000,
4500000, 4500000, 4500000, 5000000, 5100000,
5200000, 5300000, 5400000, 5500000, 5500000,
5500000
};
static const unsigned int vout2_volt_table[] = {
1800000, 1780000, 1760000, 1740000, 1720000,
1700000, 1680000, 1660000, 1800000, 1820000,
1840000, 1860000, 1880000, 1900000, 1920000,
1940000
};
static const unsigned int voutl1_volt_table[] = {
2500000, 2540000, 2580000, 2620000, 2660000,
2700000, 2740000, 2780000, 2500000, 2460000,
2420000, 2380000, 2340000, 2300000, 2260000,
2220000
};
static const struct linear_range vout1_xvd_ranges[] = {
REGULATOR_LINEAR_RANGE(225000, 0x01, 0x2b, 0),
REGULATOR_LINEAR_RANGE(225000, 0x2c, 0x54, 5000),
REGULATOR_LINEAR_RANGE(425000, 0x55, 0x7f, 0),
};
static const struct linear_range vout234_xvd_ranges[] = {
REGULATOR_LINEAR_RANGE(17000, 0x01, 0x0f, 0),
REGULATOR_LINEAR_RANGE(17000, 0x10, 0x6d, 1000),
REGULATOR_LINEAR_RANGE(110000, 0x6e, 0x7f, 0),
};
static const struct linear_range voutL1_xvd_ranges[] = {
REGULATOR_LINEAR_RANGE(34000, 0x01, 0x0f, 0),
REGULATOR_LINEAR_RANGE(34000, 0x10, 0x6d, 2000),
REGULATOR_LINEAR_RANGE(220000, 0x6e, 0x7f, 0),
};
static struct linear_range voutS1_ocw_ranges_internal[] = {
REGULATOR_LINEAR_RANGE(200000, 0x01, 0x04, 0),
REGULATOR_LINEAR_RANGE(250000, 0x05, 0x18, 50000),
REGULATOR_LINEAR_RANGE(1200000, 0x19, 0x3f, 0),
};
static struct linear_range voutS1_ocw_ranges[] = {
REGULATOR_LINEAR_RANGE(50000, 0x01, 0x04, 0),
REGULATOR_LINEAR_RANGE(60000, 0x05, 0x18, 10000),
REGULATOR_LINEAR_RANGE(250000, 0x19, 0x3f, 0),
};
static struct linear_range voutS1_ocp_ranges_internal[] = {
REGULATOR_LINEAR_RANGE(300000, 0x01, 0x06, 0),
REGULATOR_LINEAR_RANGE(350000, 0x7, 0x1b, 50000),
REGULATOR_LINEAR_RANGE(1350000, 0x1c, 0x3f, 0),
};
static struct linear_range voutS1_ocp_ranges[] = {
REGULATOR_LINEAR_RANGE(70000, 0x01, 0x06, 0),
REGULATOR_LINEAR_RANGE(80000, 0x7, 0x1b, 10000),
REGULATOR_LINEAR_RANGE(280000, 0x1c, 0x3f, 0),
};
struct bd957x_regulator_data {
struct regulator_desc desc;
int base_voltage;
struct regulator_dev *rdev;
int ovd_notif;
int uvd_notif;
int temp_notif;
int ovd_err;
int uvd_err;
int temp_err;
const struct linear_range *xvd_ranges;
int num_xvd_ranges;
bool oc_supported;
unsigned int ovd_reg;
unsigned int uvd_reg;
unsigned int xvd_mask;
unsigned int ocp_reg;
unsigned int ocp_mask;
unsigned int ocw_reg;
unsigned int ocw_mask;
unsigned int ocw_rfet;
};
#define BD9576_NUM_REGULATORS 6
#define BD9576_NUM_OVD_REGULATORS 5
struct bd957x_data {
struct bd957x_regulator_data regulator_data[BD9576_NUM_REGULATORS];
struct regmap *regmap;
struct delayed_work therm_irq_suppress;
struct delayed_work ovd_irq_suppress;
struct delayed_work uvd_irq_suppress;
unsigned int therm_irq;
unsigned int ovd_irq;
unsigned int uvd_irq;
spinlock_t err_lock;