2 * linux/drivers/leds-pwm.c
4 * simple PWM based LED control
6 * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
8 * based on leds-gpio.c by Raphael Assenat <raph@8d.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/platform_device.h>
20 #include <linux/leds.h>
21 #include <linux/err.h>
22 #include <linux/pwm.h>
23 #include <linux/leds_pwm.h>
24 #include <linux/slab.h>
27 struct led_classdev cdev
;
28 struct pwm_device
*pwm
;
29 unsigned int active_low
;
33 static void led_pwm_set(struct led_classdev
*led_cdev
,
34 enum led_brightness brightness
)
36 struct led_pwm_data
*led_dat
=
37 container_of(led_cdev
, struct led_pwm_data
, cdev
);
38 unsigned int max
= led_dat
->cdev
.max_brightness
;
39 unsigned int period
= led_dat
->period
;
41 if (brightness
== 0) {
42 pwm_config(led_dat
->pwm
, 0, period
);
43 pwm_disable(led_dat
->pwm
);
45 pwm_config(led_dat
->pwm
, brightness
* period
/ max
, period
);
46 pwm_enable(led_dat
->pwm
);
50 static int led_pwm_probe(struct platform_device
*pdev
)
52 struct led_pwm_platform_data
*pdata
= pdev
->dev
.platform_data
;
53 struct led_pwm
*cur_led
;
54 struct led_pwm_data
*leds_data
, *led_dat
;
60 leds_data
= kzalloc(sizeof(struct led_pwm_data
) * pdata
->num_leds
,
65 for (i
= 0; i
< pdata
->num_leds
; i
++) {
66 cur_led
= &pdata
->leds
[i
];
67 led_dat
= &leds_data
[i
];
69 led_dat
->pwm
= pwm_request(cur_led
->pwm_id
,
71 if (IS_ERR(led_dat
->pwm
)) {
72 ret
= PTR_ERR(led_dat
->pwm
);
73 dev_err(&pdev
->dev
, "unable to request PWM %d\n",
78 led_dat
->cdev
.name
= cur_led
->name
;
79 led_dat
->cdev
.default_trigger
= cur_led
->default_trigger
;
80 led_dat
->active_low
= cur_led
->active_low
;
81 led_dat
->period
= cur_led
->pwm_period_ns
;
82 led_dat
->cdev
.brightness_set
= led_pwm_set
;
83 led_dat
->cdev
.brightness
= LED_OFF
;
84 led_dat
->cdev
.max_brightness
= cur_led
->max_brightness
;
85 led_dat
->cdev
.flags
|= LED_CORE_SUSPENDRESUME
;
87 ret
= led_classdev_register(&pdev
->dev
, &led_dat
->cdev
);
89 pwm_free(led_dat
->pwm
);
94 platform_set_drvdata(pdev
, leds_data
);
100 for (i
= i
- 1; i
>= 0; i
--) {
101 led_classdev_unregister(&leds_data
[i
].cdev
);
102 pwm_free(leds_data
[i
].pwm
);
111 static int __devexit
led_pwm_remove(struct platform_device
*pdev
)
114 struct led_pwm_platform_data
*pdata
= pdev
->dev
.platform_data
;
115 struct led_pwm_data
*leds_data
;
117 leds_data
= platform_get_drvdata(pdev
);
119 for (i
= 0; i
< pdata
->num_leds
; i
++) {
120 led_classdev_unregister(&leds_data
[i
].cdev
);
121 pwm_free(leds_data
[i
].pwm
);
129 static struct platform_driver led_pwm_driver
= {
130 .probe
= led_pwm_probe
,
131 .remove
= __devexit_p(led_pwm_remove
),
134 .owner
= THIS_MODULE
,
138 static int __init
led_pwm_init(void)
140 return platform_driver_register(&led_pwm_driver
);
143 static void __exit
led_pwm_exit(void)
145 platform_driver_unregister(&led_pwm_driver
);
148 module_init(led_pwm_init
);
149 module_exit(led_pwm_exit
);
151 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
152 MODULE_DESCRIPTION("PWM LED driver for PXA");
153 MODULE_LICENSE("GPL");
154 MODULE_ALIAS("platform:leds-pwm");