From patchwork Mon Jan 20 06:34:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AFF2BC33CB7 for ; Mon, 20 Jan 2020 06:34:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 856E3207E0 for ; Mon, 20 Jan 2020 06:34:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726400AbgATGe0 (ORCPT ); Mon, 20 Jan 2020 01:34:26 -0500 Received: from mail-lj1-f193.google.com ([209.85.208.193]:35477 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725783AbgATGeZ (ORCPT ); Mon, 20 Jan 2020 01:34:25 -0500 Received: by mail-lj1-f193.google.com with SMTP id j1so32545937lja.2; Sun, 19 Jan 2020 22:34:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=f4ChqbDOYd2LD4JuxUF62S0BVlUZ1wXoNBEwyK9ff3E=; b=f0bwxbIwEMrDkehMFyiSHUVqhD/YgQ+wyubiKAgLs+XO+DKrnbDD94cEh1cJc9oGCo WzOBHErljTXlqyVxC/aAPYIST+Rf2z3osKs0maDXaWlU7643dxrfymHFShba8FyDPphy wZgnMJg8xwaVZbbkM/hKpbcKYFSwRxSmEC3wGzBsSnReaMDeSMiXInxFcIX7djxA6E0M zx5D7HZpoa92PfA95vXo69dAUij8xRZNojpO6N4r1aXw62pxyFvyHQTAvqBKdks0zdJL bYVVizlAgyUq2H3YFngoZJq1QWnO8froGg6+e/p06Tc+cz83+wFcMXyRl+n8G3N0saiF Rchw== X-Gm-Message-State: APjAAAUuqeeqExVrXsmq7xKlda3AZarAw1vWSkn5+227YSN4ENeXBGxF jG4liMaq01uQEruXQuTX93I= X-Google-Smtp-Source: APXvYqzaDxJLH9Al9Dnes/srgA8qc38LW57M6w/b1qhyMyIqmyO80cbtxmACBXTv4wp3yHl1SecarQ== X-Received: by 2002:a2e:9196:: with SMTP id f22mr13326220ljg.18.1579502062520; Sun, 19 Jan 2020 22:34:22 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id r2sm4246983lff.63.2020.01.19.22.34.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:34:21 -0800 (PST) Date: Mon, 20 Jan 2020 08:34:10 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 01/13] dt-bindings: leds: ROHM BD71282 PMIC LED driver Message-ID: <35bf147cc3077ceda9689655e5a23dad8098dbb2.1579501711.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Document ROHM BD71828 PMIC LED driver device tree bindings. Signed-off-by: Matti Vaittinen Reviewed-by: Rob Herring Acked-by: Pavel Machek --- No changes since v10 .../bindings/leds/rohm,bd71828-leds.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml diff --git a/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml b/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml new file mode 100644 index 000000000000..b50f4bcc98f1 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/rohm,bd71828-leds.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM BD71828 Power Management Integrated Circuit LED driver + +maintainers: + - Matti Vaittinen + +description: | + This module is part of the ROHM BD71828 MFD device. For more details + see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml. + + The LED controller is represented as a sub-node of the PMIC node on the device + tree. + + The device has two LED outputs referred as GRNLED and AMBLED in data-sheet. + +select: false + +properties: + compatible: + const: rohm,bd71828-leds + +patternProperties: + "^led-[1-2]$": + type: object + description: + Properties for a single LED. + properties: + #allOf: + #- $ref: "common.yaml#" + rohm,led-compatible: + description: LED identification string + allOf: + - $ref: "/schemas/types.yaml#/definitions/string" + - enum: + - bd71828-ambled + - bd71828-grnled + function: + description: + Purpose of LED as defined in dt-bindings/leds/common.h + $ref: "/schemas/types.yaml#/definitions/string" + color: + description: + LED colour as defined in dt-bindings/leds/common.h + $ref: "/schemas/types.yaml#/definitions/uint32" + +required: + - compatible From patchwork Mon Jan 20 06:35:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207376 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46AACC33CB7 for ; Mon, 20 Jan 2020 06:35:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1EAEB2073A for ; Mon, 20 Jan 2020 06:35:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726761AbgATGfd (ORCPT ); Mon, 20 Jan 2020 01:35:33 -0500 Received: from mail-lj1-f193.google.com ([209.85.208.193]:33481 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725872AbgATGfd (ORCPT ); Mon, 20 Jan 2020 01:35:33 -0500 Received: by mail-lj1-f193.google.com with SMTP id y6so32635062lji.0; Sun, 19 Jan 2020 22:35:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=yhnSdz3XkEFd+78V1ypU22Mb7BmmaZGpzOJ1wkbDV8M=; b=TtAwSZOFYltCG7NdmgPhmH5E5d9tbPDcO94hQQ0gWBhvz/tHUnH2PnVF4f6nXnzq5/ rMnNd61lBa8TAE5NiSnnsRg9bUqWAXez3l001VFOwybqzE31rIlf1/NkH0LytInpMXPN gGF9l+ao/0XZsL1GyxLt8fuzTQbdPN2d2DZ8CljmULiNIjaw68mCOq2k72g6v0Hiey0R Bkw+MPQiNluvzLzDMEARl6lksASqF8ASTtNfoV00QTfEfGJL/zh4RVrRlqvXYfN2IIr9 r/vjYC/MOBDXL60lnbesSvT+dOniFRculCiSy+c2Rm5VaYACM7jnt7O67bNOgQ0VCh1n Gd/g== X-Gm-Message-State: APjAAAUlNVfqO4sOQ0X+Mtmie6ZYRBQ/an1mgtPbAEximDGlQqPAA6UX tKTUvWesJdAIr+gdRbLZsiw= X-Google-Smtp-Source: APXvYqwCP/zIkF2ObXGu22nIE5LPZcwClv/eW/j/p14qkPcBaQFaK+7hTi8l2JHl7xCPHy/cZduPZQ== X-Received: by 2002:a2e:8758:: with SMTP id q24mr12844388ljj.157.1579502129797; Sun, 19 Jan 2020 22:35:29 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id d4sm15933668lfn.42.2020.01.19.22.35.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:35:29 -0800 (PST) Date: Mon, 20 Jan 2020 08:35:17 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 03/13] mfd: rohm PMICs - use platform_device_id to match MFD sub-devices Message-ID: <13994480cab6d5d6376c8f5228572e55ca06e479.1579501711.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Thanks to Stephen Boyd I today learned we can use platform_device_id to do device and module matching for MFD sub-devices! Do device matching using the platform_device_id instead of using explicit module_aliases to load modules and custom parent-data field to do module loading and sub-device matching. Signed-off-by: Matti Vaittinen Acked-for-MFD-by: Lee Jones --- No changes since v10 drivers/clk/clk-bd718x7.c | 12 ++++++++- drivers/mfd/rohm-bd70528.c | 3 +-- drivers/mfd/rohm-bd718x7.c | 39 ++++++++++++++++++++++----- drivers/regulator/bd718x7-regulator.c | 17 +++++++++--- include/linux/mfd/rohm-generic.h | 3 +-- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index 00926c587390..33699ee1bdf3 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -74,6 +74,7 @@ static int bd71837_clk_probe(struct platform_device *pdev) .name = "bd718xx-32k-out", .ops = &bd71837_clk_ops, }; + enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL); if (!c) @@ -87,7 +88,7 @@ static int bd71837_clk_probe(struct platform_device *pdev) dev_err(&pdev->dev, "No parent clk found\n"); return -EINVAL; } - switch (mfd->chip_type) { + switch (chip) { case ROHM_CHIP_TYPE_BD71837: case ROHM_CHIP_TYPE_BD71847: c->reg = BD718XX_REG_OUT32K; @@ -121,11 +122,20 @@ static int bd71837_clk_probe(struct platform_device *pdev) return rval; } +static const struct platform_device_id bd718x7_clk_id[] = { + { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 }, + { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 }, + { "bd70528-clk", ROHM_CHIP_TYPE_BD70528 }, + { }, +}; +MODULE_DEVICE_TABLE(platform, bd718x7_clk_id); + static struct platform_driver bd71837_clk = { .driver = { .name = "bd718xx-clk", }, .probe = bd71837_clk_probe, + .id_table = bd718x7_clk_id, }; module_platform_driver(bd71837_clk); diff --git a/drivers/mfd/rohm-bd70528.c b/drivers/mfd/rohm-bd70528.c index ef6786fd3b00..5c44d3b77b3e 100644 --- a/drivers/mfd/rohm-bd70528.c +++ b/drivers/mfd/rohm-bd70528.c @@ -48,7 +48,7 @@ static struct mfd_cell bd70528_mfd_cells[] = { * We use BD71837 driver to drive the clock block. Only differences to * BD70528 clock gate are the register address and mask. */ - { .name = "bd718xx-clk", }, + { .name = "bd70528-clk", }, { .name = "bd70528-wdt", }, { .name = "bd70528-power", @@ -236,7 +236,6 @@ static int bd70528_i2c_probe(struct i2c_client *i2c, dev_set_drvdata(&i2c->dev, &bd70528->chip); - bd70528->chip.chip_type = ROHM_CHIP_TYPE_BD70528; bd70528->chip.regmap = devm_regmap_init_i2c(i2c, &bd70528_regmap); if (IS_ERR(bd70528->chip.regmap)) { dev_err(&i2c->dev, "Failed to initialize Regmap\n"); diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c index 85e7f5133365..bb86ec829079 100644 --- a/drivers/mfd/rohm-bd718x7.c +++ b/drivers/mfd/rohm-bd718x7.c @@ -30,14 +30,24 @@ static struct gpio_keys_platform_data bd718xx_powerkey_data = { .name = "bd718xx-pwrkey", }; -static struct mfd_cell bd718xx_mfd_cells[] = { +static struct mfd_cell bd71837_mfd_cells[] = { { .name = "gpio-keys", .platform_data = &bd718xx_powerkey_data, .pdata_size = sizeof(bd718xx_powerkey_data), }, - { .name = "bd718xx-clk", }, - { .name = "bd718xx-pmic", }, + { .name = "bd71837-clk", }, + { .name = "bd71837-pmic", }, +}; + +static struct mfd_cell bd71847_mfd_cells[] = { + { + .name = "gpio-keys", + .platform_data = &bd718xx_powerkey_data, + .pdata_size = sizeof(bd718xx_powerkey_data), + }, + { .name = "bd71847-clk", }, + { .name = "bd71847-pmic", }, }; static const struct regmap_irq bd718xx_irqs[] = { @@ -124,6 +134,9 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, { struct bd718xx *bd718xx; int ret; + unsigned int chip_type; + struct mfd_cell *mfd; + int cells; if (!i2c->irq) { dev_err(&i2c->dev, "No IRQ configured\n"); @@ -136,8 +149,21 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, return -ENOMEM; bd718xx->chip_irq = i2c->irq; - bd718xx->chip.chip_type = (unsigned int)(uintptr_t) - of_device_get_match_data(&i2c->dev); + chip_type = (unsigned int)(uintptr_t) + of_device_get_match_data(&i2c->dev); + switch (chip_type) { + case ROHM_CHIP_TYPE_BD71837: + mfd = bd71837_mfd_cells; + cells = ARRAY_SIZE(bd71837_mfd_cells); + break; + case ROHM_CHIP_TYPE_BD71847: + mfd = bd71847_mfd_cells; + cells = ARRAY_SIZE(bd71847_mfd_cells); + break; + default: + dev_err(&i2c->dev, "Unknown device type"); + return -EINVAL; + } bd718xx->chip.dev = &i2c->dev; dev_set_drvdata(&i2c->dev, bd718xx); @@ -170,8 +196,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c, button.irq = ret; ret = devm_mfd_add_devices(bd718xx->chip.dev, PLATFORM_DEVID_AUTO, - bd718xx_mfd_cells, - ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0, + mfd, cells, NULL, 0, regmap_irq_get_domain(bd718xx->irq_data)); if (ret) dev_err(&i2c->dev, "Failed to create subdevices\n"); diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index 13a43eee2e46..6beaf867d9cb 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -1164,6 +1164,7 @@ static int bd718xx_probe(struct platform_device *pdev) int i, j, err; bool use_snvs; + enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; mfd = dev_get_drvdata(pdev->dev.parent); if (!mfd) { @@ -1172,8 +1173,8 @@ static int bd718xx_probe(struct platform_device *pdev) goto err; } - if (mfd->chip.chip_type >= ROHM_CHIP_TYPE_AMOUNT || - !pmic_regulators[mfd->chip.chip_type].r_datas) { + if (chip >= ROHM_CHIP_TYPE_AMOUNT || chip < 0 || + !pmic_regulators[chip].r_datas) { dev_err(&pdev->dev, "Unsupported chip type\n"); err = -EINVAL; goto err; @@ -1215,13 +1216,13 @@ static int bd718xx_probe(struct platform_device *pdev) } } - for (i = 0; i < pmic_regulators[mfd->chip.chip_type].r_amount; i++) { + for (i = 0; i < pmic_regulators[chip].r_amount; i++) { const struct regulator_desc *desc; struct regulator_dev *rdev; const struct bd718xx_regulator_data *r; - r = &pmic_regulators[mfd->chip.chip_type].r_datas[i]; + r = &pmic_regulators[chip].r_datas[i]; desc = &r->desc; config.dev = pdev->dev.parent; @@ -1281,11 +1282,19 @@ static int bd718xx_probe(struct platform_device *pdev) return err; } +static const struct platform_device_id bd718x7_pmic_id[] = { + { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 }, + { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 }, + { }, +}; +MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id); + static struct platform_driver bd718xx_regulator = { .driver = { .name = "bd718xx-pmic", }, .probe = bd718xx_probe, + .id_table = bd718x7_pmic_id, }; module_platform_driver(bd718xx_regulator); diff --git a/include/linux/mfd/rohm-generic.h b/include/linux/mfd/rohm-generic.h index bff15ac26f2c..922f88008232 100644 --- a/include/linux/mfd/rohm-generic.h +++ b/include/linux/mfd/rohm-generic.h @@ -4,7 +4,7 @@ #ifndef __LINUX_MFD_ROHM_H__ #define __LINUX_MFD_ROHM_H__ -enum { +enum rohm_chip_type { ROHM_CHIP_TYPE_BD71837 = 0, ROHM_CHIP_TYPE_BD71847, ROHM_CHIP_TYPE_BD70528, @@ -12,7 +12,6 @@ enum { }; struct rohm_regmap_dev { - unsigned int chip_type; struct device *dev; struct regmap *regmap; }; From patchwork Mon Jan 20 06:36:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207375 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42EE4C33CA1 for ; Mon, 20 Jan 2020 06:36:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0397820684 for ; Mon, 20 Jan 2020 06:36:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726130AbgATGgp (ORCPT ); Mon, 20 Jan 2020 01:36:45 -0500 Received: from mail-lj1-f196.google.com ([209.85.208.196]:34303 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725872AbgATGgp (ORCPT ); Mon, 20 Jan 2020 01:36:45 -0500 Received: by mail-lj1-f196.google.com with SMTP id z22so32609998ljg.1; Sun, 19 Jan 2020 22:36:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=aQtMjyFJUTlxoPHaAi7oOIFButPxkYrjWIxkZ6Qm8eM=; b=TaPH2Fx2nXEaLugyNj4IHhElrUVIvgGNHrJ62xopmnE7RF+rBd7iegH+XVYkrMGXxJ vycuiHEj6u/uF6/psenzfNdbuwFVcyLqXF0f5vW/t57qVWlhEkwLVzGgPXRk+3fWqA2Q JDgVRCJAJojBRlxsP3Bagxjl0QABfTsxZkwxG0AuGnw2/3J5yElSRIcvrMp1oSCoA1Ji pIDlQz+E5a2o7Hzpc+D/j7IzfviFrx/104UfCeYh3D5RNECCAkOVr+dlFe5b9rRviqqf 9WLX8CPbaVCq5O+WCSUDKc0fByT+YK/G8v+duK86TGk+413MF2/WW6eOO5IBFmk/dnnc d7PA== X-Gm-Message-State: APjAAAVRtLupW45sGdzRLHjHwgsuvU4rB1ttkQIGD/iWst+WCR1jkbSQ ZdOZzwJHIDNbRGOhvP1Ll3Y= X-Google-Smtp-Source: APXvYqwt2psk08kUF5Xf7+ROAFv7XyxfimyAWtqYHXJe7sR5uF//wN1gXj4ePC0D+XFDygBXiXLHEQ== X-Received: by 2002:a2e:995a:: with SMTP id r26mr12620254ljj.78.1579502199437; Sun, 19 Jan 2020 22:36:39 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id d24sm2168634lfl.58.2020.01.19.22.36.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:36:38 -0800 (PST) Date: Mon, 20 Jan 2020 08:36:27 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 05/13] mfd: bd71828: Support ROHM BD71828 PMIC - core Message-ID: <8804091ff0cf8fff6b76365c449d8cda86a4fa10.1579501711.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org BD71828GW is a single-chip power management IC for battery-powered portable devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA single-cell linear charger. Also included is a Coulomb counter, a real-time clock (RTC), 3 GPO/regulator control pins, HALL input and a 32.768 kHz clock gate. Add MFD core driver providing interrupt controller facilities and i2c access to sub device drivers. Signed-off-by: Matti Vaittinen Acked-for-MFD-by: Lee Jones --- No changes since v10 drivers/mfd/Kconfig | 15 ++ drivers/mfd/Makefile | 1 + drivers/mfd/rohm-bd71828.c | 318 +++++++++++++++++++++++ include/linux/mfd/rohm-bd71828.h | 425 +++++++++++++++++++++++++++++++ include/linux/mfd/rohm-generic.h | 1 + 5 files changed, 760 insertions(+) create mode 100644 drivers/mfd/rohm-bd71828.c create mode 100644 include/linux/mfd/rohm-bd71828.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 420900852166..c3c9432ef51c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1906,6 +1906,21 @@ config MFD_ROHM_BD70528 10 bits SAR ADC for battery temperature monitor and 1S battery charger. +config MFD_ROHM_BD71828 + tristate "ROHM BD71828 Power Management IC" + depends on I2C=y + depends on OF + select REGMAP_I2C + select REGMAP_IRQ + select MFD_CORE + help + Select this option to get support for the ROHM BD71828 Power + Management IC. BD71828GW is a single-chip power management IC for + battery-powered portable devices. The IC integrates 7 buck + converters, 7 LDOs, and a 1500 mA single-cell linear charger. + Also included is a Coulomb counter, a real-time clock (RTC), and + a 32.768 kHz clock gate. + config MFD_STM32_LPTIMER tristate "Support for STM32 Low-Power Timer" depends on (ARCH_STM32 && OF) || COMPILE_TEST diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index aed99f08739f..61b3093af39d 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -252,6 +252,7 @@ obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o +obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_STMFX) += stmfx.o diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c new file mode 100644 index 000000000000..0ec386c9f26b --- /dev/null +++ b/drivers/mfd/rohm-bd71828.c @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (C) 2019 ROHM Semiconductors +// +// ROHM BD71828 PMIC driver + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct resource rtc_irqs[] = { + DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"), + DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"), + DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd71828-rtc-alm-2"), +}; + +static struct mfd_cell bd71828_mfd_cells[] = { + { .name = "bd71828-pmic", }, + { .name = "bd71828-gpio", }, + { .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" }, + /* + * We use BD71837 driver to drive the clock block. Only differences to + * BD70528 clock gate are the register address and mask. + */ + { .name = "bd71828-clk", }, + { .name = "bd71827-power", }, + { + .name = "bd71828-rtc", + .resources = rtc_irqs, + .num_resources = ARRAY_SIZE(rtc_irqs), + }, +}; + +static const struct regmap_range volatile_ranges[] = { + { + .range_min = BD71828_REG_PS_CTRL_1, + .range_max = BD71828_REG_PS_CTRL_1, + }, { + .range_min = BD71828_REG_PS_CTRL_3, + .range_max = BD71828_REG_PS_CTRL_3, + }, { + .range_min = BD71828_REG_RTC_SEC, + .range_max = BD71828_REG_RTC_YEAR, + }, { + /* + * For now make all charger registers volatile because many + * needs to be and because the charger block is not that + * performance critical. + */ + .range_min = BD71828_REG_CHG_STATE, + .range_max = BD71828_REG_CHG_FULL, + }, { + .range_min = BD71828_REG_INT_MAIN, + .range_max = BD71828_REG_IO_STAT, + }, +}; + +static const struct regmap_access_table volatile_regs = { + .yes_ranges = &volatile_ranges[0], + .n_yes_ranges = ARRAY_SIZE(volatile_ranges), +}; + +static struct regmap_config bd71828_regmap = { + .reg_bits = 8, + .val_bits = 8, + .volatile_table = &volatile_regs, + .max_register = BD71828_MAX_REGISTER, + .cache_type = REGCACHE_RBTREE, +}; + +/* + * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can + * access corect sub-IRQ registers based on bits that are set in main IRQ + * register. + */ + +static unsigned int bit0_offsets[] = {11}; /* RTC IRQ */ +static unsigned int bit1_offsets[] = {10}; /* TEMP IRQ */ +static unsigned int bit2_offsets[] = {6, 7, 8, 9}; /* BAT MON IRQ */ +static unsigned int bit3_offsets[] = {5}; /* BAT IRQ */ +static unsigned int bit4_offsets[] = {4}; /* CHG IRQ */ +static unsigned int bit5_offsets[] = {3}; /* VSYS IRQ */ +static unsigned int bit6_offsets[] = {1, 2}; /* DCIN IRQ */ +static unsigned int bit7_offsets[] = {0}; /* BUCK IRQ */ + +static struct regmap_irq_sub_irq_map bd71828_sub_irq_offsets[] = { + REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets), + REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets), +}; + +static struct regmap_irq bd71828_irqs[] = { + REGMAP_IRQ_REG(BD71828_INT_BUCK1_OCP, 0, BD71828_INT_BUCK1_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_BUCK2_OCP, 0, BD71828_INT_BUCK2_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_BUCK3_OCP, 0, BD71828_INT_BUCK3_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_BUCK4_OCP, 0, BD71828_INT_BUCK4_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_BUCK5_OCP, 0, BD71828_INT_BUCK5_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_BUCK6_OCP, 0, BD71828_INT_BUCK6_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_BUCK7_OCP, 0, BD71828_INT_BUCK7_OCP_MASK), + REGMAP_IRQ_REG(BD71828_INT_PGFAULT, 0, BD71828_INT_PGFAULT_MASK), + /* DCIN1 interrupts */ + REGMAP_IRQ_REG(BD71828_INT_DCIN_DET, 1, BD71828_INT_DCIN_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_DCIN_RMV, 1, BD71828_INT_DCIN_RMV_MASK), + REGMAP_IRQ_REG(BD71828_INT_CLPS_OUT, 1, BD71828_INT_CLPS_OUT_MASK), + REGMAP_IRQ_REG(BD71828_INT_CLPS_IN, 1, BD71828_INT_CLPS_IN_MASK), + /* DCIN2 interrupts */ + REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2, + BD71828_INT_DCIN_MON_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2, + BD71828_INT_DCIN_MON_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_LONGPUSH, 2, BD71828_INT_LONGPUSH_MASK), + REGMAP_IRQ_REG(BD71828_INT_MIDPUSH, 2, BD71828_INT_MIDPUSH_MASK), + REGMAP_IRQ_REG(BD71828_INT_SHORTPUSH, 2, BD71828_INT_SHORTPUSH_MASK), + REGMAP_IRQ_REG(BD71828_INT_PUSH, 2, BD71828_INT_PUSH_MASK), + REGMAP_IRQ_REG(BD71828_INT_WDOG, 2, BD71828_INT_WDOG_MASK), + REGMAP_IRQ_REG(BD71828_INT_SWRESET, 2, BD71828_INT_SWRESET_MASK), + /* Vsys */ + REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3, + BD71828_INT_VSYS_UV_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3, + BD71828_INT_VSYS_UV_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3, + BD71828_INT_VSYS_LOW_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3, + BD71828_INT_VSYS_LOW_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3, + BD71828_INT_VSYS_HALL_IN_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3, + BD71828_INT_VSYS_HALL_TOGGLE_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3, + BD71828_INT_VSYS_MON_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3, + BD71828_INT_VSYS_MON_DET_MASK), + /* Charger */ + REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4, + BD71828_INT_CHG_DCIN_ILIM_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4, + BD71828_INT_CHG_TOPOFF_TO_DONE_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4, + BD71828_INT_CHG_WDG_TEMP_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4, + BD71828_INT_CHG_WDG_TIME_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4, + BD71828_INT_CHG_RECHARGE_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4, + BD71828_INT_CHG_RECHARGE_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 4, + BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK), + REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4, + BD71828_INT_CHG_STATE_TRANSITION_MASK), + /* Battery */ + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5, + BD71828_INT_BAT_TEMP_NORMAL_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5, + BD71828_INT_BAT_TEMP_ERANGE_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5, + BD71828_INT_BAT_TEMP_WARN_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5, + BD71828_INT_BAT_REMOVED_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5, + BD71828_INT_BAT_DETECTED_MASK), + REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5, + BD71828_INT_THERM_REMOVED_MASK), + REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5, + BD71828_INT_THERM_DETECTED_MASK), + /* Battery Mon 1 */ + REGMAP_IRQ_REG(BD71828_INT_BAT_DEAD, 6, BD71828_INT_BAT_DEAD_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6, + BD71828_INT_BAT_SHORTC_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6, + BD71828_INT_BAT_SHORTC_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6, + BD71828_INT_BAT_LOW_VOLT_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6, + BD71828_INT_BAT_LOW_VOLT_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6, + BD71828_INT_BAT_OVER_VOLT_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6, + BD71828_INT_BAT_OVER_VOLT_DET_MASK), + /* Battery Mon 2 */ + REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7, + BD71828_INT_BAT_MON_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7, + BD71828_INT_BAT_MON_DET_MASK), + /* Battery Mon 3 (Coulomb counter) */ + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8, + BD71828_INT_BAT_CC_MON1_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8, + BD71828_INT_BAT_CC_MON2_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8, + BD71828_INT_BAT_CC_MON3_MASK), + /* Battery Mon 4 */ + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9, + BD71828_INT_BAT_OVER_CURR_1_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9, + BD71828_INT_BAT_OVER_CURR_1_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9, + BD71828_INT_BAT_OVER_CURR_2_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9, + BD71828_INT_BAT_OVER_CURR_2_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9, + BD71828_INT_BAT_OVER_CURR_3_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9, + BD71828_INT_BAT_OVER_CURR_3_DET_MASK), + /* Temperature */ + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10, + BD71828_INT_TEMP_BAT_LOW_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10, + BD71828_INT_TEMP_BAT_LOW_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10, + BD71828_INT_TEMP_BAT_HI_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10, + BD71828_INT_TEMP_BAT_HI_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_RES, 10, + BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_DET, 10, + BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_DET, 10, + BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK), + REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_RES, 10, + BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK), + /* RTC Alarm */ + REGMAP_IRQ_REG(BD71828_INT_RTC0, 11, BD71828_INT_RTC0_MASK), + REGMAP_IRQ_REG(BD71828_INT_RTC1, 11, BD71828_INT_RTC1_MASK), + REGMAP_IRQ_REG(BD71828_INT_RTC2, 11, BD71828_INT_RTC2_MASK), +}; + +static struct regmap_irq_chip bd71828_irq_chip = { + .name = "bd71828_irq", + .main_status = BD71828_REG_INT_MAIN, + .irqs = &bd71828_irqs[0], + .num_irqs = ARRAY_SIZE(bd71828_irqs), + .status_base = BD71828_REG_INT_BUCK, + .mask_base = BD71828_REG_INT_MASK_BUCK, + .ack_base = BD71828_REG_INT_BUCK, + .mask_invert = true, + .init_ack_masked = true, + .num_regs = 12, + .num_main_regs = 1, + .sub_reg_offsets = &bd71828_sub_irq_offsets[0], + .num_main_status_bits = 8, + .irq_reg_stride = 1, +}; + +static int bd71828_i2c_probe(struct i2c_client *i2c) +{ + struct rohm_regmap_dev *chip; + struct regmap_irq_chip_data *irq_data; + int ret; + + if (!i2c->irq) { + dev_err(&i2c->dev, "No IRQ configured\n"); + return -EINVAL; + } + + chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + dev_set_drvdata(&i2c->dev, chip); + + chip->regmap = devm_regmap_init_i2c(i2c, &bd71828_regmap); + if (IS_ERR(chip->regmap)) { + dev_err(&i2c->dev, "Failed to initialize Regmap\n"); + return PTR_ERR(chip->regmap); + } + + ret = devm_regmap_add_irq_chip(&i2c->dev, chip->regmap, + i2c->irq, IRQF_ONESHOT, 0, + &bd71828_irq_chip, &irq_data); + if (ret) { + dev_err(&i2c->dev, "Failed to add IRQ chip\n"); + return ret; + } + + dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n", + bd71828_irq_chip.num_irqs); + + ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, + bd71828_mfd_cells, + ARRAY_SIZE(bd71828_mfd_cells), NULL, 0, + regmap_irq_get_domain(irq_data)); + if (ret) + dev_err(&i2c->dev, "Failed to create subdevices\n"); + + return ret; +} + +static const struct of_device_id bd71828_of_match[] = { + { .compatible = "rohm,bd71828", }, + { }, +}; +MODULE_DEVICE_TABLE(of, bd71828_of_match); + +static struct i2c_driver bd71828_drv = { + .driver = { + .name = "rohm-bd71828", + .of_match_table = bd71828_of_match, + }, + .probe_new = &bd71828_i2c_probe, +}; +module_i2c_driver(bd71828_drv); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("ROHM BD71828 Power Management IC driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h new file mode 100644 index 000000000000..eb0557eb5314 --- /dev/null +++ b/include/linux/mfd/rohm-bd71828.h @@ -0,0 +1,425 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2019 ROHM Semiconductors */ + +#ifndef __LINUX_MFD_BD71828_H__ +#define __LINUX_MFD_BD71828_H__ + +#include + +/* Regulator IDs */ +enum { + BD71828_BUCK1, + BD71828_BUCK2, + BD71828_BUCK3, + BD71828_BUCK4, + BD71828_BUCK5, + BD71828_BUCK6, + BD71828_BUCK7, + BD71828_LDO1, + BD71828_LDO2, + BD71828_LDO3, + BD71828_LDO4, + BD71828_LDO5, + BD71828_LDO6, + BD71828_LDO_SNVS, + BD71828_REGULATOR_AMOUNT, +}; + +#define BD71828_BUCK1267_VOLTS 0xEF +#define BD71828_BUCK3_VOLTS 0x10 +#define BD71828_BUCK4_VOLTS 0x20 +#define BD71828_BUCK5_VOLTS 0x10 +#define BD71828_LDO_VOLTS 0x32 +/* LDO6 is fixed 1.8V voltage */ +#define BD71828_LDO_6_VOLTAGE 1800000 + +/* Registers and masks*/ + +/* MODE control */ +#define BD71828_REG_PS_CTRL_1 0x04 +#define BD71828_REG_PS_CTRL_2 0x05 +#define BD71828_REG_PS_CTRL_3 0x06 + +//#define BD71828_REG_SWRESET 0x06 +#define BD71828_MASK_RUN_LVL_CTRL 0x30 + +/* Regulator control masks */ + +#define BD71828_MASK_RAMP_DELAY 0x6 + +#define BD71828_MASK_RUN_EN 0x08 +#define BD71828_MASK_SUSP_EN 0x04 +#define BD71828_MASK_IDLE_EN 0x02 +#define BD71828_MASK_LPSR_EN 0x01 + +#define BD71828_MASK_RUN0_EN 0x01 +#define BD71828_MASK_RUN1_EN 0x02 +#define BD71828_MASK_RUN2_EN 0x04 +#define BD71828_MASK_RUN3_EN 0x08 + +#define BD71828_MASK_DVS_BUCK1_CTRL 0x10 +#define BD71828_DVS_BUCK1_CTRL_I2C 0 +#define BD71828_DVS_BUCK1_USE_RUNLVL 0x10 + +#define BD71828_MASK_DVS_BUCK2_CTRL 0x20 +#define BD71828_DVS_BUCK2_CTRL_I2C 0 +#define BD71828_DVS_BUCK2_USE_RUNLVL 0x20 + +#define BD71828_MASK_DVS_BUCK6_CTRL 0x40 +#define BD71828_DVS_BUCK6_CTRL_I2C 0 +#define BD71828_DVS_BUCK6_USE_RUNLVL 0x40 + +#define BD71828_MASK_DVS_BUCK7_CTRL 0x80 +#define BD71828_DVS_BUCK7_CTRL_I2C 0 +#define BD71828_DVS_BUCK7_USE_RUNLVL 0x80 + +#define BD71828_MASK_BUCK1267_VOLT 0xff +#define BD71828_MASK_BUCK3_VOLT 0x1f +#define BD71828_MASK_BUCK4_VOLT 0x3f +#define BD71828_MASK_BUCK5_VOLT 0x1f +#define BD71828_MASK_LDO_VOLT 0x3f + +/* Regulator control regs */ +#define BD71828_REG_BUCK1_EN 0x08 +#define BD71828_REG_BUCK1_CTRL 0x09 +#define BD71828_REG_BUCK1_MODE 0x0a +#define BD71828_REG_BUCK1_IDLE_VOLT 0x0b +#define BD71828_REG_BUCK1_SUSP_VOLT 0x0c +#define BD71828_REG_BUCK1_VOLT 0x0d + +#define BD71828_REG_BUCK2_EN 0x12 +#define BD71828_REG_BUCK2_CTRL 0x13 +#define BD71828_REG_BUCK2_MODE 0x14 +#define BD71828_REG_BUCK2_IDLE_VOLT 0x15 +#define BD71828_REG_BUCK2_SUSP_VOLT 0x16 +#define BD71828_REG_BUCK2_VOLT 0x17 + +#define BD71828_REG_BUCK3_EN 0x1c +#define BD71828_REG_BUCK3_MODE 0x1d +#define BD71828_REG_BUCK3_VOLT 0x1e + +#define BD71828_REG_BUCK4_EN 0x1f +#define BD71828_REG_BUCK4_MODE 0x20 +#define BD71828_REG_BUCK4_VOLT 0x21 + +#define BD71828_REG_BUCK5_EN 0x22 +#define BD71828_REG_BUCK5_MODE 0x23 +#define BD71828_REG_BUCK5_VOLT 0x24 + +#define BD71828_REG_BUCK6_EN 0x25 +#define BD71828_REG_BUCK6_CTRL 0x26 +#define BD71828_REG_BUCK6_MODE 0x27 +#define BD71828_REG_BUCK6_IDLE_VOLT 0x28 +#define BD71828_REG_BUCK6_SUSP_VOLT 0x29 +#define BD71828_REG_BUCK6_VOLT 0x2a + +#define BD71828_REG_BUCK7_EN 0x2f +#define BD71828_REG_BUCK7_CTRL 0x30 +#define BD71828_REG_BUCK7_MODE 0x31 +#define BD71828_REG_BUCK7_IDLE_VOLT 0x32 +#define BD71828_REG_BUCK7_SUSP_VOLT 0x33 +#define BD71828_REG_BUCK7_VOLT 0x34 + +#define BD71828_REG_LDO1_EN 0x39 +#define BD71828_REG_LDO1_VOLT 0x3a +#define BD71828_REG_LDO2_EN 0x3b +#define BD71828_REG_LDO2_VOLT 0x3c +#define BD71828_REG_LDO3_EN 0x3d +#define BD71828_REG_LDO3_VOLT 0x3e +#define BD71828_REG_LDO4_EN 0x3f +#define BD71828_REG_LDO4_VOLT 0x40 +#define BD71828_REG_LDO5_EN 0x41 +#define BD71828_REG_LDO5_VOLT 0x43 +#define BD71828_REG_LDO5_VOLT_OPT 0x42 +#define BD71828_REG_LDO6_EN 0x44 +//#define BD71828_REG_LDO6_VOLT 0x4 +#define BD71828_REG_LDO7_EN 0x45 +#define BD71828_REG_LDO7_VOLT 0x46 + +/* GPIO */ + +#define BD71828_GPIO_DRIVE_MASK 0x2 +#define BD71828_GPIO_OPEN_DRAIN 0x0 +#define BD71828_GPIO_PUSH_PULL 0x2 +#define BD71828_GPIO_OUT_HI 0x1 +#define BD71828_GPIO_OUT_LO 0x0 +#define BD71828_GPIO_OUT_MASK 0x1 + +#define BD71828_REG_GPIO_CTRL1 0x47 +#define BD71828_REG_GPIO_CTRL2 0x48 +#define BD71828_REG_GPIO_CTRL3 0x49 +#define BD71828_REG_IO_STAT 0xed + +/* RTC */ +#define BD71828_REG_RTC_SEC 0x4c +#define BD71828_REG_RTC_MINUTE 0x4d +#define BD71828_REG_RTC_HOUR 0x4e +#define BD71828_REG_RTC_WEEK 0x4f +#define BD71828_REG_RTC_DAY 0x50 +#define BD71828_REG_RTC_MONTH 0x51 +#define BD71828_REG_RTC_YEAR 0x52 + +#define BD71828_REG_RTC_ALM0_SEC 0x53 +#define BD71828_REG_RTC_ALM0_MINUTE 0x54 +#define BD71828_REG_RTC_ALM0_HOUR 0x55 +#define BD71828_REG_RTC_ALM0_WEEK 0x56 +#define BD71828_REG_RTC_ALM0_DAY 0x57 +#define BD71828_REG_RTC_ALM0_MONTH 0x58 +#define BD71828_REG_RTC_ALM0_YEAR 0x59 +#define BD71828_REG_RTC_ALM0_MASK 0x61 + +#define BD71828_REG_RTC_ALM1_SEC 0x5a +#define BD71828_REG_RTC_ALM1_MINUTE 0x5b +#define BD71828_REG_RTC_ALM1_HOUR 0x5c +#define BD71828_REG_RTC_ALM1_WEEK 0x5d +#define BD71828_REG_RTC_ALM1_DAY 0x5e +#define BD71828_REG_RTC_ALM1_MONTH 0x5f +#define BD71828_REG_RTC_ALM1_YEAR 0x60 +#define BD71828_REG_RTC_ALM1_MASK 0x62 + +#define BD71828_REG_RTC_ALM2 0x63 + +/* Charger/Battey */ +#define BD71828_REG_CHG_STATE 0x65 +#define BD71828_REG_CHG_FULL 0xd2 + +/* CLK */ +#define BD71828_REG_OUT32K 0x4B + +/* LEDs */ +#define BD71828_REG_LED_CTRL 0x4A +#define BD71828_MASK_LED_AMBER 0x80 +#define BD71828_MASK_LED_GREEN 0x40 +#define BD71828_LED_ON 0xff +#define BD71828_LED_OFF 0x0 + +/* IRQ registers */ +#define BD71828_REG_INT_MASK_BUCK 0xd3 +#define BD71828_REG_INT_MASK_DCIN1 0xd4 +#define BD71828_REG_INT_MASK_DCIN2 0xd5 +#define BD71828_REG_INT_MASK_VSYS 0xd6 +#define BD71828_REG_INT_MASK_CHG 0xd7 +#define BD71828_REG_INT_MASK_BAT 0xd8 +#define BD71828_REG_INT_MASK_BAT_MON1 0xd9 +#define BD71828_REG_INT_MASK_BAT_MON2 0xda +#define BD71828_REG_INT_MASK_BAT_MON3 0xdb +#define BD71828_REG_INT_MASK_BAT_MON4 0xdc +#define BD71828_REG_INT_MASK_TEMP 0xdd +#define BD71828_REG_INT_MASK_RTC 0xde + + +#define BD71828_REG_INT_MAIN 0xdf +#define BD71828_REG_INT_BUCK 0xe0 +#define BD71828_REG_INT_DCIN1 0xe1 +#define BD71828_REG_INT_DCIN2 0xe2 +#define BD71828_REG_INT_VSYS 0xe3 +#define BD71828_REG_INT_CHG 0xe4 +#define BD71828_REG_INT_BAT 0xe5 +#define BD71828_REG_INT_BAT_MON1 0xe6 +#define BD71828_REG_INT_BAT_MON2 0xe7 +#define BD71828_REG_INT_BAT_MON3 0xe8 +#define BD71828_REG_INT_BAT_MON4 0xe9 +#define BD71828_REG_INT_TEMP 0xea +#define BD71828_REG_INT_RTC 0xeb +#define BD71828_REG_INT_UPDATE 0xec + +#define BD71828_MAX_REGISTER BD71828_REG_IO_STAT + +/* Masks for main IRQ register bits */ +enum { + BD71828_INT_BUCK, +#define BD71828_INT_BUCK_MASK BIT(BD71828_INT_BUCK) + BD71828_INT_DCIN, +#define BD71828_INT_DCIN_MASK BIT(BD71828_INT_DCIN) + BD71828_INT_VSYS, +#define BD71828_INT_VSYS_MASK BIT(BD71828_INT_VSYS) + BD71828_INT_CHG, +#define BD71828_INT_CHG_MASK BIT(BD71828_INT_CHG) + BD71828_INT_BAT, +#define BD71828_INT_BAT_MASK BIT(BD71828_INT_BAT) + BD71828_INT_BAT_MON, +#define BD71828_INT_BAT_MON_MASK BIT(BD71828_INT_BAT_MON) + BD71828_INT_TEMP, +#define BD71828_INT_TEMP_MASK BIT(BD71828_INT_TEMP) + BD71828_INT_RTC, +#define BD71828_INT_RTC_MASK BIT(BD71828_INT_RTC) +}; + +/* Interrupts */ +enum { + /* BUCK reg interrupts */ + BD71828_INT_BUCK1_OCP, + BD71828_INT_BUCK2_OCP, + BD71828_INT_BUCK3_OCP, + BD71828_INT_BUCK4_OCP, + BD71828_INT_BUCK5_OCP, + BD71828_INT_BUCK6_OCP, + BD71828_INT_BUCK7_OCP, + BD71828_INT_PGFAULT, + /* DCIN1 interrupts */ + BD71828_INT_DCIN_DET, + BD71828_INT_DCIN_RMV, + BD71828_INT_CLPS_OUT, + BD71828_INT_CLPS_IN, + /* DCIN2 interrupts */ + BD71828_INT_DCIN_MON_RES, + BD71828_INT_DCIN_MON_DET, + BD71828_INT_LONGPUSH, + BD71828_INT_MIDPUSH, + BD71828_INT_SHORTPUSH, + BD71828_INT_PUSH, + BD71828_INT_WDOG, + BD71828_INT_SWRESET, + /* Vsys */ + BD71828_INT_VSYS_UV_RES, + BD71828_INT_VSYS_UV_DET, + BD71828_INT_VSYS_LOW_RES, + BD71828_INT_VSYS_LOW_DET, + BD71828_INT_VSYS_HALL_IN, + BD71828_INT_VSYS_HALL_TOGGLE, + BD71828_INT_VSYS_MON_RES, + BD71828_INT_VSYS_MON_DET, + /* Charger */ + BD71828_INT_CHG_DCIN_ILIM, + BD71828_INT_CHG_TOPOFF_TO_DONE, + BD71828_INT_CHG_WDG_TEMP, + BD71828_INT_CHG_WDG_TIME, + BD71828_INT_CHG_RECHARGE_RES, + BD71828_INT_CHG_RECHARGE_DET, + BD71828_INT_CHG_RANGED_TEMP_TRANSITION, + BD71828_INT_CHG_STATE_TRANSITION, + /* Battery */ + BD71828_INT_BAT_TEMP_NORMAL, + BD71828_INT_BAT_TEMP_ERANGE, + BD71828_INT_BAT_TEMP_WARN, + BD71828_INT_BAT_REMOVED, + BD71828_INT_BAT_DETECTED, + BD71828_INT_THERM_REMOVED, + BD71828_INT_THERM_DETECTED, + /* Battery Mon 1 */ + BD71828_INT_BAT_DEAD, + BD71828_INT_BAT_SHORTC_RES, + BD71828_INT_BAT_SHORTC_DET, + BD71828_INT_BAT_LOW_VOLT_RES, + BD71828_INT_BAT_LOW_VOLT_DET, + BD71828_INT_BAT_OVER_VOLT_RES, + BD71828_INT_BAT_OVER_VOLT_DET, + /* Battery Mon 2 */ + BD71828_INT_BAT_MON_RES, + BD71828_INT_BAT_MON_DET, + /* Battery Mon 3 (Coulomb counter) */ + BD71828_INT_BAT_CC_MON1, + BD71828_INT_BAT_CC_MON2, + BD71828_INT_BAT_CC_MON3, + /* Battery Mon 4 */ + BD71828_INT_BAT_OVER_CURR_1_RES, + BD71828_INT_BAT_OVER_CURR_1_DET, + BD71828_INT_BAT_OVER_CURR_2_RES, + BD71828_INT_BAT_OVER_CURR_2_DET, + BD71828_INT_BAT_OVER_CURR_3_RES, + BD71828_INT_BAT_OVER_CURR_3_DET, + /* Temperature */ + BD71828_INT_TEMP_BAT_LOW_RES, + BD71828_INT_TEMP_BAT_LOW_DET, + BD71828_INT_TEMP_BAT_HI_RES, + BD71828_INT_TEMP_BAT_HI_DET, + BD71828_INT_TEMP_CHIP_OVER_125_RES, + BD71828_INT_TEMP_CHIP_OVER_125_DET, + BD71828_INT_TEMP_CHIP_OVER_VF_DET, + BD71828_INT_TEMP_CHIP_OVER_VF_RES, + /* RTC Alarm */ + BD71828_INT_RTC0, + BD71828_INT_RTC1, + BD71828_INT_RTC2, +}; + +#define BD71828_INT_BUCK1_OCP_MASK 0x1 +#define BD71828_INT_BUCK2_OCP_MASK 0x2 +#define BD71828_INT_BUCK3_OCP_MASK 0x4 +#define BD71828_INT_BUCK4_OCP_MASK 0x8 +#define BD71828_INT_BUCK5_OCP_MASK 0x10 +#define BD71828_INT_BUCK6_OCP_MASK 0x20 +#define BD71828_INT_BUCK7_OCP_MASK 0x40 +#define BD71828_INT_PGFAULT_MASK 0x80 + +#define BD71828_INT_DCIN_DET_MASK 0x1 +#define BD71828_INT_DCIN_RMV_MASK 0x2 +#define BD71828_INT_CLPS_OUT_MASK 0x4 +#define BD71828_INT_CLPS_IN_MASK 0x8 + /* DCIN2 interrupts */ +#define BD71828_INT_DCIN_MON_RES_MASK 0x1 +#define BD71828_INT_DCIN_MON_DET_MASK 0x2 +#define BD71828_INT_LONGPUSH_MASK 0x4 +#define BD71828_INT_MIDPUSH_MASK 0x8 +#define BD71828_INT_SHORTPUSH_MASK 0x10 +#define BD71828_INT_PUSH_MASK 0x20 +#define BD71828_INT_WDOG_MASK 0x40 +#define BD71828_INT_SWRESET_MASK 0x80 + /* Vsys */ +#define BD71828_INT_VSYS_UV_RES_MASK 0x1 +#define BD71828_INT_VSYS_UV_DET_MASK 0x2 +#define BD71828_INT_VSYS_LOW_RES_MASK 0x4 +#define BD71828_INT_VSYS_LOW_DET_MASK 0x8 +#define BD71828_INT_VSYS_HALL_IN_MASK 0x10 +#define BD71828_INT_VSYS_HALL_TOGGLE_MASK 0x20 +#define BD71828_INT_VSYS_MON_RES_MASK 0x40 +#define BD71828_INT_VSYS_MON_DET_MASK 0x80 + /* Charger */ +#define BD71828_INT_CHG_DCIN_ILIM_MASK 0x1 +#define BD71828_INT_CHG_TOPOFF_TO_DONE_MASK 0x2 +#define BD71828_INT_CHG_WDG_TEMP_MASK 0x4 +#define BD71828_INT_CHG_WDG_TIME_MASK 0x8 +#define BD71828_INT_CHG_RECHARGE_RES_MASK 0x10 +#define BD71828_INT_CHG_RECHARGE_DET_MASK 0x20 +#define BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK 0x40 +#define BD71828_INT_CHG_STATE_TRANSITION_MASK 0x80 + /* Battery */ +#define BD71828_INT_BAT_TEMP_NORMAL_MASK 0x1 +#define BD71828_INT_BAT_TEMP_ERANGE_MASK 0x2 +#define BD71828_INT_BAT_TEMP_WARN_MASK 0x4 +#define BD71828_INT_BAT_REMOVED_MASK 0x10 +#define BD71828_INT_BAT_DETECTED_MASK 0x20 +#define BD71828_INT_THERM_REMOVED_MASK 0x40 +#define BD71828_INT_THERM_DETECTED_MASK 0x80 + /* Battery Mon 1 */ +#define BD71828_INT_BAT_DEAD_MASK 0x2 +#define BD71828_INT_BAT_SHORTC_RES_MASK 0x4 +#define BD71828_INT_BAT_SHORTC_DET_MASK 0x8 +#define BD71828_INT_BAT_LOW_VOLT_RES_MASK 0x10 +#define BD71828_INT_BAT_LOW_VOLT_DET_MASK 0x20 +#define BD71828_INT_BAT_OVER_VOLT_RES_MASK 0x40 +#define BD71828_INT_BAT_OVER_VOLT_DET_MASK 0x80 + /* Battery Mon 2 */ +#define BD71828_INT_BAT_MON_RES_MASK 0x1 +#define BD71828_INT_BAT_MON_DET_MASK 0x2 + /* Battery Mon 3 (Coulomb counter) */ +#define BD71828_INT_BAT_CC_MON1_MASK 0x1 +#define BD71828_INT_BAT_CC_MON2_MASK 0x2 +#define BD71828_INT_BAT_CC_MON3_MASK 0x4 + /* Battery Mon 4 */ +#define BD71828_INT_BAT_OVER_CURR_1_RES_MASK 0x1 +#define BD71828_INT_BAT_OVER_CURR_1_DET_MASK 0x2 +#define BD71828_INT_BAT_OVER_CURR_2_RES_MASK 0x4 +#define BD71828_INT_BAT_OVER_CURR_2_DET_MASK 0x8 +#define BD71828_INT_BAT_OVER_CURR_3_RES_MASK 0x10 +#define BD71828_INT_BAT_OVER_CURR_3_DET_MASK 0x20 + /* Temperature */ +#define BD71828_INT_TEMP_BAT_LOW_RES_MASK 0x1 +#define BD71828_INT_TEMP_BAT_LOW_DET_MASK 0x2 +#define BD71828_INT_TEMP_BAT_HI_RES_MASK 0x4 +#define BD71828_INT_TEMP_BAT_HI_DET_MASK 0x8 +#define BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK 0x10 +#define BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK 0x20 +#define BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK 0x40 +#define BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK 0x80 + /* RTC Alarm */ +#define BD71828_INT_RTC0_MASK 0x1 +#define BD71828_INT_RTC1_MASK 0x2 +#define BD71828_INT_RTC2_MASK 0x4 + +#define BD71828_OUT32K_EN 0x1 +#define BD71828_OUT_TYPE_MASK 0x2 +#define BD71828_OUT_TYPE_OPEN_DRAIN 0x0 +#define BD71828_OUT_TYPE_CMOS 0x2 + +#endif /* __LINUX_MFD_BD71828_H__ */ diff --git a/include/linux/mfd/rohm-generic.h b/include/linux/mfd/rohm-generic.h index 922f88008232..ff3dd7578fd3 100644 --- a/include/linux/mfd/rohm-generic.h +++ b/include/linux/mfd/rohm-generic.h @@ -8,6 +8,7 @@ enum rohm_chip_type { ROHM_CHIP_TYPE_BD71837 = 0, ROHM_CHIP_TYPE_BD71847, ROHM_CHIP_TYPE_BD70528, + ROHM_CHIP_TYPE_BD71828, ROHM_CHIP_TYPE_AMOUNT }; From patchwork Mon Jan 20 06:37:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207374 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY,USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7048DC33CB7 for ; Mon, 20 Jan 2020 06:37:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 517E22077C for ; Mon, 20 Jan 2020 06:37:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725872AbgATGhj (ORCPT ); Mon, 20 Jan 2020 01:37:39 -0500 Received: from mail-lf1-f66.google.com ([209.85.167.66]:41346 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725788AbgATGhj (ORCPT ); Mon, 20 Jan 2020 01:37:39 -0500 Received: by mail-lf1-f66.google.com with SMTP id m30so23060752lfp.8; Sun, 19 Jan 2020 22:37:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=g8ysw4/yA+4uYX9itP0v+Y3HyyS0BidZBKmk2oSyIqk=; b=n7szQB+ALQ+G8Hzg9ObGjyPELGbgbeXTg+9zSEmTGHFO34bKLAU4593jYOzK7PULJ0 V5IaVreM9MKU5AGsnml3Cya02P8ovL4IHdHHz1R2hyj2eFVUXMa01b5ttCEa/B51ps6H OrnkBrTrmzUkvL+zARmCxpuyRCqwM3BM5YcOv1sgt+vZ6XsjwaWNpFus3hurKTah3yKW cJoUbMRIWuw/vKUPQITVCAkVCZ4svCL5CT9jaI0cm3RhG54DRhq7oarw6/3T0BqNBjzJ HH7bt/JvLY7w2D+wvttu2UhmV21YojbYz90oc7sjPNWKVDv7doXXWucldxydUAXi6pBj ZRqg== X-Gm-Message-State: APjAAAW9JwAZRtxpzX/jAXbzB2xCOQjojBs/AkuLpl2hisqy9vezmioV ZFQE/j50vTzw2IAnDc5vRro= X-Google-Smtp-Source: APXvYqw7+kSqTWkA4vdtLcqY06wto7mFx/VTxxxMr1bRZSsi3TTX/5KlOoqYNnu+ws4ZGEwgW+8odA== X-Received: by 2002:ac2:5a43:: with SMTP id r3mr12558514lfn.150.1579502255380; Sun, 19 Jan 2020 22:37:35 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id d20sm16094916ljg.95.2020.01.19.22.37.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:37:34 -0800 (PST) Date: Mon, 20 Jan 2020 08:37:28 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 07/13] clk: bd718x7: Support ROHM BD71828 clk block Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org BD71828GW is a single-chip power management IC for battery-powered portable devices. Add support for controlling BD71828 clk using bd718x7 driver. Signed-off-by: Matti Vaittinen Acked-for-MFD-by: Lee Jones Acked-by: Stephen Boyd --- No changes since v10 drivers/clk/Kconfig | 6 ++--- drivers/clk/clk-bd718x7.c | 38 +++++++++++++++++++++++--------- include/linux/mfd/rohm-bd70528.h | 6 ----- include/linux/mfd/rohm-bd71828.h | 4 ---- include/linux/mfd/rohm-bd718x7.h | 6 ----- 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 45653a0e6ecd..ac5981ce2477 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -305,10 +305,10 @@ config COMMON_CLK_MMP2 Support for Marvell MMP2 and MMP3 SoC clocks config COMMON_CLK_BD718XX - tristate "Clock driver for ROHM BD718x7 PMIC" - depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 + tristate "Clock driver for 32K clk gates on ROHM PMICs" + depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828 help - This driver supports ROHM BD71837, ROHM BD71847 and + This driver supports ROHM BD71837, ROHM BD71847, ROHM BD71828 and ROHM BD70528 PMICs clock gates. config COMMON_CLK_FIXED_MMIO diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index 33699ee1bdf3..b52e8d6f660c 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -7,12 +7,25 @@ #include #include #include -#include -#include +#include #include #include #include +/* clk control registers */ +/* BD70528 */ +#define BD70528_REG_OUT32K 0x2c +/* BD71828 */ +#define BD71828_REG_OUT32K 0x4B +/* BD71837 and BD71847 */ +#define BD718XX_REG_OUT32K 0x2E + +/* + * BD71837, BD71847, BD70528 and BD71828 all use bit [0] to clk output control + */ +#define CLK_OUT_EN_MASK BIT(0) + + struct bd718xx_clk { struct clk_hw hw; u8 reg; @@ -21,10 +34,8 @@ struct bd718xx_clk { struct rohm_regmap_dev *mfd; }; -static int bd71837_clk_set(struct clk_hw *hw, int status) +static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status) { - struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); - return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status); } @@ -33,14 +44,16 @@ static void bd71837_clk_disable(struct clk_hw *hw) int rv; struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); - rv = bd71837_clk_set(hw, 0); + rv = bd71837_clk_set(c, 0); if (rv) dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv); } static int bd71837_clk_enable(struct clk_hw *hw) { - return bd71837_clk_set(hw, 1); + struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw); + + return bd71837_clk_set(c, 0xffffffff); } static int bd71837_clk_is_enabled(struct clk_hw *hw) @@ -92,11 +105,15 @@ static int bd71837_clk_probe(struct platform_device *pdev) case ROHM_CHIP_TYPE_BD71837: case ROHM_CHIP_TYPE_BD71847: c->reg = BD718XX_REG_OUT32K; - c->mask = BD718XX_OUT32K_EN; + c->mask = CLK_OUT_EN_MASK; + break; + case ROHM_CHIP_TYPE_BD71828: + c->reg = BD71828_REG_OUT32K; + c->mask = CLK_OUT_EN_MASK; break; case ROHM_CHIP_TYPE_BD70528: - c->reg = BD70528_REG_CLK_OUT; - c->mask = BD70528_CLK_OUT_EN_MASK; + c->reg = BD70528_REG_OUT32K; + c->mask = CLK_OUT_EN_MASK; break; default: dev_err(&pdev->dev, "Unknown clk chip\n"); @@ -126,6 +143,7 @@ static const struct platform_device_id bd718x7_clk_id[] = { { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 }, { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 }, { "bd70528-clk", ROHM_CHIP_TYPE_BD70528 }, + { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 }, { }, }; MODULE_DEVICE_TABLE(platform, bd718x7_clk_id); diff --git a/include/linux/mfd/rohm-bd70528.h b/include/linux/mfd/rohm-bd70528.h index 1013e60c5b25..2ad2320d0a96 100644 --- a/include/linux/mfd/rohm-bd70528.h +++ b/include/linux/mfd/rohm-bd70528.h @@ -89,10 +89,6 @@ struct bd70528_data { #define BD70528_REG_GPIO3_OUT 0x52 #define BD70528_REG_GPIO4_OUT 0x54 -/* clk control */ - -#define BD70528_REG_CLK_OUT 0x2c - /* RTC */ #define BD70528_REG_RTC_COUNT_H 0x2d @@ -309,8 +305,6 @@ enum { #define BD70528_GPIO_IN_STATE_BASE 1 -#define BD70528_CLK_OUT_EN_MASK 0x1 - /* RTC masks to mask out reserved bits */ #define BD70528_MASK_RTC_SEC 0x7f diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h index eb0557eb5314..d013e03f742d 100644 --- a/include/linux/mfd/rohm-bd71828.h +++ b/include/linux/mfd/rohm-bd71828.h @@ -183,9 +183,6 @@ enum { #define BD71828_REG_CHG_STATE 0x65 #define BD71828_REG_CHG_FULL 0xd2 -/* CLK */ -#define BD71828_REG_OUT32K 0x4B - /* LEDs */ #define BD71828_REG_LED_CTRL 0x4A #define BD71828_MASK_LED_AMBER 0x80 @@ -417,7 +414,6 @@ enum { #define BD71828_INT_RTC1_MASK 0x2 #define BD71828_INT_RTC2_MASK 0x4 -#define BD71828_OUT32K_EN 0x1 #define BD71828_OUT_TYPE_MASK 0x2 #define BD71828_OUT_TYPE_OPEN_DRAIN 0x0 #define BD71828_OUT_TYPE_CMOS 0x2 diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h index 7f2dbde402a1..bee2474a8f9f 100644 --- a/include/linux/mfd/rohm-bd718x7.h +++ b/include/linux/mfd/rohm-bd718x7.h @@ -191,12 +191,6 @@ enum { #define IRQ_ON_REQ 0x02 #define IRQ_STBY_REQ 0x01 -/* BD718XX_REG_OUT32K bits */ -#define BD718XX_OUT32K_EN 0x01 - -/* BD7183XX gated clock rate */ -#define BD718XX_CLK_RATE 32768 - /* ROHM BD718XX irqs */ enum { BD718XX_INT_STBY_REQ, From patchwork Mon Jan 20 06:40:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207373 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_RHS_DOB, USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EEB19C33CB7 for ; Mon, 20 Jan 2020 06:40:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CB41320684 for ; Mon, 20 Jan 2020 06:40:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726476AbgATGkQ (ORCPT ); Mon, 20 Jan 2020 01:40:16 -0500 Received: from mail-lj1-f196.google.com ([209.85.208.196]:41321 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726130AbgATGkP (ORCPT ); Mon, 20 Jan 2020 01:40:15 -0500 Received: by mail-lj1-f196.google.com with SMTP id h23so32581043ljc.8; Sun, 19 Jan 2020 22:40:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=Ti2mw/YL/6hGaTuHkBNAjoJ6DZuX9vUnGvzlaHyxER0=; b=AhljdnI9DUVmEnRRziU+dfdjd5D8+0PyhIimz3agvyLN6vjtfkBLg6Am6TGjpUIiz8 rrebFynJG0hHFzxuQ7cpYBB5KmJduoxVD8u3qCJwM0YCNyXDNCVS6Vzy2LFiHAhlj06x o3dzo3G+z3yWEY8S25M68kvD8n/TQ1f7FkO40uukJ/nB0g98eFo2sWHimRY8ouezLcqI dgaFoJ50gYlhzwkXGsNQ6pTRjrFIGutRd88kEuZ3iV/JGHDiyma8wH9DFma1Hxbe3waL hYy4hPwMyGKAlIr1GFMbPrZs7YUkYG1C87veTAMU66UggEqJc7NmaCAFCU9QgtqBmGVY XHmg== X-Gm-Message-State: APjAAAUtMTkELUCv9kBdEHdXH8Nuzi21UNpknzAzS2NZF1Jjf+WJB/Er +uL1poqanNV3PJtGeUvuB0U= X-Google-Smtp-Source: APXvYqw020kK5mtjfTjdWee9gOV86bUZSOMv9XvQjnMy2HUyiAYNUgjIr+x0F4mLlx2K/chHyPvdOg== X-Received: by 2002:a2e:9243:: with SMTP id v3mr12855882ljg.73.1579502412764; Sun, 19 Jan 2020 22:40:12 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id n3sm16175245lfk.61.2020.01.19.22.40.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:40:12 -0800 (PST) Date: Mon, 20 Jan 2020 08:40:00 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 09/13] mfd: bd70528: Fix hour register mask Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org When RTC is used in 24H mode (and it is by this driver) the maximum hour value is 24 in BCD. This occupies bits [5:0] - which means correct mask for HOUR register is 0x3f not 0x1f. Fix the mask Fixes: 32a4a4ebf768 ("rtc: bd70528: Initial support for ROHM bd70528 RTC") Signed-off-by: Matti Vaittinen Acked-by: Alexandre Belloni Acked-for-MFD-by: Lee Jones --- No changes since v10 include/linux/mfd/rohm-bd70528.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mfd/rohm-bd70528.h b/include/linux/mfd/rohm-bd70528.h index 2ad2320d0a96..edae6f7afd8e 100644 --- a/include/linux/mfd/rohm-bd70528.h +++ b/include/linux/mfd/rohm-bd70528.h @@ -311,7 +311,7 @@ enum { #define BD70528_MASK_RTC_MINUTE 0x7f #define BD70528_MASK_RTC_HOUR_24H 0x80 #define BD70528_MASK_RTC_HOUR_PM 0x20 -#define BD70528_MASK_RTC_HOUR 0x1f +#define BD70528_MASK_RTC_HOUR 0x3f #define BD70528_MASK_RTC_DAY 0x3f #define BD70528_MASK_RTC_WEEK 0x07 #define BD70528_MASK_RTC_MONTH 0x1f From patchwork Mon Jan 20 06:41:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207372 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D77FC33CB8 for ; Mon, 20 Jan 2020 06:42:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3F7352087F for ; Mon, 20 Jan 2020 06:42:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726465AbgATGmI (ORCPT ); Mon, 20 Jan 2020 01:42:08 -0500 Received: from mail-lj1-f194.google.com ([209.85.208.194]:41454 "EHLO mail-lj1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725783AbgATGmI (ORCPT ); Mon, 20 Jan 2020 01:42:08 -0500 Received: by mail-lj1-f194.google.com with SMTP id h23so32584965ljc.8; Sun, 19 Jan 2020 22:42:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=Wbukz6aJucWvDSpuKncuYS08xxLEF4ekzHb2TLKVqlk=; b=oUf6qVMXpcKp/a1ThzzysKp0KLkvE3U+4DsLx36RFGy1Lhi6wUT/uqTnorp/ccxbkc kaz9gBxd8TOQa4cfuQSIK0Sp3fOk0V5JDwfY7XXLE8G1F/v0MLp1olarquHkL206JYJc UbybR3x8paXqcEH80H/6pZQOKlMBM2IqRdzibneApbuT3ny/CSc4ixjhV0O7KnwdKSdR XykypyvQhyVLhVyAFtnwP6Mp2QoLEVOMIYOYL0r0HXts7fIBO726+fRg+U38x8qh/QUs fHQX6qs7Z9Ks27kwiq1yeNQ46eDE9lYDzi1adUCJGF8N2+QOSVuO8DvZ1+NyLSkkCfJC aMHg== X-Gm-Message-State: APjAAAW6XJ19ZZ+er72qWlOKzEUucBxBC+pk7IFq5bBsHsBCVQt14Huq KtPMicUd/2THa9/sE5mfXOU= X-Google-Smtp-Source: APXvYqzW5mi1IdtUugzIglefaCDOwCJYSjEAKoxNC4yM9TRgqPlDmLyLida0pwRHI0zUdmbDvkE7Bw== X-Received: by 2002:a2e:8699:: with SMTP id l25mr10029349lji.137.1579502524316; Sun, 19 Jan 2020 22:42:04 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id v16sm3187799lfp.92.2020.01.19.22.42.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:42:03 -0800 (PST) Date: Mon, 20 Jan 2020 08:41:52 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 11/13] gpio: bd71828: Initial support for ROHM BD71828 PMIC GPIOs Message-ID: <9796bc38436152f73981993bf32fe7cfac1c71b1.1579501711.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org ROHM BD71828 PMIC contains 4 pins which can be configured by OTP to be used for general purposes. First 3 can be used as outputs and 4.th pin can be used as input. Allow them to be controlled via GPIO framework. The driver assumes all of the pins are configured as GPIOs and trusts that the reserved pins in other OTP configurations are excluded from control using "gpio-reserved-ranges" device tree property (or left untouched by GPIO users). Typical use for 4.th pin (input) is to use it as HALL sensor input so that this pin state is toggled when HALL sensor detects LID position change (from close to open or open to close). PMIC HW implements some extra logic which allows PMIC to power-up the system when this pin is toggled. Please see the data sheet for details of GPIO options which can be selected by OTP settings. Signed-off-by: Matti Vaittinen Reviewed-by: Bartosz Golaszewski Reviewed-by: Linus Walleij --- No changes since v10 drivers/gpio/Kconfig | 12 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-bd71828.c | 159 ++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 drivers/gpio/gpio-bd71828.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 2ed599236a1c..9a0bdf9ea463 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1021,6 +1021,18 @@ config GPIO_BD70528 This driver can also be built as a module. If so, the module will be called gpio-bd70528. +config GPIO_BD71828 + tristate "ROHM BD71828 GPIO support" + depends on MFD_ROHM_BD71828 + help + Support for GPIOs on ROHM BD71828 PMIC. There are three GPIOs + available on the ROHM PMIC in total. The GPIOs are limited to + outputs only and pins must be configured to GPIO outputs by + OTP. Enable this only if you want to use these pins as outputs. + + This driver can also be built as a module. If so, the module + will be called gpio-bd71828. + config GPIO_BD9571MWV tristate "ROHM BD9571 GPIO support" depends on MFD_BD9571MWV diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 34eb8b2b12dd..8629b81b5c17 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o obj-$(CONFIG_GPIO_BD70528) += gpio-bd70528.o +obj-$(CONFIG_GPIO_BD71828) += gpio-bd71828.o obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o diff --git a/drivers/gpio/gpio-bd71828.c b/drivers/gpio/gpio-bd71828.c new file mode 100644 index 000000000000..04aade9e0a4d --- /dev/null +++ b/drivers/gpio/gpio-bd71828.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2018 ROHM Semiconductors + +#include +#include +#include +#include +#include + +#define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off)) +#define HALL_GPIO_OFFSET 3 + +/* + * These defines can be removed when + * "gpio: Add definition for GPIO direction" + * (9208b1e77d6e8e9776f34f46ef4079ecac9c3c25 in GPIO tree) gets merged, + */ +#ifndef GPIO_LINE_DIRECTION_IN + #define GPIO_LINE_DIRECTION_IN 1 + #define GPIO_LINE_DIRECTION_OUT 0 +#endif + +struct bd71828_gpio { + struct rohm_regmap_dev chip; + struct gpio_chip gpio; +}; + +static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + int ret; + struct bd71828_gpio *bdgpio = gpiochip_get_data(chip); + u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO; + + /* + * The HALL input pin can only be used as input. If this is the pin + * we are dealing with - then we are done + */ + if (offset == HALL_GPIO_OFFSET) + return; + + ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset), + BD71828_GPIO_OUT_MASK, val); + if (ret) + dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value); +} + +static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + int ret; + unsigned int val; + struct bd71828_gpio *bdgpio = gpiochip_get_data(chip); + + if (offset == HALL_GPIO_OFFSET) + ret = regmap_read(bdgpio->chip.regmap, BD71828_REG_IO_STAT, + &val); + else + ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset), + &val); + if (!ret) + ret = (val & BD71828_GPIO_OUT_MASK); + + return ret; +} + +static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset, + unsigned long config) +{ + struct bd71828_gpio *bdgpio = gpiochip_get_data(chip); + + if (offset == HALL_GPIO_OFFSET) + return -ENOTSUPP; + + switch (pinconf_to_config_param(config)) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + return regmap_update_bits(bdgpio->chip.regmap, + GPIO_OUT_REG(offset), + BD71828_GPIO_DRIVE_MASK, + BD71828_GPIO_OPEN_DRAIN); + case PIN_CONFIG_DRIVE_PUSH_PULL: + return regmap_update_bits(bdgpio->chip.regmap, + GPIO_OUT_REG(offset), + BD71828_GPIO_DRIVE_MASK, + BD71828_GPIO_PUSH_PULL); + default: + break; + } + return -ENOTSUPP; +} + +static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + /* + * Pin usage is selected by OTP data. We can't read it runtime. Hence + * we trust that if the pin is not excluded by "gpio-reserved-ranges" + * the OTP configuration is set to OUT. (Other pins but HALL input pin + * on BD71828 can't really be used for general purpose input - input + * states are used for specific cases like regulator control or + * PMIC_ON_REQ. + */ + if (offset == HALL_GPIO_OFFSET) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + +static int bd71828_probe(struct platform_device *pdev) +{ + struct bd71828_gpio *bdgpio; + struct rohm_regmap_dev *bd71828; + + bd71828 = dev_get_drvdata(pdev->dev.parent); + if (!bd71828) { + dev_err(&pdev->dev, "No MFD driver data\n"); + return -EINVAL; + } + + bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio), + GFP_KERNEL); + if (!bdgpio) + return -ENOMEM; + + bdgpio->chip.dev = &pdev->dev; + bdgpio->gpio.parent = pdev->dev.parent; + bdgpio->gpio.label = "bd71828-gpio"; + bdgpio->gpio.owner = THIS_MODULE; + bdgpio->gpio.get_direction = bd71828_get_direction; + bdgpio->gpio.set_config = bd71828_gpio_set_config; + bdgpio->gpio.can_sleep = true; + bdgpio->gpio.get = bd71828_gpio_get; + bdgpio->gpio.set = bd71828_gpio_set; + bdgpio->gpio.base = -1; + + /* + * See if we need some implementation to mark some PINs as + * not controllable based on DT info or if core can handle + * "gpio-reserved-ranges" and exclude them from control + */ + bdgpio->gpio.ngpio = 4; + bdgpio->gpio.of_node = pdev->dev.parent->of_node; + bdgpio->chip.regmap = bd71828->regmap; + + return devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio, + bdgpio); +} + +static struct platform_driver bd71828_gpio = { + .driver = { + .name = "bd71828-gpio" + }, + .probe = bd71828_probe, +}; + +module_platform_driver(bd71828_gpio); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("BD71828 voltage regulator driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd71828-gpio"); From patchwork Mon Jan 20 06:42:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207371 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6A9E1C33CA1 for ; Mon, 20 Jan 2020 06:43:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3F29C20684 for ; Mon, 20 Jan 2020 06:43:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726388AbgATGnI (ORCPT ); Mon, 20 Jan 2020 01:43:08 -0500 Received: from mail-lf1-f67.google.com ([209.85.167.67]:43504 "EHLO mail-lf1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725851AbgATGnI (ORCPT ); Mon, 20 Jan 2020 01:43:08 -0500 Received: by mail-lf1-f67.google.com with SMTP id 9so23128623lfq.10; Sun, 19 Jan 2020 22:43:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=WlsJ1bdLMM+9iZ/WknprTZmuOL+z7ZUhJlUIYfYOJ8c=; b=oUGLSV+7iTQgspoo0Ik3hib6CZCPlT+VpwrP7o5+7k7c8kax/SuqdsQ01WmJyda7zL l2Bjr6lhHmVaJbwECRZ9m9JRSRDZB9crK4aiFGWisKCJT2q1cJ9bg3MYYUmaKvnNEpiB ZflyMMA/+sVfotJyPdCIu1PsxGuZW6byee9oN/q4nNCCTTgMGdg6dC8P/r7+q/eKaqhG gB04Dl2eoBEwxWpZNqZRBKIkfkQmFMv5Dny52YQqLaAbMuqwDKFbHDPccNtUrWbLex+8 UJa+7sb54rOFT581oedQF7BI9rgNo0VFKbKisJixrCVAjN+IdgmWUBAW7jwk12b7Xv9d AQdQ== X-Gm-Message-State: APjAAAUwIoa7+kjiKgPuHjbntTiTDMlfFIFV8IY9IJsMOyZu2tyvpGXN SjsJ0lDrWAMv6HQyRANY9no= X-Google-Smtp-Source: APXvYqxYirNnMa730deFVonZ1ccxf2PdyTN7OqsvVjiW/8ObICZfRy4yilDyuu9znkc/r3VFlb9tpw== X-Received: by 2002:a19:4a:: with SMTP id 71mr12473192lfa.50.1579502584465; Sun, 19 Jan 2020 22:43:04 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id f16sm16029651ljn.17.2020.01.19.22.43.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jan 2020 22:43:03 -0800 (PST) Date: Mon, 20 Jan 2020 08:42:52 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Liam Girdwood , Mark Brown , Jonathan Corbet , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Alessandro Zummo , Alexandre Belloni , Greg Kroah-Hartman , Arnd Bergmann , Mauro Carvalho Chehab , Wolfram Sang , Phil Edworthy , Noralf =?iso-8859-1?q?Tr=F8nnes?= , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v11 13/13] led: bd71828: Support LED outputs on ROHM BD71828 PMIC Message-ID: <63bc7ce4a05fd5c46d06ca0368370d884ccb250c.1579501711.git.matti.vaittinen@fi.rohmeurope.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org ROHM BD71828 power management IC has two LED outputs for charge status and button pressing indications. The LED outputs can also be forced by SW so add driver allowing to use these LEDs for other indications as well. Leds are controlled by SW using 'Force ON' bits. Please note the constrains mentioned in data-sheet: 1. If one LED is forced ON - then also the other LED is forced. => You can't use SW control to force ON one LED and allow HW to control the other. 2. You can't force both LEDs OFF. If the FORCE bit for both LED's is zero, then LEDs are controlled by HW and indicate button/charger states as explained in data-sheet. Signed-off-by: Matti Vaittinen --- No changes since v10 drivers/leds/Kconfig | 10 +++ drivers/leds/Makefile | 1 + drivers/leds/leds-bd71828.c | 118 ++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 drivers/leds/leds-bd71828.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 4b68520ac251..db408e03e296 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -545,6 +545,16 @@ config LEDS_BD2802 This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. +config LEDS_BD71828 + tristate "LED driver for LEDS on ROHM BD71828 PMIC" + depends on LEDS_CLASS + depends on MFD_ROHM_BD71828 + help + This option enables support for LED outputs located on ROHM + BD71828 power management IC. ROHM BD71828 has two led output pins + which can be left to indicate HW states or controlled by SW. Say + yes here if you want to enable SW control for these LEDs. + config LEDS_INTEL_SS4200 tristate "LED driver for Intel NAS SS4200 series" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 2da39e896ce8..a5164acfaf51 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o +obj-$(CONFIG_LEDS_BD71828) += leds-bd71828.o obj-$(CONFIG_LEDS_CPCAP) += leds-cpcap.o obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o diff --git a/drivers/leds/leds-bd71828.c b/drivers/leds/leds-bd71828.c new file mode 100644 index 000000000000..a02c2ac4a70b --- /dev/null +++ b/drivers/leds/leds-bd71828.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2019 ROHM Semiconductors + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BD71828_LED_TO_DATA(l) ((l)->id == ID_GREEN_LED ? \ + container_of((l), struct bd71828_leds, green) : \ + container_of((l), struct bd71828_leds, amber)) + +/* Names for led identification - these match the data sheet names */ +enum { + ID_GREEN_LED, + ID_AMBER_LED, + ID_NMBR_OF, +}; + +struct bd71828_led { + struct led_init_data init_data; + int id; + struct led_classdev l; + u8 force_mask; +}; + +struct bd71828_leds { + struct rohm_regmap_dev *bd71828; + struct bd71828_led green; + struct bd71828_led amber; +}; + +static int bd71828_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct bd71828_led *l = container_of(led_cdev, struct bd71828_led, l); + struct bd71828_leds *data; + unsigned int val = BD71828_LED_OFF; + + data = BD71828_LED_TO_DATA(l); + if (value != LED_OFF) + val = BD71828_LED_ON; + + return regmap_update_bits(data->bd71828->regmap, BD71828_REG_LED_CTRL, + l->force_mask, val); +} + +static int bd71828_led_probe(struct platform_device *pdev) +{ + struct rohm_regmap_dev *bd71828; + struct bd71828_leds *l; + struct bd71828_led *g, *a; + int ret; + + bd71828 = dev_get_drvdata(pdev->dev.parent); + l = devm_kzalloc(&pdev->dev, sizeof(*l), GFP_KERNEL); + if (!l) + return -ENOMEM; + l->bd71828 = bd71828; + a = &l->amber; + g = &l->green; + + /* Fill in details for 'AMBLED' */ + a->init_data.match_property.name = "rohm,led-compatible"; + a->init_data.match_property.raw_val = "bd71828-ambled"; + a->init_data.match_property.size = strlen("bd71828-ambled"); + a->id = ID_AMBER_LED; + a->force_mask = BD71828_MASK_LED_AMBER; + + /* Fill in details for 'GRNLED' */ + g->init_data.match_property.name = "rohm,led-compatible"; + g->init_data.match_property.raw_val = "bd71828-grnled"; + g->init_data.match_property.size = strlen("bd71828-grnled"); + g->id = ID_GREEN_LED; + g->force_mask = BD71828_MASK_LED_GREEN; + + a->l.brightness_set_blocking = bd71828_led_brightness_set; + g->l.brightness_set_blocking = bd71828_led_brightness_set; + + ret = devm_led_classdev_register_ext(&pdev->dev, &g->l, &g->init_data); + if (ret) + return ret; + + return devm_led_classdev_register_ext(&pdev->dev, &a->l, &a->init_data); +} + +/* + * Device is instantiated through parent MFD device and device matching is done + * through platform_device_id. + * + * However, the *module* matching will be done trough DT aliases. This requires + * of_device_id table - but no .of_match_table as *device* matching is still + * done through platform_device_id. + */ +static const struct of_device_id bd71828_dt_match[] __used = { + { .compatible = "rohm,bd71828-leds" }, + { } +}; +MODULE_DEVICE_TABLE(of, bd71828_dt_match); + +static struct platform_driver bd71828_led_driver = { + .driver = { + .name = "bd71828-led", + }, + .probe = bd71828_led_probe, +}; + +module_platform_driver(bd71828_led_driver); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("ROHM BD71828 LED driver"); +MODULE_LICENSE("GPL");