From nobody Mon Feb 9 01:36:21 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A320DC0015E for ; Tue, 11 Jul 2023 16:28:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231819AbjGKQ2r (ORCPT ); Tue, 11 Jul 2023 12:28:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230119AbjGKQ2l (ORCPT ); Tue, 11 Jul 2023 12:28:41 -0400 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CDE4410D5; Tue, 11 Jul 2023 09:28:39 -0700 (PDT) Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36BFOFRf027386; Tue, 11 Jul 2023 12:28:34 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 3rq4q6kcdx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Jul 2023 12:28:34 -0400 Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 36BGSXIf062722 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 11 Jul 2023 12:28:33 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 11 Jul 2023 12:28:32 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 11 Jul 2023 12:28:32 -0400 Received: from okan.localdomain ([10.158.19.61]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 36BGS1ST025938; Tue, 11 Jul 2023 12:28:23 -0400 From: Okan Sahin To: CC: Rob Herring , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Ibrahim Tilki , , Subject: [PATCH v2 1/2] dt-bindings: regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator Date: Tue, 11 Jul 2023 19:27:47 +0300 Message-ID: <20230711162751.7094-2-okan.sahin@analog.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230711162751.7094-1-okan.sahin@analog.com> References: <20230711162751.7094-1-okan.sahin@analog.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: 8Y9cHGhEQrtAmMMcJ_S8n0dpqTuVtvyv X-Proofpoint-ORIG-GUID: 8Y9cHGhEQrtAmMMcJ_S8n0dpqTuVtvyv X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-11_08,2023-07-11_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 phishscore=0 spamscore=0 bulkscore=0 mlxlogscore=999 malwarescore=0 impostorscore=0 adultscore=0 lowpriorityscore=0 priorityscore=1501 clxscore=1011 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2305260000 definitions=main-2307110148 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add ADI MAX77857/59 and MAX77831 Regulator device tree document. Signed-off-by: Okan Sahin Reviewed-by: Rob Herring --- .../bindings/regulator/adi,max77857.yaml | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/adi,max7785= 7.yaml diff --git a/Documentation/devicetree/bindings/regulator/adi,max77857.yaml = b/Documentation/devicetree/bindings/regulator/adi,max77857.yaml new file mode 100644 index 000000000000..4b6d0d794ba9 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/adi,max77857.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2022 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/adi,max77857.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices MAX77857 Buck-Boost Converter + +maintainers: + - Ibrahim Tilki + +description: Analog Devices MAX77857 Buck-Boost Converter + +properties: + compatible: + enum: + - adi,max77831 + - adi,max77857 + - adi,max77859 + - adi,max77859a + + reg: + description: I2C address of the device + items: + - enum: [0x66, 0x67, 0x6E, 0x6F] + + interrupts: + maxItems: 1 + + adi,switch-frequency-hz: + description: Switching frequency of the Buck-Boost converter in Hz. + items: + - enum: [1200000, 1500000, 1800000, 2100000] + + adi,rtop-ohms: + description: Top feedback resistor value in ohms for external feedback. + minimum: 150000 + maximum: 330000 + + adi,rbot-ohms: + description: Bottom feedback resistor value in ohms for external feedb= ack. + +dependencies: + adi,rtop-ohms: [ 'adi,rbot-ohms' ] + adi,rbot-ohms: [ 'adi,rtop-ohms' ] + +required: + - compatible + - reg + +allOf: + - $ref: regulator.yaml# + - if: + properties: + compatible: + contains: + enum: + - adi,max77831 + + then: + properties: + adi,switch-frequency-hz: + items: + enum: [1200000, 1500000, 1800000] + +unevaluatedProperties: false + +examples: + - | + #include + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + regulator@66 { + reg =3D <0x66>; + compatible =3D "adi,max77857"; + interrupt-parent =3D <&gpio>; + interrupts =3D <26 IRQ_TYPE_EDGE_FALLING>; + + adi,rtop-ohms =3D <312000>; + adi,rbot-ohms =3D <12000>; + }; + }; --=20 2.30.2 From nobody Mon Feb 9 01:36:21 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28EDFC0015E for ; Tue, 11 Jul 2023 16:38:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232172AbjGKQiv (ORCPT ); Tue, 11 Jul 2023 12:38:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229476AbjGKQir (ORCPT ); Tue, 11 Jul 2023 12:38:47 -0400 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0B2A10C7; Tue, 11 Jul 2023 09:38:43 -0700 (PDT) Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 36BFOF8k027393; Tue, 11 Jul 2023 12:38:38 -0400 Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 3rq4q6ke3v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 11 Jul 2023 12:38:38 -0400 Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 36BGcb31063636 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 11 Jul 2023 12:38:37 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 11 Jul 2023 12:38:36 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 11 Jul 2023 12:38:35 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 11 Jul 2023 12:38:35 -0400 Received: from okan.localdomain ([10.158.19.61]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 36BGS1SU025938; Tue, 11 Jul 2023 12:38:22 -0400 From: Okan Sahin To: CC: Liam Girdwood , Mark Brown , "Rob Herring" , Krzysztof Kozlowski , Conor Dooley , Ibrahim Tilki , , Subject: [PATCH v2 2/2] regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator Support Date: Tue, 11 Jul 2023 19:27:48 +0300 Message-ID: <20230711162751.7094-3-okan.sahin@analog.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230711162751.7094-1-okan.sahin@analog.com> References: <20230711162751.7094-1-okan.sahin@analog.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: qgax915CBrtEpUU_J_W595ACJHXRF17- X-Proofpoint-ORIG-GUID: qgax915CBrtEpUU_J_W595ACJHXRF17- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-07-11_09,2023-07-11_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 phishscore=0 spamscore=0 bulkscore=0 mlxlogscore=999 malwarescore=0 impostorscore=0 adultscore=0 lowpriorityscore=0 priorityscore=1501 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2305260000 definitions=main-2307110150 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Regulator driver for MAX77857/59 and MAX77831. The MAX77857 is a high-efficiency, high-performance buck-boost converter targeted for systems requiring a wide input voltage range (2.5V to 16V). The MAX77859 is high-Efficiency Buck-Boost Converter for USB-PD/PPS Applications. It has wide input range (2.5V to 22V) The MAX77831 is a high-efficiency, high-performance buck-boost converter targeted for systems requiring wide input voltage range (2.5V to 16V). Signed-off-by: Okan Sahin --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/max77857-regulator.c | 459 +++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 drivers/regulator/max77857-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index e5f3613c15fa..09eaa1cd90de 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -573,6 +573,16 @@ config REGULATOR_MAX77650 Semiconductor. This device has a SIMO with three independent power rails and an LDO. =20 +config REGULATOR_MAX77857 + tristate "ADI MAX77857/MAX77831 regulator support" + depends on I2C + select REGMAP_I2C + help + This driver controls a ADI MAX77857 and MAX77831 regulators. + via I2C bus. MAX77857 and MAX77831 are high efficiency buck-boost + converters with input voltage range (2.5V to 16V). Say Y here to + enable the regulator driver + config REGULATOR_MAX8649 tristate "Maxim 8649 voltage regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 58dfe0147cd4..e7230846b680 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_REGULATOR_MAX77686) +=3D max77686-regulator.o obj-$(CONFIG_REGULATOR_MAX77693) +=3D max77693-regulator.o obj-$(CONFIG_REGULATOR_MAX77802) +=3D max77802-regulator.o obj-$(CONFIG_REGULATOR_MAX77826) +=3D max77826-regulator.o +obj-$(CONFIG_REGULATOR_MAX77857) +=3D max77857-regulator.o obj-$(CONFIG_REGULATOR_MC13783) +=3D mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) +=3D mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=3D mc13xxx-regulator-core.o diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max= 77857-regulator.c new file mode 100644 index 000000000000..9a566e2d73b4 --- /dev/null +++ b/drivers/regulator/max77857-regulator.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023 Analog Devices, Inc. + * ADI Regulator driver for the MAX77857 + * MAX77859 and MAX77831. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX77857_REG_INT_SRC 0x10 +#define MAX77857_REG_INT_MASK 0x11 +#define MAX77857_REG_CONT1 0x12 +#define MAX77857_REG_CONT2 0x13 +#define MAX77857_REG_CONT3 0x14 + +#define MAX77857_INT_SRC_OCP BIT(0) +#define MAX77857_INT_SRC_THS BIT(1) +#define MAX77857_INT_SRC_HARDSHORT BIT(2) +#define MAX77857_INT_SRC_OVP BIT(3) +#define MAX77857_INT_SRC_POK BIT(4) + +#define MAX77857_ILIM_MASK GENMASK(2, 0) +#define MAX77857_CONT1_FREQ GENMASK(4, 3) +#define MAX77857_CONT3_FPWM BIT(5) + +#define MAX77859_REG_INT_SRC 0x11 +#define MAX77859_REG_CONT1 0x13 +#define MAX77859_REG_CONT2 0x14 +#define MAX77859_REG_CONT3 0x15 +#define MAX77859_REG_CONT5 0x17 +#define MAX77859_CONT2_FPWM BIT(2) +#define MAX77859_CONT2_INTB BIT(3) +#define MAX77859_CONT3_DVS_START BIT(2) +#define MAX77859_VOLTAGE_SEL_MASK GENMASK(9, 0) + +#define MAX77859_CURRENT_MIN 1000000 +#define MAX77859_CURRENT_MAX 5000000 +#define MAX77859_CURRENT_STEP 50000 + +enum max77857_id { + ID_MAX77831 =3D 1, + ID_MAX77857, + ID_MAX77859, + ID_MAX77859A, +}; + +static bool max77857_volatile_reg(struct device *dev, unsigned int reg) +{ + enum max77857_id id =3D (enum max77857_id)dev_get_drvdata(dev); + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + return reg =3D=3D MAX77857_REG_INT_SRC; + case ID_MAX77859: + case ID_MAX77859A: + return reg =3D=3D MAX77859_REG_INT_SRC; + default: + return true; + } +} + +struct regmap_config max77857_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .cache_type =3D REGCACHE_RBTREE, + .volatile_reg =3D max77857_volatile_reg, +}; + +static int max77857_get_status(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret =3D regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val); + if (ret) + return ret; + + if (FIELD_GET(MAX77857_INT_SRC_POK, val)) + return REGULATOR_STATUS_ON; + + return REGULATOR_STATUS_ERROR; +} + +static unsigned int max77857_get_mode(struct regulator_dev *rdev) +{ + enum max77857_id id =3D (enum max77857_id)rdev_get_drvdata(rdev); + unsigned int regval; + int ret; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + ret =3D regmap_read(rdev->regmap, MAX77857_REG_CONT3, ®val); + if (ret) + return ret; + + if (FIELD_GET(MAX77857_CONT3_FPWM, regval)) + return REGULATOR_MODE_FAST; + + break; + case ID_MAX77859: + case ID_MAX77859A: + ret =3D regmap_read(rdev->regmap, MAX77859_REG_CONT2, ®val); + if (ret) + return ret; + + if (FIELD_GET(MAX77859_CONT2_FPWM, regval)) + return REGULATOR_MODE_FAST; + + break; + default: + return -EINVAL; + } + + return REGULATOR_MODE_NORMAL; +} + +static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + enum max77857_id id =3D (enum max77857_id)rdev_get_drvdata(rdev); + unsigned int reg, val; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + reg =3D MAX77857_REG_CONT3; + val =3D MAX77857_CONT3_FPWM; + break; + case ID_MAX77859: + case ID_MAX77859A: + reg =3D MAX77859_REG_CONT2; + val =3D MAX77859_CONT2_FPWM; + break; + default: + return -EINVAL; + } + + switch (mode) { + case REGULATOR_MODE_FAST: + return regmap_set_bits(rdev->regmap, reg, val); + case REGULATOR_MODE_NORMAL: + return regmap_clear_bits(rdev->regmap, reg, val); + default: + return -EINVAL; + } +} + +static int max77857_get_error_flags(struct regulator_dev *rdev, + unsigned int *flags) +{ + unsigned int val; + int ret; + + ret =3D regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val); + if (ret) + return ret; + + *flags =3D 0; + + if (FIELD_GET(MAX77857_INT_SRC_OVP, val)) + *flags |=3D REGULATOR_ERROR_OVER_VOLTAGE_WARN; + + if (FIELD_GET(MAX77857_INT_SRC_OCP, val) || + FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val)) + *flags |=3D REGULATOR_ERROR_OVER_CURRENT; + + if (FIELD_GET(MAX77857_INT_SRC_THS, val)) + *flags |=3D REGULATOR_ERROR_OVER_TEMP; + + if (!FIELD_GET(MAX77857_INT_SRC_POK, val)) + *flags |=3D REGULATOR_ERROR_FAIL; + + return 0; +} + +static struct linear_range max77859_lin_ranges[] =3D { + REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000) +}; + +static const unsigned int max77859_ramp_table[4] =3D { + 1000, 500, 250, 125 +}; + +static int max77859_set_voltage_sel(struct regulator_dev *rdev, + unsigned int sel) +{ + __be16 reg; + int ret; + + reg =3D cpu_to_be16(sel); + + ret =3D regmap_bulk_write(rdev->regmap, MAX77859_REG_CONT3, ®, 2); + if (ret) + return ret; + + /* actually apply new voltage */ + return regmap_set_bits(rdev->regmap, MAX77859_REG_CONT3, + MAX77859_CONT3_DVS_START); +} + +int max77859_get_voltage_sel(struct regulator_dev *rdev) +{ + __be16 reg; + int ret; + + ret =3D regmap_bulk_read(rdev->regmap, MAX77859_REG_CONT3, ®, 2); + if (ret) + return ret; + + return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg)); +} + +int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int= max_uA) +{ + u32 selector; + + if (max_uA < MAX77859_CURRENT_MIN) + return -EINVAL; + + selector =3D 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_ST= EP; + + selector =3D clamp_val(selector, 0x00, 0x7F); + + return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector); +} + +int max77859_get_current_limit(struct regulator_dev *rdev) +{ + u32 selector; + int ret; + + ret =3D regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector); + if (ret) + return ret; + + if (selector <=3D 0x12) + return MAX77859_CURRENT_MIN; + + if (selector >=3D 0x64) + return MAX77859_CURRENT_MAX; + + return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP; +} + +static const struct regulator_ops max77859_regulator_ops =3D { + .list_voltage =3D regulator_list_voltage_linear_range, + .set_voltage_sel =3D max77859_set_voltage_sel, + .get_voltage_sel =3D max77859_get_voltage_sel, + .set_ramp_delay =3D regulator_set_ramp_delay_regmap, + .get_status =3D max77857_get_status, + .set_mode =3D max77857_set_mode, + .get_mode =3D max77857_get_mode, + .get_error_flags =3D max77857_get_error_flags, +}; + +static const struct regulator_ops max77859a_regulator_ops =3D { + .list_voltage =3D regulator_list_voltage_linear_range, + .set_voltage_sel =3D max77859_set_voltage_sel, + .get_voltage_sel =3D max77859_get_voltage_sel, + .set_current_limit =3D max77859_set_current_limit, + .get_current_limit =3D max77859_get_current_limit, + .set_ramp_delay =3D regulator_set_ramp_delay_regmap, + .get_status =3D max77857_get_status, + .set_mode =3D max77857_set_mode, + .get_mode =3D max77857_get_mode, + .get_error_flags =3D max77857_get_error_flags, +}; + +static const struct regulator_ops max77857_regulator_ops =3D { + .list_voltage =3D regulator_list_voltage_linear_range, + .set_voltage_sel =3D regulator_set_voltage_sel_regmap, + .get_voltage_sel =3D regulator_get_voltage_sel_regmap, + .set_ramp_delay =3D regulator_set_ramp_delay_regmap, + .get_status =3D max77857_get_status, + .set_mode =3D max77857_set_mode, + .get_mode =3D max77857_get_mode, + .get_error_flags =3D max77857_get_error_flags, +}; + +static struct linear_range max77857_lin_ranges[] =3D { + REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500) +}; + +static const unsigned int max77857_switch_freq[] =3D { + 1200000, 1500000, 1800000, 2100000 +}; + +static const unsigned int max77857_ramp_table[2][4] =3D { + { 1333, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */ + { 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */ +}; + +static struct regulator_desc max77857_regulator_desc =3D { + .ops =3D &max77857_regulator_ops, + .name =3D "max77857", + .linear_ranges =3D max77857_lin_ranges, + .n_linear_ranges =3D ARRAY_SIZE(max77857_lin_ranges), + .vsel_mask =3D 0xFF, + .vsel_reg =3D MAX77857_REG_CONT2, + .ramp_delay_table =3D max77857_ramp_table[0], + .n_ramp_values =3D ARRAY_SIZE(max77857_ramp_table[0]), + .ramp_reg =3D MAX77857_REG_CONT3, + .ramp_mask =3D GENMASK(1, 0), + .ramp_delay =3D max77857_ramp_table[0][0], + .owner =3D THIS_MODULE, +}; + +static void max77857_calc_range(struct device *dev, enum max77857_id id) +{ + struct linear_range *range; + unsigned long vref_step; + u32 rtop =3D 0; + u32 rbot =3D 0; + + device_property_read_u32(dev, "adi,rtop-ohms", &rtop); + device_property_read_u32(dev, "adi,rbot-ohms", &rbot); + + if (!rbot || !rtop) + return; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + range =3D max77857_lin_ranges; + vref_step =3D 4900UL; + break; + case ID_MAX77859: + case ID_MAX77859A: + range =3D max77859_lin_ranges; + vref_step =3D 1250UL; + break; + } + + range->step =3D DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot); + range->min =3D range->step * range->min_sel; +} + +static int max77857_probe(struct i2c_client *client) +{ + const struct i2c_device_id *i2c_id; + struct device *dev =3D &client->dev; + struct regulator_config cfg =3D { }; + struct regulator_dev *rdev; + struct regmap *regmap; + enum max77857_id id; + u32 switch_freq =3D 0; + int ret; + + i2c_id =3D i2c_client_get_device_id(client); + if (!i2c_id) + return -EINVAL; + + id =3D i2c_id->driver_data; + + dev_set_drvdata(dev, (void *)id); + + if (id =3D=3D ID_MAX77859 || id =3D=3D ID_MAX77859A) { + max77857_regulator_desc.ops =3D &max77859_regulator_ops; + max77857_regulator_desc.linear_ranges =3D max77859_lin_ranges; + max77857_regulator_desc.ramp_delay_table =3D max77859_ramp_table; + max77857_regulator_desc.ramp_delay =3D max77859_ramp_table[0]; + } + + if (id =3D=3D ID_MAX77859A) + max77857_regulator_desc.ops =3D &max77859a_regulator_ops; + + max77857_calc_range(dev, id); + + regmap =3D devm_regmap_init_i2c(client, &max77857_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "cannot initialize regmap\n"); + + device_property_read_u32(dev, "adi,switch-frequency-hz", &switch_freq); + if (switch_freq) { + switch_freq =3D find_closest(switch_freq, max77857_switch_freq, + ARRAY_SIZE(max77857_switch_freq)); + + if (id =3D=3D ID_MAX77831 && switch_freq =3D=3D 3) + switch_freq =3D 2; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + ret =3D regmap_update_bits(regmap, MAX77857_REG_CONT1, + MAX77857_CONT1_FREQ, switch_freq); + + if (switch_freq >=3D 2) + break; + + max77857_regulator_desc.ramp_delay_table =3D max77857_ramp_table[1]; + max77857_regulator_desc.ramp_delay =3D max77857_ramp_table[1][0]; + break; + case ID_MAX77859: + case ID_MAX77859A: + ret =3D regmap_update_bits(regmap, MAX77859_REG_CONT1, + MAX77857_CONT1_FREQ, switch_freq); + break; + } + if (ret) + return ret; + } + + cfg.dev =3D dev; + cfg.driver_data =3D (void *)id; + cfg.regmap =3D regmap; + cfg.init_data =3D of_get_regulator_init_data(dev, dev->of_node, + &max77857_regulator_desc); + if (!cfg.init_data) + return -ENOMEM; + + rdev =3D devm_regulator_register(dev, &max77857_regulator_desc, &cfg); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "cannot register regulator\n"); + + return 0; +} + +const struct i2c_device_id max77857_id[] =3D { + { "max77831", ID_MAX77831 }, + { "max77857", ID_MAX77857 }, + { "max77859", ID_MAX77859 }, + { "max77859a", ID_MAX77859A }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max77857_id); + +static const struct of_device_id max77857_of_id[] =3D { + { .compatible =3D "adi,max77831", .data =3D (void *)ID_MAX77831 }, + { .compatible =3D "adi,max77857", .data =3D (void *)ID_MAX77857 }, + { .compatible =3D "adi,max77859", .data =3D (void *)ID_MAX77859 }, + { .compatible =3D "adi,max77859a", .data =3D (void *)ID_MAX77859A }, + { } +}; +MODULE_DEVICE_TABLE(of, max77857_of_id); + +struct i2c_driver max77857_driver =3D { + .driver =3D { + .name =3D "max77857", + .of_match_table =3D max77857_of_id, + }, + .id_table =3D max77857_id, + .probe_new =3D max77857_probe, +}; +module_i2c_driver(max77857_driver); + +MODULE_DESCRIPTION("Analog Devices MAX77857 Buck-Boost Converter Driver"); +MODULE_AUTHOR("Ibrahim Tilki "); +MODULE_AUTHOR("Okan Sahin "); +MODULE_LICENSE("GPL"); --=20 2.30.2