From patchwork Fri Aug 3 00:18:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Masney X-Patchwork-Id: 10554341 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E39113BB for ; Fri, 3 Aug 2018 00:19:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E3472C469 for ; Fri, 3 Aug 2018 00:19:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 122132C48D; Fri, 3 Aug 2018 00:19:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8BEC62C469 for ; Fri, 3 Aug 2018 00:19:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732321AbeHCCMm (ORCPT ); Thu, 2 Aug 2018 22:12:42 -0400 Received: from onstation.org ([52.200.56.107]:33992 "EHLO onstation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732186AbeHCCMl (ORCPT ); Thu, 2 Aug 2018 22:12:41 -0400 Received: from xilitla.hsd1.wv.comcast.net (c-98-236-77-125.hsd1.wv.comcast.net [98.236.77.125]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: masneyb) by onstation.org (Postfix) with ESMTPSA id 78D0B2A21; Fri, 3 Aug 2018 00:19:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=onstation.org; s=default; t=1533255546; bh=mHEtt3mdtf9jFoWW7rav+wlHLtQl5QrX40REfm5zuDw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TD0NMzWGtP0690lgwA91uNtVIL0cDmZNkEbRpioTZaglphucEVMGWbuHsHDlGSxkT tsIo3o1J4MqB8e4E5hBpd9u4fsClj2S53y53ePLR7bg+1x9P47ocH0XKaJnlsslHUq fsE5jC3GsNJfyWpxRM36NXY50DWQOI68YW6mUrWc= From: Brian Masney To: jic23@kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, andy.gross@linaro.org, david.brown@linaro.org, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org Cc: jonathan@marek.ca, jmaneyrol@invensense.com, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net, mkelly@xevo.com, fischerdouglasc@gmail.com, bshah@kde.org, ctatlor97@gmail.com Subject: [PATCH v3 5/9] iio: tsl2772: add support for regulator framework Date: Thu, 2 Aug 2018 20:18:56 -0400 Message-Id: <20180803001900.25371-6-masneyb@onstation.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803001900.25371-1-masneyb@onstation.org> References: <20180803001900.25371-1-masneyb@onstation.org> Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds support for the regulator framework to the tsl2772 driver. Driver was tested using a LG Nexus 5 (hammerhead) phone with the two regulators and on a Raspberry Pi 2 without any regulators controlling the power to the sensor. Signed-off-by: Brian Masney --- drivers/iio/light/tsl2772.c | 95 ++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c index ae00edf0d87e..4a11bf77a4d0 100644 --- a/drivers/iio/light/tsl2772.c +++ b/drivers/iio/light/tsl2772.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Cal defs */ #define PROX_STAT_CAL 0 @@ -109,6 +110,9 @@ #define TSL2772_MAX_PROX_LEDS 2 +#define TSL2772_BOOT_MIN_SLEEP_TIME 10000 +#define TSL2772_BOOT_MAX_SLEEP_TIME 28000 + /* Device family members */ enum { tsl2571, @@ -156,6 +160,8 @@ struct tsl2772_chip { struct mutex prox_mutex; struct mutex als_mutex; struct i2c_client *client; + struct regulator *vdd_supply; + struct regulator *vddio_supply; u16 prox_data; struct tsl2772_als_info als_cur_info; struct tsl2772_settings settings; @@ -676,6 +682,52 @@ static int tsl2772_als_calibrate(struct iio_dev *indio_dev) return ret; } +static void tsl2772_disable_regulators_action(void *_data) +{ + struct tsl2772_chip *chip = _data; + + regulator_disable(chip->vdd_supply); + regulator_disable(chip->vddio_supply); +} + +static int tsl2772_enable_regulator(struct tsl2772_chip *chip, + struct regulator *regulator) +{ + int ret; + + ret = regulator_enable(regulator); + if (ret < 0) { + dev_err(&chip->client->dev, "Failed to enable regulator: %d\n", + ret); + return ret; + } + + return 0; +} + +static struct regulator *tsl2772_get_regulator(struct tsl2772_chip *chip, + char *name) +{ + struct regulator *regulator; + int ret; + + regulator = devm_regulator_get(&chip->client->dev, name); + if (IS_ERR(regulator)) { + if (PTR_ERR(regulator) != -EPROBE_DEFER) + dev_err(&chip->client->dev, + "Failed to get %s regulator %d\n", + name, (int)PTR_ERR(regulator)); + + return regulator; + } + + ret = tsl2772_enable_regulator(chip, regulator); + if (ret < 0) + return ERR_PTR(ret); + + return regulator; +} + static int tsl2772_chip_on(struct iio_dev *indio_dev) { struct tsl2772_chip *chip = iio_priv(indio_dev); @@ -1733,6 +1785,27 @@ static int tsl2772_probe(struct i2c_client *clientp, chip->client = clientp; i2c_set_clientdata(clientp, indio_dev); + chip->vddio_supply = tsl2772_get_regulator(chip, "vddio"); + if (IS_ERR(chip->vddio_supply)) + return PTR_ERR(chip->vddio_supply); + + chip->vdd_supply = tsl2772_get_regulator(chip, "vdd"); + if (IS_ERR(chip->vdd_supply)) { + regulator_disable(chip->vddio_supply); + return PTR_ERR(chip->vdd_supply); + } + + ret = devm_add_action(&clientp->dev, tsl2772_disable_regulators_action, + chip); + if (ret < 0) { + tsl2772_disable_regulators_action(chip); + dev_err(&clientp->dev, "Failed to setup regulator cleanup action %d\n", + ret); + return ret; + } + + usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME); + ret = i2c_smbus_read_byte_data(chip->client, TSL2772_CMD_REG | TSL2772_CHIPID); if (ret < 0) @@ -1806,13 +1879,33 @@ static int tsl2772_probe(struct i2c_client *clientp, static int tsl2772_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); + int ret; - return tsl2772_chip_off(indio_dev); + ret = tsl2772_chip_off(indio_dev); + regulator_disable(chip->vdd_supply); + regulator_disable(chip->vddio_supply); + + return ret; } static int tsl2772_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2772_chip *chip = iio_priv(indio_dev); + int ret; + + ret = tsl2772_enable_regulator(chip, chip->vddio_supply); + if (ret < 0) + return ret; + + ret = tsl2772_enable_regulator(chip, chip->vdd_supply); + if (ret < 0) { + regulator_disable(chip->vddio_supply); + return ret; + } + + usleep_range(TSL2772_BOOT_MIN_SLEEP_TIME, TSL2772_BOOT_MAX_SLEEP_TIME); return tsl2772_chip_on(indio_dev); }