From patchwork Tue Aug 15 20:04:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 801746 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xX3SH1LTwz9sR9 for ; Wed, 16 Aug 2017 06:07:59 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753379AbdHOUGL (ORCPT ); Tue, 15 Aug 2017 16:06:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36080 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753114AbdHOUGI (ORCPT ); Tue, 15 Aug 2017 16:06:08 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 06BB57ACD4; Tue, 15 Aug 2017 20:06:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 06BB57ACD4 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=hdegoede@redhat.com Received: from dhcp-45-79.space.revspace.nl.com (ovpn-112-17.ams2.redhat.com [10.36.112.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D42E4F294; Tue, 15 Aug 2017 20:06:00 +0000 (UTC) From: Hans de Goede To: Wolfram Sang , Guenter Roeck , Heikki Krogerus , Sebastian Reichel , Darren Hart , Andy Shevchenko , Greg Kroah-Hartman Cc: Hans de Goede , Liam Breck , Tony Lindgren , linux-i2c@vger.kernel.org, linux-pm@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org Subject: [PATCH v2 09/14] power: supply: bq24190_charger: Export 5V boost converter as regulator Date: Tue, 15 Aug 2017 22:04:57 +0200 Message-Id: <20170815200502.17339-10-hdegoede@redhat.com> In-Reply-To: <20170815200502.17339-1-hdegoede@redhat.com> References: <20170815200502.17339-1-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 15 Aug 2017 20:06:08 +0000 (UTC) Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Register the 5V boost converter as a regulator named "usb_otg_vbus". This commit also adds support for bq24190_platform_data, through which non device-tree platforms can pass the regulator_init_data (containing mappings for the consumer amongst other things). Signed-off-by: Hans de Goede --- Changes in v2: -Use "usb_otg_vbus" as default name for the regulator -Add support for passing regulator_init_data for non device-tree platforms -Register the regulator later, to avoid it showing up and shortly later disappearing again on probe errors (e.g. -EPROBE_DEFER). --- drivers/power/supply/bq24190_charger.c | 126 +++++++++++++++++++++++++++++++++ include/linux/power/bq24190_charger.h | 18 +++++ 2 files changed, 144 insertions(+) create mode 100644 include/linux/power/bq24190_charger.h diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index d5a707e..073cd9d 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c @@ -16,6 +16,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -504,6 +507,125 @@ static int bq24190_sysfs_create_group(struct bq24190_dev_info *bdi) static inline void bq24190_sysfs_remove_group(struct bq24190_dev_info *bdi) {} #endif +#ifdef CONFIG_REGULATOR +static int bq24190_vbus_enable(struct regulator_dev *dev) +{ + struct bq24190_dev_info *bdi = rdev_get_drvdata(dev); + int ret; + + ret = pm_runtime_get_sync(bdi->dev); + if (ret < 0) { + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); + pm_runtime_put_noidle(bdi->dev); + return ret; + } + + ret = bq24190_write_mask(bdi, BQ24190_REG_POC, + BQ24190_REG_POC_CHG_CONFIG_MASK, + BQ24190_REG_POC_CHG_CONFIG_SHIFT, + BQ24190_REG_POC_CHG_CONFIG_OTG); + + pm_runtime_mark_last_busy(bdi->dev); + pm_runtime_put_autosuspend(bdi->dev); + + return ret; +} + +static int bq24190_vbus_disable(struct regulator_dev *dev) +{ + struct bq24190_dev_info *bdi = rdev_get_drvdata(dev); + int ret; + + ret = pm_runtime_get_sync(bdi->dev); + if (ret < 0) { + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); + pm_runtime_put_noidle(bdi->dev); + return ret; + } + + ret = bq24190_write_mask(bdi, BQ24190_REG_POC, + BQ24190_REG_POC_CHG_CONFIG_MASK, + BQ24190_REG_POC_CHG_CONFIG_SHIFT, + BQ24190_REG_POC_CHG_CONFIG_CHARGE); + + pm_runtime_mark_last_busy(bdi->dev); + pm_runtime_put_autosuspend(bdi->dev); + + return ret; +} + +static int bq24190_vbus_is_enabled(struct regulator_dev *dev) +{ + struct bq24190_dev_info *bdi = rdev_get_drvdata(dev); + int ret; + u8 val; + + ret = pm_runtime_get_sync(bdi->dev); + if (ret < 0) { + dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); + pm_runtime_put_noidle(bdi->dev); + return ret; + } + + ret = bq24190_read_mask(bdi, BQ24190_REG_POC, + BQ24190_REG_POC_CHG_CONFIG_MASK, + BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val); + + pm_runtime_mark_last_busy(bdi->dev); + pm_runtime_put_autosuspend(bdi->dev); + + return ret ? ret : val == BQ24190_REG_POC_CHG_CONFIG_OTG; +} + +static const struct regulator_ops bq24190_vbus_ops = { + .enable = bq24190_vbus_enable, + .disable = bq24190_vbus_disable, + .is_enabled = bq24190_vbus_is_enabled, +}; + +static const struct regulator_desc bq24190_vbus_desc = { + .name = "usb_otg_vbus", + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .ops = &bq24190_vbus_ops, + .fixed_uV = 5000000, + .n_voltages = 1, +}; + +static const struct regulator_init_data bq24190_vbus_init_data = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi) +{ + struct bq24190_platform_data *pdata = bdi->dev->platform_data; + struct regulator_config cfg = { }; + struct regulator_dev *reg; + int ret = 0; + + cfg.dev = bdi->dev; + if (pdata && pdata->regulator_init_data) + cfg.init_data = pdata->regulator_init_data; + else + cfg.init_data = &bq24190_vbus_init_data; + cfg.driver_data = bdi; + reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg); + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + dev_err(bdi->dev, "Can't register regulator: %d\n", ret); + } + + return ret; +} +#else +static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi) +{ + return 0; +} +#endif + /* * According to the "Host Mode and default Mode" section of the * manual, a write to any register causes the bq24190 to switch @@ -1577,6 +1699,10 @@ static int bq24190_probe(struct i2c_client *client, goto out_sysfs; } + ret = bq24190_register_vbus_regulator(bdi); + if (ret < 0) + goto out_sysfs; + if (bdi->extcon) { INIT_DELAYED_WORK(&bdi->extcon_work, bq24190_extcon_work); bdi->extcon_nb.notifier_call = bq24190_extcon_event; diff --git a/include/linux/power/bq24190_charger.h b/include/linux/power/bq24190_charger.h new file mode 100644 index 0000000..45ce7f1 --- /dev/null +++ b/include/linux/power/bq24190_charger.h @@ -0,0 +1,18 @@ +/* + * Platform data for the TI bq24190 battery charger driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _BQ24190_CHARGER_H_ +#define _BQ24190_CHARGER_H_ + +#include + +struct bq24190_platform_data { + const struct regulator_init_data *regulator_init_data; +}; + +#endif