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

max77693-regulator.c (8763B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// max77693.c - Regulator driver for the Maxim 77693 and 77843
      4//
      5// Copyright (C) 2013-2015 Samsung Electronics
      6// Jonghwa Lee <jonghwa3.lee@samsung.com>
      7// Krzysztof Kozlowski <krzk@kernel.org>
      8//
      9// This driver is based on max77686.c
     10
     11#include <linux/err.h>
     12#include <linux/slab.h>
     13#include <linux/platform_device.h>
     14#include <linux/module.h>
     15#include <linux/export.h>
     16#include <linux/regulator/driver.h>
     17#include <linux/regulator/machine.h>
     18#include <linux/mfd/max77693.h>
     19#include <linux/mfd/max77693-common.h>
     20#include <linux/mfd/max77693-private.h>
     21#include <linux/mfd/max77843-private.h>
     22#include <linux/regulator/of_regulator.h>
     23#include <linux/regmap.h>
     24
     25/*
     26 * ID for MAX77843 regulators.
     27 * There is no need for such for MAX77693.
     28 */
     29enum max77843_regulator_type {
     30	MAX77843_SAFEOUT1 = 0,
     31	MAX77843_SAFEOUT2,
     32	MAX77843_CHARGER,
     33
     34	MAX77843_NUM,
     35};
     36
     37/* Register differences between chargers: MAX77693 and MAX77843 */
     38struct chg_reg_data {
     39	unsigned int linear_reg;
     40	unsigned int linear_mask;
     41	unsigned int uA_step;
     42	unsigned int min_sel;
     43};
     44
     45/*
     46 * MAX77693 CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
     47 * 0x00, 0x01, 0x2, 0x03	= 60 mA
     48 * 0x04 ~ 0x7E			= (60 + (X - 3) * 20) mA
     49 * Actually for MAX77693 the driver manipulates the maximum input current,
     50 * not the fast charge current (output). This should be fixed.
     51 *
     52 * On MAX77843 the calculation formula is the same (except values).
     53 * Fortunately it properly manipulates the fast charge current.
     54 */
     55static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
     56{
     57	const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
     58	unsigned int chg_min_uA = rdev->constraints->min_uA;
     59	unsigned int chg_max_uA = rdev->constraints->max_uA;
     60	unsigned int reg, sel;
     61	unsigned int val;
     62	int ret;
     63
     64	ret = regmap_read(rdev->regmap, reg_data->linear_reg, &reg);
     65	if (ret < 0)
     66		return ret;
     67
     68	sel = reg & reg_data->linear_mask;
     69
     70	/* the first four codes for charger current are all 60mA */
     71	if (sel <= reg_data->min_sel)
     72		sel = 0;
     73	else
     74		sel -= reg_data->min_sel;
     75
     76	val = chg_min_uA + reg_data->uA_step * sel;
     77	if (val > chg_max_uA)
     78		return -EINVAL;
     79
     80	return val;
     81}
     82
     83static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
     84						int min_uA, int max_uA)
     85{
     86	const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
     87	unsigned int chg_min_uA = rdev->constraints->min_uA;
     88	int sel = 0;
     89
     90	while (chg_min_uA + reg_data->uA_step * sel < min_uA)
     91		sel++;
     92
     93	if (chg_min_uA + reg_data->uA_step * sel > max_uA)
     94		return -EINVAL;
     95
     96	/* the first four codes for charger current are all 60mA */
     97	sel += reg_data->min_sel;
     98
     99	return regmap_write(rdev->regmap, reg_data->linear_reg, sel);
    100}
    101/* end of CHARGER regulator ops */
    102
    103/* Returns regmap suitable for given regulator on chosen device */
    104static struct regmap *max77693_get_regmap(enum max77693_types type,
    105					  struct max77693_dev *max77693,
    106					  int reg_id)
    107{
    108	if (type == TYPE_MAX77693)
    109		return max77693->regmap;
    110
    111	/* Else: TYPE_MAX77843 */
    112	switch (reg_id) {
    113	case MAX77843_SAFEOUT1:
    114	case MAX77843_SAFEOUT2:
    115		return max77693->regmap;
    116	case MAX77843_CHARGER:
    117		return max77693->regmap_chg;
    118	default:
    119		return max77693->regmap;
    120	}
    121}
    122
    123static const unsigned int max77693_safeout_table[] = {
    124	4850000,
    125	4900000,
    126	4950000,
    127	3300000,
    128};
    129
    130static const struct regulator_ops max77693_safeout_ops = {
    131	.list_voltage		= regulator_list_voltage_table,
    132	.is_enabled		= regulator_is_enabled_regmap,
    133	.enable			= regulator_enable_regmap,
    134	.disable		= regulator_disable_regmap,
    135	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
    136	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
    137};
    138
    139static const struct regulator_ops max77693_charger_ops = {
    140	.is_enabled		= regulator_is_enabled_regmap,
    141	.enable			= regulator_enable_regmap,
    142	.disable		= regulator_disable_regmap,
    143	.get_current_limit	= max77693_chg_get_current_limit,
    144	.set_current_limit	= max77693_chg_set_current_limit,
    145};
    146
    147#define max77693_regulator_desc_esafeout(_num)	{		\
    148	.name		= "ESAFEOUT"#_num,			\
    149	.id		= MAX77693_ESAFEOUT##_num,		\
    150	.of_match	= of_match_ptr("ESAFEOUT"#_num),	\
    151	.regulators_node	= of_match_ptr("regulators"),	\
    152	.n_voltages	= 4,					\
    153	.ops		= &max77693_safeout_ops,		\
    154	.type		= REGULATOR_VOLTAGE,			\
    155	.owner		= THIS_MODULE,				\
    156	.volt_table	= max77693_safeout_table,		\
    157	.vsel_reg	= MAX77693_CHG_REG_SAFEOUT_CTRL,	\
    158	.vsel_mask	= SAFEOUT_CTRL_SAFEOUT##_num##_MASK,	\
    159	.enable_reg	= MAX77693_CHG_REG_SAFEOUT_CTRL,	\
    160	.enable_mask	= SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK ,	\
    161}
    162
    163static const struct regulator_desc max77693_supported_regulators[] = {
    164	max77693_regulator_desc_esafeout(1),
    165	max77693_regulator_desc_esafeout(2),
    166	{
    167		.name = "CHARGER",
    168		.id = MAX77693_CHARGER,
    169		.of_match = of_match_ptr("CHARGER"),
    170		.regulators_node = of_match_ptr("regulators"),
    171		.ops = &max77693_charger_ops,
    172		.type = REGULATOR_CURRENT,
    173		.owner = THIS_MODULE,
    174		.enable_reg = MAX77693_CHG_REG_CHG_CNFG_00,
    175		.enable_mask = CHG_CNFG_00_CHG_MASK |
    176				CHG_CNFG_00_BUCK_MASK,
    177		.enable_val = CHG_CNFG_00_CHG_MASK | CHG_CNFG_00_BUCK_MASK,
    178	},
    179};
    180
    181static const struct chg_reg_data max77693_chg_reg_data = {
    182	.linear_reg	= MAX77693_CHG_REG_CHG_CNFG_09,
    183	.linear_mask	= CHG_CNFG_09_CHGIN_ILIM_MASK,
    184	.uA_step	= 20000,
    185	.min_sel	= 3,
    186};
    187
    188#define	max77843_regulator_desc_esafeout(num)	{			\
    189	.name		= "SAFEOUT" # num,				\
    190	.id		= MAX77843_SAFEOUT ## num,			\
    191	.ops		= &max77693_safeout_ops,			\
    192	.of_match	= of_match_ptr("SAFEOUT" # num),		\
    193	.regulators_node = of_match_ptr("regulators"),			\
    194	.type		= REGULATOR_VOLTAGE,				\
    195	.owner		= THIS_MODULE,					\
    196	.n_voltages	= ARRAY_SIZE(max77693_safeout_table),		\
    197	.volt_table	= max77693_safeout_table,			\
    198	.enable_reg	= MAX77843_SYS_REG_SAFEOUTCTRL,			\
    199	.enable_mask	= MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num,	\
    200	.vsel_reg	= MAX77843_SYS_REG_SAFEOUTCTRL,			\
    201	.vsel_mask	= MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \
    202}
    203
    204static const struct regulator_desc max77843_supported_regulators[] = {
    205	[MAX77843_SAFEOUT1] = max77843_regulator_desc_esafeout(1),
    206	[MAX77843_SAFEOUT2] = max77843_regulator_desc_esafeout(2),
    207	[MAX77843_CHARGER] = {
    208		.name		= "CHARGER",
    209		.id		= MAX77843_CHARGER,
    210		.ops		= &max77693_charger_ops,
    211		.of_match	= of_match_ptr("CHARGER"),
    212		.regulators_node = of_match_ptr("regulators"),
    213		.type		= REGULATOR_CURRENT,
    214		.owner		= THIS_MODULE,
    215		.enable_reg	= MAX77843_CHG_REG_CHG_CNFG_00,
    216		.enable_mask	= MAX77843_CHG_MASK,
    217		.enable_val	= MAX77843_CHG_MASK,
    218	},
    219};
    220
    221static const struct chg_reg_data max77843_chg_reg_data = {
    222	.linear_reg	= MAX77843_CHG_REG_CHG_CNFG_02,
    223	.linear_mask	= MAX77843_CHG_FAST_CHG_CURRENT_MASK,
    224	.uA_step	= MAX77843_CHG_FAST_CHG_CURRENT_STEP,
    225	.min_sel	= 2,
    226};
    227
    228static int max77693_pmic_probe(struct platform_device *pdev)
    229{
    230	enum max77693_types type = platform_get_device_id(pdev)->driver_data;
    231	struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
    232	const struct regulator_desc *regulators;
    233	unsigned int regulators_size;
    234	int i;
    235	struct regulator_config config = { };
    236
    237	config.dev = iodev->dev;
    238
    239	switch (type) {
    240	case TYPE_MAX77693:
    241		regulators = max77693_supported_regulators;
    242		regulators_size = ARRAY_SIZE(max77693_supported_regulators);
    243		config.driver_data = (void *)&max77693_chg_reg_data;
    244		break;
    245	case TYPE_MAX77843:
    246		regulators = max77843_supported_regulators;
    247		regulators_size = ARRAY_SIZE(max77843_supported_regulators);
    248		config.driver_data = (void *)&max77843_chg_reg_data;
    249		break;
    250	default:
    251		dev_err(&pdev->dev, "Unsupported device type: %u\n", type);
    252		return -ENODEV;
    253	}
    254
    255	for (i = 0; i < regulators_size; i++) {
    256		struct regulator_dev *rdev;
    257
    258		config.regmap = max77693_get_regmap(type, iodev,
    259						    regulators[i].id);
    260
    261		rdev = devm_regulator_register(&pdev->dev,
    262						&regulators[i], &config);
    263		if (IS_ERR(rdev)) {
    264			dev_err(&pdev->dev,
    265				"Failed to initialize regulator-%d\n", i);
    266			return PTR_ERR(rdev);
    267		}
    268	}
    269
    270	return 0;
    271}
    272
    273static const struct platform_device_id max77693_pmic_id[] = {
    274	{ "max77693-pmic", TYPE_MAX77693 },
    275	{ "max77843-regulator", TYPE_MAX77843 },
    276	{},
    277};
    278
    279MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
    280
    281static struct platform_driver max77693_pmic_driver = {
    282	.driver = {
    283		   .name = "max77693-pmic",
    284		   },
    285	.probe = max77693_pmic_probe,
    286	.id_table = max77693_pmic_id,
    287};
    288
    289static int __init max77693_pmic_init(void)
    290{
    291	return platform_driver_register(&max77693_pmic_driver);
    292}
    293subsys_initcall(max77693_pmic_init);
    294
    295static void __exit max77693_pmic_cleanup(void)
    296{
    297	platform_driver_unregister(&max77693_pmic_driver);
    298}
    299module_exit(max77693_pmic_cleanup);
    300
    301MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver");
    302MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
    303MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>");
    304MODULE_LICENSE("GPL");