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 = dev_get_platdata(&pdev->dev); 90 config.driver_data = pcf; 91 config.regmap = pcf->regmap; 92 93 rdev = devm_regulator_register(&pdev->dev, ®ulators[pdev->id], 94 &config); 95 if (IS_ERR(rdev)) 96 return PTR_ERR(rdev); 97 98 platform_set_drvdata(pdev, rdev); 99 100 if (pcf->pdata->regulator_registered) 101 pcf->pdata->regulator_registered(pcf, pdev->id); 102 103 return 0; 104} 105 106static struct platform_driver pcf50633_regulator_driver = { 107 .driver = { 108 .name = "pcf50633-regulator", 109 }, 110 .probe = pcf50633_regulator_probe, 111}; 112 113static int __init pcf50633_regulator_init(void) 114{ 115 return platform_driver_register(&pcf50633_regulator_driver); 116} 117subsys_initcall(pcf50633_regulator_init); 118 119static void __exit pcf50633_regulator_exit(void) 120{ 121 platform_driver_unregister(&pcf50633_regulator_driver); 122} 123module_exit(pcf50633_regulator_exit); 124 125MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); 126MODULE_DESCRIPTION("PCF50633 regulator driver"); 127MODULE_LICENSE("GPL"); 128MODULE_ALIAS("platform:pcf50633-regulator"); 129