From patchwork Mon Jul 13 11:26:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Krzysztof Kozlowski X-Patchwork-Id: 6778521 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B4F989F2F0 for ; Mon, 13 Jul 2015 11:29:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E8E8205DB for ; Mon, 13 Jul 2015 11:29:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 41ACB20588 for ; Mon, 13 Jul 2015 11:29:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752407AbbGML3O (ORCPT ); Mon, 13 Jul 2015 07:29:14 -0400 Received: from mail-pa0-f52.google.com ([209.85.220.52]:33363 "EHLO mail-pa0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752117AbbGML22 (ORCPT ); Mon, 13 Jul 2015 07:28:28 -0400 Received: by padck2 with SMTP id ck2so41490931pad.0; Mon, 13 Jul 2015 04:28:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AetWjZ7HJ5ZE4dGhuFdCexAjqJHMd12mArlCmnf13s0=; b=gF0zOrrsonuscAELykzlgkKz3D8OMSahp3TaFlC9UcUQ2gw443RZUT15fxyqkQzuyI gy5qTu38HzfCT4sV4MXSYvn2tTFJSMlAOHZxhzxCOK09a2ki4z3361C4g/q87Mx9XYut AmDUgeY/s7tSDH+jhHhdSb21KTLQ4QxH9MGXIL3HrENskkrXHKaxJb5oBBSQaHY7i9/3 BlBijRDqGfH7+mGTbsYqh5TSu0+Kw9AnWucYYD6PBJY2x2nr1q1L/N4AvALu7ByEYsPl GkpkdxeTlVwaoXd1IUgqeq7anBacBPjnuHu5V0EC9vrYPUt9uq/UtdSXS+o8qmGU4LLd lvYg== X-Received: by 10.70.95.69 with SMTP id di5mr5972593pdb.80.1436786907530; Mon, 13 Jul 2015 04:28:27 -0700 (PDT) Received: from localhost.localdomain ([125.130.175.98]) by smtp.gmail.com with ESMTPSA id pn6sm18566591pdb.72.2015.07.13.04.28.22 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 13 Jul 2015 04:28:26 -0700 (PDT) From: Krzysztof Kozlowski To: David Woodhouse , Liam Girdwood , Mark Brown , linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, linux-pm@vger.kernel.org, Bryan Wu , Richard Purdie , Jacek Anaszewski , linux-leds@vger.kernel.org Cc: Chanwoo Choi , MyungJoo Ham , Dmitry Torokhov , Samuel Ortiz , Lee Jones , Sebastian Reichel , Dmitry Eremin-Solenikov , Krzysztof Kozlowski Subject: [PATCH v4 8/9] regulator: max77693: Add support for MAX77843 device Date: Mon, 13 Jul 2015 20:26:57 +0900 Message-Id: <1436786818-14115-9-git-send-email-k.kozlowski.k@gmail.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1436786818-14115-1-git-send-email-k.kozlowski.k@gmail.com> References: <1436786818-14115-1-git-send-email-k.kozlowski.k@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The charger and safeout parts of MAX77843 are almost the same as MAX77693. From regulator point of view the only differences are the constraints and register values related to these constraints. Now the max77693 regulator driver can be used for MAX77843 device. Signed-off-by: Krzysztof Kozlowski Acked-by: Mark Brown --- drivers/regulator/Kconfig | 8 +-- drivers/regulator/max77693.c | 125 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 117 insertions(+), 16 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index bef3bde6971b..b1022c2fd877 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -407,13 +407,13 @@ config REGULATOR_MAX77686 Exynos-4 chips to control VARM and VINT voltages. config REGULATOR_MAX77693 - tristate "Maxim MAX77693 regulator" - depends on MFD_MAX77693 + tristate "Maxim 77693/77843 regulator" + depends on (MFD_MAX77693 || MFD_MAX77843) help - This driver controls a Maxim 77693 regulator via I2C bus. + This driver controls a Maxim 77693/77843 regulators via I2C bus. The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2' and one current regulator 'CHARGER'. This is suitable for - Exynos-4x12 chips. + Exynos-4x12 (MAX77693) or Exynos5433 (MAX77843) SoC chips. config REGULATOR_MAX77802 tristate "Maxim 77802 regulator" diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index 5b30dc42679c..918745d1c5e4 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c @@ -1,8 +1,9 @@ /* - * max77693.c - Regulator driver for the Maxim 77693 + * max77693.c - Regulator driver for the Maxim 77693 and 77843 * - * Copyright (C) 2013 Samsung Electronics + * Copyright (C) 2013-2015 Samsung Electronics * Jonghwa Lee + * Krzysztof Kozlowski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,11 +31,24 @@ #include #include #include +#include #include #include #include -/* Charger regulator differences between MAX77693 and MAX77843 */ +/* + * ID for MAX77843 regulators. + * There is no need for such for MAX77693. + */ +enum max77843_regulator_type { + MAX77843_SAFEOUT1 = 0, + MAX77843_SAFEOUT2, + MAX77843_CHARGER, + + MAX77843_NUM, +}; + +/* Register differences between chargers: MAX77693 and MAX77843 */ struct chg_reg_data { unsigned int linear_reg; unsigned int linear_mask; @@ -43,9 +57,14 @@ struct chg_reg_data { }; /* - * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA + * MAX77693 CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA * 0x00, 0x01, 0x2, 0x03 = 60 mA * 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA + * Actually for MAX77693 the driver manipulates the maximum input current, + * not the fast charge current (output). This should be fixed. + * + * On MAX77843 the calculation formula is the same (except values). + * Fortunately it properly manipulates the fast charge current. */ static int max77693_chg_get_current_limit(struct regulator_dev *rdev) { @@ -95,6 +114,26 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev, } /* end of CHARGER regulator ops */ +/* Returns regmap suitable for given regulator on chosen device */ +static struct regmap *max77693_get_regmap(enum max77693_types type, + struct max77693_dev *max77693, + int reg_id) +{ + if (type == TYPE_MAX77693) + return max77693->regmap; + + /* Else: TYPE_MAX77843 */ + switch (reg_id) { + case MAX77843_SAFEOUT1: + case MAX77843_SAFEOUT2: + return max77693->regmap; + case MAX77843_CHARGER: + return max77693->regmap_chg; + default: + return max77693->regmap; + } +} + static const unsigned int max77693_safeout_table[] = { 4850000, 4900000, @@ -119,7 +158,7 @@ static struct regulator_ops max77693_charger_ops = { .set_current_limit = max77693_chg_set_current_limit, }; -#define regulator_desc_esafeout(_num) { \ +#define max77693_regulator_desc_esafeout(_num) { \ .name = "ESAFEOUT"#_num, \ .id = MAX77693_ESAFEOUT##_num, \ .of_match = of_match_ptr("ESAFEOUT"#_num), \ @@ -135,9 +174,9 @@ static struct regulator_ops max77693_charger_ops = { .enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \ } -static const struct regulator_desc regulators[] = { - regulator_desc_esafeout(1), - regulator_desc_esafeout(2), +static const struct regulator_desc max77693_supported_regulators[] = { + max77693_regulator_desc_esafeout(1), + max77693_regulator_desc_esafeout(2), { .name = "CHARGER", .id = MAX77693_CHARGER, @@ -160,19 +199,79 @@ static const struct chg_reg_data max77693_chg_reg_data = { .min_sel = 3, }; +#define max77843_regulator_desc_esafeout(num) { \ + .name = "SAFEOUT" # num, \ + .id = MAX77843_SAFEOUT ## num, \ + .ops = &max77693_safeout_ops, \ + .of_match = of_match_ptr("SAFEOUT" # num), \ + .regulators_node = of_match_ptr("regulators"), \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .n_voltages = ARRAY_SIZE(max77693_safeout_table), \ + .volt_table = max77693_safeout_table, \ + .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \ + .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num, \ + .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \ + .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \ +} + +static const struct regulator_desc max77843_supported_regulators[] = { + [MAX77843_SAFEOUT1] = max77843_regulator_desc_esafeout(1), + [MAX77843_SAFEOUT2] = max77843_regulator_desc_esafeout(2), + [MAX77843_CHARGER] = { + .name = "CHARGER", + .id = MAX77843_CHARGER, + .ops = &max77693_charger_ops, + .of_match = of_match_ptr("CHARGER"), + .regulators_node = of_match_ptr("regulators"), + .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, + .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00, + .enable_mask = MAX77843_CHG_MASK, + .enable_val = MAX77843_CHG_MASK, + }, +}; + +static const struct chg_reg_data max77843_chg_reg_data = { + .linear_reg = MAX77843_CHG_REG_CHG_CNFG_02, + .linear_mask = MAX77843_CHG_FAST_CHG_CURRENT_MASK, + .uA_step = MAX77843_CHG_FAST_CHG_CURRENT_STEP, + .min_sel = 2, +}; + static int max77693_pmic_probe(struct platform_device *pdev) { + enum max77693_types type = platform_get_device_id(pdev)->driver_data; struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); + const struct regulator_desc *regulators; + unsigned int regulators_size; int i; struct regulator_config config = { }; config.dev = iodev->dev; - config.regmap = iodev->regmap; - config.driver_data = (void *)&max77693_chg_reg_data; - for (i = 0; i < ARRAY_SIZE(regulators); i++) { + switch (type) { + case TYPE_MAX77693: + regulators = max77693_supported_regulators; + regulators_size = ARRAY_SIZE(max77693_supported_regulators); + config.driver_data = (void *)&max77693_chg_reg_data; + break; + case TYPE_MAX77843: + regulators = max77843_supported_regulators; + regulators_size = ARRAY_SIZE(max77843_supported_regulators); + config.driver_data = (void *)&max77843_chg_reg_data; + break; + default: + dev_err(&pdev->dev, "Unsupported device type: %u\n", type); + return -ENODEV; + } + + for (i = 0; i < regulators_size; i++) { struct regulator_dev *rdev; + config.regmap = max77693_get_regmap(type, iodev, + regulators[i].id); + rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); if (IS_ERR(rdev)) { @@ -187,6 +286,7 @@ static int max77693_pmic_probe(struct platform_device *pdev) static const struct platform_device_id max77693_pmic_id[] = { { "max77693-pmic", TYPE_MAX77693 }, + { "max77843-regulator", TYPE_MAX77843 }, {}, }; @@ -202,6 +302,7 @@ static struct platform_driver max77693_pmic_driver = { module_platform_driver(max77693_pmic_driver); -MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver"); +MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver"); MODULE_AUTHOR("Jonghwa Lee "); +MODULE_AUTHOR("Krzysztof Kozlowski "); MODULE_LICENSE("GPL");