Root/target/linux/adm5120/files/drivers/leds/ledtrig-adm5120-switch.c

1/*
2 * LED ADM5120 Switch Port State Trigger
3 *
4 * Copyright (C) 2007 Bernhard Held <bernhard at bernhardheld.de>
5 * Copyright (C) 2007-2008 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * This file was based on: drivers/leds/ledtrig-timer.c
8 * Copyright 2005-2006 Openedhand Ltd.
9 * Author: Richard Purdie
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/device.h>
21
22#include <linux/gpio.h>
23
24#include "leds.h"
25
26#define DRV_NAME "port_state"
27#define DRV_DESC "LED ADM5120 Switch Port State Trigger"
28
29struct port_state {
30    char *name;
31    unsigned int value;
32};
33
34#define PORT_STATE(n,v) {.name = (n), .value = (v)}
35
36static struct port_state port_states[] = {
37    PORT_STATE("off", LED_OFF),
38    PORT_STATE("on", LED_FULL),
39    PORT_STATE("flash", ADM5120_GPIO_FLASH),
40    PORT_STATE("link", ADM5120_GPIO_LINK),
41    PORT_STATE("speed", ADM5120_GPIO_SPEED),
42    PORT_STATE("duplex", ADM5120_GPIO_DUPLEX),
43    PORT_STATE("act", ADM5120_GPIO_ACT),
44    PORT_STATE("coll", ADM5120_GPIO_COLL),
45    PORT_STATE("link_act", ADM5120_GPIO_LINK_ACT),
46    PORT_STATE("duplex_coll", ADM5120_GPIO_DUPLEX_COLL),
47    PORT_STATE("10M_act", ADM5120_GPIO_10M_ACT),
48    PORT_STATE("100M_act", ADM5120_GPIO_100M_ACT),
49};
50
51static ssize_t led_port_state_show(struct device *dev,
52        struct device_attribute *attr, char *buf)
53{
54    struct led_classdev *led_cdev = dev_get_drvdata(dev);
55    struct port_state *state = led_cdev->trigger_data;
56    int len = 0;
57    int i;
58
59    *buf = '\0';
60    for (i = 0; i < ARRAY_SIZE(port_states); i++) {
61        if (&port_states[i] == state)
62            len += sprintf(buf+len, "[%s] ", port_states[i].name);
63        else
64            len += sprintf(buf+len, "%s ", port_states[i].name);
65    }
66    len += sprintf(buf+len, "\n");
67
68    return len;
69}
70
71static ssize_t led_port_state_store(struct device *dev,
72        struct device_attribute *attr, const char *buf, size_t size)
73{
74    struct led_classdev *led_cdev = dev_get_drvdata(dev);
75    size_t len;
76    int i;
77
78    for (i = 0; i < ARRAY_SIZE(port_states); i++) {
79        len = strlen(port_states[i].name);
80        if (strncmp(port_states[i].name, buf, len) != 0)
81            continue;
82
83        if (buf[len] != '\0' && buf[len] != '\n')
84            continue;
85
86        led_cdev->trigger_data = &port_states[i];
87        led_set_brightness(led_cdev, port_states[i].value);
88        return size;
89    }
90
91    return -EINVAL;
92}
93
94static DEVICE_ATTR(port_state, 0644, led_port_state_show,
95             led_port_state_store);
96
97static void adm5120_switch_trig_activate(struct led_classdev *led_cdev)
98{
99    struct port_state *state = port_states;
100    int rc;
101
102    led_cdev->trigger_data = state;
103
104    rc = device_create_file(led_cdev->dev, &dev_attr_port_state);
105    if (rc)
106        goto err;
107
108    led_set_brightness(led_cdev, state->value);
109
110    return;
111err:
112    led_cdev->trigger_data = NULL;
113}
114
115static void adm5120_switch_trig_deactivate(struct led_classdev *led_cdev)
116{
117    struct port_state *state = led_cdev->trigger_data;
118
119    if (!state)
120        return;
121
122    device_remove_file(led_cdev->dev, &dev_attr_port_state);
123
124}
125
126static struct led_trigger adm5120_switch_led_trigger = {
127    .name = DRV_NAME,
128    .activate = adm5120_switch_trig_activate,
129    .deactivate = adm5120_switch_trig_deactivate,
130};
131
132static int __init adm5120_switch_trig_init(void)
133{
134    led_trigger_register(&adm5120_switch_led_trigger);
135    return 0;
136}
137
138static void __exit adm5120_switch_trig_exit(void)
139{
140    led_trigger_unregister(&adm5120_switch_led_trigger);
141}
142
143module_init(adm5120_switch_trig_init);
144module_exit(adm5120_switch_trig_exit);
145
146MODULE_AUTHOR("Bernhard Held <bernhard at bernhardheld.de>, "
147        "Gabor Juhos <juhosg@openwrt.org>");
148MODULE_DESCRIPTION(DRV_DESC);
149MODULE_LICENSE("GPL v2");
150

Archive Download this file



interactive