Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * PCAP2 Regulator Driver
0004  *
0005  * Copyright (c) 2009 Daniel Ribeiro <drwyrm@gmail.com>
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/init.h>
0011 #include <linux/err.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/regulator/driver.h>
0014 #include <linux/regulator/machine.h>
0015 #include <linux/mfd/ezx-pcap.h>
0016 
0017 static const unsigned int V1_table[] = {
0018     2775000, 1275000, 1600000, 1725000, 1825000, 1925000, 2075000, 2275000,
0019 };
0020 
0021 static const unsigned int V2_table[] = {
0022     2500000, 2775000,
0023 };
0024 
0025 static const unsigned int V3_table[] = {
0026     1075000, 1275000, 1550000, 1725000, 1876000, 1950000, 2075000, 2275000,
0027 };
0028 
0029 static const unsigned int V4_table[] = {
0030     1275000, 1550000, 1725000, 1875000, 1950000, 2075000, 2275000, 2775000,
0031 };
0032 
0033 static const unsigned int V5_table[] = {
0034     1875000, 2275000, 2475000, 2775000,
0035 };
0036 
0037 static const unsigned int V6_table[] = {
0038     2475000, 2775000,
0039 };
0040 
0041 static const unsigned int V7_table[] = {
0042     1875000, 2775000,
0043 };
0044 
0045 #define V8_table V4_table
0046 
0047 static const unsigned int V9_table[] = {
0048     1575000, 1875000, 2475000, 2775000,
0049 };
0050 
0051 static const unsigned int V10_table[] = {
0052     5000000,
0053 };
0054 
0055 static const unsigned int VAUX1_table[] = {
0056     1875000, 2475000, 2775000, 3000000,
0057 };
0058 
0059 #define VAUX2_table VAUX1_table
0060 
0061 static const unsigned int VAUX3_table[] = {
0062     1200000, 1200000, 1200000, 1200000, 1400000, 1600000, 1800000, 2000000,
0063     2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000,
0064 };
0065 
0066 static const unsigned int VAUX4_table[] = {
0067     1800000, 1800000, 3000000, 5000000,
0068 };
0069 
0070 static const unsigned int VSIM_table[] = {
0071     1875000, 3000000,
0072 };
0073 
0074 static const unsigned int VSIM2_table[] = {
0075     1875000,
0076 };
0077 
0078 static const unsigned int VVIB_table[] = {
0079     1300000, 1800000, 2000000, 3000000,
0080 };
0081 
0082 static const unsigned int SW1_table[] = {
0083      900000,  950000, 1000000, 1050000, 1100000, 1150000, 1200000, 1250000,
0084     1300000, 1350000, 1400000, 1450000, 1500000, 1600000, 1875000, 2250000,
0085 };
0086 
0087 #define SW2_table SW1_table
0088 
0089 struct pcap_regulator {
0090     const u8 reg;
0091     const u8 en;
0092     const u8 index;
0093     const u8 stby;
0094     const u8 lowpwr;
0095 };
0096 
0097 #define NA 0xff
0098 
0099 #define VREG_INFO(_vreg, _reg, _en, _index, _stby, _lowpwr)     \
0100     [_vreg] = {                         \
0101         .reg        = _reg,                 \
0102         .en     = _en,                  \
0103         .index      = _index,               \
0104         .stby       = _stby,                \
0105         .lowpwr     = _lowpwr,              \
0106     }
0107 
0108 static struct pcap_regulator vreg_table[] = {
0109     VREG_INFO(V1,    PCAP_REG_VREG1,   1,  2,  18, 0),
0110     VREG_INFO(V2,    PCAP_REG_VREG1,   5,  6,  19, 22),
0111     VREG_INFO(V3,    PCAP_REG_VREG1,   7,  8,  20, 23),
0112     VREG_INFO(V4,    PCAP_REG_VREG1,   11, 12, 21, 24),
0113     /* V5 STBY and LOWPWR are on PCAP_REG_VREG2 */
0114     VREG_INFO(V5,    PCAP_REG_VREG1,   15, 16, 12, 19),
0115 
0116     VREG_INFO(V6,    PCAP_REG_VREG2,   1,  2,  14, 20),
0117     VREG_INFO(V7,    PCAP_REG_VREG2,   3,  4,  15, 21),
0118     VREG_INFO(V8,    PCAP_REG_VREG2,   5,  6,  16, 22),
0119     VREG_INFO(V9,    PCAP_REG_VREG2,   9,  10, 17, 23),
0120     VREG_INFO(V10,   PCAP_REG_VREG2,   10, NA, 18, 24),
0121 
0122     VREG_INFO(VAUX1, PCAP_REG_AUXVREG, 1,  2,  22, 23),
0123     /* VAUX2 ... VSIM2 STBY and LOWPWR are on PCAP_REG_LOWPWR */
0124     VREG_INFO(VAUX2, PCAP_REG_AUXVREG, 4,  5,  0,  1),
0125     VREG_INFO(VAUX3, PCAP_REG_AUXVREG, 7,  8,  2,  3),
0126     VREG_INFO(VAUX4, PCAP_REG_AUXVREG, 12, 13, 4,  5),
0127     VREG_INFO(VSIM,  PCAP_REG_AUXVREG, 17, 18, NA, 6),
0128     VREG_INFO(VSIM2, PCAP_REG_AUXVREG, 16, NA, NA, 7),
0129     VREG_INFO(VVIB,  PCAP_REG_AUXVREG, 19, 20, NA, NA),
0130 
0131     VREG_INFO(SW1,   PCAP_REG_SWCTRL,  1,  2,  NA, NA),
0132     VREG_INFO(SW2,   PCAP_REG_SWCTRL,  6,  7,  NA, NA),
0133     /* SW3 STBY is on PCAP_REG_AUXVREG */
0134     VREG_INFO(SW3,   PCAP_REG_SWCTRL,  11, 12, 24, NA),
0135 
0136     /* SWxS used to control SWx voltage on standby */
0137 /*  VREG_INFO(SW1S,  PCAP_REG_LOWPWR,  NA, 12, NA, NA),
0138     VREG_INFO(SW2S,  PCAP_REG_LOWPWR,  NA, 20, NA, NA), */
0139 };
0140 
0141 static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev,
0142                       unsigned selector)
0143 {
0144     struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
0145     void *pcap = rdev_get_drvdata(rdev);
0146 
0147     /* the regulator doesn't support voltage switching */
0148     if (rdev->desc->n_voltages == 1)
0149         return -EINVAL;
0150 
0151     return ezx_pcap_set_bits(pcap, vreg->reg,
0152                  (rdev->desc->n_voltages - 1) << vreg->index,
0153                  selector << vreg->index);
0154 }
0155 
0156 static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev)
0157 {
0158     struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
0159     void *pcap = rdev_get_drvdata(rdev);
0160     u32 tmp;
0161 
0162     if (rdev->desc->n_voltages == 1)
0163         return 0;
0164 
0165     ezx_pcap_read(pcap, vreg->reg, &tmp);
0166     tmp = ((tmp >> vreg->index) & (rdev->desc->n_voltages - 1));
0167     return tmp;
0168 }
0169 
0170 static int pcap_regulator_enable(struct regulator_dev *rdev)
0171 {
0172     struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
0173     void *pcap = rdev_get_drvdata(rdev);
0174 
0175     if (vreg->en == NA)
0176         return -EINVAL;
0177 
0178     return ezx_pcap_set_bits(pcap, vreg->reg, 1 << vreg->en, 1 << vreg->en);
0179 }
0180 
0181 static int pcap_regulator_disable(struct regulator_dev *rdev)
0182 {
0183     struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
0184     void *pcap = rdev_get_drvdata(rdev);
0185 
0186     if (vreg->en == NA)
0187         return -EINVAL;
0188 
0189     return ezx_pcap_set_bits(pcap, vreg->reg, 1 << vreg->en, 0);
0190 }
0191 
0192 static int pcap_regulator_is_enabled(struct regulator_dev *rdev)
0193 {
0194     struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
0195     void *pcap = rdev_get_drvdata(rdev);
0196     u32 tmp;
0197 
0198     if (vreg->en == NA)
0199         return -EINVAL;
0200 
0201     ezx_pcap_read(pcap, vreg->reg, &tmp);
0202     return (tmp >> vreg->en) & 1;
0203 }
0204 
0205 static const struct regulator_ops pcap_regulator_ops = {
0206     .list_voltage   = regulator_list_voltage_table,
0207     .set_voltage_sel = pcap_regulator_set_voltage_sel,
0208     .get_voltage_sel = pcap_regulator_get_voltage_sel,
0209     .enable     = pcap_regulator_enable,
0210     .disable    = pcap_regulator_disable,
0211     .is_enabled = pcap_regulator_is_enabled,
0212 };
0213 
0214 #define VREG(_vreg)                     \
0215     [_vreg] = {                     \
0216         .name       = #_vreg,           \
0217         .id     = _vreg,            \
0218         .n_voltages = ARRAY_SIZE(_vreg##_table),    \
0219         .volt_table = _vreg##_table,        \
0220         .ops        = &pcap_regulator_ops,      \
0221         .type       = REGULATOR_VOLTAGE,        \
0222         .owner      = THIS_MODULE,          \
0223     }
0224 
0225 static const struct regulator_desc pcap_regulators[] = {
0226     VREG(V1), VREG(V2), VREG(V3), VREG(V4), VREG(V5), VREG(V6), VREG(V7),
0227     VREG(V8), VREG(V9), VREG(V10), VREG(VAUX1), VREG(VAUX2), VREG(VAUX3),
0228     VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2),
0229 };
0230 
0231 static int pcap_regulator_probe(struct platform_device *pdev)
0232 {
0233     struct regulator_dev *rdev;
0234     void *pcap = dev_get_drvdata(pdev->dev.parent);
0235     struct regulator_config config = { };
0236 
0237     config.dev = &pdev->dev;
0238     config.init_data = dev_get_platdata(&pdev->dev);
0239     config.driver_data = pcap;
0240 
0241     rdev = devm_regulator_register(&pdev->dev, &pcap_regulators[pdev->id],
0242                        &config);
0243     if (IS_ERR(rdev))
0244         return PTR_ERR(rdev);
0245 
0246     platform_set_drvdata(pdev, rdev);
0247 
0248     return 0;
0249 }
0250 
0251 static struct platform_driver pcap_regulator_driver = {
0252     .driver = {
0253         .name   = "pcap-regulator",
0254     },
0255     .probe  = pcap_regulator_probe,
0256 };
0257 
0258 static int __init pcap_regulator_init(void)
0259 {
0260     return platform_driver_register(&pcap_regulator_driver);
0261 }
0262 
0263 static void __exit pcap_regulator_exit(void)
0264 {
0265     platform_driver_unregister(&pcap_regulator_driver);
0266 }
0267 
0268 subsys_initcall(pcap_regulator_init);
0269 module_exit(pcap_regulator_exit);
0270 
0271 MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
0272 MODULE_DESCRIPTION("PCAP2 Regulator Driver");
0273 MODULE_LICENSE("GPL");