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
mfd
tps6105x.c
Go to the documentation of this file.
1
/*
2
* Core driver for TPS61050/61052 boost converters, used for while LED
3
* driving, audio power amplification, white LED flash, and generic
4
* boost conversion. Additionally it provides a 1-bit GPIO pin (out or in)
5
* and a flash synchronization pin to synchronize flash events when used as
6
* flashgun.
7
*
8
* Copyright (C) 2011 ST-Ericsson SA
9
* Written on behalf of Linaro for ST-Ericsson
10
*
11
* Author: Linus Walleij <
[email protected]
>
12
*
13
* License terms: GNU General Public License (GPL) version 2
14
*/
15
16
#include <linux/module.h>
17
#include <
linux/init.h
>
18
#include <linux/i2c.h>
19
#include <
linux/mutex.h
>
20
#include <
linux/gpio.h
>
21
#include <
linux/spinlock.h
>
22
#include <linux/slab.h>
23
#include <
linux/err.h
>
24
#include <
linux/regulator/driver.h
>
25
#include <
linux/mfd/core.h
>
26
#include <
linux/mfd/tps6105x.h
>
27
28
int
tps6105x_set
(
struct
tps6105x
*
tps6105x
,
u8
reg
,
u8
value
)
29
{
30
int
ret
;
31
32
ret =
mutex_lock_interruptible
(&tps6105x->
lock
);
33
if
(ret)
34
return
ret
;
35
ret =
i2c_smbus_write_byte_data
(tps6105x->
client
, reg, value);
36
mutex_unlock
(&tps6105x->
lock
);
37
if
(ret < 0)
38
return
ret
;
39
40
return
0;
41
}
42
EXPORT_SYMBOL
(
tps6105x_set
);
43
44
int
tps6105x_get
(
struct
tps6105x
*
tps6105x
,
u8
reg
,
u8
*
buf
)
45
{
46
int
ret
;
47
48
ret =
mutex_lock_interruptible
(&tps6105x->
lock
);
49
if
(ret)
50
return
ret
;
51
ret =
i2c_smbus_read_byte_data
(tps6105x->
client
, reg);
52
mutex_unlock
(&tps6105x->
lock
);
53
if
(ret < 0)
54
return
ret
;
55
56
*buf =
ret
;
57
return
0;
58
}
59
EXPORT_SYMBOL
(
tps6105x_get
);
60
61
/*
62
* Masks off the bits in the mask and sets the bits in the bitvalues
63
* parameter in one atomic operation
64
*/
65
int
tps6105x_mask_and_set
(
struct
tps6105x
*
tps6105x
,
u8
reg
,
66
u8
bitmask
,
u8
bitvalues)
67
{
68
int
ret
;
69
u8
regval
;
70
71
ret =
mutex_lock_interruptible
(&tps6105x->
lock
);
72
if
(ret)
73
return
ret
;
74
ret =
i2c_smbus_read_byte_data
(tps6105x->
client
, reg);
75
if
(ret < 0)
76
goto
fail;
77
regval =
ret
;
78
regval = (~bitmask &
regval
) | (bitmask & bitvalues);
79
ret =
i2c_smbus_write_byte_data
(tps6105x->
client
, reg, regval);
80
fail:
81
mutex_unlock
(&tps6105x->
lock
);
82
if
(ret < 0)
83
return
ret
;
84
85
return
0;
86
}
87
EXPORT_SYMBOL
(
tps6105x_mask_and_set
);
88
89
static
int
__devinit
tps6105x_startup(
struct
tps6105x
*
tps6105x
)
90
{
91
int
ret
;
92
u8
regval
;
93
94
ret =
tps6105x_get
(tps6105x,
TPS6105X_REG_0
, ®val);
95
if
(ret)
96
return
ret
;
97
switch
(regval >>
TPS6105X_REG0_MODE_SHIFT
) {
98
case
TPS6105X_REG0_MODE_SHUTDOWN
:
99
dev_info
(&tps6105x->
client
->dev,
100
"TPS6105x found in SHUTDOWN mode\n"
);
101
break
;
102
case
TPS6105X_REG0_MODE_TORCH
:
103
dev_info
(&tps6105x->
client
->dev,
104
"TPS6105x found in TORCH mode\n"
);
105
break
;
106
case
TPS6105X_REG0_MODE_TORCH_FLASH
:
107
dev_info
(&tps6105x->
client
->dev,
108
"TPS6105x found in FLASH mode\n"
);
109
break
;
110
case
TPS6105X_REG0_MODE_VOLTAGE
:
111
dev_info
(&tps6105x->
client
->dev,
112
"TPS6105x found in VOLTAGE mode\n"
);
113
break
;
114
default
:
115
break
;
116
}
117
118
return
ret
;
119
}
120
121
/*
122
* MFD cells - we have one cell which is selected operation
123
* mode, and we always have a GPIO cell.
124
*/
125
static
struct
mfd_cell
tps6105x_cells[] = {
126
{
127
/* name will be runtime assigned */
128
.id = -1,
129
},
130
{
131
.name =
"tps6105x-gpio"
,
132
.id = -1,
133
},
134
};
135
136
static
int
__devinit
tps6105x_probe(
struct
i2c_client
*
client
,
137
const
struct
i2c_device_id
*
id
)
138
{
139
struct
tps6105x *tps6105x;
140
struct
tps6105x_platform_data
*
pdata
;
141
int
ret
;
142
int
i
;
143
144
tps6105x =
kmalloc
(
sizeof
(*tps6105x),
GFP_KERNEL
);
145
if
(!tps6105x)
146
return
-
ENOMEM
;
147
148
i2c_set_clientdata(client, tps6105x);
149
tps6105x->
client
=
client
;
150
pdata = client->
dev
.platform_data;
151
tps6105x->
pdata
=
pdata
;
152
mutex_init
(&tps6105x->
lock
);
153
154
ret = tps6105x_startup(tps6105x);
155
if
(ret) {
156
dev_err
(&client->
dev
,
"chip initialization failed\n"
);
157
goto
fail;
158
}
159
160
/* Remove warning texts when you implement new cell drivers */
161
switch
(pdata->
mode
) {
162
case
TPS6105X_MODE_SHUTDOWN
:
163
dev_info
(&client->
dev
,
164
"present, not used for anything, only GPIO\n"
);
165
break
;
166
case
TPS6105X_MODE_TORCH
:
167
tps6105x_cells[0].
name
=
"tps6105x-leds"
;
168
dev_warn
(&client->
dev
,
169
"torch mode is unsupported\n"
);
170
break
;
171
case
TPS6105X_MODE_TORCH_FLASH
:
172
tps6105x_cells[0].
name
=
"tps6105x-flash"
;
173
dev_warn
(&client->
dev
,
174
"flash mode is unsupported\n"
);
175
break
;
176
case
TPS6105X_MODE_VOLTAGE
:
177
tps6105x_cells[0].
name
=
"tps6105x-regulator"
;
178
break
;
179
default
:
180
break
;
181
}
182
183
/* Set up and register the platform devices. */
184
for
(i = 0; i <
ARRAY_SIZE
(tps6105x_cells); i++) {
185
/* One state holder for all drivers, this is simple */
186
tps6105x_cells[
i
].
platform_data
= tps6105x;
187
tps6105x_cells[
i
].
pdata_size
=
sizeof
(*tps6105x);
188
}
189
190
ret =
mfd_add_devices
(&client->
dev
, 0, tps6105x_cells,
191
ARRAY_SIZE
(tps6105x_cells),
NULL
, 0,
NULL
);
192
if
(ret)
193
goto
fail;
194
195
return
0;
196
197
fail:
198
kfree
(tps6105x);
199
return
ret
;
200
}
201
202
static
int
__devexit
tps6105x_remove(
struct
i2c_client
*client)
203
{
204
struct
tps6105x *tps6105x = i2c_get_clientdata(client);
205
206
mfd_remove_devices
(&client->
dev
);
207
208
/* Put chip in shutdown mode */
209
tps6105x_mask_and_set
(tps6105x,
TPS6105X_REG_0
,
210
TPS6105X_REG0_MODE_MASK
,
211
TPS6105X_MODE_SHUTDOWN
<<
TPS6105X_REG0_MODE_SHIFT
);
212
213
kfree
(tps6105x);
214
return
0;
215
}
216
217
static
const
struct
i2c_device_id
tps6105x_id[] = {
218
{
"tps61050"
, 0 },
219
{
"tps61052"
, 0 },
220
{ }
221
};
222
MODULE_DEVICE_TABLE
(i2c, tps6105x_id);
223
224
static
struct
i2c_driver
tps6105x_driver = {
225
.driver = {
226
.name =
"tps6105x"
,
227
},
228
.probe = tps6105x_probe,
229
.remove =
__devexit_p
(tps6105x_remove),
230
.id_table = tps6105x_id,
231
};
232
233
static
int
__init
tps6105x_init(
void
)
234
{
235
return
i2c_add_driver(&tps6105x_driver);
236
}
237
subsys_initcall
(tps6105x_init);
238
239
static
void
__exit
tps6105x_exit(
void
)
240
{
241
i2c_del_driver
(&tps6105x_driver);
242
}
243
module_exit
(tps6105x_exit);
244
245
MODULE_AUTHOR
(
"Linus Walleij"
);
246
MODULE_DESCRIPTION
(
"TPS6105x White LED Boost Converter Driver"
);
247
MODULE_LICENSE
(
"GPL v2"
);
Generated on Thu Jan 10 2013 13:54:15 for Linux Kernel by
1.8.2