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

rc5t583-regulator.c (5495B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Regulator driver for RICOH RC5T583 power management chip.
      4 *
      5 * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
      6 * Author: Laxman dewangan <ldewangan@nvidia.com>
      7 *
      8 * based on code
      9 *      Copyright (C) 2011 RICOH COMPANY,LTD
     10 */
     11
     12#include <linux/module.h>
     13#include <linux/init.h>
     14#include <linux/slab.h>
     15#include <linux/err.h>
     16#include <linux/platform_device.h>
     17#include <linux/regulator/driver.h>
     18#include <linux/regulator/machine.h>
     19#include <linux/gpio.h>
     20#include <linux/mfd/rc5t583.h>
     21
     22struct rc5t583_regulator_info {
     23	int			deepsleep_id;
     24
     25	/* Regulator register address.*/
     26	uint8_t			reg_disc_reg;
     27	uint8_t			disc_bit;
     28	uint8_t			deepsleep_reg;
     29
     30	/* Regulator specific turn-on delay  and voltage settling time*/
     31	int			enable_uv_per_us;
     32
     33	/* Used by regulator core */
     34	struct regulator_desc	desc;
     35};
     36
     37static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
     38{
     39	struct rc5t583_regulator_info *reg_info = rdev_get_drvdata(rdev);
     40	int vsel = regulator_get_voltage_sel_regmap(rdev);
     41	int curr_uV = regulator_list_voltage_linear(rdev, vsel);
     42
     43	return DIV_ROUND_UP(curr_uV, reg_info->enable_uv_per_us);
     44}
     45
     46static const struct regulator_ops rc5t583_ops = {
     47	.is_enabled		= regulator_is_enabled_regmap,
     48	.enable			= regulator_enable_regmap,
     49	.disable		= regulator_disable_regmap,
     50	.enable_time		= rc5t583_regulator_enable_time,
     51	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
     52	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
     53	.list_voltage		= regulator_list_voltage_linear,
     54	.map_voltage		= regulator_map_voltage_linear,
     55	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
     56};
     57
     58#define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
     59		_vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \
     60{								\
     61	.reg_disc_reg	= RC5T583_REG_##_disc_reg,		\
     62	.disc_bit	= _disc_bit,				\
     63	.deepsleep_reg	= RC5T583_REG_##_id##DAC_DS,		\
     64	.enable_uv_per_us = _enable_mv * 1000,			\
     65	.deepsleep_id	= RC5T583_DS_##_id,			\
     66	.desc = {						\
     67		.name = "rc5t583-regulator-"#_id,		\
     68		.id = RC5T583_REGULATOR_##_id,			\
     69		.n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \
     70		.ops = &rc5t583_ops,				\
     71		.type = REGULATOR_VOLTAGE,			\
     72		.owner = THIS_MODULE,				\
     73		.vsel_reg = RC5T583_REG_##_id##DAC,		\
     74		.vsel_mask = _vout_mask,			\
     75		.enable_reg = RC5T583_REG_##_en_reg,		\
     76		.enable_mask = BIT(_en_bit),			\
     77		.min_uV	= _min_mv * 1000,			\
     78		.uV_step = _step_uV,				\
     79		.ramp_delay = 40 * 1000,			\
     80	},							\
     81}
     82
     83static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = {
     84	RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4),
     85	RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14),
     86	RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14),
     87	RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14),
     88	RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160),
     89	RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160),
     90	RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160),
     91	RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160),
     92	RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133),
     93	RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267),
     94	RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133),
     95	RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233),
     96	RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233),
     97	RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
     98};
     99
    100static int rc5t583_regulator_probe(struct platform_device *pdev)
    101{
    102	struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
    103	struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
    104	struct regulator_config config = { };
    105	struct regulator_dev *rdev;
    106	struct rc5t583_regulator_info *ri;
    107	int ret;
    108	int id;
    109
    110	if (!pdata) {
    111		dev_err(&pdev->dev, "No platform data, exiting...\n");
    112		return -ENODEV;
    113	}
    114
    115	for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
    116		ri = &rc5t583_reg_info[id];
    117
    118		if (ri->deepsleep_id == RC5T583_DS_NONE)
    119			goto skip_ext_pwr_config;
    120
    121		ret = rc5t583_ext_power_req_config(rc5t583->dev,
    122				ri->deepsleep_id,
    123				pdata->regulator_ext_pwr_control[id],
    124				pdata->regulator_deepsleep_slot[id]);
    125		/*
    126		 * Configuring external control is not a major issue,
    127		 * just give warning.
    128		 */
    129		if (ret < 0)
    130			dev_warn(&pdev->dev,
    131				"Failed to configure ext control %d\n", id);
    132
    133skip_ext_pwr_config:
    134		config.dev = &pdev->dev;
    135		config.init_data = pdata->reg_init_data[id];
    136		config.driver_data = ri;
    137		config.regmap = rc5t583->regmap;
    138
    139		rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
    140		if (IS_ERR(rdev)) {
    141			dev_err(&pdev->dev, "Failed to register regulator %s\n",
    142						ri->desc.name);
    143			return PTR_ERR(rdev);
    144		}
    145	}
    146	return 0;
    147}
    148
    149static struct platform_driver rc5t583_regulator_driver = {
    150	.driver	= {
    151		.name	= "rc5t583-regulator",
    152	},
    153	.probe		= rc5t583_regulator_probe,
    154};
    155
    156static int __init rc5t583_regulator_init(void)
    157{
    158	return platform_driver_register(&rc5t583_regulator_driver);
    159}
    160subsys_initcall(rc5t583_regulator_init);
    161
    162static void __exit rc5t583_regulator_exit(void)
    163{
    164	platform_driver_unregister(&rc5t583_regulator_driver);
    165}
    166module_exit(rc5t583_regulator_exit);
    167
    168MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
    169MODULE_DESCRIPTION("RC5T583 regulator driver");
    170MODULE_ALIAS("platform:rc5t583-regulator");
    171MODULE_LICENSE("GPL v2");