cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

twl6030-regulator.c (20068B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Split TWL6030 logic from twl-regulator.c:
      4 * Copyright (C) 2008 David Brownell
      5 *
      6 * Copyright (C) 2016 Nicolae Rosia <nicolae.rosia@gmail.com>
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/string.h>
     11#include <linux/slab.h>
     12#include <linux/init.h>
     13#include <linux/err.h>
     14#include <linux/platform_device.h>
     15#include <linux/of.h>
     16#include <linux/of_device.h>
     17#include <linux/regulator/driver.h>
     18#include <linux/regulator/machine.h>
     19#include <linux/regulator/of_regulator.h>
     20#include <linux/mfd/twl.h>
     21#include <linux/delay.h>
     22
     23struct twlreg_info {
     24	/* start of regulator's PM_RECEIVER control register bank */
     25	u8			base;
     26
     27	/* twl resource ID, for resource control state machine */
     28	u8			id;
     29
     30	u8			flags;
     31
     32	/* used by regulator core */
     33	struct regulator_desc	desc;
     34
     35	/* chip specific features */
     36	unsigned long		features;
     37
     38	/* data passed from board for external get/set voltage */
     39	void			*data;
     40};
     41
     42
     43/* LDO control registers ... offset is from the base of its register bank.
     44 * The first three registers of all power resource banks help hardware to
     45 * manage the various resource groups.
     46 */
     47/* Common offset in TWL4030/6030 */
     48#define VREG_GRP		0
     49/* TWL6030 register offsets */
     50#define VREG_TRANS		1
     51#define VREG_STATE		2
     52#define VREG_VOLTAGE		3
     53#define VREG_VOLTAGE_SMPS	4
     54/* TWL6030 Misc register offsets */
     55#define VREG_BC_ALL		1
     56#define VREG_BC_REF		2
     57#define VREG_BC_PROC		3
     58#define VREG_BC_CLK_RST		4
     59
     60/* TWL6030 LDO register values for VREG_VOLTAGE */
     61#define TWL6030_VREG_VOLTAGE_WR_S   BIT(7)
     62
     63/* TWL6030 LDO register values for CFG_STATE */
     64#define TWL6030_CFG_STATE_OFF	0x00
     65#define TWL6030_CFG_STATE_ON	0x01
     66#define TWL6030_CFG_STATE_OFF2	0x02
     67#define TWL6030_CFG_STATE_SLEEP	0x03
     68#define TWL6030_CFG_STATE_GRP_SHIFT	5
     69#define TWL6030_CFG_STATE_APP_SHIFT	2
     70#define TWL6030_CFG_STATE_APP_MASK	(0x03 << TWL6030_CFG_STATE_APP_SHIFT)
     71#define TWL6030_CFG_STATE_APP(v)	(((v) & TWL6030_CFG_STATE_APP_MASK) >>\
     72						TWL6030_CFG_STATE_APP_SHIFT)
     73
     74/* Flags for SMPS Voltage reading and LDO reading*/
     75#define SMPS_OFFSET_EN		BIT(0)
     76#define SMPS_EXTENDED_EN	BIT(1)
     77#define TWL_6030_WARM_RESET	BIT(3)
     78
     79/* twl6032 SMPS EPROM values */
     80#define TWL6030_SMPS_OFFSET		0xB0
     81#define TWL6030_SMPS_MULT		0xB3
     82#define SMPS_MULTOFFSET_SMPS4	BIT(0)
     83#define SMPS_MULTOFFSET_VIO	BIT(1)
     84#define SMPS_MULTOFFSET_SMPS3	BIT(6)
     85
     86static inline int
     87twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
     88{
     89	u8 value;
     90	int status;
     91
     92	status = twl_i2c_read_u8(slave_subgp,
     93			&value, info->base + offset);
     94	return (status < 0) ? status : value;
     95}
     96
     97static inline int
     98twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset,
     99						 u8 value)
    100{
    101	return twl_i2c_write_u8(slave_subgp,
    102			value, info->base + offset);
    103}
    104
    105/* generic power resource operations, which work on all regulators */
    106static int twlreg_grp(struct regulator_dev *rdev)
    107{
    108	return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_RECEIVER,
    109								 VREG_GRP);
    110}
    111
    112/*
    113 * Enable/disable regulators by joining/leaving the P1 (processor) group.
    114 * We assume nobody else is updating the DEV_GRP registers.
    115 */
    116/* definition for 6030 family */
    117#define P3_GRP_6030	BIT(2)		/* secondary processor, modem, etc */
    118#define P2_GRP_6030	BIT(1)		/* "peripherals" */
    119#define P1_GRP_6030	BIT(0)		/* CPU/Linux */
    120
    121static int twl6030reg_is_enabled(struct regulator_dev *rdev)
    122{
    123	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    124	int			grp = 0, val;
    125
    126	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS))) {
    127		grp = twlreg_grp(rdev);
    128		if (grp < 0)
    129			return grp;
    130		grp &= P1_GRP_6030;
    131	} else {
    132		grp = 1;
    133	}
    134
    135	val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
    136	val = TWL6030_CFG_STATE_APP(val);
    137
    138	return grp && (val == TWL6030_CFG_STATE_ON);
    139}
    140
    141#define PB_I2C_BUSY	BIT(0)
    142#define PB_I2C_BWEN	BIT(1)
    143
    144
    145static int twl6030reg_enable(struct regulator_dev *rdev)
    146{
    147	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    148	int			grp = 0;
    149	int			ret;
    150
    151	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
    152		grp = twlreg_grp(rdev);
    153	if (grp < 0)
    154		return grp;
    155
    156	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
    157			grp << TWL6030_CFG_STATE_GRP_SHIFT |
    158			TWL6030_CFG_STATE_ON);
    159	return ret;
    160}
    161
    162static int twl6030reg_disable(struct regulator_dev *rdev)
    163{
    164	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    165	int			grp = 0;
    166	int			ret;
    167
    168	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
    169		grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;
    170
    171	/* For 6030, set the off state for all grps enabled */
    172	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
    173			(grp) << TWL6030_CFG_STATE_GRP_SHIFT |
    174			TWL6030_CFG_STATE_OFF);
    175
    176	return ret;
    177}
    178
    179static int twl6030reg_get_status(struct regulator_dev *rdev)
    180{
    181	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    182	int			val;
    183
    184	val = twlreg_grp(rdev);
    185	if (val < 0)
    186		return val;
    187
    188	val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
    189
    190	switch (TWL6030_CFG_STATE_APP(val)) {
    191	case TWL6030_CFG_STATE_ON:
    192		return REGULATOR_STATUS_NORMAL;
    193
    194	case TWL6030_CFG_STATE_SLEEP:
    195		return REGULATOR_STATUS_STANDBY;
    196
    197	case TWL6030_CFG_STATE_OFF:
    198	case TWL6030_CFG_STATE_OFF2:
    199	default:
    200		break;
    201	}
    202
    203	return REGULATOR_STATUS_OFF;
    204}
    205
    206static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
    207{
    208	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    209	int grp = 0;
    210	int val;
    211
    212	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
    213		grp = twlreg_grp(rdev);
    214
    215	if (grp < 0)
    216		return grp;
    217
    218	/* Compose the state register settings */
    219	val = grp << TWL6030_CFG_STATE_GRP_SHIFT;
    220	/* We can only set the mode through state machine commands... */
    221	switch (mode) {
    222	case REGULATOR_MODE_NORMAL:
    223		val |= TWL6030_CFG_STATE_ON;
    224		break;
    225	case REGULATOR_MODE_STANDBY:
    226		val |= TWL6030_CFG_STATE_SLEEP;
    227		break;
    228
    229	default:
    230		return -EINVAL;
    231	}
    232
    233	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val);
    234}
    235
    236static int twl6030coresmps_set_voltage(struct regulator_dev *rdev, int min_uV,
    237	int max_uV, unsigned *selector)
    238{
    239	return -ENODEV;
    240}
    241
    242static int twl6030coresmps_get_voltage(struct regulator_dev *rdev)
    243{
    244	return -ENODEV;
    245}
    246
    247static const struct regulator_ops twl6030coresmps_ops = {
    248	.set_voltage	= twl6030coresmps_set_voltage,
    249	.get_voltage	= twl6030coresmps_get_voltage,
    250};
    251
    252static int
    253twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
    254{
    255	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    256
    257	if (info->flags & TWL_6030_WARM_RESET)
    258		selector |= TWL6030_VREG_VOLTAGE_WR_S;
    259
    260	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
    261			    selector);
    262}
    263
    264static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev)
    265{
    266	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    267	int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
    268
    269	if (info->flags & TWL_6030_WARM_RESET)
    270		vsel &= ~TWL6030_VREG_VOLTAGE_WR_S;
    271
    272	return vsel;
    273}
    274
    275static const struct regulator_ops twl6030ldo_ops = {
    276	.list_voltage	= regulator_list_voltage_linear_range,
    277
    278	.set_voltage_sel = twl6030ldo_set_voltage_sel,
    279	.get_voltage_sel = twl6030ldo_get_voltage_sel,
    280
    281	.enable		= twl6030reg_enable,
    282	.disable	= twl6030reg_disable,
    283	.is_enabled	= twl6030reg_is_enabled,
    284
    285	.set_mode	= twl6030reg_set_mode,
    286
    287	.get_status	= twl6030reg_get_status,
    288};
    289
    290static const struct regulator_ops twl6030fixed_ops = {
    291	.list_voltage	= regulator_list_voltage_linear,
    292
    293	.enable		= twl6030reg_enable,
    294	.disable	= twl6030reg_disable,
    295	.is_enabled	= twl6030reg_is_enabled,
    296
    297	.set_mode	= twl6030reg_set_mode,
    298
    299	.get_status	= twl6030reg_get_status,
    300};
    301
    302/*
    303 * SMPS status and control
    304 */
    305
    306static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)
    307{
    308	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    309
    310	int voltage = 0;
    311
    312	switch (info->flags) {
    313	case SMPS_OFFSET_EN:
    314		voltage = 100000;
    315		fallthrough;
    316	case 0:
    317		switch (index) {
    318		case 0:
    319			voltage = 0;
    320			break;
    321		case 58:
    322			voltage = 1350 * 1000;
    323			break;
    324		case 59:
    325			voltage = 1500 * 1000;
    326			break;
    327		case 60:
    328			voltage = 1800 * 1000;
    329			break;
    330		case 61:
    331			voltage = 1900 * 1000;
    332			break;
    333		case 62:
    334			voltage = 2100 * 1000;
    335			break;
    336		default:
    337			voltage += (600000 + (12500 * (index - 1)));
    338		}
    339		break;
    340	case SMPS_EXTENDED_EN:
    341		switch (index) {
    342		case 0:
    343			voltage = 0;
    344			break;
    345		case 58:
    346			voltage = 2084 * 1000;
    347			break;
    348		case 59:
    349			voltage = 2315 * 1000;
    350			break;
    351		case 60:
    352			voltage = 2778 * 1000;
    353			break;
    354		case 61:
    355			voltage = 2932 * 1000;
    356			break;
    357		case 62:
    358			voltage = 3241 * 1000;
    359			break;
    360		default:
    361			voltage = (1852000 + (38600 * (index - 1)));
    362		}
    363		break;
    364	case SMPS_OFFSET_EN | SMPS_EXTENDED_EN:
    365		switch (index) {
    366		case 0:
    367			voltage = 0;
    368			break;
    369		case 58:
    370			voltage = 4167 * 1000;
    371			break;
    372		case 59:
    373			voltage = 2315 * 1000;
    374			break;
    375		case 60:
    376			voltage = 2778 * 1000;
    377			break;
    378		case 61:
    379			voltage = 2932 * 1000;
    380			break;
    381		case 62:
    382			voltage = 3241 * 1000;
    383			break;
    384		default:
    385			voltage = (2161000 + (38600 * (index - 1)));
    386		}
    387		break;
    388	}
    389
    390	return voltage;
    391}
    392
    393static int twl6030smps_map_voltage(struct regulator_dev *rdev, int min_uV,
    394				   int max_uV)
    395{
    396	struct twlreg_info *info = rdev_get_drvdata(rdev);
    397	int vsel = 0;
    398
    399	switch (info->flags) {
    400	case 0:
    401		if (min_uV == 0)
    402			vsel = 0;
    403		else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
    404			vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
    405			vsel++;
    406		}
    407		/* Values 1..57 for vsel are linear and can be calculated
    408		 * values 58..62 are non linear.
    409		 */
    410		else if ((min_uV > 1900000) && (min_uV <= 2100000))
    411			vsel = 62;
    412		else if ((min_uV > 1800000) && (min_uV <= 1900000))
    413			vsel = 61;
    414		else if ((min_uV > 1500000) && (min_uV <= 1800000))
    415			vsel = 60;
    416		else if ((min_uV > 1350000) && (min_uV <= 1500000))
    417			vsel = 59;
    418		else if ((min_uV > 1300000) && (min_uV <= 1350000))
    419			vsel = 58;
    420		else
    421			return -EINVAL;
    422		break;
    423	case SMPS_OFFSET_EN:
    424		if (min_uV == 0)
    425			vsel = 0;
    426		else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
    427			vsel = DIV_ROUND_UP(min_uV - 700000, 12500);
    428			vsel++;
    429		}
    430		/* Values 1..57 for vsel are linear and can be calculated
    431		 * values 58..62 are non linear.
    432		 */
    433		else if ((min_uV > 1900000) && (min_uV <= 2100000))
    434			vsel = 62;
    435		else if ((min_uV > 1800000) && (min_uV <= 1900000))
    436			vsel = 61;
    437		else if ((min_uV > 1500000) && (min_uV <= 1800000))
    438			vsel = 60;
    439		else if ((min_uV > 1350000) && (min_uV <= 1500000))
    440			vsel = 59;
    441		else
    442			return -EINVAL;
    443		break;
    444	case SMPS_EXTENDED_EN:
    445		if (min_uV == 0) {
    446			vsel = 0;
    447		} else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
    448			vsel = DIV_ROUND_UP(min_uV - 1852000, 38600);
    449			vsel++;
    450		}
    451		break;
    452	case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
    453		if (min_uV == 0) {
    454			vsel = 0;
    455		} else if ((min_uV >= 2161000) && (min_uV <= 4321000)) {
    456			vsel = DIV_ROUND_UP(min_uV - 2161000, 38600);
    457			vsel++;
    458		}
    459		break;
    460	}
    461
    462	return vsel;
    463}
    464
    465static int twl6030smps_set_voltage_sel(struct regulator_dev *rdev,
    466				       unsigned int selector)
    467{
    468	struct twlreg_info *info = rdev_get_drvdata(rdev);
    469
    470	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
    471			    selector);
    472}
    473
    474static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
    475{
    476	struct twlreg_info	*info = rdev_get_drvdata(rdev);
    477
    478	return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS);
    479}
    480
    481static const struct regulator_ops twlsmps_ops = {
    482	.list_voltage		= twl6030smps_list_voltage,
    483	.map_voltage		= twl6030smps_map_voltage,
    484
    485	.set_voltage_sel	= twl6030smps_set_voltage_sel,
    486	.get_voltage_sel	= twl6030smps_get_voltage_sel,
    487
    488	.enable			= twl6030reg_enable,
    489	.disable		= twl6030reg_disable,
    490	.is_enabled		= twl6030reg_is_enabled,
    491
    492	.set_mode		= twl6030reg_set_mode,
    493
    494	.get_status		= twl6030reg_get_status,
    495};
    496
    497/*----------------------------------------------------------------------*/
    498static const struct linear_range twl6030ldo_linear_range[] = {
    499	REGULATOR_LINEAR_RANGE(0, 0, 0, 0),
    500	REGULATOR_LINEAR_RANGE(1000000, 1, 24, 100000),
    501	REGULATOR_LINEAR_RANGE(2750000, 31, 31, 0),
    502};
    503
    504#define TWL6030_ADJUSTABLE_SMPS(label) \
    505static const struct twlreg_info TWL6030_INFO_##label = { \
    506	.desc = { \
    507		.name = #label, \
    508		.id = TWL6030_REG_##label, \
    509		.ops = &twl6030coresmps_ops, \
    510		.type = REGULATOR_VOLTAGE, \
    511		.owner = THIS_MODULE, \
    512		}, \
    513	}
    514
    515#define TWL6030_ADJUSTABLE_LDO(label, offset) \
    516static const struct twlreg_info TWL6030_INFO_##label = { \
    517	.base = offset, \
    518	.desc = { \
    519		.name = #label, \
    520		.id = TWL6030_REG_##label, \
    521		.n_voltages = 32, \
    522		.linear_ranges = twl6030ldo_linear_range, \
    523		.n_linear_ranges = ARRAY_SIZE(twl6030ldo_linear_range), \
    524		.ops = &twl6030ldo_ops, \
    525		.type = REGULATOR_VOLTAGE, \
    526		.owner = THIS_MODULE, \
    527		}, \
    528	}
    529
    530#define TWL6032_ADJUSTABLE_LDO(label, offset) \
    531static const struct twlreg_info TWL6032_INFO_##label = { \
    532	.base = offset, \
    533	.desc = { \
    534		.name = #label, \
    535		.id = TWL6032_REG_##label, \
    536		.n_voltages = 32, \
    537		.linear_ranges = twl6030ldo_linear_range, \
    538		.n_linear_ranges = ARRAY_SIZE(twl6030ldo_linear_range), \
    539		.ops = &twl6030ldo_ops, \
    540		.type = REGULATOR_VOLTAGE, \
    541		.owner = THIS_MODULE, \
    542		}, \
    543	}
    544
    545#define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \
    546static const struct twlreg_info TWLFIXED_INFO_##label = { \
    547	.base = offset, \
    548	.id = 0, \
    549	.desc = { \
    550		.name = #label, \
    551		.id = TWL6030##_REG_##label, \
    552		.n_voltages = 1, \
    553		.ops = &twl6030fixed_ops, \
    554		.type = REGULATOR_VOLTAGE, \
    555		.owner = THIS_MODULE, \
    556		.min_uV = mVolts * 1000, \
    557		.enable_time = turnon_delay, \
    558		.of_map_mode = NULL, \
    559		}, \
    560	}
    561
    562#define TWL6032_ADJUSTABLE_SMPS(label, offset) \
    563static const struct twlreg_info TWLSMPS_INFO_##label = { \
    564	.base = offset, \
    565	.desc = { \
    566		.name = #label, \
    567		.id = TWL6032_REG_##label, \
    568		.n_voltages = 63, \
    569		.ops = &twlsmps_ops, \
    570		.type = REGULATOR_VOLTAGE, \
    571		.owner = THIS_MODULE, \
    572		}, \
    573	}
    574
    575/* VUSBCP is managed *only* by the USB subchip */
    576/* 6030 REG with base as PMC Slave Misc : 0x0030 */
    577/* Turnon-delay and remap configuration values for 6030 are not
    578   verified since the specification is not public */
    579TWL6030_ADJUSTABLE_SMPS(VDD1);
    580TWL6030_ADJUSTABLE_SMPS(VDD2);
    581TWL6030_ADJUSTABLE_SMPS(VDD3);
    582TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54);
    583TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58);
    584TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c);
    585TWL6030_ADJUSTABLE_LDO(VMMC, 0x68);
    586TWL6030_ADJUSTABLE_LDO(VPP, 0x6c);
    587TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74);
    588/* 6025 are renamed compared to 6030 versions */
    589TWL6032_ADJUSTABLE_LDO(LDO2, 0x54);
    590TWL6032_ADJUSTABLE_LDO(LDO4, 0x58);
    591TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c);
    592TWL6032_ADJUSTABLE_LDO(LDO5, 0x68);
    593TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c);
    594TWL6032_ADJUSTABLE_LDO(LDO7, 0x74);
    595TWL6032_ADJUSTABLE_LDO(LDO6, 0x60);
    596TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64);
    597TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70);
    598TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0);
    599TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0);
    600TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0);
    601TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0);
    602TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0);
    603TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0);
    604TWL6032_ADJUSTABLE_SMPS(SMPS3, 0x34);
    605TWL6032_ADJUSTABLE_SMPS(SMPS4, 0x10);
    606TWL6032_ADJUSTABLE_SMPS(VIO, 0x16);
    607
    608static u8 twl_get_smps_offset(void)
    609{
    610	u8 value;
    611
    612	twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
    613			TWL6030_SMPS_OFFSET);
    614	return value;
    615}
    616
    617static u8 twl_get_smps_mult(void)
    618{
    619	u8 value;
    620
    621	twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
    622			TWL6030_SMPS_MULT);
    623	return value;
    624}
    625
    626#define TWL_OF_MATCH(comp, family, label) \
    627	{ \
    628		.compatible = comp, \
    629		.data = &family##_INFO_##label, \
    630	}
    631
    632#define TWL6030_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6030, label)
    633#define TWL6032_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWL6032, label)
    634#define TWLFIXED_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLFIXED, label)
    635#define TWLSMPS_OF_MATCH(comp, label) TWL_OF_MATCH(comp, TWLSMPS, label)
    636
    637static const struct of_device_id twl_of_match[] = {
    638	TWL6030_OF_MATCH("ti,twl6030-vdd1", VDD1),
    639	TWL6030_OF_MATCH("ti,twl6030-vdd2", VDD2),
    640	TWL6030_OF_MATCH("ti,twl6030-vdd3", VDD3),
    641	TWL6030_OF_MATCH("ti,twl6030-vaux1", VAUX1_6030),
    642	TWL6030_OF_MATCH("ti,twl6030-vaux2", VAUX2_6030),
    643	TWL6030_OF_MATCH("ti,twl6030-vaux3", VAUX3_6030),
    644	TWL6030_OF_MATCH("ti,twl6030-vmmc", VMMC),
    645	TWL6030_OF_MATCH("ti,twl6030-vpp", VPP),
    646	TWL6030_OF_MATCH("ti,twl6030-vusim", VUSIM),
    647	TWL6032_OF_MATCH("ti,twl6032-ldo2", LDO2),
    648	TWL6032_OF_MATCH("ti,twl6032-ldo4", LDO4),
    649	TWL6032_OF_MATCH("ti,twl6032-ldo3", LDO3),
    650	TWL6032_OF_MATCH("ti,twl6032-ldo5", LDO5),
    651	TWL6032_OF_MATCH("ti,twl6032-ldo1", LDO1),
    652	TWL6032_OF_MATCH("ti,twl6032-ldo7", LDO7),
    653	TWL6032_OF_MATCH("ti,twl6032-ldo6", LDO6),
    654	TWL6032_OF_MATCH("ti,twl6032-ldoln", LDOLN),
    655	TWL6032_OF_MATCH("ti,twl6032-ldousb", LDOUSB),
    656	TWLFIXED_OF_MATCH("ti,twl6030-vana", VANA),
    657	TWLFIXED_OF_MATCH("ti,twl6030-vcxio", VCXIO),
    658	TWLFIXED_OF_MATCH("ti,twl6030-vdac", VDAC),
    659	TWLFIXED_OF_MATCH("ti,twl6030-vusb", VUSB),
    660	TWLFIXED_OF_MATCH("ti,twl6030-v1v8", V1V8),
    661	TWLFIXED_OF_MATCH("ti,twl6030-v2v1", V2V1),
    662	TWLSMPS_OF_MATCH("ti,twl6032-smps3", SMPS3),
    663	TWLSMPS_OF_MATCH("ti,twl6032-smps4", SMPS4),
    664	TWLSMPS_OF_MATCH("ti,twl6032-vio", VIO),
    665	{},
    666};
    667MODULE_DEVICE_TABLE(of, twl_of_match);
    668
    669static int twlreg_probe(struct platform_device *pdev)
    670{
    671	int id;
    672	struct twlreg_info		*info;
    673	const struct twlreg_info	*template;
    674	struct regulator_init_data	*initdata;
    675	struct regulation_constraints	*c;
    676	struct regulator_dev		*rdev;
    677	struct regulator_config		config = { };
    678	struct device_node		*np = pdev->dev.of_node;
    679
    680	template = of_device_get_match_data(&pdev->dev);
    681	if (!template)
    682		return -ENODEV;
    683
    684	id = template->desc.id;
    685	initdata = of_get_regulator_init_data(&pdev->dev, np, &template->desc);
    686	if (!initdata)
    687		return -EINVAL;
    688
    689	info = devm_kmemdup(&pdev->dev, template, sizeof(*info), GFP_KERNEL);
    690	if (!info)
    691		return -ENOMEM;
    692
    693	/* Constrain board-specific capabilities according to what
    694	 * this driver and the chip itself can actually do.
    695	 */
    696	c = &initdata->constraints;
    697	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
    698	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
    699				| REGULATOR_CHANGE_MODE
    700				| REGULATOR_CHANGE_STATUS;
    701
    702	switch (id) {
    703	case TWL6032_REG_SMPS3:
    704		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
    705			info->flags |= SMPS_EXTENDED_EN;
    706		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
    707			info->flags |= SMPS_OFFSET_EN;
    708		break;
    709	case TWL6032_REG_SMPS4:
    710		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
    711			info->flags |= SMPS_EXTENDED_EN;
    712		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
    713			info->flags |= SMPS_OFFSET_EN;
    714		break;
    715	case TWL6032_REG_VIO:
    716		if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
    717			info->flags |= SMPS_EXTENDED_EN;
    718		if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
    719			info->flags |= SMPS_OFFSET_EN;
    720		break;
    721	}
    722
    723	if (of_get_property(np, "ti,retain-on-reset", NULL))
    724		info->flags |= TWL_6030_WARM_RESET;
    725
    726	config.dev = &pdev->dev;
    727	config.init_data = initdata;
    728	config.driver_data = info;
    729	config.of_node = np;
    730
    731	rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
    732	if (IS_ERR(rdev)) {
    733		dev_err(&pdev->dev, "can't register %s, %ld\n",
    734				info->desc.name, PTR_ERR(rdev));
    735		return PTR_ERR(rdev);
    736	}
    737	platform_set_drvdata(pdev, rdev);
    738
    739	/* NOTE:  many regulators support short-circuit IRQs (presentable
    740	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
    741	 *  - SC_CONFIG
    742	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
    743	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
    744	 *  - IT_CONFIG
    745	 */
    746
    747	return 0;
    748}
    749
    750MODULE_ALIAS("platform:twl6030_reg");
    751
    752static struct platform_driver twlreg_driver = {
    753	.probe		= twlreg_probe,
    754	/* NOTE: short name, to work around driver model truncation of
    755	 * "twl_regulator.12" (and friends) to "twl_regulator.1".
    756	 */
    757	.driver  = {
    758		.name  = "twl6030_reg",
    759		.of_match_table = of_match_ptr(twl_of_match),
    760	},
    761};
    762
    763static int __init twlreg_init(void)
    764{
    765	return platform_driver_register(&twlreg_driver);
    766}
    767subsys_initcall(twlreg_init);
    768
    769static void __exit twlreg_exit(void)
    770{
    771	platform_driver_unregister(&twlreg_driver);
    772}
    773module_exit(twlreg_exit)
    774
    775MODULE_DESCRIPTION("TWL6030 regulator driver");
    776MODULE_LICENSE("GPL");