diff options
| -rw-r--r-- | target/linux/brcm63xx/patches-2.6.32/211-nxp-74hc164-gpio-chip-driver.patch | 279 | ||||
| -rw-r--r-- | target/linux/brcm63xx/patches-2.6.33/211-nxp-74hc164-gpio-chip-driver.patch | 279 | 
2 files changed, 558 insertions, 0 deletions
| diff --git a/target/linux/brcm63xx/patches-2.6.32/211-nxp-74hc164-gpio-chip-driver.patch b/target/linux/brcm63xx/patches-2.6.32/211-nxp-74hc164-gpio-chip-driver.patch new file mode 100644 index 000000000..8e50ee740 --- /dev/null +++ b/target/linux/brcm63xx/patches-2.6.32/211-nxp-74hc164-gpio-chip-driver.patch @@ -0,0 +1,279 @@ +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -230,4 +230,12 @@ config GPIO_UCB1400 + 	  To compile this driver as a module, choose M here: the + 	  module will be called ucb1400_gpio. +  ++comment "Other GPIO expanders" ++ ++config GPIO_NXP_74HC164 ++       tristate "NXP 74HC164 Output expanders" ++       help ++         Platform driver for NXP 74HC164 8-output Expanders. This ++         provides a GPIO interface supporting outputs. ++ + endif +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_GPIO_MAX7301)	+= max7301.o + obj-$(CONFIG_GPIO_MAX732X)	+= max732x.o + obj-$(CONFIG_GPIO_MC33880)	+= mc33880.o + obj-$(CONFIG_GPIO_MCP23S08)	+= mcp23s08.o ++obj-$(CONFIG_GPIO_NXP_74HC164)	+= nxp_74hc164.o + obj-$(CONFIG_GPIO_PCA953X)	+= pca953x.o + obj-$(CONFIG_GPIO_PCF857X)	+= pcf857x.o + obj-$(CONFIG_GPIO_PL061)	+= pl061.o +--- /dev/null ++++ b/drivers/gpio/nxp_74hc164.c +@@ -0,0 +1,226 @@ ++/* ++ *  NXP 74HC164 - output expander  GPIO driver ++ * ++ *  Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> ++ *  Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> ++ * ++ *  This program is free software; you can redistribute it and/or modify ++ *  it under the terms of the GNU General Public License version 2 as ++ *  published by the Free Software Foundation. ++ * ++ *  Copy from nxp_74hc153.c code ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/gpio.h> ++#include <linux/bitops.h> ++#include <linux/platform_device.h> ++#include <linux/nxp_74hc164.h> ++ ++#define NXP_74HC164_NUM_GPIOS	8 ++ ++struct nxp_74hc164_chip { ++	struct device		*parent; ++	struct gpio_chip	gpio_chip; ++	struct mutex		lock; ++	long			mask; ++}; ++ ++static void nxp_74hc164_set_value(struct gpio_chip *, unsigned, int); ++ ++static struct nxp_74hc164_chip *gpio_to_nxp(struct gpio_chip *gc) ++{ ++	return container_of(gc, struct nxp_74hc164_chip, gpio_chip); ++} ++ ++static int nxp_74hc164_direction_input(struct gpio_chip *gc, unsigned offset) ++{ ++	WARN_ON(1); ++	return -EINVAL; ++} ++ ++static int nxp_74hc164_direction_output(struct gpio_chip *gc, ++					unsigned offset, int val) ++{ ++	nxp_74hc164_set_value(gc, offset, val); ++	return 0; ++} ++ ++static int nxp_74hc164_get_value(struct gpio_chip *gc, unsigned offset) ++{ ++	struct nxp_74hc164_chip *nxp = gpio_to_nxp(gc); ++	int ret; ++ ++	mutex_lock(&nxp->lock); ++	ret = test_bit(offset, &nxp->mask); ++	mutex_unlock(&nxp->lock); ++ ++	return ret; ++} ++ ++static void nxp_74hc164_set_value(struct gpio_chip *gc, ++				  unsigned offset, int val) ++{ ++	struct nxp_74hc164_chip *nxp; ++	struct nxp_74hc164_platform_data *pdata; ++	long mask; ++	int refresh; ++	int i; ++ ++	nxp = gpio_to_nxp(gc); ++	pdata = nxp->parent->platform_data; ++ ++	mutex_lock(&nxp->lock); ++	if (val) ++		refresh = (test_and_set_bit(offset, &nxp->mask) != val); ++	else ++		refresh = (test_and_clear_bit(offset, &nxp->mask) != val); ++ ++	if (refresh) { ++		mask = nxp->mask; ++		for (i = 8; i > 0; --i, mask <<= 1) { ++			gpio_set_value(pdata->gpio_pin_data, mask & 0x80); ++			gpio_set_value(pdata->gpio_pin_clk, 1); ++			gpio_set_value(pdata->gpio_pin_clk, 0); ++		} ++	} ++	mutex_unlock(&nxp->lock); ++} ++ ++static int __devinit nxp_74hc164_probe(struct platform_device *pdev) ++{ ++	struct nxp_74hc164_platform_data *pdata; ++	struct nxp_74hc164_chip *nxp; ++	struct gpio_chip *gc; ++	int err; ++ ++	pdata = pdev->dev.platform_data; ++	if (pdata == NULL) { ++		dev_dbg(&pdev->dev, "no platform data specified\n"); ++		return -EINVAL; ++	} ++ ++	nxp = kzalloc(sizeof(struct nxp_74hc164_chip), GFP_KERNEL); ++	if (nxp == NULL) { ++		dev_err(&pdev->dev, "no memory for private data\n"); ++		return -ENOMEM; ++	} ++ ++	err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev)); ++	if (err) { ++		dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++			pdata->gpio_pin_clk, err); ++		goto err_free_nxp; ++	} ++ ++	err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev)); ++	if (err) { ++		dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++			pdata->gpio_pin_data, err); ++		goto err_free_clk; ++	} ++ ++	err = gpio_direction_output(pdata->gpio_pin_clk, 0); ++	if (err) { ++		dev_err(&pdev->dev, ++			"unable to set direction of gpio %u, err=%d\n", ++			pdata->gpio_pin_clk, err); ++		goto err_free_data; ++	} ++ ++	err = gpio_direction_output(pdata->gpio_pin_data, 0); ++	if (err) { ++		dev_err(&pdev->dev, ++			"unable to set direction of gpio %u, err=%d\n", ++			pdata->gpio_pin_data, err); ++		goto err_free_data; ++	} ++ ++	nxp->parent = &pdev->dev; ++	mutex_init(&nxp->lock); ++ ++	gc = &nxp->gpio_chip; ++ ++	gc->direction_input  = nxp_74hc164_direction_input; ++	gc->direction_output = nxp_74hc164_direction_output; ++	gc->get = nxp_74hc164_get_value; ++	gc->set = nxp_74hc164_set_value; ++	gc->can_sleep = 1; ++ ++	gc->base = pdata->gpio_base; ++	gc->ngpio = NXP_74HC164_NUM_GPIOS; ++	gc->label = dev_name(nxp->parent); ++	gc->dev = nxp->parent; ++	gc->owner = THIS_MODULE; ++ ++	err = gpiochip_add(&nxp->gpio_chip); ++	if (err) { ++		dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); ++		goto err_free_data; ++	} ++ ++	platform_set_drvdata(pdev, nxp); ++	return 0; ++ ++ err_free_data: ++	gpio_free(pdata->gpio_pin_data); ++ err_free_clk: ++	gpio_free(pdata->gpio_pin_clk); ++ err_free_nxp: ++	kfree(nxp); ++	return err; ++} ++ ++static int nxp_74hc164_remove(struct platform_device *pdev) ++{ ++	struct nxp_74hc164_chip *nxp = platform_get_drvdata(pdev); ++	struct nxp_74hc164_platform_data *pdata = pdev->dev.platform_data; ++ ++	if (nxp) { ++		int err; ++ ++		err = gpiochip_remove(&nxp->gpio_chip); ++		if (err) { ++			dev_err(&pdev->dev, ++				"unable to remove gpio chip, err=%d\n", ++				err); ++			return err; ++		} ++ ++		gpio_free(pdata->gpio_pin_clk); ++		gpio_free(pdata->gpio_pin_data); ++ ++		kfree(nxp); ++		platform_set_drvdata(pdev, NULL); ++	} ++ ++	return 0; ++} ++ ++static struct platform_driver nxp_74hc164_driver = { ++	.probe		= nxp_74hc164_probe, ++	.remove		= __devexit_p(nxp_74hc164_remove), ++	.driver = { ++		.name	= NXP_74HC164_DRIVER_NAME, ++		.owner	= THIS_MODULE, ++	}, ++}; ++ ++static int __init nxp_74hc164_init(void) ++{ ++	return platform_driver_register(&nxp_74hc164_driver); ++} ++subsys_initcall(nxp_74hc164_init); ++ ++static void __exit nxp_74hc164_exit(void) ++{ ++	platform_driver_unregister(&nxp_74hc164_driver); ++} ++module_exit(nxp_74hc164_exit); ++ ++MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); ++MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); ++MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC164"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" NXP_74HC164_DRIVER_NAME); +--- /dev/null ++++ b/include/linux/nxp_74hc164.h +@@ -0,0 +1,22 @@ ++/* ++ *  NXP 74HC164 - Dual 4-input multiplexer defines ++ * ++ *  Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> ++ * ++ *  This program is free software; you can redistribute it and/or modify ++ *  it under the terms of the GNU General Public License version 2 as ++ *  published by the Free Software Foundation. ++ */ ++ ++#ifndef _NXP_74HC164_H ++#define _NXP_74HC164_H ++ ++#define NXP_74HC164_DRIVER_NAME "nxp-74hc164" ++ ++struct nxp_74hc164_platform_data { ++	unsigned	gpio_base; ++	unsigned	gpio_pin_data; ++	unsigned	gpio_pin_clk; ++}; ++ ++#endif /* _NXP_74HC164_H */ diff --git a/target/linux/brcm63xx/patches-2.6.33/211-nxp-74hc164-gpio-chip-driver.patch b/target/linux/brcm63xx/patches-2.6.33/211-nxp-74hc164-gpio-chip-driver.patch new file mode 100644 index 000000000..3c4fe72fe --- /dev/null +++ b/target/linux/brcm63xx/patches-2.6.33/211-nxp-74hc164-gpio-chip-driver.patch @@ -0,0 +1,279 @@ +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -255,4 +255,12 @@ config GPIO_UCB1400 + 	  To compile this driver as a module, choose M here: the + 	  module will be called ucb1400_gpio. +  ++comment "Other GPIO expanders" ++ ++config GPIO_NXP_74HC164 ++       tristate "NXP 74HC164 Output expanders" ++       help ++         Platform driver for NXP 74HC164 8-output Expanders. This ++         provides a GPIO interface supporting outputs. ++ + endif +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_GPIO_MAX7301)	+= max7301.o + obj-$(CONFIG_GPIO_MAX732X)	+= max732x.o + obj-$(CONFIG_GPIO_MC33880)	+= mc33880.o + obj-$(CONFIG_GPIO_MCP23S08)	+= mcp23s08.o ++obj-$(CONFIG_GPIO_NXP_74HC164)	+= nxp_74hc164.o + obj-$(CONFIG_GPIO_PCA953X)	+= pca953x.o + obj-$(CONFIG_GPIO_PCF857X)	+= pcf857x.o + obj-$(CONFIG_GPIO_PL061)	+= pl061.o +--- /dev/null ++++ b/drivers/gpio/nxp_74hc164.c +@@ -0,0 +1,226 @@ ++/* ++ *  NXP 74HC164 - output expander  GPIO driver ++ * ++ *  Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> ++ *  Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> ++ * ++ *  This program is free software; you can redistribute it and/or modify ++ *  it under the terms of the GNU General Public License version 2 as ++ *  published by the Free Software Foundation. ++ * ++ *  Copy from nxp_74hc153.c code ++ */ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/gpio.h> ++#include <linux/bitops.h> ++#include <linux/platform_device.h> ++#include <linux/nxp_74hc164.h> ++ ++#define NXP_74HC164_NUM_GPIOS	8 ++ ++struct nxp_74hc164_chip { ++	struct device		*parent; ++	struct gpio_chip	gpio_chip; ++	struct mutex		lock; ++	long			mask; ++}; ++ ++static void nxp_74hc164_set_value(struct gpio_chip *, unsigned, int); ++ ++static struct nxp_74hc164_chip *gpio_to_nxp(struct gpio_chip *gc) ++{ ++	return container_of(gc, struct nxp_74hc164_chip, gpio_chip); ++} ++ ++static int nxp_74hc164_direction_input(struct gpio_chip *gc, unsigned offset) ++{ ++	WARN_ON(1); ++	return -EINVAL; ++} ++ ++static int nxp_74hc164_direction_output(struct gpio_chip *gc, ++					unsigned offset, int val) ++{ ++	nxp_74hc164_set_value(gc, offset, val); ++	return 0; ++} ++ ++static int nxp_74hc164_get_value(struct gpio_chip *gc, unsigned offset) ++{ ++	struct nxp_74hc164_chip *nxp = gpio_to_nxp(gc); ++	int ret; ++ ++	mutex_lock(&nxp->lock); ++	ret = test_bit(offset, &nxp->mask); ++	mutex_unlock(&nxp->lock); ++ ++	return ret; ++} ++ ++static void nxp_74hc164_set_value(struct gpio_chip *gc, ++				  unsigned offset, int val) ++{ ++	struct nxp_74hc164_chip *nxp; ++	struct nxp_74hc164_platform_data *pdata; ++	long mask; ++	int refresh; ++	int i; ++ ++	nxp = gpio_to_nxp(gc); ++	pdata = nxp->parent->platform_data; ++ ++	mutex_lock(&nxp->lock); ++	if (val) ++		refresh = (test_and_set_bit(offset, &nxp->mask) != val); ++	else ++		refresh = (test_and_clear_bit(offset, &nxp->mask) != val); ++ ++	if (refresh) { ++		mask = nxp->mask; ++		for (i = 8; i > 0; --i, mask <<= 1) { ++			gpio_set_value(pdata->gpio_pin_data, mask & 0x80); ++			gpio_set_value(pdata->gpio_pin_clk, 1); ++			gpio_set_value(pdata->gpio_pin_clk, 0); ++		} ++	} ++	mutex_unlock(&nxp->lock); ++} ++ ++static int __devinit nxp_74hc164_probe(struct platform_device *pdev) ++{ ++	struct nxp_74hc164_platform_data *pdata; ++	struct nxp_74hc164_chip *nxp; ++	struct gpio_chip *gc; ++	int err; ++ ++	pdata = pdev->dev.platform_data; ++	if (pdata == NULL) { ++		dev_dbg(&pdev->dev, "no platform data specified\n"); ++		return -EINVAL; ++	} ++ ++	nxp = kzalloc(sizeof(struct nxp_74hc164_chip), GFP_KERNEL); ++	if (nxp == NULL) { ++		dev_err(&pdev->dev, "no memory for private data\n"); ++		return -ENOMEM; ++	} ++ ++	err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev)); ++	if (err) { ++		dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++			pdata->gpio_pin_clk, err); ++		goto err_free_nxp; ++	} ++ ++	err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev)); ++	if (err) { ++		dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n", ++			pdata->gpio_pin_data, err); ++		goto err_free_clk; ++	} ++ ++	err = gpio_direction_output(pdata->gpio_pin_clk, 0); ++	if (err) { ++		dev_err(&pdev->dev, ++			"unable to set direction of gpio %u, err=%d\n", ++			pdata->gpio_pin_clk, err); ++		goto err_free_data; ++	} ++ ++	err = gpio_direction_output(pdata->gpio_pin_data, 0); ++	if (err) { ++		dev_err(&pdev->dev, ++			"unable to set direction of gpio %u, err=%d\n", ++			pdata->gpio_pin_data, err); ++		goto err_free_data; ++	} ++ ++	nxp->parent = &pdev->dev; ++	mutex_init(&nxp->lock); ++ ++	gc = &nxp->gpio_chip; ++ ++	gc->direction_input  = nxp_74hc164_direction_input; ++	gc->direction_output = nxp_74hc164_direction_output; ++	gc->get = nxp_74hc164_get_value; ++	gc->set = nxp_74hc164_set_value; ++	gc->can_sleep = 1; ++ ++	gc->base = pdata->gpio_base; ++	gc->ngpio = NXP_74HC164_NUM_GPIOS; ++	gc->label = dev_name(nxp->parent); ++	gc->dev = nxp->parent; ++	gc->owner = THIS_MODULE; ++ ++	err = gpiochip_add(&nxp->gpio_chip); ++	if (err) { ++		dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err); ++		goto err_free_data; ++	} ++ ++	platform_set_drvdata(pdev, nxp); ++	return 0; ++ ++ err_free_data: ++	gpio_free(pdata->gpio_pin_data); ++ err_free_clk: ++	gpio_free(pdata->gpio_pin_clk); ++ err_free_nxp: ++	kfree(nxp); ++	return err; ++} ++ ++static int nxp_74hc164_remove(struct platform_device *pdev) ++{ ++	struct nxp_74hc164_chip *nxp = platform_get_drvdata(pdev); ++	struct nxp_74hc164_platform_data *pdata = pdev->dev.platform_data; ++ ++	if (nxp) { ++		int err; ++ ++		err = gpiochip_remove(&nxp->gpio_chip); ++		if (err) { ++			dev_err(&pdev->dev, ++				"unable to remove gpio chip, err=%d\n", ++				err); ++			return err; ++		} ++ ++		gpio_free(pdata->gpio_pin_clk); ++		gpio_free(pdata->gpio_pin_data); ++ ++		kfree(nxp); ++		platform_set_drvdata(pdev, NULL); ++	} ++ ++	return 0; ++} ++ ++static struct platform_driver nxp_74hc164_driver = { ++	.probe		= nxp_74hc164_probe, ++	.remove		= __devexit_p(nxp_74hc164_remove), ++	.driver = { ++		.name	= NXP_74HC164_DRIVER_NAME, ++		.owner	= THIS_MODULE, ++	}, ++}; ++ ++static int __init nxp_74hc164_init(void) ++{ ++	return platform_driver_register(&nxp_74hc164_driver); ++} ++subsys_initcall(nxp_74hc164_init); ++ ++static void __exit nxp_74hc164_exit(void) ++{ ++	platform_driver_unregister(&nxp_74hc164_driver); ++} ++module_exit(nxp_74hc164_exit); ++ ++MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); ++MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); ++MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC164"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" NXP_74HC164_DRIVER_NAME); +--- /dev/null ++++ b/include/linux/nxp_74hc164.h +@@ -0,0 +1,22 @@ ++/* ++ *  NXP 74HC164 - Dual 4-input multiplexer defines ++ * ++ *  Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> ++ * ++ *  This program is free software; you can redistribute it and/or modify ++ *  it under the terms of the GNU General Public License version 2 as ++ *  published by the Free Software Foundation. ++ */ ++ ++#ifndef _NXP_74HC164_H ++#define _NXP_74HC164_H ++ ++#define NXP_74HC164_DRIVER_NAME "nxp-74hc164" ++ ++struct nxp_74hc164_platform_data { ++	unsigned	gpio_base; ++	unsigned	gpio_pin_data; ++	unsigned	gpio_pin_clk; ++}; ++ ++#endif /* _NXP_74HC164_H */ | 
