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        int ret;
  37
  38        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
  39
  40        mc13xxx_lock(priv->mc13xxx);
  41        ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
  42                        mc13xxx_regulators[id].enable_bit,
  43                        mc13xxx_regulators[id].enable_bit);
  44        mc13xxx_unlock(priv->mc13xxx);
  45
  46        return ret;
  47}
  48
  49static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
  50{
  51        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
  52        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
  53        int id = rdev_get_id(rdev);
  54        int ret;
  55
  56        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
  57
  58        mc13xxx_lock(priv->mc13xxx);
  59        ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
  60                        mc13xxx_regulators[id].enable_bit, 0);
  61        mc13xxx_unlock(priv->mc13xxx);
  62
  63        return ret;
  64}
  65
  66static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
  67{
  68        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
  69        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
  70        int ret, id = rdev_get_id(rdev);
  71        unsigned int val;
  72
  73        mc13xxx_lock(priv->mc13xxx);
  74        ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
  75        mc13xxx_unlock(priv->mc13xxx);
  76
  77        if (ret)
  78                return ret;
  79
  80        return (val & mc13xxx_regulators[id].enable_bit) != 0;
  81}
  82
  83int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
  84                                                unsigned selector)
  85{
  86        int id = rdev_get_id(rdev);
  87        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
  88        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
  89
  90        if (selector >= mc13xxx_regulators[id].desc.n_voltages)
  91                return -EINVAL;
  92
  93        return mc13xxx_regulators[id].voltages[selector];
  94}
  95EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage);
  96
  97int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
  98                                                int min_uV, int max_uV)
  99{
 100        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 101        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
 102        int reg_id = rdev_get_id(rdev);
 103        int i;
 104        int bestmatch;
 105        int bestindex;
 106
 107        /*
 108         * Locate the minimum voltage fitting the criteria on
 109         * this regulator. The switchable voltages are not
 110         * in strict falling order so we need to check them
 111         * all for the best match.
 112         */
 113        bestmatch = INT_MAX;
 114        bestindex = -1;
 115        for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) {
 116                if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV &&
 117                    mc13xxx_regulators[reg_id].voltages[i] < bestmatch) {
 118                        bestmatch = mc13xxx_regulators[reg_id].voltages[i];
 119                        bestindex = i;
 120                }
 121        }
 122
 123        if (bestindex < 0 || bestmatch > max_uV) {
 124                dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
 125                                min_uV, max_uV);
 126                return -EINVAL;
 127        }
 128        return bestindex;
 129}
 130EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index);
 131
 132static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
 133                int max_uV, unsigned *selector)
 134{
 135        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 136        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
 137        int value, id = rdev_get_id(rdev);
 138        int ret;
 139
 140        dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
 141                __func__, id, min_uV, max_uV);
 142
 143        /* Find the best index */
 144        value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
 145        dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
 146        if (value < 0)
 147                return value;
 148
 149        mc13xxx_lock(priv->mc13xxx);
 150        ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
 151                        mc13xxx_regulators[id].vsel_mask,
 152                        value << mc13xxx_regulators[id].vsel_shift);
 153        mc13xxx_unlock(priv->mc13xxx);
 154
 155        return ret;
 156}
 157
 158static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
 159{
 160        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 161        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
 162        int ret, id = rdev_get_id(rdev);
 163        unsigned int val;
 164
 165        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 166
 167        mc13xxx_lock(priv->mc13xxx);
 168        ret = mc13xxx_reg_read(priv->mc13xxx,
 169                                mc13xxx_regulators[id].vsel_reg, &val);
 170        mc13xxx_unlock(priv->mc13xxx);
 171
 172        if (ret)
 173                return ret;
 174
 175        val = (val & mc13xxx_regulators[id].vsel_mask)
 176                >> mc13xxx_regulators[id].vsel_shift;
 177
 178        dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
 179
 180        BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages);
 181
 182        return mc13xxx_regulators[id].voltages[val];
 183}
 184
 185struct regulator_ops mc13xxx_regulator_ops = {
 186        .enable = mc13xxx_regulator_enable,
 187        .disable = mc13xxx_regulator_disable,
 188        .is_enabled = mc13xxx_regulator_is_enabled,
 189        .list_voltage = mc13xxx_regulator_list_voltage,
 190        .set_voltage = mc13xxx_regulator_set_voltage,
 191        .get_voltage = mc13xxx_regulator_get_voltage,
 192};
 193EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops);
 194
 195int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
 196               int max_uV, unsigned *selector)
 197{
 198        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 199        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
 200        int id = rdev_get_id(rdev);
 201
 202        dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
 203                __func__, id, min_uV, max_uV);
 204
 205        if (min_uV >= mc13xxx_regulators[id].voltages[0] &&
 206            max_uV <= mc13xxx_regulators[id].voltages[0])
 207                return 0;
 208        else
 209                return -EINVAL;
 210}
 211EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage);
 212
 213int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev)
 214{
 215        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
 216        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
 217        int id = rdev_get_id(rdev);
 218
 219        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 220
 221        return mc13xxx_regulators[id].voltages[0];
 222}
 223EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage);
 224
 225struct regulator_ops mc13xxx_fixed_regulator_ops = {
 226        .enable = mc13xxx_regulator_enable,
 227        .disable = mc13xxx_regulator_disable,
 228        .is_enabled = mc13xxx_regulator_is_enabled,
 229        .list_voltage = mc13xxx_regulator_list_voltage,
 230        .set_voltage = mc13xxx_fixed_regulator_set_voltage,
 231        .get_voltage = mc13xxx_fixed_regulator_get_voltage,
 232};
 233EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops);
 234
 235int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev)
 236{
 237        return 1;
 238}
 239EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled);
 240
 241#ifdef CONFIG_OF
 242int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
 243{
 244        struct device_node *parent, *child;
 245        int num = 0;
 246
 247        of_node_get(pdev->dev.parent->of_node);
 248        parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
 249        if (!parent)
 250                return -ENODEV;
 251
 252        for_each_child_of_node(parent, child)
 253                num++;
 254
 255        return num;
 256}
 257EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
 258
 259struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
 260        struct platform_device *pdev, struct mc13xxx_regulator *regulators,
 261        int num_regulators)
 262{
 263        struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
 264        struct mc13xxx_regulator_init_data *data, *p;
 265        struct device_node *parent, *child;
 266        int i;
 267
 268        of_node_get(pdev->dev.parent->of_node);
 269        parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
 270        if (!parent)
 271                return NULL;
 272
 273        data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators,
 274                            GFP_KERNEL);
 275        if (!data)
 276                return NULL;
 277        p = data;
 278
 279        for_each_child_of_node(parent, child) {
 280                for (i = 0; i < num_regulators; i++) {
 281                        if (!of_node_cmp(child->name,
 282                                         regulators[i].desc.name)) {
 283                                p->id = i;
 284                                p->init_data = of_get_regulator_init_data(
 285                                                        &pdev->dev, child);
 286                                p->node = child;
 287                                p++;
 288                                break;
 289                        }
 290                }
 291        }
 292
 293        return data;
 294}
 295EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt);
 296#endif
 297
 298MODULE_LICENSE("GPL v2");
 299MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
 300MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
 301MODULE_ALIAS("mc13xxx-regulator-core");
 302
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.