18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// max77802.c - Regulator driver for the Maxim 77802 48c2ecf20Sopenharmony_ci// 58c2ecf20Sopenharmony_ci// Copyright (C) 2013-2014 Google, Inc 68c2ecf20Sopenharmony_ci// Simon Glass <sjg@chromium.org> 78c2ecf20Sopenharmony_ci// 88c2ecf20Sopenharmony_ci// Copyright (C) 2012 Samsung Electronics 98c2ecf20Sopenharmony_ci// Chiwoong Byun <woong.byun@samsung.com> 108c2ecf20Sopenharmony_ci// Jonghwa Lee <jonghwa3.lee@samsung.com> 118c2ecf20Sopenharmony_ci// 128c2ecf20Sopenharmony_ci// This driver is based on max8997.c 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/kernel.h> 158c2ecf20Sopenharmony_ci#include <linux/bug.h> 168c2ecf20Sopenharmony_ci#include <linux/err.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include <linux/module.h> 198c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 208c2ecf20Sopenharmony_ci#include <linux/regulator/driver.h> 218c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h> 228c2ecf20Sopenharmony_ci#include <linux/regulator/of_regulator.h> 238c2ecf20Sopenharmony_ci#include <linux/mfd/max77686.h> 248c2ecf20Sopenharmony_ci#include <linux/mfd/max77686-private.h> 258c2ecf20Sopenharmony_ci#include <dt-bindings/regulator/maxim,max77802.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* Default ramp delay in case it is not manually set */ 288c2ecf20Sopenharmony_ci#define MAX77802_RAMP_DELAY 100000 /* uV/us */ 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define MAX77802_OPMODE_SHIFT_LDO 6 318c2ecf20Sopenharmony_ci#define MAX77802_OPMODE_BUCK234_SHIFT 4 328c2ecf20Sopenharmony_ci#define MAX77802_OPMODE_MASK 0x3 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define MAX77802_VSEL_MASK 0x3F 358c2ecf20Sopenharmony_ci#define MAX77802_DVS_VSEL_MASK 0xFF 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define MAX77802_RAMP_RATE_MASK_2BIT 0xC0 388c2ecf20Sopenharmony_ci#define MAX77802_RAMP_RATE_SHIFT_2BIT 6 398c2ecf20Sopenharmony_ci#define MAX77802_RAMP_RATE_MASK_4BIT 0xF0 408c2ecf20Sopenharmony_ci#define MAX77802_RAMP_RATE_SHIFT_4BIT 4 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#define MAX77802_STATUS_OFF 0x0 438c2ecf20Sopenharmony_ci#define MAX77802_OFF_PWRREQ 0x1 448c2ecf20Sopenharmony_ci#define MAX77802_LP_PWRREQ 0x2 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* MAX77802 has two register formats: 2-bit and 4-bit */ 478c2ecf20Sopenharmony_cistatic const unsigned int ramp_table_77802_2bit[] = { 488c2ecf20Sopenharmony_ci 12500, 498c2ecf20Sopenharmony_ci 25000, 508c2ecf20Sopenharmony_ci 50000, 518c2ecf20Sopenharmony_ci 100000, 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic unsigned int ramp_table_77802_4bit[] = { 558c2ecf20Sopenharmony_ci 1000, 2000, 3030, 4000, 568c2ecf20Sopenharmony_ci 5000, 5880, 7140, 8330, 578c2ecf20Sopenharmony_ci 9090, 10000, 11110, 12500, 588c2ecf20Sopenharmony_ci 16670, 25000, 50000, 100000, 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistruct max77802_regulator_prv { 628c2ecf20Sopenharmony_ci /* Array indexed by regulator id */ 638c2ecf20Sopenharmony_ci unsigned int opmode[MAX77802_REG_MAX]; 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic inline unsigned int max77802_map_mode(unsigned int mode) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci return mode == MAX77802_OPMODE_NORMAL ? 698c2ecf20Sopenharmony_ci REGULATOR_MODE_NORMAL : REGULATOR_MODE_STANDBY; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic int max77802_get_opmode_shift(int id) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 && 758c2ecf20Sopenharmony_ci id <= MAX77802_BUCK10)) 768c2ecf20Sopenharmony_ci return 0; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (id >= MAX77802_BUCK2 && id <= MAX77802_BUCK4) 798c2ecf20Sopenharmony_ci return MAX77802_OPMODE_BUCK234_SHIFT; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (id >= MAX77802_LDO1 && id <= MAX77802_LDO35) 828c2ecf20Sopenharmony_ci return MAX77802_OPMODE_SHIFT_LDO; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci return -EINVAL; 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/** 888c2ecf20Sopenharmony_ci * max77802_set_suspend_disable - Disable the regulator during system suspend 898c2ecf20Sopenharmony_ci * @rdev: regulator to mark as disabled 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * All regulators expect LDO 1, 3, 20 and 21 support OFF by PWRREQ. 928c2ecf20Sopenharmony_ci * Configure the regulator so the PMIC will turn it OFF during system suspend. 938c2ecf20Sopenharmony_ci */ 948c2ecf20Sopenharmony_cistatic int max77802_set_suspend_disable(struct regulator_dev *rdev) 958c2ecf20Sopenharmony_ci{ 968c2ecf20Sopenharmony_ci unsigned int val = MAX77802_OFF_PWRREQ; 978c2ecf20Sopenharmony_ci struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); 988c2ecf20Sopenharmony_ci unsigned int id = rdev_get_id(rdev); 998c2ecf20Sopenharmony_ci int shift = max77802_get_opmode_shift(id); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) 1028c2ecf20Sopenharmony_ci return -EINVAL; 1038c2ecf20Sopenharmony_ci max77802->opmode[id] = val; 1048c2ecf20Sopenharmony_ci return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 1058c2ecf20Sopenharmony_ci rdev->desc->enable_mask, val << shift); 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* 1098c2ecf20Sopenharmony_ci * Some LDOs support Low Power Mode while the system is running. 1108c2ecf20Sopenharmony_ci * 1118c2ecf20Sopenharmony_ci * LDOs 1, 3, 20, 21. 1128c2ecf20Sopenharmony_ci */ 1138c2ecf20Sopenharmony_cistatic int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); 1168c2ecf20Sopenharmony_ci unsigned int id = rdev_get_id(rdev); 1178c2ecf20Sopenharmony_ci unsigned int val; 1188c2ecf20Sopenharmony_ci int shift = max77802_get_opmode_shift(id); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci switch (mode) { 1218c2ecf20Sopenharmony_ci case REGULATOR_MODE_STANDBY: 1228c2ecf20Sopenharmony_ci val = MAX77802_OPMODE_LP; /* ON in Low Power Mode */ 1238c2ecf20Sopenharmony_ci break; 1248c2ecf20Sopenharmony_ci case REGULATOR_MODE_NORMAL: 1258c2ecf20Sopenharmony_ci val = MAX77802_OPMODE_NORMAL; /* ON in Normal Mode */ 1268c2ecf20Sopenharmony_ci break; 1278c2ecf20Sopenharmony_ci default: 1288c2ecf20Sopenharmony_ci dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", 1298c2ecf20Sopenharmony_ci rdev->desc->name, mode); 1308c2ecf20Sopenharmony_ci return -EINVAL; 1318c2ecf20Sopenharmony_ci } 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) 1348c2ecf20Sopenharmony_ci return -EINVAL; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci max77802->opmode[id] = val; 1378c2ecf20Sopenharmony_ci return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 1388c2ecf20Sopenharmony_ci rdev->desc->enable_mask, val << shift); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic unsigned max77802_get_mode(struct regulator_dev *rdev) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); 1448c2ecf20Sopenharmony_ci unsigned int id = rdev_get_id(rdev); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) 1478c2ecf20Sopenharmony_ci return -EINVAL; 1488c2ecf20Sopenharmony_ci return max77802_map_mode(max77802->opmode[id]); 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci/** 1528c2ecf20Sopenharmony_ci * max77802_set_suspend_mode - set regulator opmode when the system is suspended 1538c2ecf20Sopenharmony_ci * @rdev: regulator to change mode 1548c2ecf20Sopenharmony_ci * @mode: operating mode to be set 1558c2ecf20Sopenharmony_ci * 1568c2ecf20Sopenharmony_ci * Will set the operating mode for the regulators during system suspend. 1578c2ecf20Sopenharmony_ci * This function is valid for the three different enable control logics: 1588c2ecf20Sopenharmony_ci * 1598c2ecf20Sopenharmony_ci * Enable Control Logic1 by PWRREQ (BUCK 2-4 and LDOs 2, 4-19, 22-35) 1608c2ecf20Sopenharmony_ci * Enable Control Logic2 by PWRREQ (LDOs 1, 20, 21) 1618c2ecf20Sopenharmony_ci * Enable Control Logic3 by PWRREQ (LDO 3) 1628c2ecf20Sopenharmony_ci * 1638c2ecf20Sopenharmony_ci * If setting the regulator mode fails, the function only warns but does 1648c2ecf20Sopenharmony_ci * not return an error code to avoid the regulator core to stop setting 1658c2ecf20Sopenharmony_ci * the operating mode for the remaining regulators. 1668c2ecf20Sopenharmony_ci */ 1678c2ecf20Sopenharmony_cistatic int max77802_set_suspend_mode(struct regulator_dev *rdev, 1688c2ecf20Sopenharmony_ci unsigned int mode) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); 1718c2ecf20Sopenharmony_ci unsigned int id = rdev_get_id(rdev); 1728c2ecf20Sopenharmony_ci unsigned int val; 1738c2ecf20Sopenharmony_ci int shift = max77802_get_opmode_shift(id); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) 1768c2ecf20Sopenharmony_ci return -EINVAL; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci /* 1798c2ecf20Sopenharmony_ci * If the regulator has been disabled for suspend 1808c2ecf20Sopenharmony_ci * then is invalid to try setting a suspend mode. 1818c2ecf20Sopenharmony_ci */ 1828c2ecf20Sopenharmony_ci if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) { 1838c2ecf20Sopenharmony_ci dev_warn(&rdev->dev, "%s: is disabled, mode: 0x%x not set\n", 1848c2ecf20Sopenharmony_ci rdev->desc->name, mode); 1858c2ecf20Sopenharmony_ci return 0; 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci switch (mode) { 1898c2ecf20Sopenharmony_ci case REGULATOR_MODE_STANDBY: 1908c2ecf20Sopenharmony_ci /* 1918c2ecf20Sopenharmony_ci * If the regulator opmode is normal then enable 1928c2ecf20Sopenharmony_ci * ON in Low Power Mode by PWRREQ. If the mode is 1938c2ecf20Sopenharmony_ci * already Low Power then no action is required. 1948c2ecf20Sopenharmony_ci */ 1958c2ecf20Sopenharmony_ci if (max77802->opmode[id] == MAX77802_OPMODE_NORMAL) 1968c2ecf20Sopenharmony_ci val = MAX77802_LP_PWRREQ; 1978c2ecf20Sopenharmony_ci else 1988c2ecf20Sopenharmony_ci return 0; 1998c2ecf20Sopenharmony_ci break; 2008c2ecf20Sopenharmony_ci case REGULATOR_MODE_NORMAL: 2018c2ecf20Sopenharmony_ci /* 2028c2ecf20Sopenharmony_ci * If the regulator operating mode is Low Power then 2038c2ecf20Sopenharmony_ci * normal is not a valid opmode in suspend. If the 2048c2ecf20Sopenharmony_ci * mode is already normal then no action is required. 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ci if (max77802->opmode[id] == MAX77802_OPMODE_LP) 2078c2ecf20Sopenharmony_ci dev_warn(&rdev->dev, "%s: in Low Power: 0x%x invalid\n", 2088c2ecf20Sopenharmony_ci rdev->desc->name, mode); 2098c2ecf20Sopenharmony_ci return 0; 2108c2ecf20Sopenharmony_ci default: 2118c2ecf20Sopenharmony_ci dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", 2128c2ecf20Sopenharmony_ci rdev->desc->name, mode); 2138c2ecf20Sopenharmony_ci return -EINVAL; 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 2178c2ecf20Sopenharmony_ci rdev->desc->enable_mask, val << shift); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic int max77802_enable(struct regulator_dev *rdev) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); 2238c2ecf20Sopenharmony_ci unsigned int id = rdev_get_id(rdev); 2248c2ecf20Sopenharmony_ci int shift = max77802_get_opmode_shift(id); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) 2278c2ecf20Sopenharmony_ci return -EINVAL; 2288c2ecf20Sopenharmony_ci if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) 2298c2ecf20Sopenharmony_ci max77802->opmode[id] = MAX77802_OPMODE_NORMAL; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 2328c2ecf20Sopenharmony_ci rdev->desc->enable_mask, 2338c2ecf20Sopenharmony_ci max77802->opmode[id] << shift); 2348c2ecf20Sopenharmony_ci} 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic int max77802_find_ramp_value(struct regulator_dev *rdev, 2378c2ecf20Sopenharmony_ci const unsigned int limits[], int size, 2388c2ecf20Sopenharmony_ci unsigned int ramp_delay) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci int i; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci for (i = 0; i < size; i++) { 2438c2ecf20Sopenharmony_ci if (ramp_delay <= limits[i]) 2448c2ecf20Sopenharmony_ci return i; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci /* Use maximum value for no ramp control */ 2488c2ecf20Sopenharmony_ci dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n", 2498c2ecf20Sopenharmony_ci rdev->desc->name, ramp_delay); 2508c2ecf20Sopenharmony_ci return size - 1; 2518c2ecf20Sopenharmony_ci} 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci/* Used for BUCKs 2-4 */ 2548c2ecf20Sopenharmony_cistatic int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev, 2558c2ecf20Sopenharmony_ci int ramp_delay) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci int id = rdev_get_id(rdev); 2588c2ecf20Sopenharmony_ci unsigned int ramp_value; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci if (id > MAX77802_BUCK4) { 2618c2ecf20Sopenharmony_ci dev_warn(&rdev->dev, 2628c2ecf20Sopenharmony_ci "%s: regulator: ramp delay not supported\n", 2638c2ecf20Sopenharmony_ci rdev->desc->name); 2648c2ecf20Sopenharmony_ci return -EINVAL; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit, 2678c2ecf20Sopenharmony_ci ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay); 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 2708c2ecf20Sopenharmony_ci MAX77802_RAMP_RATE_MASK_2BIT, 2718c2ecf20Sopenharmony_ci ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT); 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci/* For BUCK1, 6 */ 2758c2ecf20Sopenharmony_cistatic int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev, 2768c2ecf20Sopenharmony_ci int ramp_delay) 2778c2ecf20Sopenharmony_ci{ 2788c2ecf20Sopenharmony_ci unsigned int ramp_value; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit, 2818c2ecf20Sopenharmony_ci ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 2848c2ecf20Sopenharmony_ci MAX77802_RAMP_RATE_MASK_4BIT, 2858c2ecf20Sopenharmony_ci ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT); 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci/* 2898c2ecf20Sopenharmony_ci * LDOs 2, 4-19, 22-35 2908c2ecf20Sopenharmony_ci */ 2918c2ecf20Sopenharmony_cistatic const struct regulator_ops max77802_ldo_ops_logic1 = { 2928c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 2938c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear, 2948c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 2958c2ecf20Sopenharmony_ci .enable = max77802_enable, 2968c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 2978c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 2988c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 2998c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 3008c2ecf20Sopenharmony_ci .set_suspend_disable = max77802_set_suspend_disable, 3018c2ecf20Sopenharmony_ci .set_suspend_mode = max77802_set_suspend_mode, 3028c2ecf20Sopenharmony_ci}; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci/* 3058c2ecf20Sopenharmony_ci * LDOs 1, 20, 21, 3 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_cistatic const struct regulator_ops max77802_ldo_ops_logic2 = { 3088c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 3098c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear, 3108c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 3118c2ecf20Sopenharmony_ci .enable = max77802_enable, 3128c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 3138c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 3148c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 3158c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 3168c2ecf20Sopenharmony_ci .set_mode = max77802_set_mode, 3178c2ecf20Sopenharmony_ci .get_mode = max77802_get_mode, 3188c2ecf20Sopenharmony_ci .set_suspend_mode = max77802_set_suspend_mode, 3198c2ecf20Sopenharmony_ci}; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* BUCKS 1, 6 */ 3228c2ecf20Sopenharmony_cistatic const struct regulator_ops max77802_buck_16_dvs_ops = { 3238c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 3248c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear, 3258c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 3268c2ecf20Sopenharmony_ci .enable = max77802_enable, 3278c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 3288c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 3298c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 3308c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 3318c2ecf20Sopenharmony_ci .set_ramp_delay = max77802_set_ramp_delay_4bit, 3328c2ecf20Sopenharmony_ci .set_suspend_disable = max77802_set_suspend_disable, 3338c2ecf20Sopenharmony_ci}; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci/* BUCKs 2-4 */ 3368c2ecf20Sopenharmony_cistatic const struct regulator_ops max77802_buck_234_ops = { 3378c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 3388c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear, 3398c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 3408c2ecf20Sopenharmony_ci .enable = max77802_enable, 3418c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 3428c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 3438c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 3448c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 3458c2ecf20Sopenharmony_ci .set_ramp_delay = max77802_set_ramp_delay_2bit, 3468c2ecf20Sopenharmony_ci .set_suspend_disable = max77802_set_suspend_disable, 3478c2ecf20Sopenharmony_ci .set_suspend_mode = max77802_set_suspend_mode, 3488c2ecf20Sopenharmony_ci}; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci/* BUCKs 5, 7-10 */ 3518c2ecf20Sopenharmony_cistatic const struct regulator_ops max77802_buck_dvs_ops = { 3528c2ecf20Sopenharmony_ci .list_voltage = regulator_list_voltage_linear, 3538c2ecf20Sopenharmony_ci .map_voltage = regulator_map_voltage_linear, 3548c2ecf20Sopenharmony_ci .is_enabled = regulator_is_enabled_regmap, 3558c2ecf20Sopenharmony_ci .enable = max77802_enable, 3568c2ecf20Sopenharmony_ci .disable = regulator_disable_regmap, 3578c2ecf20Sopenharmony_ci .get_voltage_sel = regulator_get_voltage_sel_regmap, 3588c2ecf20Sopenharmony_ci .set_voltage_sel = regulator_set_voltage_sel_regmap, 3598c2ecf20Sopenharmony_ci .set_voltage_time_sel = regulator_set_voltage_time_sel, 3608c2ecf20Sopenharmony_ci .set_ramp_delay = max77802_set_ramp_delay_2bit, 3618c2ecf20Sopenharmony_ci .set_suspend_disable = max77802_set_suspend_disable, 3628c2ecf20Sopenharmony_ci}; 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci/* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */ 3658c2ecf20Sopenharmony_ci#define regulator_77802_desc_p_ldo(num, supply, log) { \ 3668c2ecf20Sopenharmony_ci .name = "LDO"#num, \ 3678c2ecf20Sopenharmony_ci .of_match = of_match_ptr("LDO"#num), \ 3688c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 3698c2ecf20Sopenharmony_ci .id = MAX77802_LDO##num, \ 3708c2ecf20Sopenharmony_ci .supply_name = "inl"#supply, \ 3718c2ecf20Sopenharmony_ci .ops = &max77802_ldo_ops_logic##log, \ 3728c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3738c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 3748c2ecf20Sopenharmony_ci .min_uV = 800000, \ 3758c2ecf20Sopenharmony_ci .uV_step = 50000, \ 3768c2ecf20Sopenharmony_ci .ramp_delay = MAX77802_RAMP_DELAY, \ 3778c2ecf20Sopenharmony_ci .n_voltages = 1 << 6, \ 3788c2ecf20Sopenharmony_ci .vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ 3798c2ecf20Sopenharmony_ci .vsel_mask = MAX77802_VSEL_MASK, \ 3808c2ecf20Sopenharmony_ci .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ 3818c2ecf20Sopenharmony_ci .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ 3828c2ecf20Sopenharmony_ci .of_map_mode = max77802_map_mode, \ 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci/* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */ 3868c2ecf20Sopenharmony_ci#define regulator_77802_desc_n_ldo(num, supply, log) { \ 3878c2ecf20Sopenharmony_ci .name = "LDO"#num, \ 3888c2ecf20Sopenharmony_ci .of_match = of_match_ptr("LDO"#num), \ 3898c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 3908c2ecf20Sopenharmony_ci .id = MAX77802_LDO##num, \ 3918c2ecf20Sopenharmony_ci .supply_name = "inl"#supply, \ 3928c2ecf20Sopenharmony_ci .ops = &max77802_ldo_ops_logic##log, \ 3938c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 3948c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 3958c2ecf20Sopenharmony_ci .min_uV = 800000, \ 3968c2ecf20Sopenharmony_ci .uV_step = 25000, \ 3978c2ecf20Sopenharmony_ci .ramp_delay = MAX77802_RAMP_DELAY, \ 3988c2ecf20Sopenharmony_ci .n_voltages = 1 << 6, \ 3998c2ecf20Sopenharmony_ci .vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ 4008c2ecf20Sopenharmony_ci .vsel_mask = MAX77802_VSEL_MASK, \ 4018c2ecf20Sopenharmony_ci .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ 4028c2ecf20Sopenharmony_ci .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ 4038c2ecf20Sopenharmony_ci .of_map_mode = max77802_map_mode, \ 4048c2ecf20Sopenharmony_ci} 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci/* BUCKs 1, 6 */ 4078c2ecf20Sopenharmony_ci#define regulator_77802_desc_16_buck(num) { \ 4088c2ecf20Sopenharmony_ci .name = "BUCK"#num, \ 4098c2ecf20Sopenharmony_ci .of_match = of_match_ptr("BUCK"#num), \ 4108c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 4118c2ecf20Sopenharmony_ci .id = MAX77802_BUCK##num, \ 4128c2ecf20Sopenharmony_ci .supply_name = "inb"#num, \ 4138c2ecf20Sopenharmony_ci .ops = &max77802_buck_16_dvs_ops, \ 4148c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 4158c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 4168c2ecf20Sopenharmony_ci .min_uV = 612500, \ 4178c2ecf20Sopenharmony_ci .uV_step = 6250, \ 4188c2ecf20Sopenharmony_ci .ramp_delay = MAX77802_RAMP_DELAY, \ 4198c2ecf20Sopenharmony_ci .n_voltages = 1 << 8, \ 4208c2ecf20Sopenharmony_ci .vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \ 4218c2ecf20Sopenharmony_ci .vsel_mask = MAX77802_DVS_VSEL_MASK, \ 4228c2ecf20Sopenharmony_ci .enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \ 4238c2ecf20Sopenharmony_ci .enable_mask = MAX77802_OPMODE_MASK, \ 4248c2ecf20Sopenharmony_ci .of_map_mode = max77802_map_mode, \ 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci/* BUCKS 2-4 */ 4288c2ecf20Sopenharmony_ci#define regulator_77802_desc_234_buck(num) { \ 4298c2ecf20Sopenharmony_ci .name = "BUCK"#num, \ 4308c2ecf20Sopenharmony_ci .of_match = of_match_ptr("BUCK"#num), \ 4318c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 4328c2ecf20Sopenharmony_ci .id = MAX77802_BUCK##num, \ 4338c2ecf20Sopenharmony_ci .supply_name = "inb"#num, \ 4348c2ecf20Sopenharmony_ci .ops = &max77802_buck_234_ops, \ 4358c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 4368c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 4378c2ecf20Sopenharmony_ci .min_uV = 600000, \ 4388c2ecf20Sopenharmony_ci .uV_step = 6250, \ 4398c2ecf20Sopenharmony_ci .ramp_delay = MAX77802_RAMP_DELAY, \ 4408c2ecf20Sopenharmony_ci .n_voltages = 0x91, \ 4418c2ecf20Sopenharmony_ci .vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \ 4428c2ecf20Sopenharmony_ci .vsel_mask = MAX77802_DVS_VSEL_MASK, \ 4438c2ecf20Sopenharmony_ci .enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \ 4448c2ecf20Sopenharmony_ci .enable_mask = MAX77802_OPMODE_MASK << \ 4458c2ecf20Sopenharmony_ci MAX77802_OPMODE_BUCK234_SHIFT, \ 4468c2ecf20Sopenharmony_ci .of_map_mode = max77802_map_mode, \ 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci/* BUCK 5 */ 4508c2ecf20Sopenharmony_ci#define regulator_77802_desc_buck5(num) { \ 4518c2ecf20Sopenharmony_ci .name = "BUCK"#num, \ 4528c2ecf20Sopenharmony_ci .of_match = of_match_ptr("BUCK"#num), \ 4538c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 4548c2ecf20Sopenharmony_ci .id = MAX77802_BUCK##num, \ 4558c2ecf20Sopenharmony_ci .supply_name = "inb"#num, \ 4568c2ecf20Sopenharmony_ci .ops = &max77802_buck_dvs_ops, \ 4578c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 4588c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 4598c2ecf20Sopenharmony_ci .min_uV = 750000, \ 4608c2ecf20Sopenharmony_ci .uV_step = 50000, \ 4618c2ecf20Sopenharmony_ci .ramp_delay = MAX77802_RAMP_DELAY, \ 4628c2ecf20Sopenharmony_ci .n_voltages = 1 << 6, \ 4638c2ecf20Sopenharmony_ci .vsel_reg = MAX77802_REG_BUCK5OUT, \ 4648c2ecf20Sopenharmony_ci .vsel_mask = MAX77802_VSEL_MASK, \ 4658c2ecf20Sopenharmony_ci .enable_reg = MAX77802_REG_BUCK5CTRL, \ 4668c2ecf20Sopenharmony_ci .enable_mask = MAX77802_OPMODE_MASK, \ 4678c2ecf20Sopenharmony_ci .of_map_mode = max77802_map_mode, \ 4688c2ecf20Sopenharmony_ci} 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci/* BUCKs 7-10 */ 4718c2ecf20Sopenharmony_ci#define regulator_77802_desc_buck7_10(num) { \ 4728c2ecf20Sopenharmony_ci .name = "BUCK"#num, \ 4738c2ecf20Sopenharmony_ci .of_match = of_match_ptr("BUCK"#num), \ 4748c2ecf20Sopenharmony_ci .regulators_node = of_match_ptr("regulators"), \ 4758c2ecf20Sopenharmony_ci .id = MAX77802_BUCK##num, \ 4768c2ecf20Sopenharmony_ci .supply_name = "inb"#num, \ 4778c2ecf20Sopenharmony_ci .ops = &max77802_buck_dvs_ops, \ 4788c2ecf20Sopenharmony_ci .type = REGULATOR_VOLTAGE, \ 4798c2ecf20Sopenharmony_ci .owner = THIS_MODULE, \ 4808c2ecf20Sopenharmony_ci .min_uV = 750000, \ 4818c2ecf20Sopenharmony_ci .uV_step = 50000, \ 4828c2ecf20Sopenharmony_ci .ramp_delay = MAX77802_RAMP_DELAY, \ 4838c2ecf20Sopenharmony_ci .n_voltages = 1 << 6, \ 4848c2ecf20Sopenharmony_ci .vsel_reg = MAX77802_REG_BUCK7OUT + (num - 7) * 3, \ 4858c2ecf20Sopenharmony_ci .vsel_mask = MAX77802_VSEL_MASK, \ 4868c2ecf20Sopenharmony_ci .enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \ 4878c2ecf20Sopenharmony_ci .enable_mask = MAX77802_OPMODE_MASK, \ 4888c2ecf20Sopenharmony_ci .of_map_mode = max77802_map_mode, \ 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic const struct regulator_desc regulators[] = { 4928c2ecf20Sopenharmony_ci regulator_77802_desc_16_buck(1), 4938c2ecf20Sopenharmony_ci regulator_77802_desc_234_buck(2), 4948c2ecf20Sopenharmony_ci regulator_77802_desc_234_buck(3), 4958c2ecf20Sopenharmony_ci regulator_77802_desc_234_buck(4), 4968c2ecf20Sopenharmony_ci regulator_77802_desc_buck5(5), 4978c2ecf20Sopenharmony_ci regulator_77802_desc_16_buck(6), 4988c2ecf20Sopenharmony_ci regulator_77802_desc_buck7_10(7), 4998c2ecf20Sopenharmony_ci regulator_77802_desc_buck7_10(8), 5008c2ecf20Sopenharmony_ci regulator_77802_desc_buck7_10(9), 5018c2ecf20Sopenharmony_ci regulator_77802_desc_buck7_10(10), 5028c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(1, 10, 2), 5038c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(2, 10, 1), 5048c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(3, 3, 2), 5058c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(4, 6, 1), 5068c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(5, 3, 1), 5078c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(6, 3, 1), 5088c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(7, 3, 1), 5098c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(8, 1, 1), 5108c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(9, 5, 1), 5118c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(10, 4, 1), 5128c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(11, 4, 1), 5138c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(12, 9, 1), 5148c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(13, 4, 1), 5158c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(14, 4, 1), 5168c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(15, 1, 1), 5178c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(17, 2, 1), 5188c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(18, 7, 1), 5198c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(19, 5, 1), 5208c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(20, 7, 2), 5218c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(21, 6, 2), 5228c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(23, 9, 1), 5238c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(24, 6, 1), 5248c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(25, 9, 1), 5258c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(26, 9, 1), 5268c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(27, 2, 1), 5278c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(28, 7, 1), 5288c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(29, 7, 1), 5298c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(30, 2, 1), 5308c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(32, 9, 1), 5318c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(33, 6, 1), 5328c2ecf20Sopenharmony_ci regulator_77802_desc_p_ldo(34, 9, 1), 5338c2ecf20Sopenharmony_ci regulator_77802_desc_n_ldo(35, 2, 1), 5348c2ecf20Sopenharmony_ci}; 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_cistatic int max77802_pmic_probe(struct platform_device *pdev) 5378c2ecf20Sopenharmony_ci{ 5388c2ecf20Sopenharmony_ci struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); 5398c2ecf20Sopenharmony_ci struct max77802_regulator_prv *max77802; 5408c2ecf20Sopenharmony_ci int i, val; 5418c2ecf20Sopenharmony_ci struct regulator_config config = { }; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci max77802 = devm_kzalloc(&pdev->dev, 5448c2ecf20Sopenharmony_ci sizeof(struct max77802_regulator_prv), 5458c2ecf20Sopenharmony_ci GFP_KERNEL); 5468c2ecf20Sopenharmony_ci if (!max77802) 5478c2ecf20Sopenharmony_ci return -ENOMEM; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci config.dev = iodev->dev; 5508c2ecf20Sopenharmony_ci config.regmap = iodev->regmap; 5518c2ecf20Sopenharmony_ci config.driver_data = max77802; 5528c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, max77802); 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci for (i = 0; i < MAX77802_REG_MAX; i++) { 5558c2ecf20Sopenharmony_ci struct regulator_dev *rdev; 5568c2ecf20Sopenharmony_ci unsigned int id = regulators[i].id; 5578c2ecf20Sopenharmony_ci int shift = max77802_get_opmode_shift(id); 5588c2ecf20Sopenharmony_ci int ret; 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val); 5618c2ecf20Sopenharmony_ci if (ret < 0) { 5628c2ecf20Sopenharmony_ci dev_warn(&pdev->dev, 5638c2ecf20Sopenharmony_ci "cannot read current mode for %d\n", i); 5648c2ecf20Sopenharmony_ci val = MAX77802_OPMODE_NORMAL; 5658c2ecf20Sopenharmony_ci } else { 5668c2ecf20Sopenharmony_ci val = val >> shift & MAX77802_OPMODE_MASK; 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci /* 5708c2ecf20Sopenharmony_ci * If the regulator is disabled and the system warm rebooted, 5718c2ecf20Sopenharmony_ci * the hardware reports OFF as the regulator operating mode. 5728c2ecf20Sopenharmony_ci * Default to operating mode NORMAL in that case. 5738c2ecf20Sopenharmony_ci */ 5748c2ecf20Sopenharmony_ci if (id < ARRAY_SIZE(max77802->opmode)) { 5758c2ecf20Sopenharmony_ci if (val == MAX77802_STATUS_OFF) 5768c2ecf20Sopenharmony_ci max77802->opmode[id] = MAX77802_OPMODE_NORMAL; 5778c2ecf20Sopenharmony_ci else 5788c2ecf20Sopenharmony_ci max77802->opmode[id] = val; 5798c2ecf20Sopenharmony_ci } 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci rdev = devm_regulator_register(&pdev->dev, 5828c2ecf20Sopenharmony_ci ®ulators[i], &config); 5838c2ecf20Sopenharmony_ci if (IS_ERR(rdev)) { 5848c2ecf20Sopenharmony_ci ret = PTR_ERR(rdev); 5858c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 5868c2ecf20Sopenharmony_ci "regulator init failed for %d: %d\n", i, ret); 5878c2ecf20Sopenharmony_ci return ret; 5888c2ecf20Sopenharmony_ci } 5898c2ecf20Sopenharmony_ci } 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci return 0; 5928c2ecf20Sopenharmony_ci} 5938c2ecf20Sopenharmony_ci 5948c2ecf20Sopenharmony_cistatic const struct platform_device_id max77802_pmic_id[] = { 5958c2ecf20Sopenharmony_ci {"max77802-pmic", 0}, 5968c2ecf20Sopenharmony_ci { }, 5978c2ecf20Sopenharmony_ci}; 5988c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(platform, max77802_pmic_id); 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_cistatic struct platform_driver max77802_pmic_driver = { 6018c2ecf20Sopenharmony_ci .driver = { 6028c2ecf20Sopenharmony_ci .name = "max77802-pmic", 6038c2ecf20Sopenharmony_ci }, 6048c2ecf20Sopenharmony_ci .probe = max77802_pmic_probe, 6058c2ecf20Sopenharmony_ci .id_table = max77802_pmic_id, 6068c2ecf20Sopenharmony_ci}; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_cimodule_platform_driver(max77802_pmic_driver); 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MAXIM 77802 Regulator Driver"); 6118c2ecf20Sopenharmony_ciMODULE_AUTHOR("Simon Glass <sjg@chromium.org>"); 6128c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 613