Re: [OpenWrt-Devel] [PATCH v5 4/5] ar71xx: add LED driver NU801
Hi, 1 comment inline On 22/09/2015 19:07, Chris R Blake wrote: > From: Chris R Blake > > The MR18 uses a 3-channel 16-bit PWM Constant Current Driver > for its status LED. > > Signed-off-by: Chris R Blake > --- > package/base-files/files/etc/init.d/led| 2 +- > .../linux/ar71xx/files/drivers/leds/leds-nu801.c | 396 > + > .../linux/ar71xx/files/include/linux/leds-nu801.h | 38 ++ > target/linux/ar71xx/modules.mk | 16 + > .../818-MIPS-ath79-add-nu801-led-driver.patch | 26 ++ > 5 files changed, 477 insertions(+), 1 deletion(-) > create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-nu801.c > create mode 100644 target/linux/ar71xx/files/include/linux/leds-nu801.h > create mode 100644 > target/linux/ar71xx/patches-4.1/818-MIPS-ath79-add-nu801-led-driver.patch > > diff --git a/package/base-files/files/etc/init.d/led > b/package/base-files/files/etc/init.d/led > index 3f45732..84cd028 100755 > --- a/package/base-files/files/etc/init.d/led > +++ b/package/base-files/files/etc/init.d/led > @@ -44,7 +44,7 @@ load_led() { > ret="$?" > > [ $default = 1 ] && > - echo 1 >/sys/class/leds/${sysfs}/brightness > + cat /sys/class/leds/${sysfs}/max_brightness > > /sys/class/leds/${sysfs}/brightness > > [ $ret = 0 ] || { > echo >&2 "Skipping trigger '$trigger' for led '$name' > due to missing kernel module" this is a nice corner case i never considered before. however this part of the patch need to go into its own patch file as it modifies a different part of openwrt. John > diff --git a/target/linux/ar71xx/files/drivers/leds/leds-nu801.c > b/target/linux/ar71xx/files/drivers/leds/leds-nu801.c > new file mode 100644 > index 000..0dfc015 > --- /dev/null > +++ b/target/linux/ar71xx/files/drivers/leds/leds-nu801.c > @@ -0,0 +1,396 @@ > +/* > + * LED driver for NU801 > + * > + * Kevin Paul Herbert > + * Copyright (c) 2012, Meraki, Inc. > + * > + * 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. > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#define MAX_NAME_LENGTH 24 > +#define NUM_COLORS 3 > + > +static const char * const led_nu801_colors[] = { "blue", "green", "red" }; > + > +struct led_nu801_led_data { > + struct led_classdev cdev; > + struct led_nu801_data *controller; > + enum led_brightness level; > + char name[MAX_NAME_LENGTH]; > +}; > + > +struct led_nu801_data { > + unsigned cki; > + unsigned sdi; > + int lei; > + struct delayed_work work; > + struct led_nu801_led_data *led_chain; > + int num_leds; > + const char *device_name; > + const char *name; > + u32 ndelay; > + atomic_t pending; > +}; > + > +static void led_nu801_work(struct work_struct *work) > +{ > + struct led_nu801_data *controller = > + container_of(work, struct led_nu801_data, work.work); > + struct led_nu801_led_data *led; > + u16 bit; > + u16 brightness; > + int index; > + > + for (index = 0; index < controller->num_leds; index++) { > + led = &controller->led_chain[index]; > + brightness = led->level << 8; /* To do: gamma correction */ > + for (bit = 0x8000; bit; bit = bit >> 1) { > + gpio_set_value(controller->sdi, > +(brightness & bit) != 0); > + gpio_set_value(controller->cki, 1); > + if (unlikely(((index == (controller->num_leds - 1)) && > + (bit == 1) && > + (controller->lei < 0 { > + udelay(600); > + } else { > + ndelay(controller->ndelay); > + } > + gpio_set_value(controller->cki, 0); > + ndelay(controller->ndelay); > + } > + } > + if (controller->lei >= 0) { > + gpio_set_value(controller->lei, 1); > + ndelay(controller->ndelay); > + gpio_set_value(controller->lei, 0); > + } > + atomic_set(&controller->pending, 1); > +} > + > +static void led_nu801_set(struct led_classdev *led_cdev, > + enum led_brightness value) > +{ > + struct led_nu801_led_data *led_dat = > + container_of(led_cdev, struct led_nu801_led_data, cdev); > + struct led_nu801_data *controller = led_dat->controller; > + > + if (led_dat->level != value) { > + led_dat->level = value; > + if (atomic_dec_and_test(&controller->pending)) > + s
[OpenWrt-Devel] [PATCH v5 4/5] ar71xx: add LED driver NU801
From: Chris R Blake The MR18 uses a 3-channel 16-bit PWM Constant Current Driver for its status LED. Signed-off-by: Chris R Blake --- package/base-files/files/etc/init.d/led| 2 +- .../linux/ar71xx/files/drivers/leds/leds-nu801.c | 396 + .../linux/ar71xx/files/include/linux/leds-nu801.h | 38 ++ target/linux/ar71xx/modules.mk | 16 + .../818-MIPS-ath79-add-nu801-led-driver.patch | 26 ++ 5 files changed, 477 insertions(+), 1 deletion(-) create mode 100644 target/linux/ar71xx/files/drivers/leds/leds-nu801.c create mode 100644 target/linux/ar71xx/files/include/linux/leds-nu801.h create mode 100644 target/linux/ar71xx/patches-4.1/818-MIPS-ath79-add-nu801-led-driver.patch diff --git a/package/base-files/files/etc/init.d/led b/package/base-files/files/etc/init.d/led index 3f45732..84cd028 100755 --- a/package/base-files/files/etc/init.d/led +++ b/package/base-files/files/etc/init.d/led @@ -44,7 +44,7 @@ load_led() { ret="$?" [ $default = 1 ] && - echo 1 >/sys/class/leds/${sysfs}/brightness + cat /sys/class/leds/${sysfs}/max_brightness > /sys/class/leds/${sysfs}/brightness [ $ret = 0 ] || { echo >&2 "Skipping trigger '$trigger' for led '$name' due to missing kernel module" diff --git a/target/linux/ar71xx/files/drivers/leds/leds-nu801.c b/target/linux/ar71xx/files/drivers/leds/leds-nu801.c new file mode 100644 index 000..0dfc015 --- /dev/null +++ b/target/linux/ar71xx/files/drivers/leds/leds-nu801.c @@ -0,0 +1,396 @@ +/* + * LED driver for NU801 + * + * Kevin Paul Herbert + * Copyright (c) 2012, Meraki, Inc. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MAX_NAME_LENGTH 24 +#define NUM_COLORS 3 + +static const char * const led_nu801_colors[] = { "blue", "green", "red" }; + +struct led_nu801_led_data { + struct led_classdev cdev; + struct led_nu801_data *controller; + enum led_brightness level; + char name[MAX_NAME_LENGTH]; +}; + +struct led_nu801_data { + unsigned cki; + unsigned sdi; + int lei; + struct delayed_work work; + struct led_nu801_led_data *led_chain; + int num_leds; + const char *device_name; + const char *name; + u32 ndelay; + atomic_t pending; +}; + +static void led_nu801_work(struct work_struct *work) +{ + struct led_nu801_data *controller = + container_of(work, struct led_nu801_data, work.work); + struct led_nu801_led_data *led; + u16 bit; + u16 brightness; + int index; + + for (index = 0; index < controller->num_leds; index++) { + led = &controller->led_chain[index]; + brightness = led->level << 8; /* To do: gamma correction */ + for (bit = 0x8000; bit; bit = bit >> 1) { + gpio_set_value(controller->sdi, + (brightness & bit) != 0); + gpio_set_value(controller->cki, 1); + if (unlikely(((index == (controller->num_leds - 1)) && + (bit == 1) && + (controller->lei < 0 { + udelay(600); + } else { + ndelay(controller->ndelay); + } + gpio_set_value(controller->cki, 0); + ndelay(controller->ndelay); + } + } + if (controller->lei >= 0) { + gpio_set_value(controller->lei, 1); + ndelay(controller->ndelay); + gpio_set_value(controller->lei, 0); + } + atomic_set(&controller->pending, 1); +} + +static void led_nu801_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct led_nu801_led_data *led_dat = + container_of(led_cdev, struct led_nu801_led_data, cdev); + struct led_nu801_data *controller = led_dat->controller; + + if (led_dat->level != value) { + led_dat->level = value; + if (atomic_dec_and_test(&controller->pending)) + schedule_delayed_work(&led_dat->controller->work, + (HZ/1000) + 1); + } +} + +static int __init led_nu801_create(struct led_nu801_data *controller, + struct device *parent, + int index, + enum led_brightness brightness, +#ifdef CONFIG_LEDS_TRIGGERS +