From patchwork Sun Sep 1 20:00:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 19660 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-gh0-f197.google.com (mail-gh0-f197.google.com [209.85.160.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5057925E36 for ; Sun, 1 Sep 2013 20:01:07 +0000 (UTC) Received: by mail-gh0-f197.google.com with SMTP id r20sf4039940ghr.0 for ; Sun, 01 Sep 2013 13:01:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=mime-version:x-gm-message-state:delivered-to:from:to:cc:subject :date:message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=zZUbnYQB2/Jad3Cwsu71Qnl0kR+6rQJlRlmjD9T/aXg=; b=W0KOq8kZ1lcglXNfgxumytAxVWijYHSA8UyDy1TujoK21Wj7j9hzBO2gHvU8dXDlrM xH/pezqEveFncDsAAlzhfREm7OKwwzRNzmESB5GiOaraQIbX/4XyQxsQ2TpRl4umiFpj p6570ICRLa99MJshtqWMamFJSBWXBxJMj+ytCLhbrmCwzkZf/zSrl0St4xjBsIz/p9+g rIhYg5DxaokI+v7v6NxJvMhYOBLOyT41y8aSx1+XLZKJD+K1FmMUZAUkEXcxYdSogD2C 7yvtQAfRfQlDBHGbQQAZKPDUZotC/KpinFfU7oml9TBCBISdBlGxIQvWDvFkCIZvG5jd kl/A== X-Received: by 10.236.14.100 with SMTP id c64mr7088394yhc.38.1378065667119; Sun, 01 Sep 2013 13:01:07 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.1.227 with SMTP id 3ls2029842qep.84.gmail; Sun, 01 Sep 2013 13:01:07 -0700 (PDT) X-Received: by 10.220.46.72 with SMTP id i8mr19640387vcf.10.1378065667008; Sun, 01 Sep 2013 13:01:07 -0700 (PDT) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id ta3si2182745vcb.71.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 01 Sep 2013 13:01:07 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id id13so2506734vcb.18 for ; Sun, 01 Sep 2013 13:01:06 -0700 (PDT) X-Gm-Message-State: ALoCoQn1u4q0DRFVDrQbqPb9atoU22RrxQXYgMCcwsnVbYfbCx+xThp86Mqa5x95vtPV6TVTDBO0 X-Received: by 10.220.88.13 with SMTP id y13mr2051411vcl.20.1378065666908; Sun, 01 Sep 2013 13:01:06 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp78767vcz; Sun, 1 Sep 2013 13:01:06 -0700 (PDT) X-Received: by 10.152.22.198 with SMTP id g6mr18019749laf.5.1378065665658; Sun, 01 Sep 2013 13:01:05 -0700 (PDT) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com [209.85.217.174]) by mx.google.com with ESMTPS id uf8si4037356lbc.30.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 01 Sep 2013 13:01:05 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.217.174 is neither permitted nor denied by best guess record for domain of linus.walleij@linaro.org) client-ip=209.85.217.174; Received: by mail-lb0-f174.google.com with SMTP id w6so3307202lbh.33 for ; Sun, 01 Sep 2013 13:01:05 -0700 (PDT) X-Received: by 10.112.42.103 with SMTP id n7mr17728739lbl.6.1378065664922; Sun, 01 Sep 2013 13:01:04 -0700 (PDT) Received: from localhost.localdomain (c83-249-209-93.bredband.comhem.se. [83.249.209.93]) by mx.google.com with ESMTPSA id js17sm4603382lab.5.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 01 Sep 2013 13:01:04 -0700 (PDT) From: Linus Walleij To: Liam Girdwood , Mark Brown Cc: Samuel Ortiz , Lee Jones , linux-kernel@vger.kernel.org, Linus Walleij Subject: [PATCH 2/4] regulator: add STw481x VMMC driver Date: Sun, 1 Sep 2013 22:00:59 +0200 Message-Id: <1378065659-18135-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.8.1.4 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The ST Microelectronics STw481x PMIC used for the Nomadik has one single software-controlled regulator for VMMC. This driver registers directly to the compatible string as there is just one regulator. Signed-off-by: Linus Walleij --- Hi Mark, I'm seeking an ACK for this driver eventually, to take it through the ARM SoC tree with the dependency MFD driver and the enablement patches. --- drivers/regulator/Kconfig | 8 ++ drivers/regulator/Makefile | 1 + drivers/regulator/stw481x-vmmc.c | 195 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 drivers/regulator/stw481x-vmmc.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f1e6ad9..7e424fc 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -374,6 +374,14 @@ config REGULATOR_PALMAS on the muxing. This is handled automatically in the driver by reading the mux info from OTP. +config REGULATOR_STW481X_VMMC + bool "ST Microelectronics STW481X VMMC regulator" + depends on MFD_STW481X + default y if MFD_STW481X + help + This driver supports the VMMC regulator in the STw481x + PMIC chips. + config REGULATOR_TPS51632 tristate "TI TPS51632 Power Regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ba4a3cf..6d53bd4 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o +obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c new file mode 100644 index 0000000..e53916e --- /dev/null +++ b/drivers/regulator/stw481x-vmmc.c @@ -0,0 +1,195 @@ +/* + * Regulator driver for STw4810/STw4811 VMMC regulator. + * + * Copyright (C) 2013 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * + * Author: Linus Walleij + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include +#include +#include + +static int stw481x_vmmc_enable(struct regulator_dev *reg) +{ + struct stw481x *stw481x = rdev_get_drvdata(reg); + int ret; + + /* First disable the external VMMC if it's active */ + ret = regmap_update_bits(stw481x->map, STW_CONF2, + STW_CONF2_VMMC_EXT, 0); + if (ret) + return ret; + + return regmap_update_bits(stw481x->map, STW_CONF1, + 0, STW_CONF1_PDN_VMMC); +} + +static int stw481x_vmmc_disable(struct regulator_dev *reg) +{ + struct stw481x *stw481x = rdev_get_drvdata(reg); + + return regmap_update_bits(stw481x->map, STW_CONF1, + STW_CONF1_PDN_VMMC, 0); +} + +static int stw481x_vmmc_is_enabled(struct regulator_dev *reg) +{ + struct stw481x *stw481x = rdev_get_drvdata(reg); + int ret; + unsigned int val; + + ret = regmap_read(stw481x->map, STW_CONF1, &val); + if (ret) + return ret; + return !!(val & STW_CONF1_PDN_VMMC); +} + +static int stw481x_vmmc_get_voltage_sel(struct regulator_dev *reg) +{ + struct stw481x *stw481x = rdev_get_drvdata(reg); + int ret; + unsigned int val; + + ret = regmap_read(stw481x->map, STW_CONF1, &val); + if (ret) + return ret; + val &= STW_CONF1_VMMC_MASK; + return (val >> 1); +} + +static int stw481x_vmmc_set_voltage_sel(struct regulator_dev *reg, + unsigned selector) +{ + struct stw481x *stw481x = rdev_get_drvdata(reg); + + return regmap_update_bits(stw481x->map, STW_CONF1, + STW_CONF1_VMMC_MASK, + (selector << 1) & STW_CONF1_VMMC_MASK); +} + +static const unsigned int stw481x_vmmc_voltages[] = { + 1800000, + 1800000, + 2850000, + 3000000, + 1850000, + 2600000, + 2700000, + 3300000, +}; + +static struct regulator_ops stw481x_vmmc_ops = { + .list_voltage = regulator_list_voltage_table, + .enable = stw481x_vmmc_enable, + .disable = stw481x_vmmc_disable, + .is_enabled = stw481x_vmmc_is_enabled, + .get_voltage_sel = stw481x_vmmc_get_voltage_sel, + .set_voltage_sel = stw481x_vmmc_set_voltage_sel, +}; + +static struct regulator_desc vmmc_regulator = { + .name = "VMMC", + .id = 0, + .ops = &stw481x_vmmc_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .n_voltages = ARRAY_SIZE(stw481x_vmmc_voltages), + .volt_table = stw481x_vmmc_voltages, + .enable_time = 200, /* FIXME: look this up */ +}; + +static ssize_t show_ctrl1(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned int val; + struct stw481x *stw481x = dev_get_platdata(dev); + + ret = regmap_read(stw481x->map, STW_CONF1, &val); + if (ret) + return ret; + + return sprintf(buf, "%#x\n", val); +}; + +static DEVICE_ATTR(ctrl1, S_IRUGO, show_ctrl1, NULL); + +static struct attribute *stw481x_vmmc_sysfs_entries[] = { + &dev_attr_ctrl1.attr, + NULL, +}; + +static struct attribute_group stw481x_vmmc_attr_group = { + .attrs = stw481x_vmmc_sysfs_entries, +}; + +static int stw481x_vmmc_regulator_probe(struct platform_device *pdev) +{ + struct stw481x *stw481x = dev_get_platdata(&pdev->dev); + struct regulator_config config = { }; + int ret; + + /* Register VMMC regulator */ + config.dev = &pdev->dev; + config.driver_data = stw481x; + config.of_node = pdev->dev.of_node; + config.init_data = of_get_regulator_init_data(&pdev->dev, + pdev->dev.of_node); + + stw481x->vmmc_regulator = regulator_register(&vmmc_regulator, &config); + if (IS_ERR(stw481x->vmmc_regulator)) { + dev_err(&pdev->dev, + "error initializing STw481x VMMC regulator\n"); + return PTR_ERR(stw481x->vmmc_regulator); + } + + ret = sysfs_create_group(&pdev->dev.kobj, &stw481x_vmmc_attr_group); + if (ret) + dev_err(&pdev->dev, "could not create sysfs group\n"); + + dev_info(&pdev->dev, "initialized STw481x VMMC regulator\n"); + return 0; +} + +static int stw481x_vmmc_regulator_remove(struct platform_device *pdev) +{ + struct stw481x *stw481x = dev_get_platdata(&pdev->dev); + + regulator_unregister(stw481x->vmmc_regulator); + return 0; +} + +static const struct of_device_id stw481x_vmmc_match[] = { + { .compatible = "st,stw481x-vmmc", }, + {}, +}; + +static struct platform_driver stw481x_vmmc_regulator_driver = { + .driver = { + .name = "stw481x-vmmc-regulator", + .owner = THIS_MODULE, + }, + .probe = stw481x_vmmc_regulator_probe, + .remove = stw481x_vmmc_regulator_remove, +}; + +static __init int stw481x_vmmc_regulator_init(void) +{ + return platform_driver_register(&stw481x_vmmc_regulator_driver); +} + +static __exit void stw481x_vmmc_regulator_exit(void) +{ + platform_driver_unregister(&stw481x_vmmc_regulator_driver); +} + +subsys_initcall(stw481x_vmmc_regulator_init); +module_exit(stw481x_vmmc_regulator_exit);