linux/drivers/regulator/mc13xxx-regulator-core.c
<<
>>
Prefs
   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
 102struct 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
 130struct 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_cmp(child->name,
 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: %s\n", child->name);
 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");
 221