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