From patchwork Tue Jul 11 16:27:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sahin, Okan" X-Patchwork-Id: 118644 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp605067vqm; Tue, 11 Jul 2023 09:31:16 -0700 (PDT) X-Google-Smtp-Source: APBJJlFiS1upko38Y5DMzhWH84fzrtajEyaOELOj63tYifSeV6KcQovjf/yXEGXpOUaPzXMP+aFe X-Received: by 2002:a2e:9844:0:b0:2b6:9fdf:d8f4 with SMTP id e4-20020a2e9844000000b002b69fdfd8f4mr13058515ljj.29.1689093076189; Tue, 11 Jul 2023 09:31:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689093076; cv=none; d=google.com; s=arc-20160816; b=Z3TUYFgVjAZgwFLnJMPPUJ7m8IAvuhHIejp8YvqdOZgWEujn/sB+/FhhqwH/p2I3ii c1kD7qjd+qKZqUq/HwO9bbo/2AgY/ID2OW4D5zwpkHTLxXmxlJgcru5/dSYimhb1TrO/ +5BdrdZY/VCBK0VlcIkGLeeh7vlFApPbP2GNfaqLA4gqUyZz9viZ6Kk3v8jHd3zj4Jjn 9LL/fdi36sNU0RPY+HhQhLjq4byuu5mPqxxxO0rxF8zba3YyhbUW2qmM3K5NNHU0mCRb 0H0PyO97ZTGJErmHZXv9sfM5glCJTG2K7nkYYzyw5W0PqoMPjz7Vc/RUnKDflTA4Q654 X3tw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=b84xNK1CnpiB2X8ZBdI8UC6daiOQ52fxdMiVNqMaVQw=; fh=FHFn93bXWyHdQCJNwZshyhto7AYkzORL7/dmVn+xoIA=; b=cPLcBVwD9+tnakJ1/BTu4J34ZQmjbGjl8EFeluMuPv+/UeECepJsxDqzgFVNxSlzSv Z+LxlKutIUz2Kq1x4adiba2PcHDs1+BpoD+VAj3w9RzZkZAkjdqbouU0GzJ4TmNw/8pI 4+kwfuHHM4MP3HbDJXq3KOSupV9bm2n33mWbzvPbroQxRZKMsj8Kghg1hgrAUf1jqvSF x3pUJ54UcR3ThbOO7R+FWZFUpSoD2Nt01X6MY+B58BjrWxCN8D2qGSldVptolxlIkqGd ARWx6+Jp4cjBj0rLqnRcUOjqyApCRykH2NE2vj5NrcUVA1TSoOMzHDGWxTx6JxuSx0qI DwYw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=analog.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id r22-20020a170906351600b0099212b34e82si2307319eja.18.2023.07.11.09.30.51; Tue, 11 Jul 2023 09:31:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=analog.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231648AbjGKQ2r (ORCPT + 99 others); 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 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 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771142461669945767 X-GMAIL-MSGID: 1771142461669945767 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,max77857.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 feedback. + +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 = <1>; + #size-cells = <0>; + + regulator@66 { + reg = <0x66>; + compatible = "adi,max77857"; + interrupt-parent = <&gpio>; + interrupts = <26 IRQ_TYPE_EDGE_FALLING>; + + adi,rtop-ohms = <312000>; + adi,rbot-ohms = <12000>; + }; + }; From patchwork Tue Jul 11 16:27:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sahin, Okan" X-Patchwork-Id: 118650 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a6b2:0:b0:3e4:2afc:c1 with SMTP id c18csp613300vqm; Tue, 11 Jul 2023 09:45:00 -0700 (PDT) X-Google-Smtp-Source: APBJJlEZnS0QjRKu46QXRjs2m2Mwjto/YXFH3A8g4/PA1JXrllH15re2S3n0MZCFZQIMnQN6vK8L X-Received: by 2002:a05:6870:f5a9:b0:1b7:613c:2eb2 with SMTP id eh41-20020a056870f5a900b001b7613c2eb2mr1272788oab.6.1689093900130; Tue, 11 Jul 2023 09:45:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689093900; cv=none; d=google.com; s=arc-20160816; b=Ee15IbDC4di8Z3Sb9UbZlDbrF1RnMmID1uaD//AstZPIIRQEvv5If7pcEwKgyb0GwS kM045lE7BhS2QA8luciWLi2ox4gtgl5S2Ovlj0rJQFM5T3d3es+NGzl3SA/WLdnQS08T DPqslG+vWhJgm7e/YkheT0oJNE7C3MhAp9hI74zSxJG6jxaEwHLEC6M/ZDjLbjWXxwv6 24xP/a8sI1UZuI6+kNX9hqUZJBUavpG3MD8uDgJgyV53dc5NvLhTvng+0enAfebss0Tg pBW0qkyAfia2pBOH9E2ctn47zWDIcZLxnak0VFk3W+rmt8lQf0ZxzmW7hdxhvWFait3h HHFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=gdiDLNUP7aNr3+IUI6tVONhNzNIRs11NdBz0NHCXhg8=; fh=apkr6pFKVWs55QC54o+e8/aoSDxQUqf3OU3Ma++EIg0=; b=XtpbJ+sBvSArleaWPc/IGC3lF3g4f6TNP20JRqay1ZGLjoZwssthRLl+3jlkGafk+/ Cb/MJzcD7HENg5/Lzf62SgAmtE8Hqf6wrKfwYDqiRy9szXG1+sa8DbnW2BdJLdktaKIL SEYSFV/FICIlnJT1mr79bbtRPhUuy6kyIAw/yi6jZrGy9ZDBGuRWhQ/nx/Wlvf/YNKGm luRMiVymuyMkSB6r6JUMCADT7NaZetLLTcvHxEoigyo0EQPjf/E+2Waba1Aczdkmf5JC Z6iw6qVZmuJnpMKYdxgiRMd8tSD0j4XpUqYq4g5WchhLXl74Sf6hIHNz3AzyPwOP1ppH ideQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=analog.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p2-20020a17090ac00200b0026384c02c03si1844502pjt.140.2023.07.11.09.44.47; Tue, 11 Jul 2023 09:45:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=analog.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232359AbjGKQiu (ORCPT + 99 others); Tue, 11 Jul 2023 12:38:50 -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 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 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771143325350469726 X-GMAIL-MSGID: 1771143325350469726 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. +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) += max77686-regulator.o obj-$(CONFIG_REGULATOR_MAX77693) += max77693-regulator.o obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o obj-$(CONFIG_REGULATOR_MAX77826) += max77826-regulator.o +obj-$(CONFIG_REGULATOR_MAX77857) += max77857-regulator.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-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 = 1, + ID_MAX77857, + ID_MAX77859, + ID_MAX77859A, +}; + +static bool max77857_volatile_reg(struct device *dev, unsigned int reg) +{ + enum max77857_id id = (enum max77857_id)dev_get_drvdata(dev); + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + return reg == MAX77857_REG_INT_SRC; + case ID_MAX77859: + case ID_MAX77859A: + return reg == MAX77859_REG_INT_SRC; + default: + return true; + } +} + +struct regmap_config max77857_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = max77857_volatile_reg, +}; + +static int max77857_get_status(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = 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 = (enum max77857_id)rdev_get_drvdata(rdev); + unsigned int regval; + int ret; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + ret = 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 = 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 = (enum max77857_id)rdev_get_drvdata(rdev); + unsigned int reg, val; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + reg = MAX77857_REG_CONT3; + val = MAX77857_CONT3_FPWM; + break; + case ID_MAX77859: + case ID_MAX77859A: + reg = MAX77859_REG_CONT2; + val = 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 = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val); + if (ret) + return ret; + + *flags = 0; + + if (FIELD_GET(MAX77857_INT_SRC_OVP, val)) + *flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN; + + if (FIELD_GET(MAX77857_INT_SRC_OCP, val) || + FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val)) + *flags |= REGULATOR_ERROR_OVER_CURRENT; + + if (FIELD_GET(MAX77857_INT_SRC_THS, val)) + *flags |= REGULATOR_ERROR_OVER_TEMP; + + if (!FIELD_GET(MAX77857_INT_SRC_POK, val)) + *flags |= REGULATOR_ERROR_FAIL; + + return 0; +} + +static struct linear_range max77859_lin_ranges[] = { + REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000) +}; + +static const unsigned int max77859_ramp_table[4] = { + 1000, 500, 250, 125 +}; + +static int max77859_set_voltage_sel(struct regulator_dev *rdev, + unsigned int sel) +{ + __be16 reg; + int ret; + + reg = cpu_to_be16(sel); + + ret = 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 = 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 = 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_STEP; + + selector = 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 = regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector); + if (ret) + return ret; + + if (selector <= 0x12) + return MAX77859_CURRENT_MIN; + + if (selector >= 0x64) + return MAX77859_CURRENT_MAX; + + return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP; +} + +static const struct regulator_ops max77859_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = max77859_set_voltage_sel, + .get_voltage_sel = max77859_get_voltage_sel, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .get_status = max77857_get_status, + .set_mode = max77857_set_mode, + .get_mode = max77857_get_mode, + .get_error_flags = max77857_get_error_flags, +}; + +static const struct regulator_ops max77859a_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = max77859_set_voltage_sel, + .get_voltage_sel = max77859_get_voltage_sel, + .set_current_limit = max77859_set_current_limit, + .get_current_limit = max77859_get_current_limit, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .get_status = max77857_get_status, + .set_mode = max77857_set_mode, + .get_mode = max77857_get_mode, + .get_error_flags = max77857_get_error_flags, +}; + +static const struct regulator_ops max77857_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .get_status = max77857_get_status, + .set_mode = max77857_set_mode, + .get_mode = max77857_get_mode, + .get_error_flags = max77857_get_error_flags, +}; + +static struct linear_range max77857_lin_ranges[] = { + REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500) +}; + +static const unsigned int max77857_switch_freq[] = { + 1200000, 1500000, 1800000, 2100000 +}; + +static const unsigned int max77857_ramp_table[2][4] = { + { 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 = { + .ops = &max77857_regulator_ops, + .name = "max77857", + .linear_ranges = max77857_lin_ranges, + .n_linear_ranges = ARRAY_SIZE(max77857_lin_ranges), + .vsel_mask = 0xFF, + .vsel_reg = MAX77857_REG_CONT2, + .ramp_delay_table = max77857_ramp_table[0], + .n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]), + .ramp_reg = MAX77857_REG_CONT3, + .ramp_mask = GENMASK(1, 0), + .ramp_delay = max77857_ramp_table[0][0], + .owner = THIS_MODULE, +}; + +static void max77857_calc_range(struct device *dev, enum max77857_id id) +{ + struct linear_range *range; + unsigned long vref_step; + u32 rtop = 0; + u32 rbot = 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 = max77857_lin_ranges; + vref_step = 4900UL; + break; + case ID_MAX77859: + case ID_MAX77859A: + range = max77859_lin_ranges; + vref_step = 1250UL; + break; + } + + range->step = DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot); + range->min = range->step * range->min_sel; +} + +static int max77857_probe(struct i2c_client *client) +{ + const struct i2c_device_id *i2c_id; + struct device *dev = &client->dev; + struct regulator_config cfg = { }; + struct regulator_dev *rdev; + struct regmap *regmap; + enum max77857_id id; + u32 switch_freq = 0; + int ret; + + i2c_id = i2c_client_get_device_id(client); + if (!i2c_id) + return -EINVAL; + + id = i2c_id->driver_data; + + dev_set_drvdata(dev, (void *)id); + + if (id == ID_MAX77859 || id == ID_MAX77859A) { + max77857_regulator_desc.ops = &max77859_regulator_ops; + max77857_regulator_desc.linear_ranges = max77859_lin_ranges; + max77857_regulator_desc.ramp_delay_table = max77859_ramp_table; + max77857_regulator_desc.ramp_delay = max77859_ramp_table[0]; + } + + if (id == ID_MAX77859A) + max77857_regulator_desc.ops = &max77859a_regulator_ops; + + max77857_calc_range(dev, id); + + regmap = 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 = find_closest(switch_freq, max77857_switch_freq, + ARRAY_SIZE(max77857_switch_freq)); + + if (id == ID_MAX77831 && switch_freq == 3) + switch_freq = 2; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + ret = regmap_update_bits(regmap, MAX77857_REG_CONT1, + MAX77857_CONT1_FREQ, switch_freq); + + if (switch_freq >= 2) + break; + + max77857_regulator_desc.ramp_delay_table = max77857_ramp_table[1]; + max77857_regulator_desc.ramp_delay = max77857_ramp_table[1][0]; + break; + case ID_MAX77859: + case ID_MAX77859A: + ret = regmap_update_bits(regmap, MAX77859_REG_CONT1, + MAX77857_CONT1_FREQ, switch_freq); + break; + } + if (ret) + return ret; + } + + cfg.dev = dev; + cfg.driver_data = (void *)id; + cfg.regmap = regmap; + cfg.init_data = of_get_regulator_init_data(dev, dev->of_node, + &max77857_regulator_desc); + if (!cfg.init_data) + return -ENOMEM; + + rdev = 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[] = { + { "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[] = { + { .compatible = "adi,max77831", .data = (void *)ID_MAX77831 }, + { .compatible = "adi,max77857", .data = (void *)ID_MAX77857 }, + { .compatible = "adi,max77859", .data = (void *)ID_MAX77859 }, + { .compatible = "adi,max77859a", .data = (void *)ID_MAX77859A }, + { } +}; +MODULE_DEVICE_TABLE(of, max77857_of_id); + +struct i2c_driver max77857_driver = { + .driver = { + .name = "max77857", + .of_match_table = max77857_of_id, + }, + .id_table = max77857_id, + .probe_new = 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");