2 * Copyright (C) ST-Ericsson SA 2010
4 * License Terms: GNU General Public License, version 2
5 * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> for ST-Ericsson
6 * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
9 #include <linux/module.h>
10 #include <linux/interrupt.h>
11 #include <linux/irq.h>
12 #include <linux/slab.h>
13 #include <linux/i2c.h>
14 #include <linux/mfd/core.h>
15 #include <linux/mfd/tc35892.h>
18 * tc35892_reg_read() - read a single TC35892 register
19 * @tc35892: Device to read from
20 * @reg: Register to read
22 int tc35892_reg_read(struct tc35892
*tc35892
, u8 reg
)
26 ret
= i2c_smbus_read_byte_data(tc35892
->i2c
, reg
);
28 dev_err(tc35892
->dev
, "failed to read reg %#x: %d\n",
33 EXPORT_SYMBOL_GPL(tc35892_reg_read
);
36 * tc35892_reg_read() - write a single TC35892 register
37 * @tc35892: Device to write to
38 * @reg: Register to read
39 * @data: Value to write
41 int tc35892_reg_write(struct tc35892
*tc35892
, u8 reg
, u8 data
)
45 ret
= i2c_smbus_write_byte_data(tc35892
->i2c
, reg
, data
);
47 dev_err(tc35892
->dev
, "failed to write reg %#x: %d\n",
52 EXPORT_SYMBOL_GPL(tc35892_reg_write
);
55 * tc35892_block_read() - read multiple TC35892 registers
56 * @tc35892: Device to read from
57 * @reg: First register
58 * @length: Number of registers
59 * @values: Buffer to write to
61 int tc35892_block_read(struct tc35892
*tc35892
, u8 reg
, u8 length
, u8
*values
)
65 ret
= i2c_smbus_read_i2c_block_data(tc35892
->i2c
, reg
, length
, values
);
67 dev_err(tc35892
->dev
, "failed to read regs %#x: %d\n",
72 EXPORT_SYMBOL_GPL(tc35892_block_read
);
75 * tc35892_block_write() - write multiple TC35892 registers
76 * @tc35892: Device to write to
77 * @reg: First register
78 * @length: Number of registers
79 * @values: Values to write
81 int tc35892_block_write(struct tc35892
*tc35892
, u8 reg
, u8 length
,
86 ret
= i2c_smbus_write_i2c_block_data(tc35892
->i2c
, reg
, length
,
89 dev_err(tc35892
->dev
, "failed to write regs %#x: %d\n",
94 EXPORT_SYMBOL_GPL(tc35892_block_write
);
97 * tc35892_set_bits() - set the value of a bitfield in a TC35892 register
98 * @tc35892: Device to write to
99 * @reg: Register to write
100 * @mask: Mask of bits to set
101 * @values: Value to set
103 int tc35892_set_bits(struct tc35892
*tc35892
, u8 reg
, u8 mask
, u8 val
)
107 mutex_lock(&tc35892
->lock
);
109 ret
= tc35892_reg_read(tc35892
, reg
);
116 ret
= tc35892_reg_write(tc35892
, reg
, ret
);
119 mutex_unlock(&tc35892
->lock
);
122 EXPORT_SYMBOL_GPL(tc35892_set_bits
);
124 static struct resource gpio_resources
[] = {
126 .start
= TC35892_INT_GPIIRQ
,
127 .end
= TC35892_INT_GPIIRQ
,
128 .flags
= IORESOURCE_IRQ
,
132 static struct mfd_cell tc35892_devs
[] = {
134 .name
= "tc35892-gpio",
135 .num_resources
= ARRAY_SIZE(gpio_resources
),
136 .resources
= &gpio_resources
[0],
140 static irqreturn_t
tc35892_irq(int irq
, void *data
)
142 struct tc35892
*tc35892
= data
;
145 status
= tc35892_reg_read(tc35892
, TC35892_IRQST
);
150 int bit
= __ffs(status
);
152 handle_nested_irq(tc35892
->irq_base
+ bit
);
153 status
&= ~(1 << bit
);
157 * A dummy read or write (to any register) appears to be necessary to
158 * have the last interrupt clear (for example, GPIO IC write) take
161 tc35892_reg_read(tc35892
, TC35892_IRQST
);
166 static void tc35892_irq_dummy(unsigned int irq
)
168 /* No mask/unmask at this level */
171 static struct irq_chip tc35892_irq_chip
= {
173 .mask
= tc35892_irq_dummy
,
174 .unmask
= tc35892_irq_dummy
,
177 static int tc35892_irq_init(struct tc35892
*tc35892
)
179 int base
= tc35892
->irq_base
;
182 for (irq
= base
; irq
< base
+ TC35892_NR_INTERNAL_IRQS
; irq
++) {
183 set_irq_chip_data(irq
, tc35892
);
184 set_irq_chip_and_handler(irq
, &tc35892_irq_chip
,
186 set_irq_nested_thread(irq
, 1);
188 set_irq_flags(irq
, IRQF_VALID
);
190 set_irq_noprobe(irq
);
197 static void tc35892_irq_remove(struct tc35892
*tc35892
)
199 int base
= tc35892
->irq_base
;
202 for (irq
= base
; irq
< base
+ TC35892_NR_INTERNAL_IRQS
; irq
++) {
204 set_irq_flags(irq
, 0);
206 set_irq_chip_and_handler(irq
, NULL
, NULL
);
207 set_irq_chip_data(irq
, NULL
);
211 static int tc35892_chip_init(struct tc35892
*tc35892
)
215 manf
= tc35892_reg_read(tc35892
, TC35892_MANFCODE
);
219 ver
= tc35892_reg_read(tc35892
, TC35892_VERSION
);
223 if (manf
!= TC35892_MANFCODE_MAGIC
) {
224 dev_err(tc35892
->dev
, "unknown manufacturer: %#x\n", manf
);
228 dev_info(tc35892
->dev
, "manufacturer: %#x, version: %#x\n", manf
, ver
);
230 /* Put everything except the IRQ module into reset */
231 ret
= tc35892_reg_write(tc35892
, TC35892_RSTCTRL
,
232 TC35892_RSTCTRL_TIMRST
233 | TC35892_RSTCTRL_ROTRST
234 | TC35892_RSTCTRL_KBDRST
235 | TC35892_RSTCTRL_GPIRST
);
239 /* Clear the reset interrupt. */
240 return tc35892_reg_write(tc35892
, TC35892_RSTINTCLR
, 0x1);
243 static int __devinit
tc35892_probe(struct i2c_client
*i2c
,
244 const struct i2c_device_id
*id
)
246 struct tc35892_platform_data
*pdata
= i2c
->dev
.platform_data
;
247 struct tc35892
*tc35892
;
250 if (!i2c_check_functionality(i2c
->adapter
, I2C_FUNC_SMBUS_BYTE_DATA
251 | I2C_FUNC_SMBUS_I2C_BLOCK
))
254 tc35892
= kzalloc(sizeof(struct tc35892
), GFP_KERNEL
);
258 mutex_init(&tc35892
->lock
);
260 tc35892
->dev
= &i2c
->dev
;
262 tc35892
->pdata
= pdata
;
263 tc35892
->irq_base
= pdata
->irq_base
;
264 tc35892
->num_gpio
= id
->driver_data
;
266 i2c_set_clientdata(i2c
, tc35892
);
268 ret
= tc35892_chip_init(tc35892
);
272 ret
= tc35892_irq_init(tc35892
);
276 ret
= request_threaded_irq(tc35892
->i2c
->irq
, NULL
, tc35892_irq
,
277 IRQF_TRIGGER_FALLING
| IRQF_ONESHOT
,
280 dev_err(tc35892
->dev
, "failed to request IRQ: %d\n", ret
);
284 ret
= mfd_add_devices(tc35892
->dev
, -1, tc35892_devs
,
285 ARRAY_SIZE(tc35892_devs
), NULL
,
288 dev_err(tc35892
->dev
, "failed to add children\n");
295 free_irq(tc35892
->i2c
->irq
, tc35892
);
297 tc35892_irq_remove(tc35892
);
299 i2c_set_clientdata(i2c
, NULL
);
304 static int __devexit
tc35892_remove(struct i2c_client
*client
)
306 struct tc35892
*tc35892
= i2c_get_clientdata(client
);
308 mfd_remove_devices(tc35892
->dev
);
310 free_irq(tc35892
->i2c
->irq
, tc35892
);
311 tc35892_irq_remove(tc35892
);
313 i2c_set_clientdata(client
, NULL
);
319 static const struct i2c_device_id tc35892_id
[] = {
323 MODULE_DEVICE_TABLE(i2c
, tc35892_id
);
325 static struct i2c_driver tc35892_driver
= {
326 .driver
.name
= "tc35892",
327 .driver
.owner
= THIS_MODULE
,
328 .probe
= tc35892_probe
,
329 .remove
= __devexit_p(tc35892_remove
),
330 .id_table
= tc35892_id
,
333 static int __init
tc35892_init(void)
335 return i2c_add_driver(&tc35892_driver
);
337 subsys_initcall(tc35892_init
);
339 static void __exit
tc35892_exit(void)
341 i2c_del_driver(&tc35892_driver
);
343 module_exit(tc35892_exit
);
345 MODULE_LICENSE("GPL v2");
346 MODULE_DESCRIPTION("TC35892 MFD core driver");
347 MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");