From patchwork Thu Dec 15 19:08:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Twiss X-Patchwork-Id: 9476807 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AB1196047D for ; Thu, 15 Dec 2016 19:43:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 981CC287BB for ; Thu, 15 Dec 2016 19:43:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8CD4528816; Thu, 15 Dec 2016 19:43:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A227D287BB for ; Thu, 15 Dec 2016 19:43:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756053AbcLOTkl (ORCPT ); Thu, 15 Dec 2016 14:40:41 -0500 Received: from mail1.bemta5.messagelabs.com ([195.245.231.145]:20982 "EHLO mail1.bemta5.messagelabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753463AbcLOTjR (ORCPT ); Thu, 15 Dec 2016 14:39:17 -0500 X-Greylist: delayed 485 seconds by postgrey-1.27 at vger.kernel.org; Thu, 15 Dec 2016 14:39:13 EST Received: from [85.158.139.19] by server-9.bemta-5.messagelabs.com id 6E/C6-01928-A7FE2585; Thu, 15 Dec 2016 19:31:06 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprDKsWRWlGSWpSXmKPExsUSt3OpsW7l+6A Ig+kzFSymPnzCZjH/yDlWi8OLXjBazL9yjdXi/tejjBbfrnQwWdz89I3V4vKuOWwWn3uPMFrc WLeP3eLJwjNMFkuvX2SyaN17BMh92MdmcXliJ7vFrRkvWB0EPNbMW8PosXPWXXaPa5vFPBbve cnksWlVJ5vHnWt72Dx2fm9g9/i8SS6AI4o1My8pvyKBNePJBPWCbfUV25ZyNDAez+li5OIQEl jPKNF7/jdLFyMnkFMh8XTCZiCbg4NXIFni7RsFkDCngKPEimcr2SBKHCRe3msCK2cTMJSY9+Y 9I4jNIqAqceD9NEaQVmEBD4mPt5RATBGBMonjvxNANjEL9LJINHZuBWvlFRCUODnzCZjNLCAh cfDFC2aQeiEBLYnlxyJBwhIC9hLT318FC0sI6Es0HouFCBtKfJ/1jQXCNpeY8eAY2wRGwVlIh s5CMnQBI9MqRo3i1KKy1CJdQ2O9pKLM9IyS3MTMHF1DA1O93NTi4sT01JzEpGK95PzcTYzAWG MAgh2M/7Z5HmKU5GBSEuXNXh4UIcSXlJ9SmZFYnBFfVJqTWnyIUYaDQ0mCN+odUE6wKDU9tSI tMwcY9TBpCQ4eJRFeKZA0b3FBYm5xZjpE6hSjopQ4bzFIQgAkkVGaB9cGSzSXGGWlhHkZgQ4R 4ilILcrNLEGVf8UozsGoJMz7/S3QFJ7MvBK46a+AFjMBLRZd4g+yuCQRISXVwLiojqHDU6L+g 9ZMvnWHiq5s/LjMbNpXezHPT4aG3VOPbj3bwskj8Tyq/m9fNdORbdt+/0yWu9o6w6mqLq7xym Zdu+c39TbtOSD/6WtJeOh2BbFZi069Yjbon9o46Vrvp62xbUtNV/tUFdxwNmGoPcL99eKv/zd YMoSDNG6vfs5o2MdoaT9h4xQlluKMREMt5qLiRACAYruCLwMAAA== X-Env-Sender: stwiss.opensource@diasemi.com X-Msg-Ref: server-14.tower-178.messagelabs.com!1481830263!75802103!7 X-Originating-IP: [94.185.165.51] X-StarScan-Received: X-StarScan-Version: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 20513 invoked from network); 15 Dec 2016 19:31:05 -0000 Received: from mailrelay2.diasemi.com (HELO sw-ex-cashub01.diasemi.com) (94.185.165.51) by server-14.tower-178.messagelabs.com with AES128-SHA encrypted SMTP; 15 Dec 2016 19:31:05 -0000 Received: from swsrvapps-01.diasemi.com (10.20.28.141) by SW-EX-CASHUB01.diasemi.com (10.20.16.140) with Microsoft SMTP Server id 14.3.248.2; Thu, 15 Dec 2016 19:31:04 +0000 Received: by swsrvapps-01.diasemi.com (Postfix, from userid 22547) id 42D933FBD0; Thu, 15 Dec 2016 19:31:03 +0000 (GMT) Message-ID: In-Reply-To: References: From: Steve Twiss Date: Thu, 15 Dec 2016 19:08:40 +0000 Subject: [PATCH V5 5/8] regulator: da9061: BUCK and LDO regulator driver To: LINUX-KERNEL , Liam Girdwood , Mark Brown CC: DEVICETREE , Dmitry Torokhov , Eduardo Valentin , Guenter Roeck , LINUX-INPUT , LINUX-PM , LINUX-WATCHDOG , Lee Jones , Mark Rutland , Rob Herring , Support Opensource , Wim Van Sebroeck , Zhang Rui MIME-Version: 1.0 X-KSE-AttachmentFiltering-Interceptor-Info: protection disabled X-KSE-ServerInfo: sw-ex-cashub01.diasemi.com, 9 X-KSE-Antivirus-Interceptor-Info: scan successful X-KSE-Antivirus-Info: Clean, bases: 15/12/2016 14:44:00 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Steve Twiss Regulator support for the DA9061 is added into the DA9062 regulator driver. The regulators for DA9061 differ from those of DA9062. A new DA9061 enumeration list for the LDOs and Bucks supported by this device is added. Regulator information added: the old regulator information for DA9062 is renamed from local_regulator_info[] to local_da9062_regulator_info[] and a new array is added to support local_da9061_regulator_info[]. The probe() function switches on the da9062_compatible_types enumeration and configures the correct da9062_regulator_info array and number of regulator entries. Kconfig is updated to reflect support for DA9061 and DA9062 regulators. Acked-by: Mark Brown Signed-off-by: Steve Twiss --- This patch applies against linux-next and v4.9 v4 -> v5 - Rebased from v4.8 to v4.9 - NO CODE CHANGE v3 -> v4 - NO CODE CHANGE - Patch renamed from [PATCH V3 6/9] to [PATCH V4 5/8] v2 -> v3 - NO CODE CHANGE - Patch renamed from [PATCH V2 06/10] to [PATCH V3 6/9] - Added Ack from Mark Brown v1 -> v2 - Patch renamed from [PATCH V1 02/10] to [PATCH V2 06/10] -- these changes were made to fix checkpatch warnings caused by the patch set dependency order - Updated header to use DA9061 and DA9062 Hi, No code changes for this version PATCH V5. As previously: These changes depend on a header file provided as part of an earlier patch [PATCH V5 4/8] from this set. The regulator probe() switches on the chip_type which uses enum da9062_compatible_types in core.h from this patch. Regards, Steve Twiss, Dialog Semiconductor Ltd. drivers/regulator/Kconfig | 4 +- drivers/regulator/da9062-regulator.c | 301 +++++++++++++++++++++++++++++++++-- 2 files changed, 292 insertions(+), 13 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 936f7cc..bbb4be6 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -188,11 +188,11 @@ config REGULATOR_DA9055 will be called da9055-regulator. config REGULATOR_DA9062 - tristate "Dialog Semiconductor DA9062 regulators" + tristate "Dialog Semiconductor DA9061/62 regulators" depends on MFD_DA9062 help Say y here to support the BUCKs and LDOs regulators found on - DA9062 PMICs. + DA9061 and DA9062 PMICs. This driver can also be built as a module. If so, the module will be called da9062-regulator. diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index 0638c8b..931be68 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -1,5 +1,5 @@ /* - * da9062-regulator.c - REGULATOR device driver for DA9062 + * Regulator device driver for DA9061 and DA9062. * Copyright (C) 2015 Dialog Semiconductor Ltd. * * This program is free software; you can redistribute it and/or @@ -28,6 +28,17 @@ /* Regulator IDs */ enum { + DA9061_ID_BUCK1, + DA9061_ID_BUCK2, + DA9061_ID_BUCK3, + DA9061_ID_LDO1, + DA9061_ID_LDO2, + DA9061_ID_LDO3, + DA9061_ID_LDO4, + DA9061_MAX_REGULATORS, +}; + +enum { DA9062_ID_BUCK1, DA9062_ID_BUCK2, DA9062_ID_BUCK3, @@ -88,15 +99,21 @@ enum { /* Regulator operations */ -/* Current limits array (in uA) BUCK1 and BUCK3. - Entry indexes corresponds to register values. */ +/* Current limits array (in uA) + * - DA9061_ID_[BUCK1|BUCK3] + * - DA9062_ID_[BUCK1|BUCK2|BUCK4] + * Entry indexes corresponds to register values. + */ static const int da9062_buck_a_limits[] = { 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 }; -/* Current limits array (in uA) for BUCK2. - Entry indexes corresponds to register values. */ +/* Current limits array (in uA) + * - DA9061_ID_BUCK2 + * - DA9062_ID_BUCK3 + * Entry indexes corresponds to register values. + */ static const int da9062_buck_b_limits[] = { 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 @@ -405,8 +422,254 @@ static int da9062_ldo_set_suspend_mode(struct regulator_dev *rdev, .set_suspend_mode = da9062_ldo_set_suspend_mode, }; -/* Regulator information */ -static const struct da9062_regulator_info local_regulator_info[] = { +/* DA9061 Regulator information */ +static const struct da9062_regulator_info local_da9061_regulator_info[] = { + { + .desc.id = DA9061_ID_BUCK1, + .desc.name = "DA9061 BUCK1", + .desc.of_match = of_match_ptr("buck1"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_buck_ops, + .desc.min_uV = (300) * 1000, + .desc.uV_step = (10) * 1000, + .desc.n_voltages = ((1570) - (300))/(10) + 1, + .current_limits = da9062_buck_a_limits, + .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.enable_reg = DA9062AA_BUCK1_CONT, + .desc.enable_mask = DA9062AA_BUCK1_EN_MASK, + .desc.vsel_reg = DA9062AA_VBUCK1_A, + .desc.vsel_mask = DA9062AA_VBUCK1_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VBUCK1_A, + __builtin_ffs((int)DA9062AA_BUCK1_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK1_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VBUCK1_B, + __builtin_ffs((int)DA9062AA_BUCK1_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK1_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VBUCK1_B, + .mode = REG_FIELD(DA9062AA_BUCK1_CFG, + __builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1), + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), + .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, + __builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1), + }, + { + .desc.id = DA9061_ID_BUCK2, + .desc.name = "DA9061 BUCK2", + .desc.of_match = of_match_ptr("buck2"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_buck_ops, + .desc.min_uV = (800) * 1000, + .desc.uV_step = (20) * 1000, + .desc.n_voltages = ((3340) - (800))/(20) + 1, + .current_limits = da9062_buck_b_limits, + .n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.enable_reg = DA9062AA_BUCK3_CONT, + .desc.enable_mask = DA9062AA_BUCK3_EN_MASK, + .desc.vsel_reg = DA9062AA_VBUCK3_A, + .desc.vsel_mask = DA9062AA_VBUCK3_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VBUCK3_A, + __builtin_ffs((int)DA9062AA_BUCK3_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK3_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VBUCK3_B, + __builtin_ffs((int)DA9062AA_BUCK3_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK3_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VBUCK3_B, + .mode = REG_FIELD(DA9062AA_BUCK3_CFG, + __builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1), + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), + .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A, + __builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1), + }, + { + .desc.id = DA9061_ID_BUCK3, + .desc.name = "DA9061 BUCK3", + .desc.of_match = of_match_ptr("buck3"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_buck_ops, + .desc.min_uV = (530) * 1000, + .desc.uV_step = (10) * 1000, + .desc.n_voltages = ((1800) - (530))/(10) + 1, + .current_limits = da9062_buck_a_limits, + .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.enable_reg = DA9062AA_BUCK4_CONT, + .desc.enable_mask = DA9062AA_BUCK4_EN_MASK, + .desc.vsel_reg = DA9062AA_VBUCK4_A, + .desc.vsel_mask = DA9062AA_VBUCK4_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VBUCK4_A, + __builtin_ffs((int)DA9062AA_BUCK4_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK4_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VBUCK4_B, + __builtin_ffs((int)DA9062AA_BUCK4_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK4_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VBUCK4_B, + .mode = REG_FIELD(DA9062AA_BUCK4_CFG, + __builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1), + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), + .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B, + __builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1), + }, + { + .desc.id = DA9061_ID_LDO1, + .desc.name = "DA9061 LDO1", + .desc.of_match = of_match_ptr("ldo1"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_ldo_ops, + .desc.min_uV = (900) * 1000, + .desc.uV_step = (50) * 1000, + .desc.n_voltages = ((3600) - (900))/(50) + 1, + .desc.enable_reg = DA9062AA_LDO1_CONT, + .desc.enable_mask = DA9062AA_LDO1_EN_MASK, + .desc.vsel_reg = DA9062AA_VLDO1_A, + .desc.vsel_mask = DA9062AA_VLDO1_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VLDO1_A, + __builtin_ffs((int)DA9062AA_LDO1_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO1_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VLDO1_B, + __builtin_ffs((int)DA9062AA_LDO1_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VLDO1_B, + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1), + .oc_event = REG_FIELD(DA9062AA_STATUS_D, + __builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO1_ILIM_MASK)) - 1), + }, + { + .desc.id = DA9061_ID_LDO2, + .desc.name = "DA9061 LDO2", + .desc.of_match = of_match_ptr("ldo2"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_ldo_ops, + .desc.min_uV = (900) * 1000, + .desc.uV_step = (50) * 1000, + .desc.n_voltages = ((3600) - (600))/(50) + 1, + .desc.enable_reg = DA9062AA_LDO2_CONT, + .desc.enable_mask = DA9062AA_LDO2_EN_MASK, + .desc.vsel_reg = DA9062AA_VLDO2_A, + .desc.vsel_mask = DA9062AA_VLDO2_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VLDO2_A, + __builtin_ffs((int)DA9062AA_LDO2_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO2_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VLDO2_B, + __builtin_ffs((int)DA9062AA_LDO2_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VLDO2_B, + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1), + .oc_event = REG_FIELD(DA9062AA_STATUS_D, + __builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO2_ILIM_MASK)) - 1), + }, + { + .desc.id = DA9061_ID_LDO3, + .desc.name = "DA9061 LDO3", + .desc.of_match = of_match_ptr("ldo3"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_ldo_ops, + .desc.min_uV = (900) * 1000, + .desc.uV_step = (50) * 1000, + .desc.n_voltages = ((3600) - (900))/(50) + 1, + .desc.enable_reg = DA9062AA_LDO3_CONT, + .desc.enable_mask = DA9062AA_LDO3_EN_MASK, + .desc.vsel_reg = DA9062AA_VLDO3_A, + .desc.vsel_mask = DA9062AA_VLDO3_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VLDO3_A, + __builtin_ffs((int)DA9062AA_LDO3_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO3_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VLDO3_B, + __builtin_ffs((int)DA9062AA_LDO3_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VLDO3_B, + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1), + .oc_event = REG_FIELD(DA9062AA_STATUS_D, + __builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO3_ILIM_MASK)) - 1), + }, + { + .desc.id = DA9061_ID_LDO4, + .desc.name = "DA9061 LDO4", + .desc.of_match = of_match_ptr("ldo4"), + .desc.regulators_node = of_match_ptr("regulators"), + .desc.ops = &da9062_ldo_ops, + .desc.min_uV = (900) * 1000, + .desc.uV_step = (50) * 1000, + .desc.n_voltages = ((3600) - (900))/(50) + 1, + .desc.enable_reg = DA9062AA_LDO4_CONT, + .desc.enable_mask = DA9062AA_LDO4_EN_MASK, + .desc.vsel_reg = DA9062AA_VLDO4_A, + .desc.vsel_mask = DA9062AA_VLDO4_A_MASK, + .desc.linear_min_sel = 0, + .sleep = REG_FIELD(DA9062AA_VLDO4_A, + __builtin_ffs((int)DA9062AA_LDO4_SL_A_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO4_SL_A_MASK)) - 1), + .suspend_sleep = REG_FIELD(DA9062AA_VLDO4_B, + __builtin_ffs((int)DA9062AA_LDO4_SL_B_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1), + .suspend_vsel_reg = DA9062AA_VLDO4_B, + .suspend = REG_FIELD(DA9062AA_DVC_1, + __builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1), + .oc_event = REG_FIELD(DA9062AA_STATUS_D, + __builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1, + sizeof(unsigned int) * 8 - + __builtin_clz((DA9062AA_LDO4_ILIM_MASK)) - 1), + }, +}; + +/* DA9062 Regulator information */ +static const struct da9062_regulator_info local_da9062_regulator_info[] = { { .desc.id = DA9062_ID_BUCK1, .desc.name = "DA9062 BUCK1", @@ -727,17 +990,33 @@ static int da9062_regulator_probe(struct platform_device *pdev) struct da9062_regulators *regulators; struct da9062_regulator *regl; struct regulator_config config = { }; + const struct da9062_regulator_info *rinfo; int irq, n, ret; size_t size; + int max_regulators; + + switch (chip->chip_type) { + case COMPAT_TYPE_DA9061: + max_regulators = DA9061_MAX_REGULATORS; + rinfo = local_da9061_regulator_info; + break; + case COMPAT_TYPE_DA9062: + max_regulators = DA9062_MAX_REGULATORS; + rinfo = local_da9062_regulator_info; + break; + default: + dev_err(chip->dev, "Unrecognised chip type\n"); + return -ENODEV; + } /* Allocate memory required by usable regulators */ size = sizeof(struct da9062_regulators) + - DA9062_MAX_REGULATORS * sizeof(struct da9062_regulator); + max_regulators * sizeof(struct da9062_regulator); regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!regulators) return -ENOMEM; - regulators->n_regulators = DA9062_MAX_REGULATORS; + regulators->n_regulators = max_regulators; platform_set_drvdata(pdev, regulators); n = 0; @@ -745,7 +1024,7 @@ static int da9062_regulator_probe(struct platform_device *pdev) /* Initialise regulator structure */ regl = ®ulators->regulator[n]; regl->hw = chip; - regl->info = &local_regulator_info[n]; + regl->info = &rinfo[n]; regl->desc = regl->info->desc; regl->desc.type = REGULATOR_VOLTAGE; regl->desc.owner = THIS_MODULE; @@ -836,6 +1115,6 @@ static void __exit da9062_regulator_cleanup(void) /* Module information */ MODULE_AUTHOR("S Twiss "); -MODULE_DESCRIPTION("REGULATOR device driver for Dialog DA9062"); +MODULE_DESCRIPTION("REGULATOR device driver for Dialog DA9062 and DA9061"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:da9062-regulators");