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

da903x-regulator.c (15063B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Regulators driver for Dialog Semiconductor DA903x
      4//
      5// Copyright (C) 2006-2008 Marvell International Ltd.
      6// Copyright (C) 2008 Compulab Ltd.
      7
      8#include <linux/kernel.h>
      9#include <linux/init.h>
     10#include <linux/err.h>
     11#include <linux/module.h>
     12#include <linux/platform_device.h>
     13#include <linux/regulator/driver.h>
     14#include <linux/regulator/machine.h>
     15#include <linux/mfd/da903x.h>
     16
     17/* DA9030 Registers */
     18#define DA9030_INVAL		(-1)
     19#define DA9030_LDO1011		(0x10)
     20#define DA9030_LDO15		(0x11)
     21#define DA9030_LDO1416		(0x12)
     22#define DA9030_LDO1819		(0x13)
     23#define DA9030_LDO17		(0x14)
     24#define DA9030_BUCK2DVM1	(0x15)
     25#define DA9030_BUCK2DVM2	(0x16)
     26#define DA9030_RCTL11		(0x17)
     27#define DA9030_RCTL21		(0x18)
     28#define DA9030_LDO1		(0x90)
     29#define DA9030_LDO23		(0x91)
     30#define DA9030_LDO45		(0x92)
     31#define DA9030_LDO6		(0x93)
     32#define DA9030_LDO78		(0x94)
     33#define DA9030_LDO912		(0x95)
     34#define DA9030_BUCK		(0x96)
     35#define DA9030_RCTL12		(0x97)
     36#define DA9030_RCTL22		(0x98)
     37#define DA9030_LDO_UNLOCK	(0xa0)
     38#define DA9030_LDO_UNLOCK_MASK	(0xe0)
     39#define DA9034_OVER1		(0x10)
     40
     41/* DA9034 Registers */
     42#define DA9034_INVAL		(-1)
     43#define DA9034_OVER2		(0x11)
     44#define DA9034_OVER3		(0x12)
     45#define DA9034_LDO643		(0x13)
     46#define DA9034_LDO987		(0x14)
     47#define DA9034_LDO1110		(0x15)
     48#define DA9034_LDO1312		(0x16)
     49#define DA9034_LDO1514		(0x17)
     50#define DA9034_VCC1		(0x20)
     51#define DA9034_ADTV1		(0x23)
     52#define DA9034_ADTV2		(0x24)
     53#define DA9034_AVRC		(0x25)
     54#define DA9034_CDTV1		(0x26)
     55#define DA9034_CDTV2		(0x27)
     56#define DA9034_CVRC		(0x28)
     57#define DA9034_SDTV1		(0x29)
     58#define DA9034_SDTV2		(0x2a)
     59#define DA9034_SVRC		(0x2b)
     60#define DA9034_MDTV1		(0x32)
     61#define DA9034_MDTV2		(0x33)
     62#define DA9034_MVRC		(0x34)
     63
     64/* DA9035 Registers. DA9034 Registers are comptabile to DA9035. */
     65#define DA9035_OVER3		(0x12)
     66#define DA9035_VCC2		(0x1f)
     67#define DA9035_3DTV1		(0x2c)
     68#define DA9035_3DTV2		(0x2d)
     69#define DA9035_3VRC		(0x2e)
     70#define DA9035_AUTOSKIP		(0x2f)
     71
     72struct da903x_regulator_info {
     73	struct regulator_desc desc;
     74
     75	int	max_uV;
     76	int	vol_reg;
     77	int	vol_shift;
     78	int	vol_nbits;
     79	int	update_reg;
     80	int	update_bit;
     81	int	enable_reg;
     82	int	enable_bit;
     83};
     84
     85static inline struct device *to_da903x_dev(struct regulator_dev *rdev)
     86{
     87	return rdev_get_dev(rdev)->parent->parent;
     88}
     89
     90static inline int check_range(struct da903x_regulator_info *info,
     91				int min_uV, int max_uV)
     92{
     93	if (min_uV < info->desc.min_uV || min_uV > info->max_uV)
     94		return -EINVAL;
     95
     96	return 0;
     97}
     98
     99/* DA9030/DA9034 common operations */
    100static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
    101{
    102	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    103	struct device *da9034_dev = to_da903x_dev(rdev);
    104	uint8_t val, mask;
    105
    106	if (rdev->desc->n_voltages == 1)
    107		return -EINVAL;
    108
    109	val = selector << info->vol_shift;
    110	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
    111
    112	return da903x_update(da9034_dev, info->vol_reg, val, mask);
    113}
    114
    115static int da903x_get_voltage_sel(struct regulator_dev *rdev)
    116{
    117	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    118	struct device *da9034_dev = to_da903x_dev(rdev);
    119	uint8_t val, mask;
    120	int ret;
    121
    122	if (rdev->desc->n_voltages == 1)
    123		return 0;
    124
    125	ret = da903x_read(da9034_dev, info->vol_reg, &val);
    126	if (ret)
    127		return ret;
    128
    129	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
    130	val = (val & mask) >> info->vol_shift;
    131
    132	return val;
    133}
    134
    135static int da903x_enable(struct regulator_dev *rdev)
    136{
    137	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    138	struct device *da9034_dev = to_da903x_dev(rdev);
    139
    140	return da903x_set_bits(da9034_dev, info->enable_reg,
    141					1 << info->enable_bit);
    142}
    143
    144static int da903x_disable(struct regulator_dev *rdev)
    145{
    146	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    147	struct device *da9034_dev = to_da903x_dev(rdev);
    148
    149	return da903x_clr_bits(da9034_dev, info->enable_reg,
    150					1 << info->enable_bit);
    151}
    152
    153static int da903x_is_enabled(struct regulator_dev *rdev)
    154{
    155	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    156	struct device *da9034_dev = to_da903x_dev(rdev);
    157	uint8_t reg_val;
    158	int ret;
    159
    160	ret = da903x_read(da9034_dev, info->enable_reg, &reg_val);
    161	if (ret)
    162		return ret;
    163
    164	return !!(reg_val & (1 << info->enable_bit));
    165}
    166
    167/* DA9030 specific operations */
    168static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev,
    169					  unsigned selector)
    170{
    171	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    172	struct device *da903x_dev = to_da903x_dev(rdev);
    173	uint8_t val, mask;
    174	int ret;
    175
    176	val = selector << info->vol_shift;
    177	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
    178	val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */
    179	mask |= DA9030_LDO_UNLOCK_MASK;
    180
    181	/* write twice */
    182	ret = da903x_update(da903x_dev, info->vol_reg, val, mask);
    183	if (ret)
    184		return ret;
    185
    186	return da903x_update(da903x_dev, info->vol_reg, val, mask);
    187}
    188
    189static int da9030_map_ldo14_voltage(struct regulator_dev *rdev,
    190				    int min_uV, int max_uV)
    191{
    192	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    193	int thresh, sel;
    194
    195	if (check_range(info, min_uV, max_uV)) {
    196		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
    197		return -EINVAL;
    198	}
    199
    200	thresh = (info->max_uV + info->desc.min_uV) / 2;
    201	if (min_uV < thresh) {
    202		sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step);
    203		sel |= 0x4;
    204	} else {
    205		sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step);
    206	}
    207
    208	return sel;
    209}
    210
    211static int da9030_list_ldo14_voltage(struct regulator_dev *rdev,
    212				     unsigned selector)
    213{
    214	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    215	int volt;
    216
    217	if (selector & 0x4)
    218		volt = rdev->desc->min_uV +
    219		       rdev->desc->uV_step * (3 - (selector & ~0x4));
    220	else
    221		volt = (info->max_uV + rdev->desc->min_uV) / 2 +
    222		       rdev->desc->uV_step * (selector & ~0x4);
    223
    224	if (volt > info->max_uV)
    225		return -EINVAL;
    226
    227	return volt;
    228}
    229
    230/* DA9034 specific operations */
    231static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
    232				      unsigned selector)
    233{
    234	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
    235	struct device *da9034_dev = to_da903x_dev(rdev);
    236	uint8_t val, mask;
    237	int ret;
    238
    239	val = selector << info->vol_shift;
    240	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
    241
    242	ret = da903x_update(da9034_dev, info->vol_reg, val, mask);
    243	if (ret)
    244		return ret;
    245
    246	ret = da903x_set_bits(da9034_dev, info->update_reg,
    247					1 << info->update_bit);
    248	return ret;
    249}
    250
    251static const struct linear_range da9034_ldo12_ranges[] = {
    252	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
    253	REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
    254};
    255
    256static const struct regulator_ops da903x_regulator_ldo_ops = {
    257	.set_voltage_sel = da903x_set_voltage_sel,
    258	.get_voltage_sel = da903x_get_voltage_sel,
    259	.list_voltage	= regulator_list_voltage_linear,
    260	.map_voltage	= regulator_map_voltage_linear,
    261	.enable		= da903x_enable,
    262	.disable	= da903x_disable,
    263	.is_enabled	= da903x_is_enabled,
    264};
    265
    266/* NOTE: this is dedicated for the insane DA9030 LDO14 */
    267static const struct regulator_ops da9030_regulator_ldo14_ops = {
    268	.set_voltage_sel = da903x_set_voltage_sel,
    269	.get_voltage_sel = da903x_get_voltage_sel,
    270	.list_voltage	= da9030_list_ldo14_voltage,
    271	.map_voltage	= da9030_map_ldo14_voltage,
    272	.enable		= da903x_enable,
    273	.disable	= da903x_disable,
    274	.is_enabled	= da903x_is_enabled,
    275};
    276
    277/* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks  */
    278static const struct regulator_ops da9030_regulator_ldo1_15_ops = {
    279	.set_voltage_sel = da9030_set_ldo1_15_voltage_sel,
    280	.get_voltage_sel = da903x_get_voltage_sel,
    281	.list_voltage	= regulator_list_voltage_linear,
    282	.map_voltage	= regulator_map_voltage_linear,
    283	.enable		= da903x_enable,
    284	.disable	= da903x_disable,
    285	.is_enabled	= da903x_is_enabled,
    286};
    287
    288static const struct regulator_ops da9034_regulator_dvc_ops = {
    289	.set_voltage_sel = da9034_set_dvc_voltage_sel,
    290	.get_voltage_sel = da903x_get_voltage_sel,
    291	.list_voltage	= regulator_list_voltage_linear,
    292	.map_voltage	= regulator_map_voltage_linear,
    293	.enable		= da903x_enable,
    294	.disable	= da903x_disable,
    295	.is_enabled	= da903x_is_enabled,
    296};
    297
    298/* NOTE: this is dedicated for the insane LDO12 */
    299static const struct regulator_ops da9034_regulator_ldo12_ops = {
    300	.set_voltage_sel = da903x_set_voltage_sel,
    301	.get_voltage_sel = da903x_get_voltage_sel,
    302	.list_voltage	= regulator_list_voltage_linear_range,
    303	.map_voltage	= regulator_map_voltage_linear_range,
    304	.enable		= da903x_enable,
    305	.disable	= da903x_disable,
    306	.is_enabled	= da903x_is_enabled,
    307};
    308
    309#define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
    310{									\
    311	.desc	= {							\
    312		.name	= "LDO" #_id,					\
    313		.ops	= &da903x_regulator_ldo_ops,			\
    314		.type	= REGULATOR_VOLTAGE,				\
    315		.id	= _pmic##_ID_LDO##_id,				\
    316		.n_voltages = (step) ? ((max - min) / step + 1) : 1,	\
    317		.owner	= THIS_MODULE,					\
    318		.min_uV	 = (min) * 1000,				\
    319		.uV_step = (step) * 1000,				\
    320	},								\
    321	.max_uV		= (max) * 1000,					\
    322	.vol_reg	= _pmic##_##vreg,				\
    323	.vol_shift	= (shift),					\
    324	.vol_nbits	= (nbits),					\
    325	.enable_reg	= _pmic##_##ereg,				\
    326	.enable_bit	= (ebit),					\
    327}
    328
    329#define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
    330{									\
    331	.desc	= {							\
    332		.name	= #_id,						\
    333		.ops	= &da9034_regulator_dvc_ops,			\
    334		.type	= REGULATOR_VOLTAGE,				\
    335		.id	= _pmic##_ID_##_id,				\
    336		.n_voltages = (step) ? ((max - min) / step + 1) : 1,	\
    337		.owner	= THIS_MODULE,					\
    338		.min_uV = (min) * 1000,					\
    339		.uV_step = (step) * 1000,				\
    340	},								\
    341	.max_uV		= (max) * 1000,					\
    342	.vol_reg	= _pmic##_##vreg,				\
    343	.vol_shift	= (0),						\
    344	.vol_nbits	= (nbits),					\
    345	.update_reg	= _pmic##_##ureg,				\
    346	.update_bit	= (ubit),					\
    347	.enable_reg	= _pmic##_##ereg,				\
    348	.enable_bit	= (ebit),					\
    349}
    350
    351#define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
    352	DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
    353
    354#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)	\
    355	DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
    356
    357#define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
    358	DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \
    359		   ereg, ebit)
    360
    361#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
    362	DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \
    363		   ereg, ebit)
    364
    365#define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
    366	DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \
    367		   ereg, ebit)
    368
    369static struct da903x_regulator_info da903x_regulator_info[] = {
    370	/* DA9030 */
    371	DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),
    372
    373	DA9030_LDO( 1, 1200, 3200, 100,    LDO1, 0, 5, RCTL12, 1),
    374	DA9030_LDO( 2, 1800, 3200, 100,   LDO23, 0, 4, RCTL12, 2),
    375	DA9030_LDO( 3, 1800, 3200, 100,   LDO23, 4, 4, RCTL12, 3),
    376	DA9030_LDO( 4, 1800, 3200, 100,   LDO45, 0, 4, RCTL12, 4),
    377	DA9030_LDO( 5, 1800, 3200, 100,   LDO45, 4, 4, RCTL12, 5),
    378	DA9030_LDO( 6, 1800, 3200, 100,    LDO6, 0, 4, RCTL12, 6),
    379	DA9030_LDO( 7, 1800, 3200, 100,   LDO78, 0, 4, RCTL12, 7),
    380	DA9030_LDO( 8, 1800, 3200, 100,   LDO78, 4, 4, RCTL22, 0),
    381	DA9030_LDO( 9, 1800, 3200, 100,  LDO912, 0, 4, RCTL22, 1),
    382	DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2),
    383	DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3),
    384	DA9030_LDO(12, 1800, 3200, 100,  LDO912, 4, 4, RCTL22, 4),
    385	DA9030_LDO(14, 2760, 2940,  30, LDO1416, 0, 3, RCTL11, 4),
    386	DA9030_LDO(15, 1100, 2650,  50,	  LDO15, 0, 5, RCTL11, 5),
    387	DA9030_LDO(16, 1100, 2650,  50, LDO1416, 3, 5, RCTL11, 6),
    388	DA9030_LDO(17, 1800, 3200, 100,   LDO17, 0, 4, RCTL11, 7),
    389	DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2),
    390	DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1),
    391	DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
    392
    393	/* DA9034 */
    394	DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
    395	DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
    396	DA9034_DVC(LDO2,  725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2),
    397	DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
    398
    399	DA9034_LDO( 3, 1800, 3300, 100,  LDO643, 0, 4, OVER3, 5),
    400	DA9034_LDO( 4, 1800, 2900,1100,  LDO643, 4, 1, OVER3, 6),
    401	DA9034_LDO( 6, 2500, 2850,  50,  LDO643, 5, 3, OVER2, 0),
    402	DA9034_LDO( 7, 2700, 3050,  50,  LDO987, 0, 3, OVER2, 1),
    403	DA9034_LDO( 8, 2700, 2850,  50,  LDO987, 3, 2, OVER2, 2),
    404	DA9034_LDO( 9, 2700, 3050,  50,  LDO987, 5, 3, OVER2, 3),
    405	DA9034_LDO(10, 2700, 3050,  50, LDO1110, 0, 3, OVER2, 4),
    406	DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5),
    407	DA9034_LDO(12, 1700, 3050,  50, LDO1312, 0, 4, OVER3, 6),
    408	DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7),
    409	DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
    410	DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
    411	DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
    412
    413	/* DA9035 */
    414	DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3),
    415};
    416
    417static inline struct da903x_regulator_info *find_regulator_info(int id)
    418{
    419	struct da903x_regulator_info *ri;
    420	int i;
    421
    422	for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) {
    423		ri = &da903x_regulator_info[i];
    424		if (ri->desc.id == id)
    425			return ri;
    426	}
    427	return NULL;
    428}
    429
    430static int da903x_regulator_probe(struct platform_device *pdev)
    431{
    432	struct da903x_regulator_info *ri = NULL;
    433	struct regulator_dev *rdev;
    434	struct regulator_config config = { };
    435
    436	ri = find_regulator_info(pdev->id);
    437	if (ri == NULL) {
    438		dev_err(&pdev->dev, "invalid regulator ID specified\n");
    439		return -EINVAL;
    440	}
    441
    442	/* Workaround for the weird LDO12 voltage setting */
    443	if (ri->desc.id == DA9034_ID_LDO12) {
    444		ri->desc.ops = &da9034_regulator_ldo12_ops;
    445		ri->desc.n_voltages = 16;
    446		ri->desc.linear_ranges = da9034_ldo12_ranges;
    447		ri->desc.n_linear_ranges = ARRAY_SIZE(da9034_ldo12_ranges);
    448	}
    449
    450	if (ri->desc.id == DA9030_ID_LDO14)
    451		ri->desc.ops = &da9030_regulator_ldo14_ops;
    452
    453	if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
    454		ri->desc.ops = &da9030_regulator_ldo1_15_ops;
    455
    456	config.dev = &pdev->dev;
    457	config.init_data = dev_get_platdata(&pdev->dev);
    458	config.driver_data = ri;
    459
    460	rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
    461	if (IS_ERR(rdev)) {
    462		dev_err(&pdev->dev, "failed to register regulator %s\n",
    463				ri->desc.name);
    464		return PTR_ERR(rdev);
    465	}
    466
    467	platform_set_drvdata(pdev, rdev);
    468	return 0;
    469}
    470
    471static struct platform_driver da903x_regulator_driver = {
    472	.driver	= {
    473		.name	= "da903x-regulator",
    474	},
    475	.probe		= da903x_regulator_probe,
    476};
    477
    478static int __init da903x_regulator_init(void)
    479{
    480	return platform_driver_register(&da903x_regulator_driver);
    481}
    482subsys_initcall(da903x_regulator_init);
    483
    484static void __exit da903x_regulator_exit(void)
    485{
    486	platform_driver_unregister(&da903x_regulator_driver);
    487}
    488module_exit(da903x_regulator_exit);
    489
    490MODULE_LICENSE("GPL");
    491MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
    492	      "Mike Rapoport <mike@compulab.co.il>");
    493MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC");
    494MODULE_ALIAS("platform:da903x-regulator");