From patchwork Thu Dec 4 12:12:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Barry Song <21cnbao@gmail.com> X-Patchwork-Id: 5437921 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 623D1BEEA8 for ; Thu, 4 Dec 2014 12:15:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4ADA0201F4 for ; Thu, 4 Dec 2014 12:15:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2DE6C201F2 for ; Thu, 4 Dec 2014 12:15:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XwVHW-0005lp-W6; Thu, 04 Dec 2014 12:13:15 +0000 Received: from mail-pa0-x22b.google.com ([2607:f8b0:400e:c03::22b]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XwVHH-0005YS-0l for linux-arm-kernel@lists.infradead.org; Thu, 04 Dec 2014 12:12:59 +0000 Received: by mail-pa0-f43.google.com with SMTP id kx10so17945137pab.2 for ; Thu, 04 Dec 2014 04:12:37 -0800 (PST) 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=40SQsS7el/UgVsODUJpuL1atjiI3LhEByXVAWgQsAvQ=; b=iK1jetxE5e7Inmflhcw/mE9BCkWIa29mJBrj2f2FwBnFDeecLI3r4jADUoEiNzeShK sa5UeWxAFwC/ABPEHkxwWWvMKRnXMZlrpDENyNKxYWHQlSfeEqqb6Q6Njvm/s2/sh+LS PfD2V0TbkE33qlHJgRc967eyLYy5NO/Kp6ju7SB7SFV2Ax+zXCDy39L5Otp1zlUrHVDD kFZ5vSTA8U16jYzB45z7mP+p24fLxbSYzB13fsGQAnee6rwRtVO2saWGLAs9IkHuAyFN KblEw6J4dtK8nRte75sLeHqQZKBb/WIQmVqNEzBcn4tv7wWd5CA8aCUGzOL2YVeiZGUP 7fyQ== X-Received: by 10.68.229.193 with SMTP id ss1mr25813313pbc.16.1417695157644; Thu, 04 Dec 2014 04:12:37 -0800 (PST) Received: from localhost.localdomain ([61.135.213.198]) by mx.google.com with ESMTPSA id ny9sm26041067pab.25.2014.12.04.04.12.30 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 04 Dec 2014 04:12:35 -0800 (PST) From: Barry Song <21cnbao@gmail.com> To: linus.walleij@linaro.org Subject: [PATCH 3/3] gpio: sx150x: add dts support for sx150x driver Date: Thu, 4 Dec 2014 20:12:10 +0800 Message-Id: <1417695130-5712-3-git-send-email-21cnbao@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1417695130-5712-1-git-send-email-21cnbao@gmail.com> References: <1417695130-5712-1-git-send-email-21cnbao@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141204_041259_136067_BAAA44A8 X-CRM114-Status: GOOD ( 20.25 ) X-Spam-Score: -0.8 (/) Cc: Wei Chen , workgroup.linux@csr.com, linux-arm-kernel@lists.infradead.org, Barry Song X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 From: Wei Chen Current sx150x gpio expander driver doesn't support DT. Now we added DT support for this driver. Signed-off-by: Wei Chen Signed-off-by: Barry Song --- .../devicetree/bindings/gpio/gpio-sx150x.txt | 69 ++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.txt | 1 + drivers/gpio/gpio-sx150x.c | 83 +++++++++++++++++++++- 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/gpio/gpio-sx150x.txt diff --git a/Documentation/devicetree/bindings/gpio/gpio-sx150x.txt b/Documentation/devicetree/bindings/gpio/gpio-sx150x.txt new file mode 100644 index 0000000..7f8a61b --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-sx150x.txt @@ -0,0 +1,69 @@ +SEMTECH SX150x GPIO expander bindings + + +Required properties: + +- compatible: should be "semtech,sx1506q", + "semtech,sx1508q", + "semtech,sx1509q". + +- reg: The I2C slave address for this device. + +- interrupt-parent: phandle of the parent interrupt controller. + +- interrupts: Interrupt specifier for the controllers interrupt. + +- #gpio-cells: Should be 2. The first cell is the GPIO number and the + second cell is used to specify optional parameters: + bit 0: polarity (0: normal, 1: inverted) + +- gpio-controller: Marks the device as a GPIO controller. + +- interrupt-controller: Marks the device as a interrupt controller. + +Optional properties: +- oscio_is_gpo: Boolean. + Whether the HW considers OSCIO as a GPO instead of as an + oscillator. + +- reset_during_probe: Boolean. + Whether the HW supports full reset of the chip at the beginning + of the probe. + +-pullup_ena:A bit-mask which enables or disables the pull-up resistor + for each IO line in the expander. = <0x0>; + +-pulldn_ena:A bit-mask which enables-or disables the pull-down resistor + for each IO line in the expander. + +-open_drain_ena:A bit-mask which enables-or disables open-drain + operation for each IO line in the expander. + +-polarity: A bit-mask which enables polarity inversion for each IO line + in the expander. + +The GPIO expander can optionally be used as an interrupt controller, in +which case it uses the default two cell specifier as described in +Documentation/devicetree/bindings/interrupt-controller/interrupts.txt. + +Example: + + i2c_gpio_expander@20{ + #gpio-cells = <2>; + #interrupt-cells = <2>; + compatible = "semtech,sx1506q"; + reg = <0x20>; + interrupt-parent = <&gpio_1>; + interrupts = <16 0>; + + gpio-controller; + interrupt-controller; + + oscio_is_gpo; + reset_during_probe; + + pullup_ena = <0x01>; + pulldn_ena = <0x10>; + open_drain_ena = <0x40>; + polarity = <0x02>; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index c177cd7..6968148 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -140,6 +140,7 @@ sandisk Sandisk Corporation sbs Smart Battery System schindler Schindler seagate Seagate Technology PLC +semtech Semtech Corporation sil Silicon Image silabs Silicon Laboratories simtek diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index b32fb38..28d2f03 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c @@ -23,6 +23,11 @@ #include #include #include +#include +#include +#include +#include +#include #define NO_UPDATE_PENDING -1 @@ -147,6 +152,13 @@ static const struct i2c_device_id sx150x_id[] = { }; MODULE_DEVICE_TABLE(i2c, sx150x_id); +static const struct of_device_id sx150x_dt_id[] = { + { .compatible = "semtech,sx1508q", .data = &sx150x_devices[0]}, + { .compatible = "semtech,sx1509q", .data = &sx150x_devices[1]}, + { .compatible = "semtech,sx1506q", .data = &sx150x_devices[2]}, + {}, +}; + static s32 sx150x_i2c_write(struct i2c_client *client, u8 reg, u8 val) { s32 err = i2c_smbus_write_byte_data(client, reg, val); @@ -472,6 +484,8 @@ static void sx150x_init_chip(struct sx150x_chip *chip, chip->gpio_chip.base = pdata->gpio_base; chip->gpio_chip.can_sleep = true; chip->gpio_chip.ngpio = chip->dev_cfg->ngpios; + chip->gpio_chip.of_node = client->dev.of_node; + chip->gpio_chip.of_gpio_n_cells = 2; if (pdata->oscio_is_gpo) ++chip->gpio_chip.ngpio; @@ -607,6 +621,66 @@ static int sx150x_install_irq_chip(struct sx150x_chip *chip, return err; } +static struct sx150x_platform_data *of_sx150x_get_platdata( + struct i2c_client *client) +{ + int rc, gpio; + struct sx150x_platform_data *pdata; + struct device_node *np; + + if (!client->dev.of_node) + return NULL; + + np = client->dev.of_node; + + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + gpio = of_get_named_gpio(np, "int-gpios", 0); + if (gpio_is_valid(gpio)) { + rc = devm_gpio_request_one(&client->dev, gpio, + GPIOF_DIR_IN, "sx150x_interrupt"); + if (rc) + return ERR_PTR(rc); + } + + pdata->irq_summary = irq_of_parse_and_map(np, 0); + if (!pdata->irq_summary) + return ERR_PTR(-EPROBE_DEFER); + + pdata->oscio_is_gpo = of_property_read_bool(np, "oscio_is_gpo"); + pdata->reset_during_probe = + of_property_read_bool(np, "reset_during_probe"); + + rc = of_property_read_u16(np, "pullup_ena", + &pdata->io_pullup_ena); + if (rc) + pdata->io_pullup_ena = 0; + + rc = of_property_read_u16(np, "pulldn_ena", + &pdata->io_pulldn_ena); + if (rc) + pdata->io_pulldn_ena = 0; + + rc = of_property_read_u16(np, "open_drain_ena", + &pdata->io_open_drain_ena); + if (rc) + pdata->io_open_drain_ena = 0; + + rc = of_property_read_u16(np, "polarity", + &pdata->io_polarity); + if (rc) + pdata->io_polarity = 0; + + /* Let OF gpiochip_add to detect dynamical gpio_base & irq_base */ + pdata->gpio_base = -1; + /* We should use the dynamical irq_base */ + pdata->irq_base = 0; + + return pdata; +} + static int sx150x_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -617,8 +691,13 @@ static int sx150x_probe(struct i2c_client *client, int rc; pdata = dev_get_platdata(&client->dev); - if (!pdata) - return -EINVAL; + if (!pdata) { + pdata = of_sx150x_get_platdata(client); + if (!pdata) + return -EINVAL; + else if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } if (!i2c_check_functionality(client->adapter, i2c_funcs)) return -ENOSYS;