X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Framips%2Fpatches-3.14%2F0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch;fp=target%2Flinux%2Framips%2Fpatches-3.14%2F0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch;h=0000000000000000000000000000000000000000;hb=2413805bdd4cb72df1e3217ab08f4b68bbd20795;hp=d81a5ddc39612ae8ac53570636c315cb68045740;hpb=2a817de16d411bfab19db2e7d0f888dd57b7829c;p=openwrt.git diff --git a/target/linux/ramips/patches-3.14/0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch b/target/linux/ramips/patches-3.14/0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch deleted file mode 100644 index d81a5ddc39..0000000000 --- a/target/linux/ramips/patches-3.14/0019-MIPS-ralink-add-pseudo-pwm-led-trigger-based-on-time.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 9de00286e20a5f5edc419698373010f1cb6ff0ce Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 27 Jul 2014 09:25:02 +0100 -Subject: [PATCH 19/57] MIPS: ralink: add pseudo pwm led trigger based on - timer0 - -Signed-off-by: John Crispin ---- - arch/mips/ralink/timer.c | 213 ++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 197 insertions(+), 16 deletions(-) - ---- a/arch/mips/ralink/timer.c -+++ b/arch/mips/ralink/timer.c -@@ -12,6 +12,8 @@ - #include - #include - #include -+#include -+#include - - #include - -@@ -23,16 +25,34 @@ - - #define TMR0CTL_ENABLE BIT(7) - #define TMR0CTL_MODE_PERIODIC BIT(4) --#define TMR0CTL_PRESCALER 1 -+#define TMR0CTL_PRESCALER 2 - #define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER) - #define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER)) - -+struct rt_timer_gpio { -+ struct list_head list; -+ struct led_classdev *led; -+}; -+ - struct rt_timer { -- struct device *dev; -- void __iomem *membase; -- int irq; -- unsigned long timer_freq; -- unsigned long timer_div; -+ struct device *dev; -+ void __iomem *membase; -+ int irq; -+ -+ unsigned long timer_freq; -+ unsigned long timer_div; -+ -+ struct list_head gpios; -+ struct led_trigger led_trigger; -+ unsigned int duty_cycle; -+ unsigned int duty; -+ -+ unsigned int fade; -+ unsigned int fade_min; -+ unsigned int fade_max; -+ unsigned int fade_speed; -+ unsigned int fade_dir; -+ unsigned int fade_count; - }; - - static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val) -@@ -48,18 +68,46 @@ static inline u32 rt_timer_r32(struct rt - static irqreturn_t rt_timer_irq(int irq, void *_rt) - { - struct rt_timer *rt = (struct rt_timer *) _rt; -+ struct rt_timer_gpio *gpio; -+ unsigned int val; - -- rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); -+ if (rt->fade && (rt->fade_count++ > rt->fade_speed)) { -+ rt->fade_count = 0; -+ if (rt->duty_cycle <= rt->fade_min) -+ rt->fade_dir = 1; -+ else if (rt->duty_cycle >= rt->fade_max) -+ rt->fade_dir = 0; -+ -+ if (rt->fade_dir) -+ rt->duty_cycle += 1; -+ else -+ rt->duty_cycle -= 1; -+ -+ } -+ -+ val = rt->timer_freq / rt->timer_div; -+ if (rt->duty) -+ val *= rt->duty_cycle; -+ else -+ val *= (100 - rt->duty_cycle); -+ val /= 100; -+ -+ if (!list_empty(&rt->gpios)) -+ list_for_each_entry(gpio, &rt->gpios, list) -+ led_set_brightness(gpio->led, !!rt->duty); -+ -+ rt->duty = !rt->duty; -+ -+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, val + 1); - rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT); - - return IRQ_HANDLED; - } - -- - static int rt_timer_request(struct rt_timer *rt) - { -- int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED, -- dev_name(rt->dev), rt); -+ int err = devm_request_irq(rt->dev, rt->irq, rt_timer_irq, -+ IRQF_DISABLED, dev_name(rt->dev), rt); - if (err) { - dev_err(rt->dev, "failed to request irq\n"); - } else { -@@ -81,8 +129,6 @@ static int rt_timer_config(struct rt_tim - else - rt->timer_div = divisor; - -- rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div); -- - return 0; - } - -@@ -108,11 +154,128 @@ static void rt_timer_disable(struct rt_t - rt_timer_w32(rt, TIMER_REG_TMR0CTL, t); - } - -+static ssize_t led_fade_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); -+ -+ return sprintf(buf, "speed: %d, min: %d, max: %d\n", rt->fade_speed, rt->fade_min, rt->fade_max); -+} -+ -+static ssize_t led_fade_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t size) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); -+ unsigned int speed = 0, min = 0, max = 0; -+ ssize_t ret = -EINVAL; -+ -+ ret = sscanf(buf, "%u %u %u", &speed, &min, &max); -+ -+ if (ret == 3) { -+ rt->fade_speed = speed; -+ rt->fade_min = min; -+ rt->fade_max = max; -+ rt->fade = 1; -+ } else { -+ rt->fade = 0; -+ } -+ -+ return size; -+} -+ -+static DEVICE_ATTR(fade, 0644, led_fade_show, led_fade_store); -+ -+static ssize_t led_duty_cycle_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); -+ -+ return sprintf(buf, "%u\n", rt->duty_cycle); -+} -+ -+static ssize_t led_duty_cycle_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t size) -+{ -+ struct led_classdev *led_cdev = dev_get_drvdata(dev); -+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); -+ unsigned long state; -+ ssize_t ret = -EINVAL; -+ -+ ret = kstrtoul(buf, 10, &state); -+ if (ret) -+ return ret; -+ -+ if (state <= 100) -+ rt->duty_cycle = state; -+ else -+ rt->duty_cycle = 100; -+ -+ rt->fade = 0; -+ -+ return size; -+} -+ -+static DEVICE_ATTR(duty_cycle, 0644, led_duty_cycle_show, led_duty_cycle_store); -+ -+static void rt_timer_trig_activate(struct led_classdev *led_cdev) -+{ -+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); -+ struct rt_timer_gpio *gpio_data; -+ int rc; -+ -+ led_cdev->trigger_data = NULL; -+ gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL); -+ if (!gpio_data) -+ return; -+ -+ rc = device_create_file(led_cdev->dev, &dev_attr_duty_cycle); -+ if (rc) -+ goto err_gpio; -+ rc = device_create_file(led_cdev->dev, &dev_attr_fade); -+ if (rc) -+ goto err_out_duty_cycle; -+ -+ led_cdev->activated = true; -+ led_cdev->trigger_data = gpio_data; -+ gpio_data->led = led_cdev; -+ list_add(&gpio_data->list, &rt->gpios); -+ led_cdev->trigger_data = gpio_data; -+ rt_timer_enable(rt); -+ return; -+ -+err_out_duty_cycle: -+ device_remove_file(led_cdev->dev, &dev_attr_duty_cycle); -+ -+err_gpio: -+ kfree(gpio_data); -+} -+ -+static void rt_timer_trig_deactivate(struct led_classdev *led_cdev) -+{ -+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); -+ struct rt_timer_gpio *gpio_data = (struct rt_timer_gpio*) led_cdev->trigger_data; -+ -+ if (led_cdev->activated) { -+ device_remove_file(led_cdev->dev, &dev_attr_duty_cycle); -+ device_remove_file(led_cdev->dev, &dev_attr_fade); -+ led_cdev->activated = false; -+ } -+ -+ list_del(&gpio_data->list); -+ rt_timer_disable(rt); -+ led_set_brightness(led_cdev, LED_OFF); -+} -+ - static int rt_timer_probe(struct platform_device *pdev) - { - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ const __be32 *divisor; - struct rt_timer *rt; - struct clk *clk; -+ int ret; - - rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL); - if (!rt) { -@@ -140,12 +303,29 @@ static int rt_timer_probe(struct platfor - if (!rt->timer_freq) - return -EINVAL; - -+ rt->duty_cycle = 100; - rt->dev = &pdev->dev; - platform_set_drvdata(pdev, rt); - -- rt_timer_request(rt); -- rt_timer_config(rt, 2); -- rt_timer_enable(rt); -+ ret = rt_timer_request(rt); -+ if (ret) -+ return ret; -+ -+ divisor = of_get_property(pdev->dev.of_node, "ralink,divisor", NULL); -+ if (divisor) -+ rt_timer_config(rt, be32_to_cpu(*divisor)); -+ else -+ rt_timer_config(rt, 200); -+ -+ rt->led_trigger.name = "pwmtimer", -+ rt->led_trigger.activate = rt_timer_trig_activate, -+ rt->led_trigger.deactivate = rt_timer_trig_deactivate, -+ -+ ret = led_trigger_register(&rt->led_trigger); -+ if (ret) -+ return ret; -+ -+ INIT_LIST_HEAD(&rt->gpios); - - dev_info(&pdev->dev, "maximum frequency is %luHz\n", rt->timer_freq); - -@@ -156,6 +336,7 @@ static int rt_timer_remove(struct platfo - { - struct rt_timer *rt = platform_get_drvdata(pdev); - -+ led_trigger_unregister(&rt->led_trigger); - rt_timer_disable(rt); - rt_timer_free(rt); - -@@ -180,6 +361,6 @@ static struct platform_driver rt_timer_d - - module_platform_driver(rt_timer_driver); - --MODULE_DESCRIPTION("Ralink RT2880 timer"); -+MODULE_DESCRIPTION("Ralink RT2880 timer / pseudo pwm"); - MODULE_AUTHOR("John Crispin