Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
leds
leds-da903x.c
Go to the documentation of this file.
1
/*
2
* LEDs driver for Dialog Semiconductor DA9030/DA9034
3
*
4
* Copyright (C) 2008 Compulab, Ltd.
5
* Mike Rapoport <
[email protected]
>
6
*
7
* Copyright (C) 2006-2008 Marvell International Ltd.
8
* Eric Miao <
[email protected]
>
9
*
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.
13
*/
14
15
#include <linux/module.h>
16
#include <linux/kernel.h>
17
#include <
linux/init.h
>
18
#include <
linux/platform_device.h
>
19
#include <
linux/leds.h
>
20
#include <
linux/workqueue.h
>
21
#include <
linux/mfd/da903x.h
>
22
#include <linux/slab.h>
23
24
#define DA9030_LED1_CONTROL 0x20
25
#define DA9030_LED2_CONTROL 0x21
26
#define DA9030_LED3_CONTROL 0x22
27
#define DA9030_LED4_CONTROL 0x23
28
#define DA9030_LEDPC_CONTROL 0x24
29
#define DA9030_MISC_CONTROL_A 0x26
/* Vibrator Control */
30
31
#define DA9034_LED1_CONTROL 0x35
32
#define DA9034_LED2_CONTROL 0x36
33
#define DA9034_VIBRA 0x40
34
35
struct
da903x_led
{
36
struct
led_classdev
cdev
;
37
struct
work_struct
work
;
38
struct
device
*
master
;
39
enum
led_brightness
new_brightness
;
40
int
id
;
41
int
flags
;
42
};
43
44
#define DA9030_LED_OFFSET(id) ((id) - DA9030_ID_LED_1)
45
#define DA9034_LED_OFFSET(id) ((id) - DA9034_ID_LED_1)
46
47
static
void
da903x_led_work(
struct
work_struct
*
work
)
48
{
49
struct
da903x_led
*
led
=
container_of
(work,
struct
da903x_led
, work);
50
uint8_t
val
;
51
int
offset
;
52
53
switch
(led->
id
) {
54
case
DA9030_ID_LED_1
:
55
case
DA9030_ID_LED_2
:
56
case
DA9030_ID_LED_3
:
57
case
DA9030_ID_LED_4
:
58
case
DA9030_ID_LED_PC
:
59
offset =
DA9030_LED_OFFSET
(led->
id
);
60
val = led->
flags
& ~0x87;
61
val |= (led->
new_brightness
) ? 0x80 : 0;
/* EN bit */
62
val |= (0x7 - (led->
new_brightness
>> 5)) & 0x7;
/* PWM<2:0> */
63
da903x_write
(led->
master
,
DA9030_LED1_CONTROL
+ offset, val);
64
break
;
65
case
DA9030_ID_VIBRA
:
66
val = led->
flags
& ~0x80;
67
val |= (led->
new_brightness
) ? 0x80 : 0;
/* EN bit */
68
da903x_write
(led->
master
,
DA9030_MISC_CONTROL_A
, val);
69
break
;
70
case
DA9034_ID_LED_1
:
71
case
DA9034_ID_LED_2
:
72
offset =
DA9034_LED_OFFSET
(led->
id
);
73
val = (led->
new_brightness
* 0x5f /
LED_FULL
) & 0x7f;
74
val |= (led->
flags
&
DA9034_LED_RAMP
) ? 0x80 : 0;
75
da903x_write
(led->
master
,
DA9034_LED1_CONTROL
+ offset, val);
76
break
;
77
case
DA9034_ID_VIBRA
:
78
val = led->
new_brightness
& 0xfe;
79
da903x_write
(led->
master
,
DA9034_VIBRA
, val);
80
break
;
81
}
82
}
83
84
static
void
da903x_led_set(
struct
led_classdev
*led_cdev,
85
enum
led_brightness
value
)
86
{
87
struct
da903x_led
*
led
;
88
89
led =
container_of
(led_cdev,
struct
da903x_led
,
cdev
);
90
led->
new_brightness
=
value
;
91
schedule_work
(&led->
work
);
92
}
93
94
static
int
__devinit
da903x_led_probe(
struct
platform_device
*pdev)
95
{
96
struct
led_info
*
pdata
= pdev->
dev
.platform_data;
97
struct
da903x_led
*
led
;
98
int
id
,
ret
;
99
100
if
(pdata ==
NULL
)
101
return
0;
102
103
id
= pdev->
id
;
104
105
if
(!((
id
>=
DA9030_ID_LED_1
&&
id
<=
DA9030_ID_VIBRA
) ||
106
(
id
>=
DA9034_ID_LED_1
&&
id
<=
DA9034_ID_VIBRA
))) {
107
dev_err
(&pdev->
dev
,
"invalid LED ID (%d) specified\n"
,
id
);
108
return
-
EINVAL
;
109
}
110
111
led =
devm_kzalloc
(&pdev->
dev
,
sizeof
(
struct
da903x_led
),
GFP_KERNEL
);
112
if
(led ==
NULL
) {
113
dev_err
(&pdev->
dev
,
"failed to alloc memory for LED%d\n"
,
id
);
114
return
-
ENOMEM
;
115
}
116
117
led->
cdev
.name = pdata->
name
;
118
led->
cdev
.default_trigger = pdata->
default_trigger
;
119
led->
cdev
.brightness_set = da903x_led_set;
120
led->
cdev
.brightness =
LED_OFF
;
121
122
led->
id
=
id
;
123
led->
flags
= pdata->
flags
;
124
led->
master
= pdev->
dev
.parent;
125
led->
new_brightness
=
LED_OFF
;
126
127
INIT_WORK
(&led->
work
, da903x_led_work);
128
129
ret =
led_classdev_register
(led->
master
, &led->
cdev
);
130
if
(ret) {
131
dev_err
(&pdev->
dev
,
"failed to register LED %d\n"
,
id
);
132
return
ret
;
133
}
134
135
platform_set_drvdata(pdev, led);
136
return
0;
137
}
138
139
static
int
__devexit
da903x_led_remove(
struct
platform_device
*pdev)
140
{
141
struct
da903x_led
*led = platform_get_drvdata(pdev);
142
143
led_classdev_unregister
(&led->
cdev
);
144
return
0;
145
}
146
147
static
struct
platform_driver
da903x_led_driver = {
148
.driver = {
149
.name =
"da903x-led"
,
150
.owner =
THIS_MODULE
,
151
},
152
.probe = da903x_led_probe,
153
.remove =
__devexit_p
(da903x_led_remove),
154
};
155
156
module_platform_driver
(da903x_led_driver);
157
158
MODULE_DESCRIPTION
(
"LEDs driver for Dialog Semiconductor DA9030/DA9034"
);
159
MODULE_AUTHOR
(
"Eric Miao <
[email protected]
>"
160
"Mike Rapoport <
[email protected]
>"
);
161
MODULE_LICENSE
(
"GPL"
);
162
MODULE_ALIAS
(
"platform:da903x-led"
);
Generated on Thu Jan 10 2013 13:42:58 for Linux Kernel by
1.8.2