diff options
| -rw-r--r-- | drivers/leds/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/leds/Makefile | 1 | ||||
| -rw-r--r-- | drivers/leds/leds-clevo-mail.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-cobalt-qube.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-cobalt-raq.c | 4 | ||||
| -rw-r--r-- | drivers/leds/leds-gpio.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-pca9532.c | 12 | ||||
| -rw-r--r-- | drivers/leds/leds-wm831x-status.c | 341 | ||||
| -rw-r--r-- | drivers/leds/ledtrig-gpio.c | 32 | ||||
| -rw-r--r-- | drivers/macintosh/via-pmu-led.c | 2 | ||||
| -rw-r--r-- | include/linux/mfd/wm831x/status.h | 34 |
11 files changed, 414 insertions, 31 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 7c8e7122aaa9..e4f599f20e38 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
| @@ -150,9 +150,9 @@ config LEDS_LP3944 | |||
| 150 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" | 150 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" |
| 151 | depends on LEDS_CLASS && I2C | 151 | depends on LEDS_CLASS && I2C |
| 152 | help | 152 | help |
| 153 | This option enables support for LEDs connected to the National | 153 | This option enables support for LEDs connected to the National |
| 154 | Semiconductor LP3944 Lighting Management Unit (LMU) also known as | 154 | Semiconductor LP3944 Lighting Management Unit (LMU) also known as |
| 155 | Fun Light Chip. | 155 | Fun Light Chip. |
| 156 | 156 | ||
| 157 | To compile this driver as a module, choose M here: the | 157 | To compile this driver as a module, choose M here: the |
| 158 | module will be called leds-lp3944. | 158 | module will be called leds-lp3944. |
| @@ -195,6 +195,13 @@ config LEDS_PCA955X | |||
| 195 | LED driver chips accessed via the I2C bus. Supported | 195 | LED driver chips accessed via the I2C bus. Supported |
| 196 | devices include PCA9550, PCA9551, PCA9552, and PCA9553. | 196 | devices include PCA9550, PCA9551, PCA9552, and PCA9553. |
| 197 | 197 | ||
| 198 | config LEDS_WM831X_STATUS | ||
| 199 | tristate "LED support for status LEDs on WM831x PMICs" | ||
| 200 | depends on LEDS_CLASS && MFD_WM831X | ||
| 201 | help | ||
| 202 | This option enables support for the status LEDs of the WM831x | ||
| 203 | series of PMICs. | ||
| 204 | |||
| 198 | config LEDS_WM8350 | 205 | config LEDS_WM8350 |
| 199 | tristate "LED Support for WM8350 AudioPlus PMIC" | 206 | tristate "LED Support for WM8350 AudioPlus PMIC" |
| 200 | depends on LEDS_CLASS && MFD_WM8350 | 207 | depends on LEDS_CLASS && MFD_WM8350 |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index e8cdcf77a4c3..46d72704d606 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
| @@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o | |||
| 26 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o | 26 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o |
| 27 | obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o | 27 | obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o |
| 28 | obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o | 28 | obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o |
| 29 | obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o | ||
| 29 | obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o | 30 | obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o |
| 30 | obj-$(CONFIG_LEDS_PWM) += leds-pwm.o | 31 | obj-$(CONFIG_LEDS_PWM) += leds-pwm.o |
| 31 | 32 | ||
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index f2242db54016..a498135a4e80 100644 --- a/drivers/leds/leds-clevo-mail.c +++ b/drivers/leds/leds-clevo-mail.c | |||
| @@ -153,7 +153,7 @@ static struct led_classdev clevo_mail_led = { | |||
| 153 | .flags = LED_CORE_SUSPENDRESUME, | 153 | .flags = LED_CORE_SUSPENDRESUME, |
| 154 | }; | 154 | }; |
| 155 | 155 | ||
| 156 | static int __init clevo_mail_led_probe(struct platform_device *pdev) | 156 | static int __devinit clevo_mail_led_probe(struct platform_device *pdev) |
| 157 | { | 157 | { |
| 158 | return led_classdev_register(&pdev->dev, &clevo_mail_led); | 158 | return led_classdev_register(&pdev->dev, &clevo_mail_led); |
| 159 | } | 159 | } |
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c index 059aa2924b1c..8816806accd2 100644 --- a/drivers/leds/leds-cobalt-qube.c +++ b/drivers/leds/leds-cobalt-qube.c | |||
| @@ -28,7 +28,7 @@ static void qube_front_led_set(struct led_classdev *led_cdev, | |||
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | static struct led_classdev qube_front_led = { | 30 | static struct led_classdev qube_front_led = { |
| 31 | .name = "qube-front", | 31 | .name = "qube::front", |
| 32 | .brightness = LED_FULL, | 32 | .brightness = LED_FULL, |
| 33 | .brightness_set = qube_front_led_set, | 33 | .brightness_set = qube_front_led_set, |
| 34 | .default_trigger = "ide-disk", | 34 | .default_trigger = "ide-disk", |
diff --git a/drivers/leds/leds-cobalt-raq.c b/drivers/leds/leds-cobalt-raq.c index 5f1ce810815f..defc212105f3 100644 --- a/drivers/leds/leds-cobalt-raq.c +++ b/drivers/leds/leds-cobalt-raq.c | |||
| @@ -49,7 +49,7 @@ static void raq_web_led_set(struct led_classdev *led_cdev, | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | static struct led_classdev raq_web_led = { | 51 | static struct led_classdev raq_web_led = { |
| 52 | .name = "raq-web", | 52 | .name = "raq::web", |
| 53 | .brightness_set = raq_web_led_set, | 53 | .brightness_set = raq_web_led_set, |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| @@ -70,7 +70,7 @@ static void raq_power_off_led_set(struct led_classdev *led_cdev, | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static struct led_classdev raq_power_off_led = { | 72 | static struct led_classdev raq_power_off_led = { |
| 73 | .name = "raq-power-off", | 73 | .name = "raq::power-off", |
| 74 | .brightness_set = raq_power_off_led_set, | 74 | .brightness_set = raq_power_off_led_set, |
| 75 | .default_trigger = "power-off", | 75 | .default_trigger = "power-off", |
| 76 | }; | 76 | }; |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 6b06638eb5b4..7467980b8cf9 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
| @@ -80,7 +80,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
| 80 | 80 | ||
| 81 | /* skip leds that aren't available */ | 81 | /* skip leds that aren't available */ |
| 82 | if (!gpio_is_valid(template->gpio)) { | 82 | if (!gpio_is_valid(template->gpio)) { |
| 83 | printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", | 83 | printk(KERN_INFO "Skipping unavailable LED gpio %d (%s)\n", |
| 84 | template->gpio, template->name); | 84 | template->gpio, template->name); |
| 85 | return 0; | 85 | return 0; |
| 86 | } | 86 | } |
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index dba8921240f2..708a8017c21d 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
| @@ -34,7 +34,7 @@ struct pca9532_data { | |||
| 34 | struct i2c_client *client; | 34 | struct i2c_client *client; |
| 35 | struct pca9532_led leds[16]; | 35 | struct pca9532_led leds[16]; |
| 36 | struct mutex update_lock; | 36 | struct mutex update_lock; |
| 37 | struct input_dev *idev; | 37 | struct input_dev *idev; |
| 38 | struct work_struct work; | 38 | struct work_struct work; |
| 39 | u8 pwm[2]; | 39 | u8 pwm[2]; |
| 40 | u8 psc[2]; | 40 | u8 psc[2]; |
| @@ -53,9 +53,9 @@ MODULE_DEVICE_TABLE(i2c, pca9532_id); | |||
| 53 | 53 | ||
| 54 | static struct i2c_driver pca9532_driver = { | 54 | static struct i2c_driver pca9532_driver = { |
| 55 | .driver = { | 55 | .driver = { |
| 56 | .name = "pca9532", | 56 | .name = "pca9532", |
| 57 | }, | 57 | }, |
| 58 | .probe = pca9532_probe, | 58 | .probe = pca9532_probe, |
| 59 | .remove = pca9532_remove, | 59 | .remove = pca9532_remove, |
| 60 | .id_table = pca9532_id, | 60 | .id_table = pca9532_id, |
| 61 | }; | 61 | }; |
| @@ -149,7 +149,7 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, | |||
| 149 | 149 | ||
| 150 | if (*delay_on == 0 && *delay_off == 0) { | 150 | if (*delay_on == 0 && *delay_off == 0) { |
| 151 | /* led subsystem ask us for a blink rate */ | 151 | /* led subsystem ask us for a blink rate */ |
| 152 | *delay_on = 1000; | 152 | *delay_on = 1000; |
| 153 | *delay_off = 1000; | 153 | *delay_off = 1000; |
| 154 | } | 154 | } |
| 155 | if (*delay_on != *delay_off || *delay_on > 1690 || *delay_on < 6) | 155 | if (*delay_on != *delay_off || *delay_on > 1690 || *delay_on < 6) |
| @@ -227,7 +227,7 @@ static int pca9532_configure(struct i2c_client *client, | |||
| 227 | break; | 227 | break; |
| 228 | case PCA9532_TYPE_LED: | 228 | case PCA9532_TYPE_LED: |
| 229 | led->state = pled->state; | 229 | led->state = pled->state; |
| 230 | led->name = pled->name; | 230 | led->name = pled->name; |
| 231 | led->ldev.name = led->name; | 231 | led->ldev.name = led->name; |
| 232 | led->ldev.brightness = LED_OFF; | 232 | led->ldev.brightness = LED_OFF; |
| 233 | led->ldev.brightness_set = pca9532_set_brightness; | 233 | led->ldev.brightness_set = pca9532_set_brightness; |
| @@ -254,7 +254,7 @@ static int pca9532_configure(struct i2c_client *client, | |||
| 254 | data->idev->name = pled->name; | 254 | data->idev->name = pled->name; |
| 255 | data->idev->phys = "i2c/pca9532"; | 255 | data->idev->phys = "i2c/pca9532"; |
| 256 | data->idev->id.bustype = BUS_HOST; | 256 | data->idev->id.bustype = BUS_HOST; |
| 257 | data->idev->id.vendor = 0x001f; | 257 | data->idev->id.vendor = 0x001f; |
| 258 | data->idev->id.product = 0x0001; | 258 | data->idev->id.product = 0x0001; |
| 259 | data->idev->id.version = 0x0100; | 259 | data->idev->id.version = 0x0100; |
| 260 | data->idev->evbit[0] = BIT_MASK(EV_SND); | 260 | data->idev->evbit[0] = BIT_MASK(EV_SND); |
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c new file mode 100644 index 000000000000..c586d05e336a --- /dev/null +++ b/drivers/leds/leds-wm831x-status.c | |||
| @@ -0,0 +1,341 @@ | |||
| 1 | /* | ||
| 2 | * LED driver for WM831x status LEDs | ||
| 3 | * | ||
| 4 | * Copyright(C) 2009 Wolfson Microelectronics PLC. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/leds.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/mfd/wm831x/core.h> | ||
| 18 | #include <linux/mfd/wm831x/pdata.h> | ||
| 19 | #include <linux/mfd/wm831x/status.h> | ||
| 20 | |||
| 21 | |||
| 22 | struct wm831x_status { | ||
| 23 | struct led_classdev cdev; | ||
| 24 | struct wm831x *wm831x; | ||
| 25 | struct work_struct work; | ||
| 26 | struct mutex mutex; | ||
| 27 | |||
| 28 | spinlock_t value_lock; | ||
| 29 | int reg; /* Control register */ | ||
| 30 | int reg_val; /* Control register value */ | ||
| 31 | |||
| 32 | int blink; | ||
| 33 | int blink_time; | ||
| 34 | int blink_cyc; | ||
| 35 | int src; | ||
| 36 | enum led_brightness brightness; | ||
| 37 | }; | ||
| 38 | |||
| 39 | #define to_wm831x_status(led_cdev) \ | ||
| 40 | container_of(led_cdev, struct wm831x_status, cdev) | ||
| 41 | |||
| 42 | static void wm831x_status_work(struct work_struct *work) | ||
| 43 | { | ||
| 44 | struct wm831x_status *led = container_of(work, struct wm831x_status, | ||
| 45 | work); | ||
| 46 | unsigned long flags; | ||
| 47 | |||
| 48 | mutex_lock(&led->mutex); | ||
| 49 | |||
| 50 | led->reg_val &= ~(WM831X_LED_SRC_MASK | WM831X_LED_MODE_MASK | | ||
| 51 | WM831X_LED_DUTY_CYC_MASK | WM831X_LED_DUR_MASK); | ||
| 52 | |||
| 53 | spin_lock_irqsave(&led->value_lock, flags); | ||
| 54 | |||
| 55 | led->reg_val |= led->src << WM831X_LED_SRC_SHIFT; | ||
| 56 | if (led->blink) { | ||
| 57 | led->reg_val |= 2 << WM831X_LED_MODE_SHIFT; | ||
| 58 | led->reg_val |= led->blink_time << WM831X_LED_DUR_SHIFT; | ||
| 59 | led->reg_val |= led->blink_cyc; | ||
| 60 | } else { | ||
| 61 | if (led->brightness != LED_OFF) | ||
| 62 | led->reg_val |= 1 << WM831X_LED_MODE_SHIFT; | ||
| 63 | } | ||
| 64 | |||
| 65 | spin_unlock_irqrestore(&led->value_lock, flags); | ||
| 66 | |||
| 67 | wm831x_reg_write(led->wm831x, led->reg, led->reg_val); | ||
| 68 | |||
| 69 | mutex_unlock(&led->mutex); | ||
| 70 | } | ||
| 71 | |||
| 72 | static void wm831x_status_set(struct led_classdev *led_cdev, | ||
| 73 | enum led_brightness value) | ||
| 74 | { | ||
| 75 | struct wm831x_status *led = to_wm831x_status(led_cdev); | ||
| 76 | unsigned long flags; | ||
| 77 | |||
| 78 | spin_lock_irqsave(&led->value_lock, flags); | ||
| 79 | led->brightness = value; | ||
| 80 | if (value == LED_OFF) | ||
| 81 | led->blink = 0; | ||
| 82 | schedule_work(&led->work); | ||
| 83 | spin_unlock_irqrestore(&led->value_lock, flags); | ||
| 84 | } | ||
| 85 | |||
| 86 | static int wm831x_status_blink_set(struct led_classdev *led_cdev, | ||
| 87 | unsigned long *delay_on, | ||
| 88 | unsigned long *delay_off) | ||
| 89 | { | ||
| 90 | struct wm831x_status *led = to_wm831x_status(led_cdev); | ||
| 91 | unsigned long flags; | ||
| 92 | int ret = 0; | ||
| 93 | |||
| 94 | /* Pick some defaults if we've not been given times */ | ||
| 95 | if (*delay_on == 0 && *delay_off == 0) { | ||
| 96 | *delay_on = 250; | ||
| 97 | *delay_off = 250; | ||
| 98 | } | ||
| 99 | |||
| 100 | spin_lock_irqsave(&led->value_lock, flags); | ||
| 101 | |||
| 102 | /* We only have a limited selection of settings, see if we can | ||
| 103 | * support the configuration we're being given */ | ||
| 104 | switch (*delay_on) { | ||
| 105 | case 1000: | ||
| 106 | led->blink_time = 0; | ||
| 107 | break; | ||
| 108 | case 250: | ||
| 109 | led->blink_time = 1; | ||
| 110 | break; | ||
| 111 | case 125: | ||
| 112 | led->blink_time = 2; | ||
| 113 | break; | ||
| 114 | case 62: | ||
| 115 | case 63: | ||
| 116 | /* Actually 62.5ms */ | ||
| 117 | led->blink_time = 3; | ||
| 118 | break; | ||
| 119 | default: | ||
| 120 | ret = -EINVAL; | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (ret == 0) { | ||
| 125 | switch (*delay_off / *delay_on) { | ||
| 126 | case 1: | ||
| 127 | led->blink_cyc = 0; | ||
| 128 | break; | ||
| 129 | case 3: | ||
| 130 | led->blink_cyc = 1; | ||
| 131 | break; | ||
| 132 | case 4: | ||
| 133 | led->blink_cyc = 2; | ||
| 134 | break; | ||
| 135 | case 8: | ||
| 136 | led->blink_cyc = 3; | ||
| 137 | break; | ||
| 138 | default: | ||
| 139 | ret = -EINVAL; | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | if (ret == 0) | ||
| 145 | led->blink = 1; | ||
| 146 | else | ||
| 147 | led->blink = 0; | ||
| 148 | |||
| 149 | /* Always update; if we fail turn off blinking since we expect | ||
| 150 | * a software fallback. */ | ||
| 151 | schedule_work(&led->work); | ||
| 152 | |||
| 153 | spin_unlock_irqrestore(&led->value_lock, flags); | ||
| 154 | |||
| 155 | return ret; | ||
| 156 | } | ||
| 157 | |||
| 158 | static const char *led_src_texts[] = { | ||
| 159 | "otp", | ||
| 160 | "power", | ||
| 161 | "charger", | ||
| 162 | "soft", | ||
| 163 | }; | ||
| 164 | |||
| 165 | static ssize_t wm831x_status_src_show(struct device *dev, | ||
| 166 | struct device_attribute *attr, char *buf) | ||
| 167 | { | ||
| 168 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
| 169 | struct wm831x_status *led = to_wm831x_status(led_cdev); | ||
| 170 | int i; | ||
| 171 | ssize_t ret = 0; | ||
| 172 | |||
| 173 | mutex_lock(&led->mutex); | ||
| 174 | |||
| 175 | for (i = 0; i < ARRAY_SIZE(led_src_texts); i++) | ||
| 176 | if (i == led->src) | ||
| 177 | ret += sprintf(&buf[ret], "[%s] ", led_src_texts[i]); | ||
| 178 | else | ||
| 179 | ret += sprintf(&buf[ret], "%s ", led_src_texts[i]); | ||
| 180 | |||
| 181 | mutex_unlock(&led->mutex); | ||
| 182 | |||
| 183 | ret += sprintf(&buf[ret], "\n"); | ||
| 184 | |||
| 185 | return ret; | ||
| 186 | } | ||
| 187 | |||
| 188 | static ssize_t wm831x_status_src_store(struct device *dev, | ||
| 189 | struct device_attribute *attr, | ||
| 190 | const char *buf, size_t size) | ||
| 191 | { | ||
| 192 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
| 193 | struct wm831x_status *led = to_wm831x_status(led_cdev); | ||
| 194 | char name[20]; | ||
| 195 | int i; | ||
| 196 | size_t len; | ||
| 197 | |||
| 198 | name[sizeof(name) - 1] = '\0'; | ||
| 199 | strncpy(name, buf, sizeof(name) - 1); | ||
| 200 | len = strlen(name); | ||
| 201 | |||
| 202 | if (len && name[len - 1] == '\n') | ||
| 203 | name[len - 1] = '\0'; | ||
| 204 | |||
| 205 | for (i = 0; i < ARRAY_SIZE(led_src_texts); i++) { | ||
| 206 | if (!strcmp(name, led_src_texts[i])) { | ||
| 207 | mutex_lock(&led->mutex); | ||
| 208 | |||
| 209 | led->src = i; | ||
| 210 | schedule_work(&led->work); | ||
| 211 | |||
| 212 | mutex_unlock(&led->mutex); | ||
| 213 | } | ||
| 214 | } | ||
| 215 | |||
| 216 | return size; | ||
| 217 | } | ||
| 218 | |||
| 219 | static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store); | ||
| 220 | |||
| 221 | static int wm831x_status_probe(struct platform_device *pdev) | ||
| 222 | { | ||
| 223 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | ||
| 224 | struct wm831x_pdata *chip_pdata; | ||
| 225 | struct wm831x_status_pdata pdata; | ||
| 226 | struct wm831x_status *drvdata; | ||
| 227 | struct resource *res; | ||
| 228 | int id = pdev->id % ARRAY_SIZE(chip_pdata->status); | ||
| 229 | int ret; | ||
| 230 | |||
| 231 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
| 232 | if (res == NULL) { | ||
| 233 | dev_err(&pdev->dev, "No I/O resource\n"); | ||
| 234 | ret = -EINVAL; | ||
| 235 | goto err; | ||
| 236 | } | ||
| 237 | |||
| 238 | drvdata = kzalloc(sizeof(struct wm831x_status), GFP_KERNEL); | ||
| 239 | if (!drvdata) | ||
| 240 | return -ENOMEM; | ||
| 241 | dev_set_drvdata(&pdev->dev, drvdata); | ||
| 242 | |||
| 243 | drvdata->wm831x = wm831x; | ||
| 244 | drvdata->reg = res->start; | ||
| 245 | |||
| 246 | if (wm831x->dev->platform_data) | ||
| 247 | chip_pdata = wm831x->dev->platform_data; | ||
| 248 | else | ||
| 249 | chip_pdata = NULL; | ||
| 250 | |||
| 251 | memset(&pdata, 0, sizeof(pdata)); | ||
| 252 | if (chip_pdata && chip_pdata->status[id]) | ||
| 253 | memcpy(&pdata, chip_pdata->status[id], sizeof(pdata)); | ||
| 254 | else | ||
| 255 | pdata.name = dev_name(&pdev->dev); | ||
| 256 | |||
| 257 | mutex_init(&drvdata->mutex); | ||
| 258 | INIT_WORK(&drvdata->work, wm831x_status_work); | ||
| 259 | spin_lock_init(&drvdata->value_lock); | ||
| 260 | |||
| 261 | /* We cache the configuration register and read startup values | ||
| 262 | * from it. */ | ||
| 263 | drvdata->reg_val = wm831x_reg_read(wm831x, drvdata->reg); | ||
| 264 | |||
| 265 | if (drvdata->reg_val & WM831X_LED_MODE_MASK) | ||
| 266 | drvdata->brightness = LED_FULL; | ||
| 267 | else | ||
| 268 | drvdata->brightness = LED_OFF; | ||
| 269 | |||
| 270 | /* Set a default source if configured, otherwise leave the | ||
| 271 | * current hardware setting. | ||
| 272 | */ | ||
| 273 | if (pdata.default_src == WM831X_STATUS_PRESERVE) { | ||
| 274 | drvdata->src = drvdata->reg_val; | ||
| 275 | drvdata->src &= WM831X_LED_SRC_MASK; | ||
| 276 | drvdata->src >>= WM831X_LED_SRC_SHIFT; | ||
| 277 | } else { | ||
| 278 | drvdata->src = pdata.default_src - 1; | ||
| 279 | } | ||
| 280 | |||
| 281 | drvdata->cdev.name = pdata.name; | ||
| 282 | drvdata->cdev.default_trigger = pdata.default_trigger; | ||
| 283 | drvdata->cdev.brightness_set = wm831x_status_set; | ||
| 284 | drvdata->cdev.blink_set = wm831x_status_blink_set; | ||
| 285 | |||
| 286 | ret = led_classdev_register(wm831x->dev, &drvdata->cdev); | ||
| 287 | if (ret < 0) { | ||
| 288 | dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); | ||
| 289 | goto err_led; | ||
| 290 | } | ||
| 291 | |||
| 292 | ret = device_create_file(drvdata->cdev.dev, &dev_attr_src); | ||
| 293 | if (ret != 0) | ||
| 294 | dev_err(&pdev->dev, | ||
| 295 | "No source control for LED: %d\n", ret); | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | |||
| 299 | err_led: | ||
| 300 | led_classdev_unregister(&drvdata->cdev); | ||
| 301 | kfree(drvdata); | ||
| 302 | err: | ||
| 303 | return ret; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int wm831x_status_remove(struct platform_device *pdev) | ||
| 307 | { | ||
| 308 | struct wm831x_status *drvdata = platform_get_drvdata(pdev); | ||
| 309 | |||
| 310 | device_remove_file(drvdata->cdev.dev, &dev_attr_src); | ||
| 311 | led_classdev_unregister(&drvdata->cdev); | ||
| 312 | kfree(drvdata); | ||
| 313 | |||
| 314 | return 0; | ||
| 315 | } | ||
| 316 | |||
| 317 | static struct platform_driver wm831x_status_driver = { | ||
| 318 | .driver = { | ||
| 319 | .name = "wm831x-status", | ||
| 320 | .owner = THIS_MODULE, | ||
| 321 | }, | ||
| 322 | .probe = wm831x_status_probe, | ||
| 323 | .remove = wm831x_status_remove, | ||
| 324 | }; | ||
| 325 | |||
| 326 | static int __devinit wm831x_status_init(void) | ||
| 327 | { | ||
| 328 | return platform_driver_register(&wm831x_status_driver); | ||
| 329 | } | ||
| 330 | module_init(wm831x_status_init); | ||
| 331 | |||
| 332 | static void wm831x_status_exit(void) | ||
| 333 | { | ||
| 334 | platform_driver_unregister(&wm831x_status_driver); | ||
| 335 | } | ||
| 336 | module_exit(wm831x_status_exit); | ||
| 337 | |||
| 338 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
| 339 | MODULE_DESCRIPTION("WM831x status LED driver"); | ||
| 340 | MODULE_LICENSE("GPL"); | ||
| 341 | MODULE_ALIAS("platform:wm831x-status"); | ||
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c index 1bc5db4ece0d..f5913372d691 100644 --- a/drivers/leds/ledtrig-gpio.c +++ b/drivers/leds/ledtrig-gpio.c | |||
| @@ -44,22 +44,22 @@ static void gpio_trig_work(struct work_struct *work) | |||
| 44 | struct gpio_trig_data, work); | 44 | struct gpio_trig_data, work); |
| 45 | int tmp; | 45 | int tmp; |
| 46 | 46 | ||
| 47 | if (!gpio_data->gpio) | 47 | if (!gpio_data->gpio) |
| 48 | return; | 48 | return; |
| 49 | 49 | ||
| 50 | tmp = gpio_get_value(gpio_data->gpio); | 50 | tmp = gpio_get_value(gpio_data->gpio); |
| 51 | if (gpio_data->inverted) | 51 | if (gpio_data->inverted) |
| 52 | tmp = !tmp; | 52 | tmp = !tmp; |
| 53 | 53 | ||
| 54 | if (tmp) { | 54 | if (tmp) { |
| 55 | if (gpio_data->desired_brightness) | 55 | if (gpio_data->desired_brightness) |
| 56 | led_set_brightness(gpio_data->led, | 56 | led_set_brightness(gpio_data->led, |
| 57 | gpio_data->desired_brightness); | 57 | gpio_data->desired_brightness); |
| 58 | else | 58 | else |
| 59 | led_set_brightness(gpio_data->led, LED_FULL); | 59 | led_set_brightness(gpio_data->led, LED_FULL); |
| 60 | } else { | 60 | } else { |
| 61 | led_set_brightness(gpio_data->led, LED_OFF); | 61 | led_set_brightness(gpio_data->led, LED_OFF); |
| 62 | } | 62 | } |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static ssize_t gpio_trig_brightness_show(struct device *dev, | 65 | static ssize_t gpio_trig_brightness_show(struct device *dev, |
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c index 55ad95671387..d242976bcfe7 100644 --- a/drivers/macintosh/via-pmu-led.c +++ b/drivers/macintosh/via-pmu-led.c | |||
| @@ -72,7 +72,7 @@ static void pmu_led_set(struct led_classdev *led_cdev, | |||
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static struct led_classdev pmu_led = { | 74 | static struct led_classdev pmu_led = { |
| 75 | .name = "pmu-front-led", | 75 | .name = "pmu-led::front", |
| 76 | #ifdef CONFIG_ADB_PMU_LED_IDE | 76 | #ifdef CONFIG_ADB_PMU_LED_IDE |
| 77 | .default_trigger = "ide-disk", | 77 | .default_trigger = "ide-disk", |
| 78 | #endif | 78 | #endif |
diff --git a/include/linux/mfd/wm831x/status.h b/include/linux/mfd/wm831x/status.h new file mode 100644 index 000000000000..6bc090d0e3ac --- /dev/null +++ b/include/linux/mfd/wm831x/status.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* | ||
| 2 | * include/linux/mfd/wm831x/status.h -- Status LEDs for WM831x | ||
| 3 | * | ||
| 4 | * Copyright 2009 Wolfson Microelectronics PLC. | ||
| 5 | * | ||
| 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __MFD_WM831X_STATUS_H__ | ||
| 16 | #define __MFD_WM831X_STATUS_H__ | ||
| 17 | |||
| 18 | #define WM831X_LED_SRC_MASK 0xC000 /* LED_SRC - [15:14] */ | ||
| 19 | #define WM831X_LED_SRC_SHIFT 14 /* LED_SRC - [15:14] */ | ||
| 20 | #define WM831X_LED_SRC_WIDTH 2 /* LED_SRC - [15:14] */ | ||
| 21 | #define WM831X_LED_MODE_MASK 0x0300 /* LED_MODE - [9:8] */ | ||
| 22 | #define WM831X_LED_MODE_SHIFT 8 /* LED_MODE - [9:8] */ | ||
| 23 | #define WM831X_LED_MODE_WIDTH 2 /* LED_MODE - [9:8] */ | ||
| 24 | #define WM831X_LED_SEQ_LEN_MASK 0x0030 /* LED_SEQ_LEN - [5:4] */ | ||
| 25 | #define WM831X_LED_SEQ_LEN_SHIFT 4 /* LED_SEQ_LEN - [5:4] */ | ||
| 26 | #define WM831X_LED_SEQ_LEN_WIDTH 2 /* LED_SEQ_LEN - [5:4] */ | ||
| 27 | #define WM831X_LED_DUR_MASK 0x000C /* LED_DUR - [3:2] */ | ||
| 28 | #define WM831X_LED_DUR_SHIFT 2 /* LED_DUR - [3:2] */ | ||
| 29 | #define WM831X_LED_DUR_WIDTH 2 /* LED_DUR - [3:2] */ | ||
| 30 | #define WM831X_LED_DUTY_CYC_MASK 0x0003 /* LED_DUTY_CYC - [1:0] */ | ||
| 31 | #define WM831X_LED_DUTY_CYC_SHIFT 0 /* LED_DUTY_CYC - [1:0] */ | ||
| 32 | #define WM831X_LED_DUTY_CYC_WIDTH 2 /* LED_DUTY_CYC - [1:0] */ | ||
| 33 | |||
| 34 | #endif | ||
