1e634cf4eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
25928f538SLaxman Dewangan /*
3f1e5ecc5SRamona Alexandra Nechita * max8973-regulator.c -- Maxim max8973A
45928f538SLaxman Dewangan *
5f1e5ecc5SRamona Alexandra Nechita * Regulator driver for MAXIM 8973A DC-DC step-down switching regulator.
65928f538SLaxman Dewangan *
75928f538SLaxman Dewangan * Copyright (c) 2012, NVIDIA Corporation.
85928f538SLaxman Dewangan *
95928f538SLaxman Dewangan * Author: Laxman Dewangan <ldewangan@nvidia.com>
105928f538SLaxman Dewangan */
115928f538SLaxman Dewangan
125928f538SLaxman Dewangan #include <linux/kernel.h>
135928f538SLaxman Dewangan #include <linux/module.h>
145928f538SLaxman Dewangan #include <linux/init.h>
155928f538SLaxman Dewangan #include <linux/err.h>
1642dc3023SGuennadi Liakhovetski #include <linux/of.h>
170f7d6eceSLaxman Dewangan #include <linux/of_device.h>
185928f538SLaxman Dewangan #include <linux/platform_device.h>
195928f538SLaxman Dewangan #include <linux/regulator/driver.h>
205928f538SLaxman Dewangan #include <linux/regulator/machine.h>
215928f538SLaxman Dewangan #include <linux/regulator/max8973-regulator.h>
2242dc3023SGuennadi Liakhovetski #include <linux/regulator/of_regulator.h>
235928f538SLaxman Dewangan #include <linux/gpio.h>
24e7d2be69SLinus Walleij #include <linux/gpio/consumer.h>
25c2ffa973SLaxman Dewangan #include <linux/of_gpio.h>
265928f538SLaxman Dewangan #include <linux/i2c.h>
275928f538SLaxman Dewangan #include <linux/slab.h>
285928f538SLaxman Dewangan #include <linux/regmap.h>
29d2d5437bSLaxman Dewangan #include <linux/thermal.h>
30d2d5437bSLaxman Dewangan #include <linux/irq.h>
31d2d5437bSLaxman Dewangan #include <linux/interrupt.h>
325928f538SLaxman Dewangan
335928f538SLaxman Dewangan /* Register definitions */
345928f538SLaxman Dewangan #define MAX8973_VOUT 0x0
355928f538SLaxman Dewangan #define MAX8973_VOUT_DVS 0x1
365928f538SLaxman Dewangan #define MAX8973_CONTROL1 0x2
375928f538SLaxman Dewangan #define MAX8973_CONTROL2 0x3
385928f538SLaxman Dewangan #define MAX8973_CHIPID1 0x4
395928f538SLaxman Dewangan #define MAX8973_CHIPID2 0x5
405928f538SLaxman Dewangan
415928f538SLaxman Dewangan #define MAX8973_MAX_VOUT_REG 2
425928f538SLaxman Dewangan
435928f538SLaxman Dewangan /* MAX8973_VOUT */
445928f538SLaxman Dewangan #define MAX8973_VOUT_ENABLE BIT(7)
455928f538SLaxman Dewangan #define MAX8973_VOUT_MASK 0x7F
465928f538SLaxman Dewangan
475928f538SLaxman Dewangan /* MAX8973_VOUT_DVS */
485928f538SLaxman Dewangan #define MAX8973_DVS_VOUT_MASK 0x7F
495928f538SLaxman Dewangan
505928f538SLaxman Dewangan /* MAX8973_CONTROL1 */
515928f538SLaxman Dewangan #define MAX8973_SNS_ENABLE BIT(7)
525928f538SLaxman Dewangan #define MAX8973_FPWM_EN_M BIT(6)
535928f538SLaxman Dewangan #define MAX8973_NFSR_ENABLE BIT(5)
545928f538SLaxman Dewangan #define MAX8973_AD_ENABLE BIT(4)
555928f538SLaxman Dewangan #define MAX8973_BIAS_ENABLE BIT(3)
565928f538SLaxman Dewangan #define MAX8973_FREQSHIFT_9PER BIT(2)
575928f538SLaxman Dewangan
585928f538SLaxman Dewangan #define MAX8973_RAMP_12mV_PER_US 0x0
595928f538SLaxman Dewangan #define MAX8973_RAMP_25mV_PER_US 0x1
605928f538SLaxman Dewangan #define MAX8973_RAMP_50mV_PER_US 0x2
615928f538SLaxman Dewangan #define MAX8973_RAMP_200mV_PER_US 0x3
623064c1f3SLaxman Dewangan #define MAX8973_RAMP_MASK 0x3
635928f538SLaxman Dewangan
645928f538SLaxman Dewangan /* MAX8973_CONTROL2 */
655928f538SLaxman Dewangan #define MAX8973_WDTMR_ENABLE BIT(6)
665928f538SLaxman Dewangan #define MAX8973_DISCH_ENBABLE BIT(5)
675928f538SLaxman Dewangan #define MAX8973_FT_ENABLE BIT(4)
68d2d5437bSLaxman Dewangan #define MAX77621_T_JUNCTION_120 BIT(7)
695928f538SLaxman Dewangan
70ffaab991SLaxman Dewangan #define MAX8973_CKKADV_TRIP_MASK 0xC
715928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_DISABLE 0xC
725928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_75mV_PER_US 0x0
735928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_150mV_PER_US 0x4
745928f538SLaxman Dewangan #define MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS 0x8
755928f538SLaxman Dewangan #define MAX8973_CONTROL_CLKADV_TRIP_MASK 0x00030000
765928f538SLaxman Dewangan
775928f538SLaxman Dewangan #define MAX8973_INDUCTOR_MIN_30_PER 0x0
785928f538SLaxman Dewangan #define MAX8973_INDUCTOR_NOMINAL 0x1
795928f538SLaxman Dewangan #define MAX8973_INDUCTOR_PLUS_30_PER 0x2
805928f538SLaxman Dewangan #define MAX8973_INDUCTOR_PLUS_60_PER 0x3
815928f538SLaxman Dewangan #define MAX8973_CONTROL_INDUCTOR_VALUE_MASK 0x00300000
825928f538SLaxman Dewangan
835928f538SLaxman Dewangan #define MAX8973_MIN_VOLATGE 606250
845928f538SLaxman Dewangan #define MAX8973_MAX_VOLATGE 1400000
855928f538SLaxman Dewangan #define MAX8973_VOLATGE_STEP 6250
865928f538SLaxman Dewangan #define MAX8973_BUCK_N_VOLTAGE 0x80
875928f538SLaxman Dewangan
88d2d5437bSLaxman Dewangan #define MAX77621_CHIPID_TJINT_S BIT(0)
89d2d5437bSLaxman Dewangan
90d2d5437bSLaxman Dewangan #define MAX77621_NORMAL_OPERATING_TEMP 100000
91d2d5437bSLaxman Dewangan #define MAX77621_TJINT_WARNING_TEMP_120 120000
92d2d5437bSLaxman Dewangan #define MAX77621_TJINT_WARNING_TEMP_140 140000
93d2d5437bSLaxman Dewangan
940f7d6eceSLaxman Dewangan enum device_id {
950f7d6eceSLaxman Dewangan MAX8973,
960f7d6eceSLaxman Dewangan MAX77621
970f7d6eceSLaxman Dewangan };
980f7d6eceSLaxman Dewangan
995928f538SLaxman Dewangan /* Maxim 8973 chip information */
1005928f538SLaxman Dewangan struct max8973_chip {
1015928f538SLaxman Dewangan struct device *dev;
1025928f538SLaxman Dewangan struct regulator_desc desc;
1035928f538SLaxman Dewangan struct regmap *regmap;
1045928f538SLaxman Dewangan bool enable_external_control;
1055928f538SLaxman Dewangan int dvs_gpio;
1065928f538SLaxman Dewangan int lru_index[MAX8973_MAX_VOUT_REG];
1075928f538SLaxman Dewangan int curr_vout_val[MAX8973_MAX_VOUT_REG];
1085928f538SLaxman Dewangan int curr_vout_reg;
1095928f538SLaxman Dewangan int curr_gpio_val;
110db892ff6SGuennadi Liakhovetski struct regulator_ops ops;
1110f7d6eceSLaxman Dewangan enum device_id id;
112d2d5437bSLaxman Dewangan int junction_temp_warning;
113d2d5437bSLaxman Dewangan int irq;
114d2d5437bSLaxman Dewangan struct thermal_zone_device *tz_device;
1155928f538SLaxman Dewangan };
1165928f538SLaxman Dewangan
1175928f538SLaxman Dewangan /*
1185928f538SLaxman Dewangan * find_voltage_set_register: Find new voltage configuration register (VOUT).
1195928f538SLaxman Dewangan * The finding of the new VOUT register will be based on the LRU mechanism.
1205928f538SLaxman Dewangan * Each VOUT register will have different voltage configured . This
1215928f538SLaxman Dewangan * Function will look if any of the VOUT register have requested voltage set
1225928f538SLaxman Dewangan * or not.
1235928f538SLaxman Dewangan * - If it is already there then it will make that register as most
1245928f538SLaxman Dewangan * recently used and return as found so that caller need not to set
1255928f538SLaxman Dewangan * the VOUT register but need to set the proper gpios to select this
1265928f538SLaxman Dewangan * VOUT register.
1275928f538SLaxman Dewangan * - If requested voltage is not found then it will use the least
1285928f538SLaxman Dewangan * recently mechanism to get new VOUT register for new configuration
1295928f538SLaxman Dewangan * and will return not_found so that caller need to set new VOUT
1305928f538SLaxman Dewangan * register and then gpios (both).
1315928f538SLaxman Dewangan */
find_voltage_set_register(struct max8973_chip * tps,int req_vsel,int * vout_reg,int * gpio_val)1325928f538SLaxman Dewangan static bool find_voltage_set_register(struct max8973_chip *tps,
1335928f538SLaxman Dewangan int req_vsel, int *vout_reg, int *gpio_val)
1345928f538SLaxman Dewangan {
1355928f538SLaxman Dewangan int i;
1365928f538SLaxman Dewangan bool found = false;
1375928f538SLaxman Dewangan int new_vout_reg = tps->lru_index[MAX8973_MAX_VOUT_REG - 1];
1385928f538SLaxman Dewangan int found_index = MAX8973_MAX_VOUT_REG - 1;
1395928f538SLaxman Dewangan
1405928f538SLaxman Dewangan for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i) {
1415928f538SLaxman Dewangan if (tps->curr_vout_val[tps->lru_index[i]] == req_vsel) {
1425928f538SLaxman Dewangan new_vout_reg = tps->lru_index[i];
1435928f538SLaxman Dewangan found_index = i;
1445928f538SLaxman Dewangan found = true;
1455928f538SLaxman Dewangan goto update_lru_index;
1465928f538SLaxman Dewangan }
1475928f538SLaxman Dewangan }
1485928f538SLaxman Dewangan
1495928f538SLaxman Dewangan update_lru_index:
1505928f538SLaxman Dewangan for (i = found_index; i > 0; i--)
1515928f538SLaxman Dewangan tps->lru_index[i] = tps->lru_index[i - 1];
1525928f538SLaxman Dewangan
1535928f538SLaxman Dewangan tps->lru_index[0] = new_vout_reg;
1545928f538SLaxman Dewangan *gpio_val = new_vout_reg;
1555928f538SLaxman Dewangan *vout_reg = MAX8973_VOUT + new_vout_reg;
1565928f538SLaxman Dewangan return found;
1575928f538SLaxman Dewangan }
1585928f538SLaxman Dewangan
max8973_dcdc_get_voltage_sel(struct regulator_dev * rdev)1595928f538SLaxman Dewangan static int max8973_dcdc_get_voltage_sel(struct regulator_dev *rdev)
1605928f538SLaxman Dewangan {
1615928f538SLaxman Dewangan struct max8973_chip *max = rdev_get_drvdata(rdev);
1625928f538SLaxman Dewangan unsigned int data;
1635928f538SLaxman Dewangan int ret;
1645928f538SLaxman Dewangan
1655928f538SLaxman Dewangan ret = regmap_read(max->regmap, max->curr_vout_reg, &data);
1665928f538SLaxman Dewangan if (ret < 0) {
1675928f538SLaxman Dewangan dev_err(max->dev, "register %d read failed, err = %d\n",
1685928f538SLaxman Dewangan max->curr_vout_reg, ret);
1695928f538SLaxman Dewangan return ret;
1705928f538SLaxman Dewangan }
1715928f538SLaxman Dewangan return data & MAX8973_VOUT_MASK;
1725928f538SLaxman Dewangan }
1735928f538SLaxman Dewangan
max8973_dcdc_set_voltage_sel(struct regulator_dev * rdev,unsigned vsel)1745928f538SLaxman Dewangan static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
1755928f538SLaxman Dewangan unsigned vsel)
1765928f538SLaxman Dewangan {
1775928f538SLaxman Dewangan struct max8973_chip *max = rdev_get_drvdata(rdev);
1785928f538SLaxman Dewangan int ret;
1795928f538SLaxman Dewangan bool found = false;
1805928f538SLaxman Dewangan int vout_reg = max->curr_vout_reg;
1815928f538SLaxman Dewangan int gpio_val = max->curr_gpio_val;
1825928f538SLaxman Dewangan
1835928f538SLaxman Dewangan /*
1845928f538SLaxman Dewangan * If gpios are available to select the VOUT register then least
1855928f538SLaxman Dewangan * recently used register for new configuration.
1865928f538SLaxman Dewangan */
187fa5f509fSLaxman Dewangan if (gpio_is_valid(max->dvs_gpio))
1885928f538SLaxman Dewangan found = find_voltage_set_register(max, vsel,
1895928f538SLaxman Dewangan &vout_reg, &gpio_val);
1905928f538SLaxman Dewangan
1915928f538SLaxman Dewangan if (!found) {
1925928f538SLaxman Dewangan ret = regmap_update_bits(max->regmap, vout_reg,
1935928f538SLaxman Dewangan MAX8973_VOUT_MASK, vsel);
1945928f538SLaxman Dewangan if (ret < 0) {
1955928f538SLaxman Dewangan dev_err(max->dev, "register %d update failed, err %d\n",
1965928f538SLaxman Dewangan vout_reg, ret);
1975928f538SLaxman Dewangan return ret;
1985928f538SLaxman Dewangan }
1995928f538SLaxman Dewangan max->curr_vout_reg = vout_reg;
2005928f538SLaxman Dewangan max->curr_vout_val[gpio_val] = vsel;
2015928f538SLaxman Dewangan }
2025928f538SLaxman Dewangan
2035928f538SLaxman Dewangan /* Select proper VOUT register vio gpios */
204fa5f509fSLaxman Dewangan if (gpio_is_valid(max->dvs_gpio)) {
2055928f538SLaxman Dewangan gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
2065928f538SLaxman Dewangan max->curr_gpio_val = gpio_val;
2075928f538SLaxman Dewangan }
2085928f538SLaxman Dewangan return 0;
2095928f538SLaxman Dewangan }
2105928f538SLaxman Dewangan
max8973_dcdc_set_mode(struct regulator_dev * rdev,unsigned int mode)2115928f538SLaxman Dewangan static int max8973_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
2125928f538SLaxman Dewangan {
2135928f538SLaxman Dewangan struct max8973_chip *max = rdev_get_drvdata(rdev);
2145928f538SLaxman Dewangan int ret;
2155928f538SLaxman Dewangan int pwm;
2165928f538SLaxman Dewangan
2175928f538SLaxman Dewangan /* Enable force PWM mode in FAST mode only. */
2185928f538SLaxman Dewangan switch (mode) {
2195928f538SLaxman Dewangan case REGULATOR_MODE_FAST:
2205928f538SLaxman Dewangan pwm = MAX8973_FPWM_EN_M;
2215928f538SLaxman Dewangan break;
2225928f538SLaxman Dewangan
2235928f538SLaxman Dewangan case REGULATOR_MODE_NORMAL:
2245928f538SLaxman Dewangan pwm = 0;
2255928f538SLaxman Dewangan break;
2265928f538SLaxman Dewangan
2275928f538SLaxman Dewangan default:
2285928f538SLaxman Dewangan return -EINVAL;
2295928f538SLaxman Dewangan }
2305928f538SLaxman Dewangan
2315928f538SLaxman Dewangan ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1,
2325928f538SLaxman Dewangan MAX8973_FPWM_EN_M, pwm);
2335928f538SLaxman Dewangan if (ret < 0)
2345928f538SLaxman Dewangan dev_err(max->dev, "register %d update failed, err %d\n",
2355928f538SLaxman Dewangan MAX8973_CONTROL1, ret);
2365928f538SLaxman Dewangan return ret;
2375928f538SLaxman Dewangan }
2385928f538SLaxman Dewangan
max8973_dcdc_get_mode(struct regulator_dev * rdev)2395928f538SLaxman Dewangan static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
2405928f538SLaxman Dewangan {
2415928f538SLaxman Dewangan struct max8973_chip *max = rdev_get_drvdata(rdev);
2425928f538SLaxman Dewangan unsigned int data;
2435928f538SLaxman Dewangan int ret;
2445928f538SLaxman Dewangan
2455928f538SLaxman Dewangan ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data);
2465928f538SLaxman Dewangan if (ret < 0) {
2475928f538SLaxman Dewangan dev_err(max->dev, "register %d read failed, err %d\n",
2485928f538SLaxman Dewangan MAX8973_CONTROL1, ret);
2495928f538SLaxman Dewangan return ret;
2505928f538SLaxman Dewangan }
2515928f538SLaxman Dewangan return (data & MAX8973_FPWM_EN_M) ?
2525928f538SLaxman Dewangan REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
2535928f538SLaxman Dewangan }
2545928f538SLaxman Dewangan
max8973_set_current_limit(struct regulator_dev * rdev,int min_ua,int max_ua)255ffaab991SLaxman Dewangan static int max8973_set_current_limit(struct regulator_dev *rdev,
256ffaab991SLaxman Dewangan int min_ua, int max_ua)
257ffaab991SLaxman Dewangan {
258ffaab991SLaxman Dewangan struct max8973_chip *max = rdev_get_drvdata(rdev);
259ffaab991SLaxman Dewangan unsigned int val;
260ffaab991SLaxman Dewangan int ret;
261ffaab991SLaxman Dewangan
262ffaab991SLaxman Dewangan if (max_ua <= 9000000)
263ffaab991SLaxman Dewangan val = MAX8973_CKKADV_TRIP_75mV_PER_US;
264ffaab991SLaxman Dewangan else if (max_ua <= 12000000)
265ffaab991SLaxman Dewangan val = MAX8973_CKKADV_TRIP_150mV_PER_US;
266ffaab991SLaxman Dewangan else
267ffaab991SLaxman Dewangan val = MAX8973_CKKADV_TRIP_DISABLE;
268ffaab991SLaxman Dewangan
269ffaab991SLaxman Dewangan ret = regmap_update_bits(max->regmap, MAX8973_CONTROL2,
270ffaab991SLaxman Dewangan MAX8973_CKKADV_TRIP_MASK, val);
271ffaab991SLaxman Dewangan if (ret < 0) {
272ffaab991SLaxman Dewangan dev_err(max->dev, "register %d update failed: %d\n",
273ffaab991SLaxman Dewangan MAX8973_CONTROL2, ret);
274ffaab991SLaxman Dewangan return ret;
275ffaab991SLaxman Dewangan }
276ffaab991SLaxman Dewangan return 0;
277ffaab991SLaxman Dewangan }
278ffaab991SLaxman Dewangan
max8973_get_current_limit(struct regulator_dev * rdev)279ffaab991SLaxman Dewangan static int max8973_get_current_limit(struct regulator_dev *rdev)
280ffaab991SLaxman Dewangan {
281ffaab991SLaxman Dewangan struct max8973_chip *max = rdev_get_drvdata(rdev);
282ffaab991SLaxman Dewangan unsigned int control2;
283ffaab991SLaxman Dewangan int ret;
284ffaab991SLaxman Dewangan
285ffaab991SLaxman Dewangan ret = regmap_read(max->regmap, MAX8973_CONTROL2, &control2);
286ffaab991SLaxman Dewangan if (ret < 0) {
287ffaab991SLaxman Dewangan dev_err(max->dev, "register %d read failed: %d\n",
288ffaab991SLaxman Dewangan MAX8973_CONTROL2, ret);
289ffaab991SLaxman Dewangan return ret;
290ffaab991SLaxman Dewangan }
291ffaab991SLaxman Dewangan switch (control2 & MAX8973_CKKADV_TRIP_MASK) {
292ffaab991SLaxman Dewangan case MAX8973_CKKADV_TRIP_DISABLE:
293ffaab991SLaxman Dewangan return 15000000;
294ffaab991SLaxman Dewangan case MAX8973_CKKADV_TRIP_150mV_PER_US:
295ffaab991SLaxman Dewangan return 12000000;
296ffaab991SLaxman Dewangan case MAX8973_CKKADV_TRIP_75mV_PER_US:
297ffaab991SLaxman Dewangan return 9000000;
298ffaab991SLaxman Dewangan default:
299ffaab991SLaxman Dewangan break;
300ffaab991SLaxman Dewangan }
301ffaab991SLaxman Dewangan return 9000000;
302ffaab991SLaxman Dewangan }
303ffaab991SLaxman Dewangan
3048590ccd4SAxel Lin static const unsigned int max8973_buck_ramp_table[] = {
3058590ccd4SAxel Lin 12000, 25000, 50000, 200000
3068590ccd4SAxel Lin };
3078590ccd4SAxel Lin
308db892ff6SGuennadi Liakhovetski static const struct regulator_ops max8973_dcdc_ops = {
3095928f538SLaxman Dewangan .get_voltage_sel = max8973_dcdc_get_voltage_sel,
3105928f538SLaxman Dewangan .set_voltage_sel = max8973_dcdc_set_voltage_sel,
3115928f538SLaxman Dewangan .list_voltage = regulator_list_voltage_linear,
3125928f538SLaxman Dewangan .set_mode = max8973_dcdc_set_mode,
3135928f538SLaxman Dewangan .get_mode = max8973_dcdc_get_mode,
3143064c1f3SLaxman Dewangan .set_voltage_time_sel = regulator_set_voltage_time_sel,
3158590ccd4SAxel Lin .set_ramp_delay = regulator_set_ramp_delay_regmap,
3165928f538SLaxman Dewangan };
3175928f538SLaxman Dewangan
max8973_init_dcdc(struct max8973_chip * max,struct max8973_regulator_platform_data * pdata)3183d68dfe3SGreg Kroah-Hartman static int max8973_init_dcdc(struct max8973_chip *max,
3195928f538SLaxman Dewangan struct max8973_regulator_platform_data *pdata)
3205928f538SLaxman Dewangan {
3215928f538SLaxman Dewangan int ret;
3225928f538SLaxman Dewangan uint8_t control1 = 0;
3235928f538SLaxman Dewangan uint8_t control2 = 0;
3243064c1f3SLaxman Dewangan unsigned int data;
3253064c1f3SLaxman Dewangan
3263064c1f3SLaxman Dewangan ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data);
3273064c1f3SLaxman Dewangan if (ret < 0) {
3283064c1f3SLaxman Dewangan dev_err(max->dev, "register %d read failed, err = %d",
3293064c1f3SLaxman Dewangan MAX8973_CONTROL1, ret);
3303064c1f3SLaxman Dewangan return ret;
3313064c1f3SLaxman Dewangan }
3323064c1f3SLaxman Dewangan control1 = data & MAX8973_RAMP_MASK;
3333064c1f3SLaxman Dewangan switch (control1) {
3343064c1f3SLaxman Dewangan case MAX8973_RAMP_12mV_PER_US:
3353064c1f3SLaxman Dewangan max->desc.ramp_delay = 12000;
3363064c1f3SLaxman Dewangan break;
3373064c1f3SLaxman Dewangan case MAX8973_RAMP_25mV_PER_US:
338366604ecSAxel Lin max->desc.ramp_delay = 25000;
3393064c1f3SLaxman Dewangan break;
3403064c1f3SLaxman Dewangan case MAX8973_RAMP_50mV_PER_US:
3413064c1f3SLaxman Dewangan max->desc.ramp_delay = 50000;
3423064c1f3SLaxman Dewangan break;
3433064c1f3SLaxman Dewangan case MAX8973_RAMP_200mV_PER_US:
3443064c1f3SLaxman Dewangan max->desc.ramp_delay = 200000;
3453064c1f3SLaxman Dewangan break;
3463064c1f3SLaxman Dewangan }
3475928f538SLaxman Dewangan
3485928f538SLaxman Dewangan if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE)
3495928f538SLaxman Dewangan control1 |= MAX8973_SNS_ENABLE;
3505928f538SLaxman Dewangan
3515928f538SLaxman Dewangan if (!(pdata->control_flags & MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE))
3525928f538SLaxman Dewangan control1 |= MAX8973_NFSR_ENABLE;
3535928f538SLaxman Dewangan
3545928f538SLaxman Dewangan if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE)
3555928f538SLaxman Dewangan control1 |= MAX8973_AD_ENABLE;
3565928f538SLaxman Dewangan
357dcd9ec6aSLaxman Dewangan if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE) {
3585928f538SLaxman Dewangan control1 |= MAX8973_BIAS_ENABLE;
359dcd9ec6aSLaxman Dewangan max->desc.enable_time = 20;
360dcd9ec6aSLaxman Dewangan } else {
361dcd9ec6aSLaxman Dewangan max->desc.enable_time = 240;
362dcd9ec6aSLaxman Dewangan }
3635928f538SLaxman Dewangan
3645928f538SLaxman Dewangan if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
3655928f538SLaxman Dewangan control1 |= MAX8973_FREQSHIFT_9PER;
3665928f538SLaxman Dewangan
367d2d5437bSLaxman Dewangan if ((pdata->junction_temp_warning == MAX77621_TJINT_WARNING_TEMP_120) &&
368d2d5437bSLaxman Dewangan (max->id == MAX77621))
369d2d5437bSLaxman Dewangan control2 |= MAX77621_T_JUNCTION_120;
370d2d5437bSLaxman Dewangan
3715928f538SLaxman Dewangan if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
3725928f538SLaxman Dewangan control2 |= MAX8973_DISCH_ENBABLE;
3735928f538SLaxman Dewangan
3745928f538SLaxman Dewangan /* Clock advance trip configuration */
3755928f538SLaxman Dewangan switch (pdata->control_flags & MAX8973_CONTROL_CLKADV_TRIP_MASK) {
3765928f538SLaxman Dewangan case MAX8973_CONTROL_CLKADV_TRIP_DISABLED:
3775928f538SLaxman Dewangan control2 |= MAX8973_CKKADV_TRIP_DISABLE;
3785928f538SLaxman Dewangan break;
3795928f538SLaxman Dewangan
3805928f538SLaxman Dewangan case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US:
3815928f538SLaxman Dewangan control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US;
3825928f538SLaxman Dewangan break;
3835928f538SLaxman Dewangan
3845928f538SLaxman Dewangan case MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US:
3855928f538SLaxman Dewangan control2 |= MAX8973_CKKADV_TRIP_150mV_PER_US;
3865928f538SLaxman Dewangan break;
3875928f538SLaxman Dewangan
3885928f538SLaxman Dewangan case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS:
3895928f538SLaxman Dewangan control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS;
3905928f538SLaxman Dewangan break;
3915928f538SLaxman Dewangan }
3925928f538SLaxman Dewangan
3935928f538SLaxman Dewangan /* Configure inductor value */
3945928f538SLaxman Dewangan switch (pdata->control_flags & MAX8973_CONTROL_INDUCTOR_VALUE_MASK) {
3955928f538SLaxman Dewangan case MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL:
3965928f538SLaxman Dewangan control2 |= MAX8973_INDUCTOR_NOMINAL;
3975928f538SLaxman Dewangan break;
3985928f538SLaxman Dewangan
3995928f538SLaxman Dewangan case MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER:
4005928f538SLaxman Dewangan control2 |= MAX8973_INDUCTOR_MIN_30_PER;
4015928f538SLaxman Dewangan break;
4025928f538SLaxman Dewangan
4035928f538SLaxman Dewangan case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER:
4045928f538SLaxman Dewangan control2 |= MAX8973_INDUCTOR_PLUS_30_PER;
4055928f538SLaxman Dewangan break;
4065928f538SLaxman Dewangan
4075928f538SLaxman Dewangan case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER:
4085928f538SLaxman Dewangan control2 |= MAX8973_INDUCTOR_PLUS_60_PER;
4095928f538SLaxman Dewangan break;
4105928f538SLaxman Dewangan }
4115928f538SLaxman Dewangan
4125928f538SLaxman Dewangan ret = regmap_write(max->regmap, MAX8973_CONTROL1, control1);
4135928f538SLaxman Dewangan if (ret < 0) {
4145928f538SLaxman Dewangan dev_err(max->dev, "register %d write failed, err = %d",
4155928f538SLaxman Dewangan MAX8973_CONTROL1, ret);
4165928f538SLaxman Dewangan return ret;
4175928f538SLaxman Dewangan }
4185928f538SLaxman Dewangan
4195928f538SLaxman Dewangan ret = regmap_write(max->regmap, MAX8973_CONTROL2, control2);
4205928f538SLaxman Dewangan if (ret < 0) {
4215928f538SLaxman Dewangan dev_err(max->dev, "register %d write failed, err = %d",
4225928f538SLaxman Dewangan MAX8973_CONTROL2, ret);
4235928f538SLaxman Dewangan return ret;
4245928f538SLaxman Dewangan }
4255928f538SLaxman Dewangan
4265928f538SLaxman Dewangan /* If external control is enabled then disable EN bit */
4270f7d6eceSLaxman Dewangan if (max->enable_external_control && (max->id == MAX8973)) {
4285928f538SLaxman Dewangan ret = regmap_update_bits(max->regmap, MAX8973_VOUT,
4295928f538SLaxman Dewangan MAX8973_VOUT_ENABLE, 0);
4305928f538SLaxman Dewangan if (ret < 0)
4315928f538SLaxman Dewangan dev_err(max->dev, "register %d update failed, err = %d",
4325928f538SLaxman Dewangan MAX8973_VOUT, ret);
4335928f538SLaxman Dewangan }
4345928f538SLaxman Dewangan return ret;
4355928f538SLaxman Dewangan }
4365928f538SLaxman Dewangan
max8973_thermal_read_temp(struct thermal_zone_device * tz,int * temp)437826855ffSDaniel Lezcano static int max8973_thermal_read_temp(struct thermal_zone_device *tz, int *temp)
438d2d5437bSLaxman Dewangan {
4393d4e1badSDaniel Lezcano struct max8973_chip *mchip = thermal_zone_device_priv(tz);
440d2d5437bSLaxman Dewangan unsigned int val;
441d2d5437bSLaxman Dewangan int ret;
442d2d5437bSLaxman Dewangan
443d2d5437bSLaxman Dewangan ret = regmap_read(mchip->regmap, MAX8973_CHIPID1, &val);
444d2d5437bSLaxman Dewangan if (ret < 0) {
445d2d5437bSLaxman Dewangan dev_err(mchip->dev, "Failed to read register CHIPID1, %d", ret);
446d2d5437bSLaxman Dewangan return ret;
447d2d5437bSLaxman Dewangan }
448d2d5437bSLaxman Dewangan
449bbc7ba0fSTom Rix /* +1 degC to trigger cool device */
450d2d5437bSLaxman Dewangan if (val & MAX77621_CHIPID_TJINT_S)
451d2d5437bSLaxman Dewangan *temp = mchip->junction_temp_warning + 1000;
452d2d5437bSLaxman Dewangan else
453d2d5437bSLaxman Dewangan *temp = MAX77621_NORMAL_OPERATING_TEMP;
454d2d5437bSLaxman Dewangan
455d2d5437bSLaxman Dewangan return 0;
456d2d5437bSLaxman Dewangan }
457d2d5437bSLaxman Dewangan
max8973_thermal_irq(int irq,void * data)458d2d5437bSLaxman Dewangan static irqreturn_t max8973_thermal_irq(int irq, void *data)
459d2d5437bSLaxman Dewangan {
460d2d5437bSLaxman Dewangan struct max8973_chip *mchip = data;
461d2d5437bSLaxman Dewangan
4620e70f466SSrinivas Pandruvada thermal_zone_device_update(mchip->tz_device,
4630e70f466SSrinivas Pandruvada THERMAL_EVENT_UNSPECIFIED);
464d2d5437bSLaxman Dewangan
465d2d5437bSLaxman Dewangan return IRQ_HANDLED;
466d2d5437bSLaxman Dewangan }
467d2d5437bSLaxman Dewangan
468826855ffSDaniel Lezcano static const struct thermal_zone_device_ops max77621_tz_ops = {
469d2d5437bSLaxman Dewangan .get_temp = max8973_thermal_read_temp,
470d2d5437bSLaxman Dewangan };
471d2d5437bSLaxman Dewangan
max8973_thermal_init(struct max8973_chip * mchip)472d2d5437bSLaxman Dewangan static int max8973_thermal_init(struct max8973_chip *mchip)
473d2d5437bSLaxman Dewangan {
474d2d5437bSLaxman Dewangan struct thermal_zone_device *tzd;
475d2d5437bSLaxman Dewangan struct irq_data *irq_data;
476d2d5437bSLaxman Dewangan unsigned long irq_flags = 0;
477d2d5437bSLaxman Dewangan int ret;
478d2d5437bSLaxman Dewangan
479d2d5437bSLaxman Dewangan if (mchip->id != MAX77621)
480d2d5437bSLaxman Dewangan return 0;
481d2d5437bSLaxman Dewangan
482826855ffSDaniel Lezcano tzd = devm_thermal_of_zone_register(mchip->dev, 0, mchip,
483d2d5437bSLaxman Dewangan &max77621_tz_ops);
484d2d5437bSLaxman Dewangan if (IS_ERR(tzd)) {
485d2d5437bSLaxman Dewangan ret = PTR_ERR(tzd);
486d2d5437bSLaxman Dewangan dev_err(mchip->dev, "Failed to register thermal sensor: %d\n",
487d2d5437bSLaxman Dewangan ret);
488d2d5437bSLaxman Dewangan return ret;
489d2d5437bSLaxman Dewangan }
490d2d5437bSLaxman Dewangan
491d2d5437bSLaxman Dewangan if (mchip->irq <= 0)
492d2d5437bSLaxman Dewangan return 0;
493d2d5437bSLaxman Dewangan
494d2d5437bSLaxman Dewangan irq_data = irq_get_irq_data(mchip->irq);
495d2d5437bSLaxman Dewangan if (irq_data)
496d2d5437bSLaxman Dewangan irq_flags = irqd_get_trigger_type(irq_data);
497d2d5437bSLaxman Dewangan
498d2d5437bSLaxman Dewangan ret = devm_request_threaded_irq(mchip->dev, mchip->irq, NULL,
499d2d5437bSLaxman Dewangan max8973_thermal_irq,
500d2d5437bSLaxman Dewangan IRQF_ONESHOT | IRQF_SHARED | irq_flags,
501d2d5437bSLaxman Dewangan dev_name(mchip->dev), mchip);
502d2d5437bSLaxman Dewangan if (ret < 0) {
503d2d5437bSLaxman Dewangan dev_err(mchip->dev, "Failed to request irq %d, %d\n",
504d2d5437bSLaxman Dewangan mchip->irq, ret);
505d2d5437bSLaxman Dewangan return ret;
506d2d5437bSLaxman Dewangan }
507d2d5437bSLaxman Dewangan
508d2d5437bSLaxman Dewangan return 0;
509d2d5437bSLaxman Dewangan }
510d2d5437bSLaxman Dewangan
5115928f538SLaxman Dewangan static const struct regmap_config max8973_regmap_config = {
5125928f538SLaxman Dewangan .reg_bits = 8,
5135928f538SLaxman Dewangan .val_bits = 8,
5145928f538SLaxman Dewangan .max_register = MAX8973_CHIPID2,
5155928f538SLaxman Dewangan .cache_type = REGCACHE_RBTREE,
5165928f538SLaxman Dewangan };
5175928f538SLaxman Dewangan
max8973_parse_dt(struct device * dev)518c2ffa973SLaxman Dewangan static struct max8973_regulator_platform_data *max8973_parse_dt(
519c2ffa973SLaxman Dewangan struct device *dev)
520c2ffa973SLaxman Dewangan {
521c2ffa973SLaxman Dewangan struct max8973_regulator_platform_data *pdata;
522c2ffa973SLaxman Dewangan struct device_node *np = dev->of_node;
523c2ffa973SLaxman Dewangan int ret;
524c2ffa973SLaxman Dewangan u32 pval;
5253692db3aSLaxman Dewangan bool etr_enable;
5263692db3aSLaxman Dewangan bool etr_sensitivity_high;
527c2ffa973SLaxman Dewangan
528c2ffa973SLaxman Dewangan pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
529c2ffa973SLaxman Dewangan if (!pdata)
530c2ffa973SLaxman Dewangan return NULL;
531c2ffa973SLaxman Dewangan
532c2ffa973SLaxman Dewangan pdata->enable_ext_control = of_property_read_bool(np,
533c2ffa973SLaxman Dewangan "maxim,externally-enable");
534c2ffa973SLaxman Dewangan pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0);
535c2ffa973SLaxman Dewangan
536c2ffa973SLaxman Dewangan ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval);
537c2ffa973SLaxman Dewangan if (!ret)
538c2ffa973SLaxman Dewangan pdata->dvs_def_state = pval;
539c2ffa973SLaxman Dewangan
540c2ffa973SLaxman Dewangan if (of_property_read_bool(np, "maxim,enable-remote-sense"))
541c2ffa973SLaxman Dewangan pdata->control_flags |= MAX8973_CONTROL_REMOTE_SENSE_ENABLE;
542c2ffa973SLaxman Dewangan
543c2ffa973SLaxman Dewangan if (of_property_read_bool(np, "maxim,enable-falling-slew-rate"))
544c2ffa973SLaxman Dewangan pdata->control_flags |=
545c2ffa973SLaxman Dewangan MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE;
546c2ffa973SLaxman Dewangan
547c2ffa973SLaxman Dewangan if (of_property_read_bool(np, "maxim,enable-active-discharge"))
548c2ffa973SLaxman Dewangan pdata->control_flags |=
549c2ffa973SLaxman Dewangan MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE;
550c2ffa973SLaxman Dewangan
551c2ffa973SLaxman Dewangan if (of_property_read_bool(np, "maxim,enable-frequency-shift"))
552c2ffa973SLaxman Dewangan pdata->control_flags |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE;
553c2ffa973SLaxman Dewangan
554c2ffa973SLaxman Dewangan if (of_property_read_bool(np, "maxim,enable-bias-control"))
555127e1062SLaxman Dewangan pdata->control_flags |= MAX8973_CONTROL_BIAS_ENABLE;
556c2ffa973SLaxman Dewangan
5573692db3aSLaxman Dewangan etr_enable = of_property_read_bool(np, "maxim,enable-etr");
5583692db3aSLaxman Dewangan etr_sensitivity_high = of_property_read_bool(np,
5593692db3aSLaxman Dewangan "maxim,enable-high-etr-sensitivity");
5603692db3aSLaxman Dewangan if (etr_sensitivity_high)
5613692db3aSLaxman Dewangan etr_enable = true;
5623692db3aSLaxman Dewangan
5633692db3aSLaxman Dewangan if (etr_enable) {
5643692db3aSLaxman Dewangan if (etr_sensitivity_high)
5653692db3aSLaxman Dewangan pdata->control_flags |=
5663692db3aSLaxman Dewangan MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US;
5673692db3aSLaxman Dewangan else
5683692db3aSLaxman Dewangan pdata->control_flags |=
5693692db3aSLaxman Dewangan MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US;
5703692db3aSLaxman Dewangan } else {
5713692db3aSLaxman Dewangan pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
5723692db3aSLaxman Dewangan }
5733692db3aSLaxman Dewangan
574d2d5437bSLaxman Dewangan pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_140;
575d2d5437bSLaxman Dewangan ret = of_property_read_u32(np, "junction-warn-millicelsius", &pval);
576d2d5437bSLaxman Dewangan if (!ret && (pval <= MAX77621_TJINT_WARNING_TEMP_120))
577d2d5437bSLaxman Dewangan pdata->junction_temp_warning = MAX77621_TJINT_WARNING_TEMP_120;
578d2d5437bSLaxman Dewangan
579c2ffa973SLaxman Dewangan return pdata;
580c2ffa973SLaxman Dewangan }
581c2ffa973SLaxman Dewangan
5820f7d6eceSLaxman Dewangan static const struct of_device_id of_max8973_match_tbl[] = {
5830f7d6eceSLaxman Dewangan { .compatible = "maxim,max8973", .data = (void *)MAX8973, },
5840f7d6eceSLaxman Dewangan { .compatible = "maxim,max77621", .data = (void *)MAX77621, },
5850f7d6eceSLaxman Dewangan { },
5860f7d6eceSLaxman Dewangan };
5870f7d6eceSLaxman Dewangan MODULE_DEVICE_TABLE(of, of_max8973_match_tbl);
5880f7d6eceSLaxman Dewangan
max8973_probe(struct i2c_client * client)5894e85e5d6SUwe Kleine-König static int max8973_probe(struct i2c_client *client)
5905928f538SLaxman Dewangan {
5914e85e5d6SUwe Kleine-König const struct i2c_device_id *id = i2c_client_get_device_id(client);
5925928f538SLaxman Dewangan struct max8973_regulator_platform_data *pdata;
59369eb0980SLaxman Dewangan struct regulator_init_data *ridata;
5945928f538SLaxman Dewangan struct regulator_config config = { };
5955928f538SLaxman Dewangan struct regulator_dev *rdev;
5965928f538SLaxman Dewangan struct max8973_chip *max;
597c2ffa973SLaxman Dewangan bool pdata_from_dt = false;
5980f7d6eceSLaxman Dewangan unsigned int chip_id;
599e7d2be69SLinus Walleij struct gpio_desc *gpiod;
600e7d2be69SLinus Walleij enum gpiod_flags gflags;
6015928f538SLaxman Dewangan int ret;
6025928f538SLaxman Dewangan
603dff91d0bSJingoo Han pdata = dev_get_platdata(&client->dev);
60442dc3023SGuennadi Liakhovetski
605c2ffa973SLaxman Dewangan if (!pdata && client->dev.of_node) {
606c2ffa973SLaxman Dewangan pdata = max8973_parse_dt(&client->dev);
607c2ffa973SLaxman Dewangan pdata_from_dt = true;
608c2ffa973SLaxman Dewangan }
609c2ffa973SLaxman Dewangan
610c2ffa973SLaxman Dewangan if (!pdata) {
6115928f538SLaxman Dewangan dev_err(&client->dev, "No Platform data");
6125928f538SLaxman Dewangan return -EIO;
6135928f538SLaxman Dewangan }
6145928f538SLaxman Dewangan
615e7d2be69SLinus Walleij if (pdata->dvs_gpio == -EPROBE_DEFER)
616c2ffa973SLaxman Dewangan return -EPROBE_DEFER;
617c2ffa973SLaxman Dewangan
6185928f538SLaxman Dewangan max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
61921024deeSSachin Kamat if (!max)
6205928f538SLaxman Dewangan return -ENOMEM;
6215928f538SLaxman Dewangan
6225928f538SLaxman Dewangan max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config);
6235928f538SLaxman Dewangan if (IS_ERR(max->regmap)) {
6245928f538SLaxman Dewangan ret = PTR_ERR(max->regmap);
6255928f538SLaxman Dewangan dev_err(&client->dev, "regmap init failed, err %d\n", ret);
6265928f538SLaxman Dewangan return ret;
6275928f538SLaxman Dewangan }
6285928f538SLaxman Dewangan
6290f7d6eceSLaxman Dewangan if (client->dev.of_node) {
6300f7d6eceSLaxman Dewangan const struct of_device_id *match;
6310f7d6eceSLaxman Dewangan
6320f7d6eceSLaxman Dewangan match = of_match_device(of_match_ptr(of_max8973_match_tbl),
6330f7d6eceSLaxman Dewangan &client->dev);
6340f7d6eceSLaxman Dewangan if (!match)
6350f7d6eceSLaxman Dewangan return -ENODATA;
6360f7d6eceSLaxman Dewangan max->id = (u32)((uintptr_t)match->data);
6370f7d6eceSLaxman Dewangan } else {
6380f7d6eceSLaxman Dewangan max->id = id->driver_data;
6390f7d6eceSLaxman Dewangan }
6400f7d6eceSLaxman Dewangan
6410f7d6eceSLaxman Dewangan ret = regmap_read(max->regmap, MAX8973_CHIPID1, &chip_id);
6420f7d6eceSLaxman Dewangan if (ret < 0) {
6430f7d6eceSLaxman Dewangan dev_err(&client->dev, "register CHIPID1 read failed, %d", ret);
6440f7d6eceSLaxman Dewangan return ret;
6450f7d6eceSLaxman Dewangan }
6460f7d6eceSLaxman Dewangan
6470f7d6eceSLaxman Dewangan dev_info(&client->dev, "CHIP-ID OTP: 0x%02x ID_M: 0x%02x\n",
6480f7d6eceSLaxman Dewangan (chip_id >> 4) & 0xF, (chip_id >> 1) & 0x7);
6490f7d6eceSLaxman Dewangan
6505928f538SLaxman Dewangan i2c_set_clientdata(client, max);
651db892ff6SGuennadi Liakhovetski max->ops = max8973_dcdc_ops;
6525928f538SLaxman Dewangan max->dev = &client->dev;
6535928f538SLaxman Dewangan max->desc.name = id->name;
6545928f538SLaxman Dewangan max->desc.id = 0;
655db892ff6SGuennadi Liakhovetski max->desc.ops = &max->ops;
6565928f538SLaxman Dewangan max->desc.type = REGULATOR_VOLTAGE;
6575928f538SLaxman Dewangan max->desc.owner = THIS_MODULE;
6585928f538SLaxman Dewangan max->desc.min_uV = MAX8973_MIN_VOLATGE;
6595928f538SLaxman Dewangan max->desc.uV_step = MAX8973_VOLATGE_STEP;
6605928f538SLaxman Dewangan max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
6618590ccd4SAxel Lin max->desc.ramp_reg = MAX8973_CONTROL1;
6628590ccd4SAxel Lin max->desc.ramp_mask = MAX8973_RAMP_MASK;
6638590ccd4SAxel Lin max->desc.ramp_delay_table = max8973_buck_ramp_table;
6648590ccd4SAxel Lin max->desc.n_ramp_values = ARRAY_SIZE(max8973_buck_ramp_table);
6655928f538SLaxman Dewangan
66669eb0980SLaxman Dewangan max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL;
66769eb0980SLaxman Dewangan max->enable_external_control = pdata->enable_ext_control;
66869eb0980SLaxman Dewangan max->curr_gpio_val = pdata->dvs_def_state;
66969eb0980SLaxman Dewangan max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
670d2d5437bSLaxman Dewangan max->junction_temp_warning = pdata->junction_temp_warning;
67169eb0980SLaxman Dewangan
6725928f538SLaxman Dewangan max->lru_index[0] = max->curr_vout_reg;
6735928f538SLaxman Dewangan
6745928f538SLaxman Dewangan if (gpio_is_valid(max->dvs_gpio)) {
6755928f538SLaxman Dewangan int gpio_flags;
6765928f538SLaxman Dewangan int i;
6775928f538SLaxman Dewangan
6785928f538SLaxman Dewangan gpio_flags = (pdata->dvs_def_state) ?
6795928f538SLaxman Dewangan GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
6805928f538SLaxman Dewangan ret = devm_gpio_request_one(&client->dev, max->dvs_gpio,
6815928f538SLaxman Dewangan gpio_flags, "max8973-dvs");
6825928f538SLaxman Dewangan if (ret) {
6835928f538SLaxman Dewangan dev_err(&client->dev,
6845928f538SLaxman Dewangan "gpio_request for gpio %d failed, err = %d\n",
6855928f538SLaxman Dewangan max->dvs_gpio, ret);
6865928f538SLaxman Dewangan return ret;
6875928f538SLaxman Dewangan }
6885928f538SLaxman Dewangan
6895928f538SLaxman Dewangan /*
6905928f538SLaxman Dewangan * Initialize the lru index with vout_reg id
6915928f538SLaxman Dewangan * The index 0 will be most recently used and
6925928f538SLaxman Dewangan * set with the max->curr_vout_reg */
6935928f538SLaxman Dewangan for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i)
6945928f538SLaxman Dewangan max->lru_index[i] = i;
6955928f538SLaxman Dewangan max->lru_index[0] = max->curr_vout_reg;
6965928f538SLaxman Dewangan max->lru_index[max->curr_vout_reg] = 0;
697b10c7f3cSMikko Perttunen } else {
698b10c7f3cSMikko Perttunen /*
699b10c7f3cSMikko Perttunen * If there is no DVS GPIO, the VOUT register
700b10c7f3cSMikko Perttunen * address is fixed.
701b10c7f3cSMikko Perttunen */
702b10c7f3cSMikko Perttunen max->ops.set_voltage_sel = regulator_set_voltage_sel_regmap;
703b10c7f3cSMikko Perttunen max->ops.get_voltage_sel = regulator_get_voltage_sel_regmap;
704b10c7f3cSMikko Perttunen max->desc.vsel_reg = max->curr_vout_reg;
705b10c7f3cSMikko Perttunen max->desc.vsel_mask = MAX8973_VOUT_MASK;
7065928f538SLaxman Dewangan }
7075928f538SLaxman Dewangan
708c2ffa973SLaxman Dewangan if (pdata_from_dt)
709c2ffa973SLaxman Dewangan pdata->reg_init_data = of_get_regulator_init_data(&client->dev,
710c2ffa973SLaxman Dewangan client->dev.of_node, &max->desc);
711c2ffa973SLaxman Dewangan
7120f7d6eceSLaxman Dewangan ridata = pdata->reg_init_data;
7130f7d6eceSLaxman Dewangan switch (max->id) {
7140f7d6eceSLaxman Dewangan case MAX8973:
7150f7d6eceSLaxman Dewangan if (!pdata->enable_ext_control) {
7160f7d6eceSLaxman Dewangan max->desc.enable_reg = MAX8973_VOUT;
7170f7d6eceSLaxman Dewangan max->desc.enable_mask = MAX8973_VOUT_ENABLE;
7180f7d6eceSLaxman Dewangan max->ops.enable = regulator_enable_regmap;
7190f7d6eceSLaxman Dewangan max->ops.disable = regulator_disable_regmap;
7200f7d6eceSLaxman Dewangan max->ops.is_enabled = regulator_is_enabled_regmap;
7210f7d6eceSLaxman Dewangan break;
7220f7d6eceSLaxman Dewangan }
7230f7d6eceSLaxman Dewangan
7240f7d6eceSLaxman Dewangan if (ridata && (ridata->constraints.always_on ||
7250f7d6eceSLaxman Dewangan ridata->constraints.boot_on))
726e7d2be69SLinus Walleij gflags = GPIOD_OUT_HIGH;
727e7d2be69SLinus Walleij else
728e7d2be69SLinus Walleij gflags = GPIOD_OUT_LOW;
72963239e4bSLinus Walleij gflags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE;
730e7d2be69SLinus Walleij gpiod = devm_gpiod_get_optional(&client->dev,
731e7d2be69SLinus Walleij "maxim,enable",
732e7d2be69SLinus Walleij gflags);
733e7d2be69SLinus Walleij if (IS_ERR(gpiod))
734e7d2be69SLinus Walleij return PTR_ERR(gpiod);
735e7d2be69SLinus Walleij if (gpiod) {
736e7d2be69SLinus Walleij config.ena_gpiod = gpiod;
737e7d2be69SLinus Walleij max->enable_external_control = true;
7380f7d6eceSLaxman Dewangan }
739e7d2be69SLinus Walleij
7400f7d6eceSLaxman Dewangan break;
7410f7d6eceSLaxman Dewangan
7420f7d6eceSLaxman Dewangan case MAX77621:
743e7d2be69SLinus Walleij /*
744e7d2be69SLinus Walleij * We do not let the core switch this regulator on/off,
745e7d2be69SLinus Walleij * we just leave it on.
746e7d2be69SLinus Walleij */
747e7d2be69SLinus Walleij gpiod = devm_gpiod_get_optional(&client->dev,
748e7d2be69SLinus Walleij "maxim,enable",
749e7d2be69SLinus Walleij GPIOD_OUT_HIGH);
750e7d2be69SLinus Walleij if (IS_ERR(gpiod))
751e7d2be69SLinus Walleij return PTR_ERR(gpiod);
752e7d2be69SLinus Walleij if (gpiod)
753e7d2be69SLinus Walleij max->enable_external_control = true;
7540f7d6eceSLaxman Dewangan
7550f7d6eceSLaxman Dewangan max->desc.enable_reg = MAX8973_VOUT;
7560f7d6eceSLaxman Dewangan max->desc.enable_mask = MAX8973_VOUT_ENABLE;
7570f7d6eceSLaxman Dewangan max->ops.enable = regulator_enable_regmap;
7580f7d6eceSLaxman Dewangan max->ops.disable = regulator_disable_regmap;
7590f7d6eceSLaxman Dewangan max->ops.is_enabled = regulator_is_enabled_regmap;
760ffaab991SLaxman Dewangan max->ops.set_current_limit = max8973_set_current_limit;
761ffaab991SLaxman Dewangan max->ops.get_current_limit = max8973_get_current_limit;
7620f7d6eceSLaxman Dewangan break;
7630f7d6eceSLaxman Dewangan default:
7640f7d6eceSLaxman Dewangan break;
7650f7d6eceSLaxman Dewangan }
7660f7d6eceSLaxman Dewangan
7675928f538SLaxman Dewangan ret = max8973_init_dcdc(max, pdata);
7685928f538SLaxman Dewangan if (ret < 0) {
7695928f538SLaxman Dewangan dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
7705928f538SLaxman Dewangan return ret;
7715928f538SLaxman Dewangan }
7725928f538SLaxman Dewangan
7735928f538SLaxman Dewangan config.dev = &client->dev;
774c2ffa973SLaxman Dewangan config.init_data = pdata->reg_init_data;
7755928f538SLaxman Dewangan config.driver_data = max;
7765928f538SLaxman Dewangan config.of_node = client->dev.of_node;
7775928f538SLaxman Dewangan config.regmap = max->regmap;
7785928f538SLaxman Dewangan
77948bd226fSLinus Walleij /*
78048bd226fSLinus Walleij * Register the regulators
78148bd226fSLinus Walleij * Turn the GPIO descriptor over to the regulator core for
78248bd226fSLinus Walleij * lifecycle management if we pass an ena_gpiod.
78348bd226fSLinus Walleij */
78448bd226fSLinus Walleij if (config.ena_gpiod)
78548bd226fSLinus Walleij devm_gpiod_unhinge(&client->dev, config.ena_gpiod);
7868d581fd0SSachin Kamat rdev = devm_regulator_register(&client->dev, &max->desc, &config);
7875928f538SLaxman Dewangan if (IS_ERR(rdev)) {
7885928f538SLaxman Dewangan ret = PTR_ERR(rdev);
7895928f538SLaxman Dewangan dev_err(max->dev, "regulator register failed, err %d\n", ret);
7905928f538SLaxman Dewangan return ret;
7915928f538SLaxman Dewangan }
7925928f538SLaxman Dewangan
793d2d5437bSLaxman Dewangan max8973_thermal_init(max);
7945928f538SLaxman Dewangan return 0;
7955928f538SLaxman Dewangan }
7965928f538SLaxman Dewangan
7975928f538SLaxman Dewangan static const struct i2c_device_id max8973_id[] = {
7980f7d6eceSLaxman Dewangan {.name = "max8973", .driver_data = MAX8973},
7990f7d6eceSLaxman Dewangan {.name = "max77621", .driver_data = MAX77621},
8005928f538SLaxman Dewangan {},
8015928f538SLaxman Dewangan };
8025928f538SLaxman Dewangan MODULE_DEVICE_TABLE(i2c, max8973_id);
8035928f538SLaxman Dewangan
8045928f538SLaxman Dewangan static struct i2c_driver max8973_i2c_driver = {
8055928f538SLaxman Dewangan .driver = {
8065928f538SLaxman Dewangan .name = "max8973",
807259b93b2SDouglas Anderson .probe_type = PROBE_PREFER_ASYNCHRONOUS,
8080f7d6eceSLaxman Dewangan .of_match_table = of_max8973_match_tbl,
8095928f538SLaxman Dewangan },
810*964e1865SUwe Kleine-König .probe = max8973_probe,
8115928f538SLaxman Dewangan .id_table = max8973_id,
8125928f538SLaxman Dewangan };
8135928f538SLaxman Dewangan
max8973_init(void)8145928f538SLaxman Dewangan static int __init max8973_init(void)
8155928f538SLaxman Dewangan {
8165928f538SLaxman Dewangan return i2c_add_driver(&max8973_i2c_driver);
8175928f538SLaxman Dewangan }
8185928f538SLaxman Dewangan subsys_initcall(max8973_init);
8195928f538SLaxman Dewangan
max8973_cleanup(void)8205928f538SLaxman Dewangan static void __exit max8973_cleanup(void)
8215928f538SLaxman Dewangan {
8225928f538SLaxman Dewangan i2c_del_driver(&max8973_i2c_driver);
8235928f538SLaxman Dewangan }
8245928f538SLaxman Dewangan module_exit(max8973_cleanup);
8255928f538SLaxman Dewangan
8265928f538SLaxman Dewangan MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
8275928f538SLaxman Dewangan MODULE_DESCRIPTION("MAX8973 voltage regulator driver");
8285928f538SLaxman Dewangan MODULE_LICENSE("GPL v2");
829