linux/drivers/regulator/pcf50633-regulator.c
<<
>>
Prefs
   1/* NXP PCF50633 PMIC Driver
   2 *
   3 * (C) 2006-2008 by Openmoko, Inc.
   4 * Author: Balaji Rao <balajirrao@openmoko.org>
   5 * All rights reserved.
   6 *
   7 * Broken down from monstrous PCF50633 driver mainly by
   8 * Harald Welte and Andy Green and Werner Almesberger
   9 *
  10 *  This program is free software; you can redistribute  it and/or modify it
  11 *  under  the terms of  the GNU General  Public License as published by the
  12 *  Free Software Foundation;  either version 2 of the  License, or (at your
  13 *  option) any later version.
  14 *
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/init.h>
  20#include <linux/device.h>
  21#include <linux/err.h>
  22#include <linux/platform_device.h>
  23
  24#include <linux/mfd/pcf50633/core.h>
  25#include <linux/mfd/pcf50633/pmic.h>
  26
  27#define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \
  28        {                                                       \
  29                .name = _name,                                  \
  30                .id = PCF50633_REGULATOR_##_id,                 \
  31                .ops = &pcf50633_regulator_ops,                 \
  32                .n_voltages = _n,                               \
  33                .min_uV = _min_uV,                              \
  34                .uV_step = _uV_step,                            \
  35                .linear_min_sel = _min_sel,                     \
  36                .type = REGULATOR_VOLTAGE,                      \
  37                .owner = THIS_MODULE,                           \
  38                .vsel_reg = PCF50633_REG_##_id##OUT,            \
  39                .vsel_mask = 0xff,                              \
  40                .enable_reg = PCF50633_REG_##_id##OUT + 1,      \
  41                .enable_mask = PCF50633_REGULATOR_ON,           \
  42        }
  43
  44static struct regulator_ops pcf50633_regulator_ops = {
  45        .set_voltage_sel = regulator_set_voltage_sel_regmap,
  46        .get_voltage_sel = regulator_get_voltage_sel_regmap,
  47        .list_voltage = regulator_list_voltage_linear,
  48        .map_voltage = regulator_map_voltage_linear,
  49        .enable = regulator_enable_regmap,
  50        .disable = regulator_disable_regmap,
  51        .is_enabled = regulator_is_enabled_regmap,
  52};
  53
  54static const struct regulator_desc regulators[] = {
  55        [PCF50633_REGULATOR_AUTO] =
  56                PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128),
  57        [PCF50633_REGULATOR_DOWN1] =
  58                PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96),
  59        [PCF50633_REGULATOR_DOWN2] =
  60                PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96),
  61        [PCF50633_REGULATOR_LDO1] =
  62                PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28),
  63        [PCF50633_REGULATOR_LDO2] =
  64                PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28),
  65        [PCF50633_REGULATOR_LDO3] =
  66                PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28),
  67        [PCF50633_REGULATOR_LDO4] =
  68                PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28),
  69        [PCF50633_REGULATOR_LDO5] =
  70                PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28),
  71        [PCF50633_REGULATOR_LDO6] =
  72                PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28),
  73        [PCF50633_REGULATOR_HCLDO] =
  74                PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28),
  75        [PCF50633_REGULATOR_MEMLDO] =
  76                PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28),
  77};
  78
  79static int pcf50633_regulator_probe(struct platform_device *pdev)
  80{
  81        struct regulator_dev *rdev;
  82        struct pcf50633 *pcf;
  83        struct regulator_config config = { };
  84
  85        /* Already set by core driver */
  86        pcf = dev_to_pcf50633(pdev->dev.parent);
  87
  88        config.dev = &pdev->dev;
  89        config.init_data = pdev->dev.platform_data;
  90        config.driver_data = pcf;
  91        config.regmap = pcf->regmap;
  92
  93        rdev = regulator_register(&regulators[pdev->id], &config);
  94        if (IS_ERR(rdev))
  95                return PTR_ERR(rdev);
  96
  97        platform_set_drvdata(pdev, rdev);
  98
  99        if (pcf->pdata->regulator_registered)
 100                pcf->pdata->regulator_registered(pcf, pdev->id);
 101
 102        return 0;
 103}
 104
 105static int pcf50633_regulator_remove(struct platform_device *pdev)
 106{
 107        struct regulator_dev *rdev = platform_get_drvdata(pdev);
 108
 109        platform_set_drvdata(pdev, NULL);
 110        regulator_unregister(rdev);
 111
 112        return 0;
 113}
 114
 115static struct platform_driver pcf50633_regulator_driver = {
 116        .driver = {
 117                .name = "pcf50633-regltr",
 118        },
 119        .probe = pcf50633_regulator_probe,
 120        .remove = pcf50633_regulator_remove,
 121};
 122
 123static int __init pcf50633_regulator_init(void)
 124{
 125        return platform_driver_register(&pcf50633_regulator_driver);
 126}
 127subsys_initcall(pcf50633_regulator_init);
 128
 129static void __exit pcf50633_regulator_exit(void)
 130{
 131        platform_driver_unregister(&pcf50633_regulator_driver);
 132}
 133module_exit(pcf50633_regulator_exit);
 134
 135MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
 136MODULE_DESCRIPTION("PCF50633 regulator driver");
 137MODULE_LICENSE("GPL");
 138MODULE_ALIAS("platform:pcf50633-regulator");
 139