From patchwork Mon Nov 14 08:22:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Twiss X-Patchwork-Id: 9426805 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 A7B0160471 for ; Mon, 14 Nov 2016 08:30:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 978C2287F7 for ; Mon, 14 Nov 2016 08:30:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C772287F8; Mon, 14 Nov 2016 08:30:15 +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 EB055287F9 for ; Mon, 14 Nov 2016 08:30:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755271AbcKNIaB (ORCPT ); Mon, 14 Nov 2016 03:30:01 -0500 Received: from mail1.bemta3.messagelabs.com ([195.245.230.161]:22696 "EHLO mail1.bemta3.messagelabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752879AbcKNI1t (ORCPT ); Mon, 14 Nov 2016 03:27:49 -0500 Received: from [85.158.137.3] by server-1.bemta-3.messagelabs.com id C1/16-23231-25579285; Mon, 14 Nov 2016 08:26:58 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprPKsWRWlGSWpSXmKPExsUSt3OpsW5QqWa Ewbt+EYupD5+wWcw/co7V4vCiF4wW869cY7W4//Uoo8W3Kx1MFjc/fWO1uLxrDpvF594jjBY3 1u1jt3iy8AyTxdLrF5ksWvceAXIf9rFZXJ7YyW5xa8YLVgcBjzXz1jB67Jx1l93j2mYxj8V7X jJ5bFrVyeZx59oeNo+d3xvYPT5vkgvgiGLNzEvKr0hgzZg89zVTwdO6ioOvutkbGNtzuhi5OI QE1jNKLNk1n62LkRPIqZDYtGseO4jNK5AssX7GViCbg4NTwFHi5WwuiBIHic4F85lAbDYBQ4l 5b94zgtgsAqoST+fdBBsjLOAh8e3TYSaQVhGBMonjvxNAVjEL9LJINHZuZYEYLyhxcuYTMJtZ QELi4IsXzCD1QgJaEsuPRYKEJQTsJaa/vwoWlhDQl2g8FgsRNpT4PusbC4RtLnF121fWCYyCs 5AMnYVk6AJGplWMGsWpRWWpRbpG5npJRZnpGSW5iZk5uoYGxnq5qcXFiempOYlJxXrJ+bmbGI ERV8/AwLiDsWWv3yFGSQ4mJVHe+EjNCCG+pPyUyozE4oz4otKc1OJDjDIcHEoSvB0lQDnBotT 01Iq0zBxg7MOkJTh4lER4l4KkeYsLEnOLM9MhUqcYFaXEedtAEgIgiYzSPLg2WLq5xCgrJczL yMDAIMRTkFqUm1mCKv+KUZyDUUmYtwFkCk9mXgnc9FdAi5mAFu8y1wBZXJKIkJJqYAxRrTs/V /WNp/fb07N7nvCbPvau1/yn9srN32tz1cTn2232ebrN7jO8qDmvLFzCTXvlO3MFe67b8cfr4g pzlt+dKDvhrfuPCWbbhJ7P+BkztWX6lC/HbkxeoNdjfsXw1+kbThXW9o9tpbb0pnu+FNhxu/P ec4/P7LERR+Odt3YE+UxW2qkkLaXEUpyRaKjFXFScCAAhTt5dMgMAAA== X-Env-Sender: stwiss.opensource@diasemi.com X-Msg-Ref: server-14.tower-38.messagelabs.com!1479112016!62255366!6 X-Originating-IP: [94.185.165.51] X-StarScan-Received: X-StarScan-Version: 9.0.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 21152 invoked from network); 14 Nov 2016 08:26:58 -0000 Received: from mailrelay2.diasemi.com (HELO sw-ex-cashub01.diasemi.com) (94.185.165.51) by server-14.tower-38.messagelabs.com with AES128-SHA encrypted SMTP; 14 Nov 2016 08:26:58 -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; Mon, 14 Nov 2016 08:26:56 +0000 Received: by swsrvapps-01.diasemi.com (Postfix, from userid 22547) id 6A5533FC00; Mon, 14 Nov 2016 08:26:55 +0000 (GMT) Message-ID: In-Reply-To: References: From: Steve Twiss Date: Mon, 14 Nov 2016 08:22:45 +0000 Subject: [PATCH V4 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: 14/11/2016 02:25: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.8 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 V4. As previously: These changes depend on a header file provided as part of an earlier patch [PATCH V4 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 6c88e31..c4f678fe 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 const struct regulator_ops da9062_ldo_ops = { .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 @@ module_exit(da9062_regulator_cleanup); /* 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");