First time and things start going wrong immediately ;)
Here's the text version:
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c
b/arch/arm/mach-davinci/board-dm646x-evm.c
index 6b1f323..e4ce15d 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -25,6 +25,8 @@
#include <linux/dma-mapping.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
#include <asm/setup.h>
#include <linux/io.h>
@@ -43,6 +45,7 @@
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c/at24.h>
+#include <linux/i2c/pcf857x.h>
#include <linux/etherdevice.h>
#include <mach/emac.h>
@@ -54,6 +57,169 @@ static struct davinci_board_config_kernel
davinci_evm_config[] __initdata = {
{ DAVINCI_TAG_UART, &davinci_evm_uart_config },
};
+/* LEDS */
+
+static struct gpio_led evm_leds[] = {
+ { .name = "DS1", .active_low = 1, },
+ { .name = "DS2", .active_low = 1, },
+ { .name = "DS3", .active_low = 1, },
+ { .name = "DS4", .active_low = 1, },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+ .num_leds = ARRAY_SIZE(evm_leds),
+ .leds = evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int evm_led_setup(struct i2c_client *client, int gpio,
unsigned int ngpio, void *c)
+{
+ struct gpio_led *leds = evm_leds;
+ int status;
+
+ while (ngpio--) {
+ leds->gpio = gpio++;
+ leds++;
+ };
+
+ evm_led_dev = platform_device_alloc("leds-gpio", 0);
+ platform_device_add_data(evm_led_dev, &evm_led_data,
sizeof(evm_led_data));
+
+ evm_led_dev->dev.parent = &client->dev;
+ status = platform_device_add(evm_led_dev);
+ if (status < 0) {
+ platform_device_put(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return status;
+}
+
+static int evm_led_teardown(struct i2c_client* client, int gpio,
unsigned ngpio, void* c)
+{
+ if (evm_led_dev) {
+ platform_device_unregister(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return 0;
+}
+
+static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL };
+
+static inline ssize_t
+evm_sw_show(struct device *d, struct device_attribute *a, char *buf, int gpio)
+{
+ char *s = gpio_get_value_cansleep(gpio) ? "on\n" : "off\n";
+
+ strcpy(buf, s);
+ return strlen(s);
+}
+
+#define SW_SHOW(id) \
+static ssize_t sw_show_##id(struct device* d, struct device_attribute
*a, char *buf) \
+{ \
+ return evm_sw_show(d, a, buf, evm_sw_gpio[id]); \
+}
+
+
+SW_SHOW(0);
+SW_SHOW(1);
+SW_SHOW(2);
+SW_SHOW(3);
+
+static struct device_attribute sw_attrs[] = {
+ __ATTR(user_sw1, S_IRUGO, sw_show_0, NULL),
+ __ATTR(user_sw2, S_IRUGO, sw_show_1, NULL),
+ __ATTR(user_sw3, S_IRUGO, sw_show_2, NULL),
+ __ATTR(user_sw4, S_IRUGO, sw_show_3, NULL),
+};
+
+
+static int evm_sw_setup(struct i2c_client *client, int gpio, unsigned
ngpio, void *c)
+{
+ int status;
+ int i;
+ char label[10];
+
+ for (i = 0; i < 4; ++i) {
+ snprintf(label, 10, "user_sw%d", i);
+ status = gpio_request(gpio, label);
+ if (status)
+ {
+ goto out_free;
+ }
+ evm_sw_gpio[i] = gpio++;
+
+ status = gpio_direction_input(evm_sw_gpio[i]);
+ if (status) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ goto out_free;
+ }
+
+ status = device_create_file(&client->dev, &sw_attrs[i]);
+ if (status) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ goto out_free;
+ }
+ }
+ return status;
+out_free:
+ for (i = 0; i < 4; ++i) {
+ if (evm_sw_gpio[i] != -EINVAL) {
+ device_remove_file(&client->dev, &sw_attrs[i]);
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ }
+ }
+ return status;
+}
+
+static int evm_sw_teardown(struct i2c_client *client, int gpio,
unsigned ngpio, void *c)
+{
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ if (evm_sw_gpio[i] != -EINVAL) {
+ device_remove_file(&client->dev, &sw_attrs[i]);
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int evm_pcf_setup(struct i2c_client *client, int gpio,
unsigned int ngpio, void *c)
+{
+ int status;
+
+ if (ngpio < 8)
+ return -EINVAL;
+
+ status = evm_sw_setup(client, gpio, 4, c);
+ if (status)
+ return status;
+
+ return evm_led_setup(client, gpio+4, 4, c);
+}
+
+static int evm_pcf_teardown(struct i2c_client *client, int gpio,
unsigned int ngpio, void *c)
+{
+ BUG_ON(ngpio < 8);
+
+ evm_sw_teardown(client, gpio, 4, c);
+ evm_led_teardown(client, gpio+4, 4, c);
+
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data = {
+ .gpio_base = DAVINCI_N_GPIO+1,
+ .setup = evm_pcf_setup,
+ .teardown = evm_pcf_teardown,
+};
+
/* Most of this EEPROM is unused, but U-Boot uses some data:
* - 0x7f00, 6 bytes Ethernet Address
* - ... newer boards may have more
@@ -104,6 +270,10 @@ static struct i2c_board_info __initdata i2c_info[] = {
I2C_BOARD_INFO("24c256", 0x50),
.platform_data = &eeprom_info,
},
+ {
+ I2C_BOARD_INFO("pcf8574a", 0x38),
+ .platform_data = &pcf_data,
+ },
};
static struct davinci_i2c_platform_data i2c_pdata = {
--
On Sun, Feb 22, 2009 at 8:00 PM, Stijn Devriendt <[email protected]> wrote:
> Hi all,
>
> This patch should add support for the LEDs and user switches on the DM6467.
> *Should* because I do not personally have a DM6467 available to me and it will
> probably not be appreciated by my employer if I use the ones at work ;)
>
> Can someone pick this patch up and test it? Compiling went fine of course.
> It's based upon the DM644X code so I don't expect much trouble.
> I reviewed the original DM644X commit and I don't expect to have forgotten
> any crucial things.
>
> Regards,
> Stijn
>
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source