18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Regulator driver for Ricoh RN5T618 PMIC 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/mfd/rn5t618.h> 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/of.h> 118c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 128c2ecf20Sopenharmony_ci#include <linux/regmap.h> 138c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h> 148c2ecf20Sopenharmony_ci#include <linux/regulator/of_regulator.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic const struct regulator_ops rn5t618_reg_ops = { 178c2ecf20Sopenharmony_ci .enable = regulator_enable_regmap, 188c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 198c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 208c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 218c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 228c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define REG(rid, ereg, emask, vreg, vmask, min, max, step) \ 268c2ecf20Sopenharmony_ci { \ 278c2ecf20Sopenharmony_ci .name = #rid, \ 288c2ecf20Sopenharmony_ci .of_match = of_match_ptr(#rid), \ 298c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 308c2ecf20Sopenharmony_ci .id = RN5T618_##rid, \ 318c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 328c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 338c2ecf20Sopenharmony_ci .ops = &rn5t618_reg_ops, \ 348c2ecf20Sopenharmony_ci .n_voltages = ((max) - (min)) / (step) + 1, \ 358c2ecf20Sopenharmony_ci .min_uV = (min), \ 368c2ecf20Sopenharmony_ci .uV_step = (step), \ 378c2ecf20Sopenharmony_ci .enable_reg = RN5T618_##ereg, \ 388c2ecf20Sopenharmony_ci .enable_mask = (emask), \ 398c2ecf20Sopenharmony_ci .vsel_reg = RN5T618_##vreg, \ 408c2ecf20Sopenharmony_ci .vsel_mask = (vmask), \ 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic const struct regulator_desc rn5t567_regulators[] = { 448c2ecf20Sopenharmony_ci /* DCDC */ 458c2ecf20Sopenharmony_ci REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), 468c2ecf20Sopenharmony_ci REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), 478c2ecf20Sopenharmony_ci REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500), 488c2ecf20Sopenharmony_ci REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500), 498c2ecf20Sopenharmony_ci /* LDO */ 508c2ecf20Sopenharmony_ci REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000), 518c2ecf20Sopenharmony_ci REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000), 528c2ecf20Sopenharmony_ci REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000), 538c2ecf20Sopenharmony_ci REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000), 548c2ecf20Sopenharmony_ci REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000), 558c2ecf20Sopenharmony_ci /* LDO RTC */ 568c2ecf20Sopenharmony_ci REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1200000, 3500000, 25000), 578c2ecf20Sopenharmony_ci REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic const struct regulator_desc rn5t618_regulators[] = { 618c2ecf20Sopenharmony_ci /* DCDC */ 628c2ecf20Sopenharmony_ci REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), 638c2ecf20Sopenharmony_ci REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), 648c2ecf20Sopenharmony_ci REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500), 658c2ecf20Sopenharmony_ci /* LDO */ 668c2ecf20Sopenharmony_ci REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000), 678c2ecf20Sopenharmony_ci REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000), 688c2ecf20Sopenharmony_ci REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000), 698c2ecf20Sopenharmony_ci REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000), 708c2ecf20Sopenharmony_ci REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000), 718c2ecf20Sopenharmony_ci /* LDO RTC */ 728c2ecf20Sopenharmony_ci REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1700000, 3500000, 25000), 738c2ecf20Sopenharmony_ci REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic const struct regulator_desc rc5t619_regulators[] = { 778c2ecf20Sopenharmony_ci /* DCDC */ 788c2ecf20Sopenharmony_ci REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), 798c2ecf20Sopenharmony_ci REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), 808c2ecf20Sopenharmony_ci REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500), 818c2ecf20Sopenharmony_ci REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500), 828c2ecf20Sopenharmony_ci REG(DCDC5, DC5CTL, BIT(0), DC5DAC, 0xff, 600000, 3500000, 12500), 838c2ecf20Sopenharmony_ci /* LDO */ 848c2ecf20Sopenharmony_ci REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000), 858c2ecf20Sopenharmony_ci REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000), 868c2ecf20Sopenharmony_ci REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 900000, 3500000, 25000), 878c2ecf20Sopenharmony_ci REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000), 888c2ecf20Sopenharmony_ci REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 600000, 3500000, 25000), 898c2ecf20Sopenharmony_ci REG(LDO6, LDOEN1, BIT(5), LDO6DAC, 0x7f, 600000, 3500000, 25000), 908c2ecf20Sopenharmony_ci REG(LDO7, LDOEN1, BIT(6), LDO7DAC, 0x7f, 900000, 3500000, 25000), 918c2ecf20Sopenharmony_ci REG(LDO8, LDOEN1, BIT(7), LDO8DAC, 0x7f, 900000, 3500000, 25000), 928c2ecf20Sopenharmony_ci REG(LDO9, LDOEN2, BIT(0), LDO9DAC, 0x7f, 900000, 3500000, 25000), 938c2ecf20Sopenharmony_ci REG(LDO10, LDOEN2, BIT(1), LDO10DAC, 0x7f, 900000, 3500000, 25000), 948c2ecf20Sopenharmony_ci /* LDO RTC */ 958c2ecf20Sopenharmony_ci REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1700000, 3500000, 25000), 968c2ecf20Sopenharmony_ci REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), 978c2ecf20Sopenharmony_ci}; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic int rn5t618_regulator_probe(struct platform_device *pdev) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); 1028c2ecf20Sopenharmony_ci struct regulator_config config = { }; 1038c2ecf20Sopenharmony_ci struct regulator_dev *rdev; 1048c2ecf20Sopenharmony_ci const struct regulator_desc *regulators; 1058c2ecf20Sopenharmony_ci int i; 1068c2ecf20Sopenharmony_ci int num_regulators = 0; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci switch (rn5t618->variant) { 1098c2ecf20Sopenharmony_ci case RN5T567: 1108c2ecf20Sopenharmony_ci regulators = rn5t567_regulators; 1118c2ecf20Sopenharmony_ci num_regulators = ARRAY_SIZE(rn5t567_regulators); 1128c2ecf20Sopenharmony_ci break; 1138c2ecf20Sopenharmony_ci case RN5T618: 1148c2ecf20Sopenharmony_ci regulators = rn5t618_regulators; 1158c2ecf20Sopenharmony_ci num_regulators = ARRAY_SIZE(rn5t618_regulators); 1168c2ecf20Sopenharmony_ci break; 1178c2ecf20Sopenharmony_ci case RC5T619: 1188c2ecf20Sopenharmony_ci regulators = rc5t619_regulators; 1198c2ecf20Sopenharmony_ci num_regulators = ARRAY_SIZE(rc5t619_regulators); 1208c2ecf20Sopenharmony_ci break; 1218c2ecf20Sopenharmony_ci default: 1228c2ecf20Sopenharmony_ci return -EINVAL; 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci config.dev = pdev->dev.parent; 1268c2ecf20Sopenharmony_ci config.regmap = rn5t618->regmap; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci for (i = 0; i < num_regulators; i++) { 1298c2ecf20Sopenharmony_ci rdev = devm_regulator_register(&pdev->dev, 1308c2ecf20Sopenharmony_ci ®ulators[i], 1318c2ecf20Sopenharmony_ci &config); 1328c2ecf20Sopenharmony_ci if (IS_ERR(rdev)) { 1338c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "failed to register %s regulator\n", 1348c2ecf20Sopenharmony_ci regulators[i].name); 1358c2ecf20Sopenharmony_ci return PTR_ERR(rdev); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci return 0; 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic struct platform_driver rn5t618_regulator_driver = { 1438c2ecf20Sopenharmony_ci .probe = rn5t618_regulator_probe, 1448c2ecf20Sopenharmony_ci .driver = { 1458c2ecf20Sopenharmony_ci .name = "rn5t618-regulator", 1468c2ecf20Sopenharmony_ci }, 1478c2ecf20Sopenharmony_ci}; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cimodule_platform_driver(rn5t618_regulator_driver); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:rn5t618-regulator"); 1528c2ecf20Sopenharmony_ciMODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); 1538c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("RN5T618 regulator driver"); 1548c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 155