From patchwork Mon Oct 15 13:16:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 12233 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id D3A3723DE2 for ; Mon, 15 Oct 2012 13:17:07 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id 65AFAA18F23 for ; Mon, 15 Oct 2012 13:17:07 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id e10so7550534iej.11 for ; Mon, 15 Oct 2012 06:17:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:x-gm-message-state; bh=OfE5NHc6ys5oDTlmR56GnyMGyN6Wd8+h6d8HrOY3QZs=; b=ml2ZAh1uRB2wtZ8cMO005tfVvVaavu8gag04DRLTIMr+MMOYi21v5kKWE55F/g/c+Z hwa/nSP8vLehPTxZ5WuWI/alGF60F4sFmM1IS6uzMnMe+O44o2IFd5GPp8+O75XhZ5Yo 6dfsJCcTw7hadIw2kGkIvWc/Itasxo5vgSNPeYemCyqq6zyqfeyGQ7gLzUUAxuiwHASe wjb+SYNvzEGq9CnXK1GerGogfevA2T1j5q8cNWmqj+mLy1SR3RhuYvord5l11VeYmwzY TYqyM8EvImE612S0+tME7O7QWd+a3ijp+uomDKrnAAqQ/lOhOeKcb5uLyBdZiy/svTot WdGA== Received: by 10.50.168.37 with SMTP id zt5mr8473731igb.57.1350307026768; Mon, 15 Oct 2012 06:17:06 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.67.148 with SMTP id n20csp572899igt; Mon, 15 Oct 2012 06:17:05 -0700 (PDT) Received: by 10.180.86.202 with SMTP id r10mr23806243wiz.12.1350307025205; Mon, 15 Oct 2012 06:17:05 -0700 (PDT) Received: from mail-we0-f178.google.com (mail-we0-f178.google.com [74.125.82.178]) by mx.google.com with ESMTPS id p3si16774208wed.12.2012.10.15.06.17.04 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 15 Oct 2012 06:17:05 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.178 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) client-ip=74.125.82.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.178 is neither permitted nor denied by best guess record for domain of lee.jones@linaro.org) smtp.mail=lee.jones@linaro.org Received: by mail-we0-f178.google.com with SMTP id r6so3747197wey.37 for ; Mon, 15 Oct 2012 06:17:04 -0700 (PDT) Received: by 10.180.104.97 with SMTP id gd1mr23839755wib.4.1350307024626; Mon, 15 Oct 2012 06:17:04 -0700 (PDT) Received: from localhost.localdomain (cpc1-aztw13-0-0-cust473.18-1.cable.virginmedia.com. [77.102.241.218]) by mx.google.com with ESMTPS id a10sm15831429wiz.4.2012.10.15.06.17.03 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 15 Oct 2012 06:17:03 -0700 (PDT) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: arnd@arndb.de, linus.walleij@stericsson.com, Lee Jones , Mark Brown Subject: [PATCH 1/2] regulator: gpio-regulator: Allow use of GPIO controlled regulators though DT Date: Mon, 15 Oct 2012 14:16:59 +0100 Message-Id: <1350307020-5910-1-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Gm-Message-State: ALoCoQk1nEwzm+nigI6F/lwSV53SlGpKaUMofDMe67tcNM50sGuz9iZTr4Ybno/py7q9o9dMpUp6 Here we provide the GPIO Regulator driver with Device Tree capability, so that when a platform is booting with DT instead of platform data we can still make full use of it. Cc: Mark Brown Signed-off-by: Lee Jones --- drivers/regulator/gpio-regulator.c | 94 ++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 8b5944f..e467d0a 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -28,9 +28,12 @@ #include #include #include +#include #include #include #include +#include +#include struct gpio_regulator_data { struct regulator_desc desc; @@ -129,6 +132,84 @@ static struct regulator_ops gpio_regulator_voltage_ops = { .list_voltage = gpio_regulator_list_voltage, }; +struct gpio_regulator_config * +of_get_gpio_regulator_config(struct device *dev, struct device_node *np) +{ + struct gpio_regulator_config *config; + struct property *prop; + const char *regtype; + int proplen, gpio, i; + + config = devm_kzalloc(dev, + sizeof(struct gpio_regulator_config), + GFP_KERNEL); + if (!config) + return ERR_PTR(-ENOMEM); + + config->init_data = of_get_regulator_init_data(dev, np); + if (!config->init_data) + return ERR_PTR(-EINVAL); + + config->supply_name = config->init_data->constraints.name; + + if (of_property_read_bool(np, "enable-active-high")) + config->enable_high = true; + + if (of_property_read_bool(np, "enable-at-boot")) + config->enabled_at_boot = true; + + of_property_read_u32(np, "startup-delay-us", &config->startup_delay); + + config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); + + /* Fetch GPIOs. */ + for (i = 0; ; i++) + if (of_get_named_gpio(np, "gpios", i) < 0) + break; + config->nr_gpios = i; + + config->gpios = devm_kzalloc(dev, + sizeof(struct gpio) * config->nr_gpios, + GFP_KERNEL); + if (!config->gpios) + return ERR_PTR(-ENOMEM); + + for (i = 0; config->nr_gpios; i++) { + gpio = of_get_named_gpio(np, "gpios", i); + if (gpio < 0) + break; + config->gpios[i].gpio = gpio; + } + + /* Fetch states. */ + prop = of_find_property(np, "states", NULL); + proplen = prop->length / sizeof(int); + + config->states = devm_kzalloc(dev, + sizeof(struct gpio_regulator_state) + * (proplen / 2), + GFP_KERNEL); + if (!config->states) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < proplen / 2; i++) { + config->states[i].value = + be32_to_cpup((int *)prop->value + (i * 2)); + config->states[i].gpios = + be32_to_cpup((int *)prop->value + (i * 2 + 1)); + } + config->nr_states = i; + + of_property_read_string(np, "regulator-type", ®type); + + if (!strncmp("voltage", regtype, 7)) + config->type = REGULATOR_VOLTAGE; + else if (!strncmp("current", regtype, 7)) + config->type = REGULATOR_CURRENT; + + return config; +} + static struct regulator_ops gpio_regulator_current_ops = { .get_current_limit = gpio_regulator_get_value, .set_current_limit = gpio_regulator_set_current_limit, @@ -137,10 +218,17 @@ static struct regulator_ops gpio_regulator_current_ops = { static int __devinit gpio_regulator_probe(struct platform_device *pdev) { struct gpio_regulator_config *config = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; struct gpio_regulator_data *drvdata; struct regulator_config cfg = { }; int ptr, ret, state; + if (np) { + config = of_get_gpio_regulator_config(&pdev->dev, np); + if (IS_ERR(config)) + return PTR_ERR(config); + } + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), GFP_KERNEL); if (drvdata == NULL) { @@ -270,12 +358,18 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id regulator_gpio_of_match[] __devinitconst = { + { .compatible = "regulator-gpio", }, + {}, +}; + static struct platform_driver gpio_regulator_driver = { .probe = gpio_regulator_probe, .remove = __devexit_p(gpio_regulator_remove), .driver = { .name = "gpio-regulator", .owner = THIS_MODULE, + .of_match_table = regulator_gpio_of_match, }, };