162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* NXP PCF50633 PMIC Driver 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * (C) 2006-2008 by Openmoko, Inc. 562306a36Sopenharmony_ci * Author: Balaji Rao <balajirrao@openmoko.org> 662306a36Sopenharmony_ci * All rights reserved. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Broken down from monstrous PCF50633 driver mainly by 962306a36Sopenharmony_ci * Harald Welte and Andy Green and Werner Almesberger 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/init.h> 1562306a36Sopenharmony_ci#include <linux/device.h> 1662306a36Sopenharmony_ci#include <linux/err.h> 1762306a36Sopenharmony_ci#include <linux/platform_device.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <linux/mfd/pcf50633/core.h> 2062306a36Sopenharmony_ci#include <linux/mfd/pcf50633/pmic.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \ 2362306a36Sopenharmony_ci { \ 2462306a36Sopenharmony_ci .name = _name, \ 2562306a36Sopenharmony_ci .id = PCF50633_REGULATOR_##_id, \ 2662306a36Sopenharmony_ci .ops = &pcf50633_regulator_ops, \ 2762306a36Sopenharmony_ci .n_voltages = _n, \ 2862306a36Sopenharmony_ci .min_uV = _min_uV, \ 2962306a36Sopenharmony_ci .uV_step = _uV_step, \ 3062306a36Sopenharmony_ci .linear_min_sel = _min_sel, \ 3162306a36Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3262306a36Sopenharmony_ci .owner = THIS_MODULE, \ 3362306a36Sopenharmony_ci .vsel_reg = PCF50633_REG_##_id##OUT, \ 3462306a36Sopenharmony_ci .vsel_mask = 0xff, \ 3562306a36Sopenharmony_ci .enable_reg = PCF50633_REG_##_id##OUT + 1, \ 3662306a36Sopenharmony_ci .enable_mask = PCF50633_REGULATOR_ON, \ 3762306a36Sopenharmony_ci } 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic const struct regulator_ops pcf50633_regulator_ops = { 4062306a36Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 4162306a36Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 4262306a36Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 4362306a36Sopenharmony_ci .map_voltage = regulator_map_voltage_linear, 4462306a36Sopenharmony_ci .enable = regulator_enable_regmap, 4562306a36Sopenharmony_ci .disable = regulator_disable_regmap, 4662306a36Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic const struct regulator_desc regulators[] = { 5062306a36Sopenharmony_ci [PCF50633_REGULATOR_AUTO] = 5162306a36Sopenharmony_ci PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128), 5262306a36Sopenharmony_ci [PCF50633_REGULATOR_DOWN1] = 5362306a36Sopenharmony_ci PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96), 5462306a36Sopenharmony_ci [PCF50633_REGULATOR_DOWN2] = 5562306a36Sopenharmony_ci PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96), 5662306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO1] = 5762306a36Sopenharmony_ci PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28), 5862306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO2] = 5962306a36Sopenharmony_ci PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28), 6062306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO3] = 6162306a36Sopenharmony_ci PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28), 6262306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO4] = 6362306a36Sopenharmony_ci PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28), 6462306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO5] = 6562306a36Sopenharmony_ci PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28), 6662306a36Sopenharmony_ci [PCF50633_REGULATOR_LDO6] = 6762306a36Sopenharmony_ci PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28), 6862306a36Sopenharmony_ci [PCF50633_REGULATOR_HCLDO] = 6962306a36Sopenharmony_ci PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28), 7062306a36Sopenharmony_ci [PCF50633_REGULATOR_MEMLDO] = 7162306a36Sopenharmony_ci PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28), 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic int pcf50633_regulator_probe(struct platform_device *pdev) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci struct regulator_dev *rdev; 7762306a36Sopenharmony_ci struct pcf50633 *pcf; 7862306a36Sopenharmony_ci struct regulator_config config = { }; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci /* Already set by core driver */ 8162306a36Sopenharmony_ci pcf = dev_to_pcf50633(pdev->dev.parent); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci config.dev = &pdev->dev; 8462306a36Sopenharmony_ci config.init_data = dev_get_platdata(&pdev->dev); 8562306a36Sopenharmony_ci config.driver_data = pcf; 8662306a36Sopenharmony_ci config.regmap = pcf->regmap; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci rdev = devm_regulator_register(&pdev->dev, ®ulators[pdev->id], 8962306a36Sopenharmony_ci &config); 9062306a36Sopenharmony_ci if (IS_ERR(rdev)) 9162306a36Sopenharmony_ci return PTR_ERR(rdev); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci platform_set_drvdata(pdev, rdev); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci if (pcf->pdata->regulator_registered) 9662306a36Sopenharmony_ci pcf->pdata->regulator_registered(pcf, pdev->id); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci return 0; 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic struct platform_driver pcf50633_regulator_driver = { 10262306a36Sopenharmony_ci .driver = { 10362306a36Sopenharmony_ci .name = "pcf50633-regulator", 10462306a36Sopenharmony_ci .probe_type = PROBE_PREFER_ASYNCHRONOUS, 10562306a36Sopenharmony_ci }, 10662306a36Sopenharmony_ci .probe = pcf50633_regulator_probe, 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic int __init pcf50633_regulator_init(void) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci return platform_driver_register(&pcf50633_regulator_driver); 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_cisubsys_initcall(pcf50633_regulator_init); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistatic void __exit pcf50633_regulator_exit(void) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci platform_driver_unregister(&pcf50633_regulator_driver); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_cimodule_exit(pcf50633_regulator_exit); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciMODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); 12262306a36Sopenharmony_ciMODULE_DESCRIPTION("PCF50633 regulator driver"); 12362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 12462306a36Sopenharmony_ciMODULE_ALIAS("platform:pcf50633-regulator"); 125