ixp4xx: remove 2.6.3{2,8} and 3.0 support
[openwrt/openwrt.git] / target / linux / ixp4xx / patches-3.0 / 020-gateworks_i2c_pld.patch
diff --git a/target/linux/ixp4xx/patches-3.0/020-gateworks_i2c_pld.patch b/target/linux/ixp4xx/patches-3.0/020-gateworks_i2c_pld.patch
deleted file mode 100644 (file)
index 13713ff..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
---- /dev/null
-+++ b/drivers/gpio/gw_i2c_pld.c
-@@ -0,0 +1,371 @@
-+/*
-+ * Gateworks I2C PLD GPIO expander
-+ *
-+ * Copyright (C) 2009 Gateworks Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/hardirq.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c/gw_i2c_pld.h>
-+#include <asm/gpio.h>
-+
-+static const struct i2c_device_id gw_i2c_pld_id[] = {
-+      { "gw_i2c_pld", 8 },
-+      { }
-+};
-+MODULE_DEVICE_TABLE(i2c, gw_i2c_pld_id);
-+
-+/*
-+ * The Gateworks I2C PLD chip only expose one read and one
-+ * write register.  Writing a "one" bit (to match the reset state) lets
-+ * that pin be used as an input. It is an open-drain model.
-+ */
-+
-+struct gw_i2c_pld {
-+      struct gpio_chip        chip;
-+      struct i2c_client       *client;
-+      unsigned                out;            /* software latch */
-+};
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * The Gateworks I2C PLD chip does not properly send the acknowledge bit
-+ * thus we cannot use standard i2c_smbus functions. We have recreated
-+ * our own here, but we still use the rt_mutex_lock to lock the i2c_bus
-+ * as the device still exists on the I2C bus.
-+*/
-+
-+#define PLD_SCL_GPIO 6
-+#define PLD_SDA_GPIO 7
-+
-+#define SCL_LO()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_LOW)
-+#define SCL_HI()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_HIGH)
-+#define SCL_EN()  gpio_line_config(PLD_SCL_GPIO, IXP4XX_GPIO_OUT)
-+#define SDA_LO()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_LOW)
-+#define SDA_HI()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_HIGH)
-+#define SDA_EN()  gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_OUT)
-+#define SDA_DIS() gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_IN)
-+#define SDA_IN(x) gpio_line_get(PLD_SDA_GPIO, &x);
-+
-+static int i2c_pld_write_byte(int address, int byte)
-+{
-+      int i;
-+
-+      address = (address << 1) & ~0x1;
-+
-+      SDA_HI();
-+      SDA_EN();
-+      SCL_EN();
-+      SCL_HI();
-+      SDA_LO();
-+      SCL_LO();
-+
-+      for (i = 7; i >= 0; i--)
-+      {
-+              if (address & (1 << i))
-+                      SDA_HI();
-+              else
-+                      SDA_LO();
-+
-+              SCL_HI();
-+              SCL_LO();
-+      }
-+
-+      SDA_DIS();
-+      SCL_HI();
-+      SDA_IN(i);
-+      SCL_LO();
-+      SDA_EN();
-+
-+      for (i = 7; i >= 0; i--)
-+      {
-+              if (byte & (1 << i))
-+      SDA_HI();
-+              else
-+                      SDA_LO();
-+              SCL_HI();
-+              SCL_LO();
-+      }
-+
-+      SDA_DIS();
-+      SCL_HI();
-+      SDA_IN(i);
-+      SCL_LO();
-+
-+      SDA_HI();
-+      SDA_EN();
-+
-+      SDA_LO();
-+      SCL_HI();
-+      SDA_HI();
-+      SCL_LO();
-+      SCL_HI();
-+
-+      return 0;
-+}
-+
-+static unsigned int i2c_pld_read_byte(int address)
-+{
-+      int i = 0, byte = 0;
-+      int bit;
-+
-+      address = (address << 1) | 0x1;
-+
-+      SDA_HI();
-+      SDA_EN();
-+      SCL_EN();
-+      SCL_HI();
-+      SDA_LO();
-+      SCL_LO();
-+
-+      for (i = 7; i >= 0; i--)
-+      {
-+              if (address & (1 << i))
-+                      SDA_HI();
-+              else
-+                      SDA_LO();
-+
-+              SCL_HI();
-+              SCL_LO();
-+      }
-+
-+      SDA_DIS();
-+      SCL_HI();
-+      SDA_IN(i);
-+      SCL_LO();
-+      SDA_EN();
-+
-+      SDA_DIS();
-+      for (i = 7; i >= 0; i--)
-+      {
-+              SCL_HI();
-+              SDA_IN(bit);
-+              byte |= bit << i;
-+              SCL_LO();
-+      }
-+
-+      SDA_LO();
-+      SCL_HI();
-+      SDA_HI();
-+      SCL_LO();
-+      SCL_HI();
-+
-+      return byte;
-+}
-+
-+
-+static int gw_i2c_pld_input8(struct gpio_chip *chip, unsigned offset)
-+{
-+      int ret;
-+      struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
-+      struct i2c_adapter *adap = gpio->client->adapter;
-+
-+      if (in_atomic() || irqs_disabled()) {
-+              ret = rt_mutex_trylock(&adap->bus_lock);
-+              if (!ret)
-+                      /* I2C activity is ongoing. */
-+                      return -EAGAIN;
-+      } else {
-+              rt_mutex_lock(&adap->bus_lock);
-+      }
-+
-+      gpio->out |= (1 << offset);
-+
-+      ret = i2c_pld_write_byte(gpio->client->addr, gpio->out);
-+
-+      rt_mutex_unlock(&adap->bus_lock);
-+
-+      return ret;
-+}
-+
-+static int gw_i2c_pld_get8(struct gpio_chip *chip, unsigned offset)
-+{
-+      int ret;
-+      s32     value;
-+      struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
-+      struct i2c_adapter *adap = gpio->client->adapter;
-+
-+      if (in_atomic() || irqs_disabled()) {
-+              ret = rt_mutex_trylock(&adap->bus_lock);
-+              if (!ret)
-+                      /* I2C activity is ongoing. */
-+                      return -EAGAIN;
-+      } else {
-+              rt_mutex_lock(&adap->bus_lock);
-+      }
-+
-+      value = i2c_pld_read_byte(gpio->client->addr);
-+
-+      rt_mutex_unlock(&adap->bus_lock);
-+
-+      return (value < 0) ? 0 : (value & (1 << offset));
-+}
-+
-+static int gw_i2c_pld_output8(struct gpio_chip *chip, unsigned offset, int value)
-+{
-+      int ret;
-+
-+      struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
-+      struct i2c_adapter *adap = gpio->client->adapter;
-+
-+      unsigned bit = 1 << offset;
-+
-+      if (in_atomic() || irqs_disabled()) {
-+              ret = rt_mutex_trylock(&adap->bus_lock);
-+              if (!ret)
-+                      /* I2C activity is ongoing. */
-+                      return -EAGAIN;
-+      } else {
-+              rt_mutex_lock(&adap->bus_lock);
-+      }
-+
-+
-+      if (value)
-+              gpio->out |= bit;
-+      else
-+              gpio->out &= ~bit;
-+
-+      ret = i2c_pld_write_byte(gpio->client->addr, gpio->out);
-+
-+      rt_mutex_unlock(&adap->bus_lock);
-+
-+      return ret;
-+}
-+
-+static void gw_i2c_pld_set8(struct gpio_chip *chip, unsigned offset, int value)
-+{
-+      gw_i2c_pld_output8(chip, offset, value);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int gw_i2c_pld_probe(struct i2c_client *client,
-+                       const struct i2c_device_id *id)
-+{
-+      struct gw_i2c_pld_platform_data *pdata;
-+      struct gw_i2c_pld *gpio;
-+      int status;
-+
-+      pdata = client->dev.platform_data;
-+      if (!pdata)
-+              return -ENODEV;
-+
-+      /* Allocate, initialize, and register this gpio_chip. */
-+      gpio = kzalloc(sizeof *gpio, GFP_KERNEL);
-+      if (!gpio)
-+              return -ENOMEM;
-+
-+      gpio->chip.base = pdata->gpio_base;
-+      gpio->chip.can_sleep = 1;
-+      gpio->chip.dev = &client->dev;
-+      gpio->chip.owner = THIS_MODULE;
-+
-+      gpio->chip.ngpio = pdata->nr_gpio;
-+      gpio->chip.direction_input = gw_i2c_pld_input8;
-+      gpio->chip.get = gw_i2c_pld_get8;
-+      gpio->chip.direction_output = gw_i2c_pld_output8;
-+      gpio->chip.set = gw_i2c_pld_set8;
-+
-+      gpio->chip.label = client->name;
-+
-+      gpio->client = client;
-+      i2c_set_clientdata(client, gpio);
-+
-+      gpio->out = 0xFF;
-+
-+      status = gpiochip_add(&gpio->chip);
-+      if (status < 0)
-+              goto fail;
-+
-+      dev_info(&client->dev, "gpios %d..%d on a %s%s\n",
-+                      gpio->chip.base,
-+                      gpio->chip.base + gpio->chip.ngpio - 1,
-+                      client->name,
-+                      client->irq ? " (irq ignored)" : "");
-+
-+      /* Let platform code set up the GPIOs and their users.
-+       * Now is the first time anyone could use them.
-+       */
-+      if (pdata->setup) {
-+              status = pdata->setup(client,
-+                              gpio->chip.base, gpio->chip.ngpio,
-+                              pdata->context);
-+              if (status < 0)
-+                      dev_warn(&client->dev, "setup --> %d\n", status);
-+      }
-+
-+      return 0;
-+
-+fail:
-+      dev_dbg(&client->dev, "probe error %d for '%s'\n",
-+                      status, client->name);
-+      kfree(gpio);
-+      return status;
-+}
-+
-+static int gw_i2c_pld_remove(struct i2c_client *client)
-+{
-+      struct gw_i2c_pld_platform_data *pdata = client->dev.platform_data;
-+      struct gw_i2c_pld *gpio = i2c_get_clientdata(client);
-+      int                             status = 0;
-+
-+      if (pdata->teardown) {
-+              status = pdata->teardown(client,
-+                              gpio->chip.base, gpio->chip.ngpio,
-+                              pdata->context);
-+              if (status < 0) {
-+                      dev_err(&client->dev, "%s --> %d\n",
-+                                      "teardown", status);
-+                      return status;
-+              }
-+      }
-+
-+      status = gpiochip_remove(&gpio->chip);
-+      if (status == 0)
-+              kfree(gpio);
-+      else
-+              dev_err(&client->dev, "%s --> %d\n", "remove", status);
-+      return status;
-+}
-+
-+static struct i2c_driver gw_i2c_pld_driver = {
-+      .driver = {
-+              .name   = "gw_i2c_pld",
-+              .owner  = THIS_MODULE,
-+      },
-+      .probe  = gw_i2c_pld_probe,
-+      .remove = gw_i2c_pld_remove,
-+      .id_table = gw_i2c_pld_id,
-+};
-+
-+static int __init gw_i2c_pld_init(void)
-+{
-+      return i2c_add_driver(&gw_i2c_pld_driver);
-+}
-+module_init(gw_i2c_pld_init);
-+
-+static void __exit gw_i2c_pld_exit(void)
-+{
-+      i2c_del_driver(&gw_i2c_pld_driver);
-+}
-+module_exit(gw_i2c_pld_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chris Lang");
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -388,6 +388,14 @@ config GPIO_RDC321X
-         Support for the RDC R321x SoC GPIOs over southbridge
-         PCI configuration space.
-+config GPIO_GW_I2C_PLD
-+      tristate "Gateworks I2C PLD GPIO Expander"
-+      depends on I2C
-+      help
-+              Say yes here to provide access to the Gateworks I2C PLD GPIO
-+              Expander. This is used at least on the GW2358-4.
-+
-+
- comment "SPI GPIO expanders:"
- config GPIO_MAX7301
---- a/drivers/gpio/Makefile
-+++ b/drivers/gpio/Makefile
-@@ -48,3 +48,4 @@ obj-$(CONFIG_GPIO_VX855)     += vx855_gpio.o
- obj-$(CONFIG_GPIO_ML_IOH)     += ml_ioh_gpio.o
- obj-$(CONFIG_AB8500_GPIO)       += ab8500-gpio.o
- obj-$(CONFIG_GPIO_TPS65910)   += tps65910-gpio.o
-+obj-$(CONFIG_GPIO_GW_I2C_PLD) += gw_i2c_pld.o
---- /dev/null
-+++ b/include/linux/i2c/gw_i2c_pld.h
-@@ -0,0 +1,20 @@
-+#ifndef __LINUX_GW_I2C_PLD_H
-+#define __LINUX_GW_I2C_PLD_H
-+
-+/**
-+ * The Gateworks I2C PLD Implements an additional 8 bits of GPIO through the PLD
-+ */
-+
-+struct gw_i2c_pld_platform_data {
-+      unsigned gpio_base;
-+      unsigned nr_gpio;
-+      int             (*setup)(struct i2c_client *client,
-+                                      int gpio, unsigned ngpio,
-+                                      void *context);
-+      int             (*teardown)(struct i2c_client *client,
-+                                      int gpio, unsigned ngpio,
-+                                      void *context);
-+      void            *context;
-+};
-+
-+#endif /* __LINUX_GW_I2C_PLD_H */