149610235SMike Rapoport /* 249610235SMike Rapoport * Regulator driver for TI TPS6586x 349610235SMike Rapoport * 449610235SMike Rapoport * Copyright (C) 2010 Compulab Ltd. 549610235SMike Rapoport * Author: Mike Rapoport <mike@compulab.co.il> 649610235SMike Rapoport * 749610235SMike Rapoport * Based on da903x 849610235SMike Rapoport * Copyright (C) 2006-2008 Marvell International Ltd. 949610235SMike Rapoport * Copyright (C) 2008 Compulab Ltd. 1049610235SMike Rapoport * 1149610235SMike Rapoport * This program is free software; you can redistribute it and/or modify 1249610235SMike Rapoport * it under the terms of the GNU General Public License version 2 as 1349610235SMike Rapoport * published by the Free Software Foundation. 1449610235SMike Rapoport */ 1549610235SMike Rapoport 1649610235SMike Rapoport #include <linux/kernel.h> 1765602c32SPaul Gortmaker #include <linux/module.h> 1849610235SMike Rapoport #include <linux/init.h> 1949610235SMike Rapoport #include <linux/err.h> 2064e48160SLaxman Dewangan #include <linux/of.h> 2149610235SMike Rapoport #include <linux/slab.h> 2249610235SMike Rapoport #include <linux/platform_device.h> 2349610235SMike Rapoport #include <linux/regulator/driver.h> 2449610235SMike Rapoport #include <linux/regulator/machine.h> 2564e48160SLaxman Dewangan #include <linux/regulator/of_regulator.h> 2649610235SMike Rapoport #include <linux/mfd/tps6586x.h> 2749610235SMike Rapoport 2849610235SMike Rapoport /* supply control and voltage setting */ 2949610235SMike Rapoport #define TPS6586X_SUPPLYENA 0x10 3049610235SMike Rapoport #define TPS6586X_SUPPLYENB 0x11 3149610235SMike Rapoport #define TPS6586X_SUPPLYENC 0x12 3249610235SMike Rapoport #define TPS6586X_SUPPLYEND 0x13 3349610235SMike Rapoport #define TPS6586X_SUPPLYENE 0x14 3449610235SMike Rapoport #define TPS6586X_VCC1 0x20 3549610235SMike Rapoport #define TPS6586X_VCC2 0x21 3649610235SMike Rapoport #define TPS6586X_SM1V1 0x23 3749610235SMike Rapoport #define TPS6586X_SM1V2 0x24 3849610235SMike Rapoport #define TPS6586X_SM1SL 0x25 3949610235SMike Rapoport #define TPS6586X_SM0V1 0x26 4049610235SMike Rapoport #define TPS6586X_SM0V2 0x27 4149610235SMike Rapoport #define TPS6586X_SM0SL 0x28 4249610235SMike Rapoport #define TPS6586X_LDO2AV1 0x29 4349610235SMike Rapoport #define TPS6586X_LDO2AV2 0x2A 4449610235SMike Rapoport #define TPS6586X_LDO2BV1 0x2F 4549610235SMike Rapoport #define TPS6586X_LDO2BV2 0x30 4649610235SMike Rapoport #define TPS6586X_LDO4V1 0x32 4749610235SMike Rapoport #define TPS6586X_LDO4V2 0x33 4849610235SMike Rapoport 4949610235SMike Rapoport /* converter settings */ 5049610235SMike Rapoport #define TPS6586X_SUPPLYV1 0x41 5149610235SMike Rapoport #define TPS6586X_SUPPLYV2 0x42 5249610235SMike Rapoport #define TPS6586X_SUPPLYV3 0x43 5349610235SMike Rapoport #define TPS6586X_SUPPLYV4 0x44 5449610235SMike Rapoport #define TPS6586X_SUPPLYV5 0x45 5549610235SMike Rapoport #define TPS6586X_SUPPLYV6 0x46 5649610235SMike Rapoport #define TPS6586X_SMODE1 0x47 5749610235SMike Rapoport #define TPS6586X_SMODE2 0x48 5849610235SMike Rapoport 5949610235SMike Rapoport struct tps6586x_regulator { 6049610235SMike Rapoport struct regulator_desc desc; 6149610235SMike Rapoport 6249610235SMike Rapoport int enable_bit[2]; 6349610235SMike Rapoport int enable_reg[2]; 6449610235SMike Rapoport 6549610235SMike Rapoport /* for DVM regulators */ 6649610235SMike Rapoport int go_reg; 6749610235SMike Rapoport int go_bit; 6849610235SMike Rapoport }; 6949610235SMike Rapoport 7049610235SMike Rapoport static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev) 7149610235SMike Rapoport { 727c7fac30SLaxman Dewangan return rdev_get_dev(rdev)->parent; 7349610235SMike Rapoport } 7449610235SMike Rapoport 75eed06517SAxel Lin static int tps6586x_set_voltage_sel(struct regulator_dev *rdev, 76eed06517SAxel Lin unsigned selector) 7749610235SMike Rapoport { 7849610235SMike Rapoport struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); 7949610235SMike Rapoport struct device *parent = to_tps6586x_dev(rdev); 80eed06517SAxel Lin int ret, val, rid = rdev_get_id(rdev); 81eed06517SAxel Lin uint8_t mask; 8249610235SMike Rapoport 837c7475c0SAxel Lin val = selector << (ffs(rdev->desc->vsel_mask) - 1); 847c7475c0SAxel Lin mask = rdev->desc->vsel_mask; 85eed06517SAxel Lin 867c7475c0SAxel Lin ret = tps6586x_update(parent, rdev->desc->vsel_reg, val, mask); 87eed06517SAxel Lin if (ret) 88eed06517SAxel Lin return ret; 89eed06517SAxel Lin 90eed06517SAxel Lin /* Update go bit for DVM regulators */ 91eed06517SAxel Lin switch (rid) { 92eed06517SAxel Lin case TPS6586X_ID_LDO_2: 93eed06517SAxel Lin case TPS6586X_ID_LDO_4: 94eed06517SAxel Lin case TPS6586X_ID_SM_0: 95eed06517SAxel Lin case TPS6586X_ID_SM_1: 96eed06517SAxel Lin ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit); 97eed06517SAxel Lin break; 98eed06517SAxel Lin } 99eed06517SAxel Lin return ret; 10049610235SMike Rapoport } 10149610235SMike Rapoport 102e1816235SAxel Lin static struct regulator_ops tps6586x_regulator_ops = { 103f4647037SAxel Lin .list_voltage = regulator_list_voltage_table, 1047c7475c0SAxel Lin .get_voltage_sel = regulator_get_voltage_sel_regmap, 105eed06517SAxel Lin .set_voltage_sel = tps6586x_set_voltage_sel, 10649610235SMike Rapoport 1077c7475c0SAxel Lin .is_enabled = regulator_is_enabled_regmap, 1087c7475c0SAxel Lin .enable = regulator_enable_regmap, 1097c7475c0SAxel Lin .disable = regulator_disable_regmap, 11049610235SMike Rapoport }; 11149610235SMike Rapoport 1129394b80cSLaxman Dewangan static struct regulator_ops tps6586x_sys_regulator_ops = { 11349610235SMike Rapoport }; 11449610235SMike Rapoport 115f4647037SAxel Lin static const unsigned int tps6586x_ldo0_voltages[] = { 116f4647037SAxel Lin 1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, 11749610235SMike Rapoport }; 11849610235SMike Rapoport 119f4647037SAxel Lin static const unsigned int tps6586x_ldo4_voltages[] = { 120f4647037SAxel Lin 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000, 121f4647037SAxel Lin 1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000, 122f4647037SAxel Lin 2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000, 123f4647037SAxel Lin 2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000, 12449610235SMike Rapoport }; 12549610235SMike Rapoport 126f4647037SAxel Lin static const unsigned int tps6586x_ldo_voltages[] = { 127f4647037SAxel Lin 1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, 1284cc2e393SGary King }; 1294cc2e393SGary King 130f4647037SAxel Lin static const unsigned int tps6586x_sm2_voltages[] = { 131f4647037SAxel Lin 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000, 132f4647037SAxel Lin 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000, 133f4647037SAxel Lin 3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000, 134f4647037SAxel Lin 4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000, 135f4647037SAxel Lin }; 136f4647037SAxel Lin 137f4647037SAxel Lin static const unsigned int tps6586x_dvm_voltages[] = { 138f4647037SAxel Lin 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, 139f4647037SAxel Lin 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, 140f4647037SAxel Lin 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 141f4647037SAxel Lin 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, 14249610235SMike Rapoport }; 14349610235SMike Rapoport 1447c7fac30SLaxman Dewangan #define TPS6586X_REGULATOR(_id, _pin_name, vdata, vreg, shift, nbits, \ 14564db657bSDanny Huang ereg0, ebit0, ereg1, ebit1) \ 14649610235SMike Rapoport .desc = { \ 1477c7fac30SLaxman Dewangan .supply_name = _pin_name, \ 14849610235SMike Rapoport .name = "REG-" #_id, \ 149e1816235SAxel Lin .ops = &tps6586x_regulator_ops, \ 15049610235SMike Rapoport .type = REGULATOR_VOLTAGE, \ 15149610235SMike Rapoport .id = TPS6586X_ID_##_id, \ 15249610235SMike Rapoport .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ 153f4647037SAxel Lin .volt_table = tps6586x_##vdata##_voltages, \ 15449610235SMike Rapoport .owner = THIS_MODULE, \ 1557c7475c0SAxel Lin .enable_reg = TPS6586X_SUPPLY##ereg0, \ 1567c7475c0SAxel Lin .enable_mask = 1 << (ebit0), \ 1577c7475c0SAxel Lin .vsel_reg = TPS6586X_##vreg, \ 1587c7475c0SAxel Lin .vsel_mask = ((1 << (nbits)) - 1) << (shift), \ 15949610235SMike Rapoport }, \ 16049610235SMike Rapoport .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ 16149610235SMike Rapoport .enable_bit[0] = (ebit0), \ 16249610235SMike Rapoport .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ 163f4647037SAxel Lin .enable_bit[1] = (ebit1), 16464db657bSDanny Huang 16564db657bSDanny Huang #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ 16664db657bSDanny Huang .go_reg = TPS6586X_##goreg, \ 16764db657bSDanny Huang .go_bit = (gobit), 16849610235SMike Rapoport 1697c7fac30SLaxman Dewangan #define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits, \ 17049610235SMike Rapoport ereg0, ebit0, ereg1, ebit1) \ 17164db657bSDanny Huang { \ 1727c7fac30SLaxman Dewangan TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits, \ 17364db657bSDanny Huang ereg0, ebit0, ereg1, ebit1) \ 17464db657bSDanny Huang } 17549610235SMike Rapoport 1767c7fac30SLaxman Dewangan #define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits, \ 17749610235SMike Rapoport ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ 17864db657bSDanny Huang { \ 1797c7fac30SLaxman Dewangan TPS6586X_REGULATOR(_id, _pname, vdata, vreg, shift, nbits, \ 18064db657bSDanny Huang ereg0, ebit0, ereg1, ebit1) \ 18164db657bSDanny Huang TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ 18264db657bSDanny Huang } 18349610235SMike Rapoport 1849394b80cSLaxman Dewangan #define TPS6586X_SYS_REGULATOR() \ 1859394b80cSLaxman Dewangan { \ 1869394b80cSLaxman Dewangan .desc = { \ 1879394b80cSLaxman Dewangan .supply_name = "sys", \ 1889394b80cSLaxman Dewangan .name = "REG-SYS", \ 1899394b80cSLaxman Dewangan .ops = &tps6586x_sys_regulator_ops, \ 1909394b80cSLaxman Dewangan .type = REGULATOR_VOLTAGE, \ 1919394b80cSLaxman Dewangan .id = TPS6586X_ID_SYS, \ 1929394b80cSLaxman Dewangan .owner = THIS_MODULE, \ 1939394b80cSLaxman Dewangan }, \ 1949394b80cSLaxman Dewangan } 1959394b80cSLaxman Dewangan 19649610235SMike Rapoport static struct tps6586x_regulator tps6586x_regulator[] = { 1979394b80cSLaxman Dewangan TPS6586X_SYS_REGULATOR(), 1987c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), 1997c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), 2009394b80cSLaxman Dewangan TPS6586X_LDO(LDO_5, "REG-SYS", ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), 2017c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), 2027c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), 2037c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), 2047c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), 2059394b80cSLaxman Dewangan TPS6586X_LDO(LDO_RTC, "REG-SYS", ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), 2067c7fac30SLaxman Dewangan TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), 2077f852e05SLaxman Dewangan TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), 20849610235SMike Rapoport 2097c7fac30SLaxman Dewangan TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, 2107c7fac30SLaxman Dewangan ENB, 3, VCC2, 6), 2117c7fac30SLaxman Dewangan TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, 2127c7fac30SLaxman Dewangan END, 3, VCC1, 6), 2137f852e05SLaxman Dewangan TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1, 2147f852e05SLaxman Dewangan ENB, 1, VCC1, 2), 2157f852e05SLaxman Dewangan TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0, 2167f852e05SLaxman Dewangan ENB, 0, VCC1, 0), 21749610235SMike Rapoport }; 21849610235SMike Rapoport 21949610235SMike Rapoport /* 22049610235SMike Rapoport * TPS6586X has 2 enable bits that are OR'ed to determine the actual 22149610235SMike Rapoport * regulator state. Clearing one of this bits allows switching 22249610235SMike Rapoport * regulator on and of with single register write. 22349610235SMike Rapoport */ 22449610235SMike Rapoport static inline int tps6586x_regulator_preinit(struct device *parent, 22549610235SMike Rapoport struct tps6586x_regulator *ri) 22649610235SMike Rapoport { 22749610235SMike Rapoport uint8_t val1, val2; 22849610235SMike Rapoport int ret; 22949610235SMike Rapoport 2301dbcf35cSDanny Huang if (ri->enable_reg[0] == ri->enable_reg[1] && 2311dbcf35cSDanny Huang ri->enable_bit[0] == ri->enable_bit[1]) 2321dbcf35cSDanny Huang return 0; 2331dbcf35cSDanny Huang 23449610235SMike Rapoport ret = tps6586x_read(parent, ri->enable_reg[0], &val1); 23549610235SMike Rapoport if (ret) 23649610235SMike Rapoport return ret; 23749610235SMike Rapoport 23849610235SMike Rapoport ret = tps6586x_read(parent, ri->enable_reg[1], &val2); 23949610235SMike Rapoport if (ret) 24049610235SMike Rapoport return ret; 24149610235SMike Rapoport 2424f586707SDanny Huang if (!(val2 & (1 << ri->enable_bit[1]))) 24349610235SMike Rapoport return 0; 24449610235SMike Rapoport 24549610235SMike Rapoport /* 24649610235SMike Rapoport * The regulator is on, but it's enabled with the bit we don't 24749610235SMike Rapoport * want to use, so we switch the enable bits 24849610235SMike Rapoport */ 2494f586707SDanny Huang if (!(val1 & (1 << ri->enable_bit[0]))) { 25049610235SMike Rapoport ret = tps6586x_set_bits(parent, ri->enable_reg[0], 25149610235SMike Rapoport 1 << ri->enable_bit[0]); 25249610235SMike Rapoport if (ret) 25349610235SMike Rapoport return ret; 25449610235SMike Rapoport } 25549610235SMike Rapoport 25649610235SMike Rapoport return tps6586x_clr_bits(parent, ri->enable_reg[1], 25749610235SMike Rapoport 1 << ri->enable_bit[1]); 25849610235SMike Rapoport } 25949610235SMike Rapoport 26064e48160SLaxman Dewangan static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev, 26164e48160SLaxman Dewangan int id, struct regulator_init_data *p) 262500c524aSXin Xie { 263500c524aSXin Xie struct device *parent = pdev->dev.parent; 264500c524aSXin Xie struct tps6586x_settings *setting = p->driver_data; 265500c524aSXin Xie uint8_t reg; 266500c524aSXin Xie 267500c524aSXin Xie if (setting == NULL) 268500c524aSXin Xie return 0; 269500c524aSXin Xie 270500c524aSXin Xie if (!(setting->slew_rate & TPS6586X_SLEW_RATE_SET)) 271500c524aSXin Xie return 0; 272500c524aSXin Xie 273500c524aSXin Xie /* only SM0 and SM1 can have the slew rate settings */ 27464e48160SLaxman Dewangan switch (id) { 275500c524aSXin Xie case TPS6586X_ID_SM_0: 276500c524aSXin Xie reg = TPS6586X_SM0SL; 277500c524aSXin Xie break; 278500c524aSXin Xie case TPS6586X_ID_SM_1: 279500c524aSXin Xie reg = TPS6586X_SM1SL; 280500c524aSXin Xie break; 281500c524aSXin Xie default: 282500c524aSXin Xie dev_warn(&pdev->dev, "Only SM0/SM1 can set slew rate\n"); 283500c524aSXin Xie return -EINVAL; 284500c524aSXin Xie } 285500c524aSXin Xie 286500c524aSXin Xie return tps6586x_write(parent, reg, 287500c524aSXin Xie setting->slew_rate & TPS6586X_SLEW_RATE_MASK); 288500c524aSXin Xie } 289500c524aSXin Xie 29049610235SMike Rapoport static inline struct tps6586x_regulator *find_regulator_info(int id) 29149610235SMike Rapoport { 29249610235SMike Rapoport struct tps6586x_regulator *ri; 29349610235SMike Rapoport int i; 29449610235SMike Rapoport 29549610235SMike Rapoport for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) { 29649610235SMike Rapoport ri = &tps6586x_regulator[i]; 29749610235SMike Rapoport if (ri->desc.id == id) 29849610235SMike Rapoport return ri; 29949610235SMike Rapoport } 30049610235SMike Rapoport return NULL; 30149610235SMike Rapoport } 30249610235SMike Rapoport 30364e48160SLaxman Dewangan #ifdef CONFIG_OF 30464e48160SLaxman Dewangan static struct of_regulator_match tps6586x_matches[] = { 30564e48160SLaxman Dewangan { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS }, 30664e48160SLaxman Dewangan { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, 30764e48160SLaxman Dewangan { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, 30864e48160SLaxman Dewangan { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, 30964e48160SLaxman Dewangan { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 }, 31064e48160SLaxman Dewangan { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 }, 31164e48160SLaxman Dewangan { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 }, 31264e48160SLaxman Dewangan { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 }, 31364e48160SLaxman Dewangan { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 }, 31464e48160SLaxman Dewangan { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 }, 31564e48160SLaxman Dewangan { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 }, 31664e48160SLaxman Dewangan { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 }, 31764e48160SLaxman Dewangan { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 }, 31864e48160SLaxman Dewangan { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 }, 31964e48160SLaxman Dewangan { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC }, 32064e48160SLaxman Dewangan }; 32164e48160SLaxman Dewangan 32264e48160SLaxman Dewangan static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( 32364e48160SLaxman Dewangan struct platform_device *pdev, 32464e48160SLaxman Dewangan struct of_regulator_match **tps6586x_reg_matches) 32564e48160SLaxman Dewangan { 32664e48160SLaxman Dewangan const unsigned int num = ARRAY_SIZE(tps6586x_matches); 32764e48160SLaxman Dewangan struct device_node *np = pdev->dev.parent->of_node; 32864e48160SLaxman Dewangan struct device_node *regs; 32964e48160SLaxman Dewangan const char *sys_rail = NULL; 33064e48160SLaxman Dewangan unsigned int i; 33164e48160SLaxman Dewangan struct tps6586x_platform_data *pdata; 33264e48160SLaxman Dewangan int err; 33364e48160SLaxman Dewangan 33464e48160SLaxman Dewangan regs = of_find_node_by_name(np, "regulators"); 33564e48160SLaxman Dewangan if (!regs) { 33664e48160SLaxman Dewangan dev_err(&pdev->dev, "regulator node not found\n"); 33764e48160SLaxman Dewangan return NULL; 33864e48160SLaxman Dewangan } 33964e48160SLaxman Dewangan 34064e48160SLaxman Dewangan err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num); 34164e48160SLaxman Dewangan if (err < 0) { 34264e48160SLaxman Dewangan dev_err(&pdev->dev, "Regulator match failed, e %d\n", err); 34364e48160SLaxman Dewangan of_node_put(regs); 34464e48160SLaxman Dewangan return NULL; 34564e48160SLaxman Dewangan } 34664e48160SLaxman Dewangan 34764e48160SLaxman Dewangan of_node_put(regs); 34864e48160SLaxman Dewangan 34964e48160SLaxman Dewangan pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 35064e48160SLaxman Dewangan if (!pdata) { 35164e48160SLaxman Dewangan dev_err(&pdev->dev, "Memory alloction failed\n"); 35264e48160SLaxman Dewangan return NULL; 35364e48160SLaxman Dewangan } 35464e48160SLaxman Dewangan 35564e48160SLaxman Dewangan for (i = 0; i < num; i++) { 35664e48160SLaxman Dewangan int id; 35764e48160SLaxman Dewangan if (!tps6586x_matches[i].init_data) 35864e48160SLaxman Dewangan continue; 35964e48160SLaxman Dewangan 36064e48160SLaxman Dewangan pdata->reg_init_data[i] = tps6586x_matches[i].init_data; 36164e48160SLaxman Dewangan id = (int)tps6586x_matches[i].driver_data; 36264e48160SLaxman Dewangan if (id == TPS6586X_ID_SYS) 36364e48160SLaxman Dewangan sys_rail = pdata->reg_init_data[i]->constraints.name; 36464e48160SLaxman Dewangan 36564e48160SLaxman Dewangan if ((id == TPS6586X_ID_LDO_5) || (id == TPS6586X_ID_LDO_RTC)) 36664e48160SLaxman Dewangan pdata->reg_init_data[i]->supply_regulator = sys_rail; 36764e48160SLaxman Dewangan } 36864e48160SLaxman Dewangan *tps6586x_reg_matches = tps6586x_matches; 36964e48160SLaxman Dewangan return pdata; 37064e48160SLaxman Dewangan } 37164e48160SLaxman Dewangan #else 37264e48160SLaxman Dewangan static struct tps6586x_platform_data *tps6586x_parse_regulator_dt( 37364e48160SLaxman Dewangan struct platform_device *pdev, 37464e48160SLaxman Dewangan struct of_regulator_match **tps6586x_reg_matches) 37564e48160SLaxman Dewangan { 37664e48160SLaxman Dewangan *tps6586x_reg_matches = NULL; 37764e48160SLaxman Dewangan return NULL; 37864e48160SLaxman Dewangan } 37964e48160SLaxman Dewangan #endif 38064e48160SLaxman Dewangan 38149610235SMike Rapoport static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) 38249610235SMike Rapoport { 38349610235SMike Rapoport struct tps6586x_regulator *ri = NULL; 384c172708dSMark Brown struct regulator_config config = { }; 38564e48160SLaxman Dewangan struct regulator_dev **rdev; 38664e48160SLaxman Dewangan struct regulator_init_data *reg_data; 38764e48160SLaxman Dewangan struct tps6586x_platform_data *pdata; 38864e48160SLaxman Dewangan struct of_regulator_match *tps6586x_reg_matches = NULL; 38964e48160SLaxman Dewangan int id; 39049610235SMike Rapoport int err; 39149610235SMike Rapoport 392*10835600SLaxman Dewangan dev_dbg(&pdev->dev, "Probing regulator\n"); 39349610235SMike Rapoport 39464e48160SLaxman Dewangan pdata = dev_get_platdata(pdev->dev.parent); 39564e48160SLaxman Dewangan if ((!pdata) && (pdev->dev.parent->of_node)) 39664e48160SLaxman Dewangan pdata = tps6586x_parse_regulator_dt(pdev, 39764e48160SLaxman Dewangan &tps6586x_reg_matches); 39864e48160SLaxman Dewangan 39964e48160SLaxman Dewangan if (!pdata) { 40064e48160SLaxman Dewangan dev_err(&pdev->dev, "Platform data not available, exiting\n"); 40164e48160SLaxman Dewangan return -ENODEV; 40264e48160SLaxman Dewangan } 40364e48160SLaxman Dewangan 40464e48160SLaxman Dewangan rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR * 40564e48160SLaxman Dewangan sizeof(*rdev), GFP_KERNEL); 40664e48160SLaxman Dewangan if (!rdev) { 40764e48160SLaxman Dewangan dev_err(&pdev->dev, "Mmemory alloc failed\n"); 40864e48160SLaxman Dewangan return -ENOMEM; 40964e48160SLaxman Dewangan } 41064e48160SLaxman Dewangan 41164e48160SLaxman Dewangan for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) { 41264e48160SLaxman Dewangan reg_data = pdata->reg_init_data[id]; 41364e48160SLaxman Dewangan 41449610235SMike Rapoport ri = find_regulator_info(id); 41564e48160SLaxman Dewangan if (!ri) { 41649610235SMike Rapoport dev_err(&pdev->dev, "invalid regulator ID specified\n"); 41764e48160SLaxman Dewangan err = -EINVAL; 41864e48160SLaxman Dewangan goto fail; 41949610235SMike Rapoport } 42049610235SMike Rapoport 42149610235SMike Rapoport err = tps6586x_regulator_preinit(pdev->dev.parent, ri); 42264e48160SLaxman Dewangan if (err) { 42364e48160SLaxman Dewangan dev_err(&pdev->dev, 42464e48160SLaxman Dewangan "regulator %d preinit failed, e %d\n", id, err); 42564e48160SLaxman Dewangan goto fail; 42664e48160SLaxman Dewangan } 42749610235SMike Rapoport 4287c7fac30SLaxman Dewangan config.dev = pdev->dev.parent; 42964e48160SLaxman Dewangan config.init_data = reg_data; 430c172708dSMark Brown config.driver_data = ri; 431c172708dSMark Brown 43264e48160SLaxman Dewangan if (tps6586x_reg_matches) 43364e48160SLaxman Dewangan config.of_node = tps6586x_reg_matches[id].of_node; 43464e48160SLaxman Dewangan 43564e48160SLaxman Dewangan rdev[id] = regulator_register(&ri->desc, &config); 43664e48160SLaxman Dewangan if (IS_ERR(rdev[id])) { 43749610235SMike Rapoport dev_err(&pdev->dev, "failed to register regulator %s\n", 43849610235SMike Rapoport ri->desc.name); 43964e48160SLaxman Dewangan err = PTR_ERR(rdev[id]); 44064e48160SLaxman Dewangan goto fail; 44164e48160SLaxman Dewangan } 44264e48160SLaxman Dewangan 44364e48160SLaxman Dewangan if (reg_data) { 44464e48160SLaxman Dewangan err = tps6586x_regulator_set_slew_rate(pdev, id, 44564e48160SLaxman Dewangan reg_data); 44664e48160SLaxman Dewangan if (err < 0) { 44764e48160SLaxman Dewangan dev_err(&pdev->dev, 44864e48160SLaxman Dewangan "Slew rate config failed, e %d\n", err); 44964e48160SLaxman Dewangan regulator_unregister(rdev[id]); 45064e48160SLaxman Dewangan goto fail; 45164e48160SLaxman Dewangan } 45264e48160SLaxman Dewangan } 45349610235SMike Rapoport } 45449610235SMike Rapoport 455e7973c3cSAxel Lin platform_set_drvdata(pdev, rdev); 45664e48160SLaxman Dewangan return 0; 45749610235SMike Rapoport 45864e48160SLaxman Dewangan fail: 45964e48160SLaxman Dewangan while (--id >= 0) 46064e48160SLaxman Dewangan regulator_unregister(rdev[id]); 46164e48160SLaxman Dewangan return err; 46249610235SMike Rapoport } 46349610235SMike Rapoport 46449610235SMike Rapoport static int __devexit tps6586x_regulator_remove(struct platform_device *pdev) 46549610235SMike Rapoport { 46664e48160SLaxman Dewangan struct regulator_dev **rdev = platform_get_drvdata(pdev); 46764e48160SLaxman Dewangan int id = TPS6586X_ID_MAX_REGULATOR; 468e7973c3cSAxel Lin 46964e48160SLaxman Dewangan while (--id >= 0) 47064e48160SLaxman Dewangan regulator_unregister(rdev[id]); 47164e48160SLaxman Dewangan 47249610235SMike Rapoport return 0; 47349610235SMike Rapoport } 47449610235SMike Rapoport 47549610235SMike Rapoport static struct platform_driver tps6586x_regulator_driver = { 47649610235SMike Rapoport .driver = { 47764e48160SLaxman Dewangan .name = "tps6586x-pmic", 47849610235SMike Rapoport .owner = THIS_MODULE, 47949610235SMike Rapoport }, 48049610235SMike Rapoport .probe = tps6586x_regulator_probe, 48149610235SMike Rapoport .remove = __devexit_p(tps6586x_regulator_remove), 48249610235SMike Rapoport }; 48349610235SMike Rapoport 48449610235SMike Rapoport static int __init tps6586x_regulator_init(void) 48549610235SMike Rapoport { 48649610235SMike Rapoport return platform_driver_register(&tps6586x_regulator_driver); 48749610235SMike Rapoport } 48849610235SMike Rapoport subsys_initcall(tps6586x_regulator_init); 48949610235SMike Rapoport 49049610235SMike Rapoport static void __exit tps6586x_regulator_exit(void) 49149610235SMike Rapoport { 49249610235SMike Rapoport platform_driver_unregister(&tps6586x_regulator_driver); 49349610235SMike Rapoport } 49449610235SMike Rapoport module_exit(tps6586x_regulator_exit); 49549610235SMike Rapoport 49649610235SMike Rapoport MODULE_LICENSE("GPL"); 49749610235SMike Rapoport MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 49849610235SMike Rapoport MODULE_DESCRIPTION("Regulator Driver for TI TPS6586X PMIC"); 49949610235SMike Rapoport MODULE_ALIAS("platform:tps6586x-regulator"); 500