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

mc13xxx-regulator-core.c (6201B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Regulator Driver for Freescale MC13xxx PMIC
      4//
      5// Copyright 2010 Yong Shen <yong.shen@linaro.org>
      6//
      7// Based on mc13783 regulator driver :
      8// Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
      9// Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
     10//
     11// Regs infos taken from mc13xxx drivers from freescale and mc13xxx.pdf file
     12// from freescale
     13
     14#include <linux/mfd/mc13xxx.h>
     15#include <linux/regulator/machine.h>
     16#include <linux/regulator/driver.h>
     17#include <linux/regulator/of_regulator.h>
     18#include <linux/platform_device.h>
     19#include <linux/kernel.h>
     20#include <linux/slab.h>
     21#include <linux/init.h>
     22#include <linux/err.h>
     23#include <linux/module.h>
     24#include <linux/of.h>
     25#include "mc13xxx.h"
     26
     27static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
     28{
     29	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
     30	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
     31	int id = rdev_get_id(rdev);
     32
     33	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
     34
     35	return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
     36			       mc13xxx_regulators[id].enable_bit,
     37			       mc13xxx_regulators[id].enable_bit);
     38}
     39
     40static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
     41{
     42	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
     43	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
     44	int id = rdev_get_id(rdev);
     45
     46	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
     47
     48	return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
     49			       mc13xxx_regulators[id].enable_bit, 0);
     50}
     51
     52static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
     53{
     54	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
     55	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
     56	int ret, id = rdev_get_id(rdev);
     57	unsigned int val;
     58
     59	ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
     60	if (ret)
     61		return ret;
     62
     63	return (val & mc13xxx_regulators[id].enable_bit) != 0;
     64}
     65
     66static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev,
     67					     unsigned selector)
     68{
     69	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
     70	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
     71	int id = rdev_get_id(rdev);
     72
     73	return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
     74			       mc13xxx_regulators[id].vsel_mask,
     75			       selector << mc13xxx_regulators[id].vsel_shift);
     76}
     77
     78static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
     79{
     80	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
     81	struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
     82	int ret, id = rdev_get_id(rdev);
     83	unsigned int val;
     84
     85	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
     86
     87	ret = mc13xxx_reg_read(priv->mc13xxx,
     88				mc13xxx_regulators[id].vsel_reg, &val);
     89	if (ret)
     90		return ret;
     91
     92	val = (val & mc13xxx_regulators[id].vsel_mask)
     93		>> mc13xxx_regulators[id].vsel_shift;
     94
     95	dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
     96
     97	BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages);
     98
     99	return rdev->desc->volt_table[val];
    100}
    101
    102const struct regulator_ops mc13xxx_regulator_ops = {
    103	.enable = mc13xxx_regulator_enable,
    104	.disable = mc13xxx_regulator_disable,
    105	.is_enabled = mc13xxx_regulator_is_enabled,
    106	.list_voltage = regulator_list_voltage_table,
    107	.set_voltage_sel = mc13xxx_regulator_set_voltage_sel,
    108	.get_voltage = mc13xxx_regulator_get_voltage,
    109};
    110EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops);
    111
    112int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
    113	       int max_uV, unsigned *selector)
    114{
    115	int id = rdev_get_id(rdev);
    116
    117	dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
    118		__func__, id, min_uV, max_uV);
    119
    120	if (min_uV <= rdev->desc->volt_table[0] &&
    121	    rdev->desc->volt_table[0] <= max_uV) {
    122		*selector = 0;
    123		return 0;
    124	} else {
    125		return -EINVAL;
    126	}
    127}
    128EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage);
    129
    130const struct regulator_ops mc13xxx_fixed_regulator_ops = {
    131	.enable = mc13xxx_regulator_enable,
    132	.disable = mc13xxx_regulator_disable,
    133	.is_enabled = mc13xxx_regulator_is_enabled,
    134	.list_voltage = regulator_list_voltage_table,
    135	.set_voltage = mc13xxx_fixed_regulator_set_voltage,
    136};
    137EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops);
    138
    139#ifdef CONFIG_OF
    140int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
    141{
    142	struct device_node *parent;
    143	int num;
    144
    145	if (!pdev->dev.parent->of_node)
    146		return -ENODEV;
    147
    148	parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
    149	if (!parent)
    150		return -ENODEV;
    151
    152	num = of_get_child_count(parent);
    153	of_node_put(parent);
    154	return num;
    155}
    156EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
    157
    158struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
    159	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
    160	int num_regulators)
    161{
    162	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
    163	struct mc13xxx_regulator_init_data *data, *p;
    164	struct device_node *parent, *child;
    165	int i, parsed = 0;
    166
    167	if (!pdev->dev.parent->of_node)
    168		return NULL;
    169
    170	parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
    171	if (!parent)
    172		return NULL;
    173
    174	data = devm_kcalloc(&pdev->dev, priv->num_regulators, sizeof(*data),
    175			    GFP_KERNEL);
    176	if (!data) {
    177		of_node_put(parent);
    178		return NULL;
    179	}
    180
    181	p = data;
    182
    183	for_each_child_of_node(parent, child) {
    184		int found = 0;
    185
    186		for (i = 0; i < num_regulators; i++) {
    187			if (!regulators[i].desc.name)
    188				continue;
    189			if (of_node_name_eq(child,
    190					 regulators[i].desc.name)) {
    191				p->id = i;
    192				p->init_data = of_get_regulator_init_data(
    193							&pdev->dev, child,
    194							&regulators[i].desc);
    195				p->node = child;
    196				p++;
    197
    198				parsed++;
    199				found = 1;
    200				break;
    201			}
    202		}
    203
    204		if (!found)
    205			dev_warn(&pdev->dev,
    206				 "Unknown regulator: %pOFn\n", child);
    207	}
    208	of_node_put(parent);
    209
    210	priv->num_regulators = parsed;
    211
    212	return data;
    213}
    214EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt);
    215#endif
    216
    217MODULE_LICENSE("GPL v2");
    218MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
    219MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
    220MODULE_ALIAS("mc13xxx-regulator-core");