2 * linux/drivers/mfd/aat2870-core.c
4 * Copyright (c) 2011, NVIDIA Corporation.
5 * Author: Jin Park <jinyoungp@nvidia.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 #include <linux/kernel.h>
23 #include <linux/init.h>
24 #include <linux/debugfs.h>
25 #include <linux/slab.h>
26 #include <linux/uaccess.h>
27 #include <linux/i2c.h>
28 #include <linux/delay.h>
29 #include <linux/gpio.h>
30 #include <linux/mfd/core.h>
31 #include <linux/mfd/aat2870.h>
32 #include <linux/regulator/machine.h>
34 static struct aat2870_register aat2870_regs
[AAT2870_REG_NUM
] = {
35 /* readable, writeable, value */
36 { 0, 1, 0x00 }, /* 0x00 AAT2870_BL_CH_EN */
37 { 0, 1, 0x16 }, /* 0x01 AAT2870_BLM */
38 { 0, 1, 0x16 }, /* 0x02 AAT2870_BLS */
39 { 0, 1, 0x56 }, /* 0x03 AAT2870_BL1 */
40 { 0, 1, 0x56 }, /* 0x04 AAT2870_BL2 */
41 { 0, 1, 0x56 }, /* 0x05 AAT2870_BL3 */
42 { 0, 1, 0x56 }, /* 0x06 AAT2870_BL4 */
43 { 0, 1, 0x56 }, /* 0x07 AAT2870_BL5 */
44 { 0, 1, 0x56 }, /* 0x08 AAT2870_BL6 */
45 { 0, 1, 0x56 }, /* 0x09 AAT2870_BL7 */
46 { 0, 1, 0x56 }, /* 0x0A AAT2870_BL8 */
47 { 0, 1, 0x00 }, /* 0x0B AAT2870_FLR */
48 { 0, 1, 0x03 }, /* 0x0C AAT2870_FM */
49 { 0, 1, 0x03 }, /* 0x0D AAT2870_FS */
50 { 0, 1, 0x10 }, /* 0x0E AAT2870_ALS_CFG0 */
51 { 0, 1, 0x06 }, /* 0x0F AAT2870_ALS_CFG1 */
52 { 0, 1, 0x00 }, /* 0x10 AAT2870_ALS_CFG2 */
53 { 1, 0, 0x00 }, /* 0x11 AAT2870_AMB */
54 { 0, 1, 0x00 }, /* 0x12 AAT2870_ALS0 */
55 { 0, 1, 0x00 }, /* 0x13 AAT2870_ALS1 */
56 { 0, 1, 0x00 }, /* 0x14 AAT2870_ALS2 */
57 { 0, 1, 0x00 }, /* 0x15 AAT2870_ALS3 */
58 { 0, 1, 0x00 }, /* 0x16 AAT2870_ALS4 */
59 { 0, 1, 0x00 }, /* 0x17 AAT2870_ALS5 */
60 { 0, 1, 0x00 }, /* 0x18 AAT2870_ALS6 */
61 { 0, 1, 0x00 }, /* 0x19 AAT2870_ALS7 */
62 { 0, 1, 0x00 }, /* 0x1A AAT2870_ALS8 */
63 { 0, 1, 0x00 }, /* 0x1B AAT2870_ALS9 */
64 { 0, 1, 0x00 }, /* 0x1C AAT2870_ALSA */
65 { 0, 1, 0x00 }, /* 0x1D AAT2870_ALSB */
66 { 0, 1, 0x00 }, /* 0x1E AAT2870_ALSC */
67 { 0, 1, 0x00 }, /* 0x1F AAT2870_ALSD */
68 { 0, 1, 0x00 }, /* 0x20 AAT2870_ALSE */
69 { 0, 1, 0x00 }, /* 0x21 AAT2870_ALSF */
70 { 0, 1, 0x00 }, /* 0x22 AAT2870_SUB_SET */
71 { 0, 1, 0x00 }, /* 0x23 AAT2870_SUB_CTRL */
72 { 0, 1, 0x00 }, /* 0x24 AAT2870_LDO_AB */
73 { 0, 1, 0x00 }, /* 0x25 AAT2870_LDO_CD */
74 { 0, 1, 0x00 }, /* 0x26 AAT2870_LDO_EN */
77 static struct mfd_cell aat2870_devs
[] = {
79 .name
= "aat2870-backlight",
81 .pdata_size
= sizeof(struct aat2870_bl_platform_data
),
84 .name
= "aat2870-regulator",
85 .id
= AAT2870_ID_LDOA
,
86 .pdata_size
= sizeof(struct regulator_init_data
),
89 .name
= "aat2870-regulator",
90 .id
= AAT2870_ID_LDOB
,
91 .pdata_size
= sizeof(struct regulator_init_data
),
94 .name
= "aat2870-regulator",
95 .id
= AAT2870_ID_LDOC
,
96 .pdata_size
= sizeof(struct regulator_init_data
),
99 .name
= "aat2870-regulator",
100 .id
= AAT2870_ID_LDOD
,
101 .pdata_size
= sizeof(struct regulator_init_data
),
105 static int __aat2870_read(struct aat2870_data
*aat2870
, u8 addr
, u8
*val
)
109 if (addr
>= AAT2870_REG_NUM
) {
110 dev_err(aat2870
->dev
, "Invalid address, 0x%02x\n", addr
);
114 if (!aat2870
->reg_cache
[addr
].readable
) {
115 *val
= aat2870
->reg_cache
[addr
].value
;
119 ret
= i2c_master_send(aat2870
->client
, &addr
, 1);
125 ret
= i2c_master_recv(aat2870
->client
, val
, 1);
132 dev_dbg(aat2870
->dev
, "read: addr=0x%02x, val=0x%02x\n", addr
, *val
);
136 static int __aat2870_write(struct aat2870_data
*aat2870
, u8 addr
, u8 val
)
141 if (addr
>= AAT2870_REG_NUM
) {
142 dev_err(aat2870
->dev
, "Invalid address, 0x%02x\n", addr
);
146 if (!aat2870
->reg_cache
[addr
].writeable
) {
147 dev_err(aat2870
->dev
, "Address 0x%02x is not writeable\n",
154 ret
= i2c_master_send(aat2870
->client
, msg
, 2);
160 aat2870
->reg_cache
[addr
].value
= val
;
162 dev_dbg(aat2870
->dev
, "write: addr=0x%02x, val=0x%02x\n", addr
, val
);
166 static int aat2870_read(struct aat2870_data
*aat2870
, u8 addr
, u8
*val
)
170 mutex_lock(&aat2870
->io_lock
);
171 ret
= __aat2870_read(aat2870
, addr
, val
);
172 mutex_unlock(&aat2870
->io_lock
);
177 static int aat2870_write(struct aat2870_data
*aat2870
, u8 addr
, u8 val
)
181 mutex_lock(&aat2870
->io_lock
);
182 ret
= __aat2870_write(aat2870
, addr
, val
);
183 mutex_unlock(&aat2870
->io_lock
);
188 static int aat2870_update(struct aat2870_data
*aat2870
, u8 addr
, u8 mask
,
195 mutex_lock(&aat2870
->io_lock
);
197 ret
= __aat2870_read(aat2870
, addr
, &old_val
);
201 new_val
= (old_val
& ~mask
) | (val
& mask
);
202 change
= old_val
!= new_val
;
204 ret
= __aat2870_write(aat2870
, addr
, new_val
);
207 mutex_unlock(&aat2870
->io_lock
);
212 static inline void aat2870_enable(struct aat2870_data
*aat2870
)
214 if (aat2870
->en_pin
>= 0)
215 gpio_set_value(aat2870
->en_pin
, 1);
217 aat2870
->is_enable
= 1;
220 static inline void aat2870_disable(struct aat2870_data
*aat2870
)
222 if (aat2870
->en_pin
>= 0)
223 gpio_set_value(aat2870
->en_pin
, 0);
225 aat2870
->is_enable
= 0;
228 #ifdef CONFIG_DEBUG_FS
229 static ssize_t
aat2870_dump_reg(struct aat2870_data
*aat2870
, char *buf
)
235 count
+= sprintf(buf
, "aat2870 registers\n");
236 for (addr
= 0; addr
< AAT2870_REG_NUM
; addr
++) {
237 count
+= sprintf(buf
+ count
, "0x%02x: ", addr
);
238 if (count
>= PAGE_SIZE
- 1)
241 ret
= aat2870
->read(aat2870
, addr
, &val
);
243 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
246 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
247 "<read fail: %d>", ret
);
249 if (count
>= PAGE_SIZE
- 1)
252 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "\n");
253 if (count
>= PAGE_SIZE
- 1)
257 /* Truncate count; min() would cause a warning */
258 if (count
>= PAGE_SIZE
)
259 count
= PAGE_SIZE
- 1;
264 static ssize_t
aat2870_reg_read_file(struct file
*file
, char __user
*user_buf
,
265 size_t count
, loff_t
*ppos
)
267 struct aat2870_data
*aat2870
= file
->private_data
;
271 buf
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
275 ret
= aat2870_dump_reg(aat2870
, buf
);
277 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, ret
);
284 static ssize_t
aat2870_reg_write_file(struct file
*file
,
285 const char __user
*user_buf
, size_t count
,
288 struct aat2870_data
*aat2870
= file
->private_data
;
292 unsigned long addr
, val
;
295 buf_size
= min(count
, (size_t)(sizeof(buf
)-1));
296 if (copy_from_user(buf
, user_buf
, buf_size
)) {
297 dev_err(aat2870
->dev
, "Failed to copy from user\n");
302 while (*start
== ' ')
305 ret
= kstrtoul(start
, 16, &addr
);
309 if (addr
>= AAT2870_REG_NUM
) {
310 dev_err(aat2870
->dev
, "Invalid address, 0x%lx\n", addr
);
314 while (*start
== ' ')
317 ret
= kstrtoul(start
, 16, &val
);
321 ret
= aat2870
->write(aat2870
, (u8
)addr
, (u8
)val
);
328 static const struct file_operations aat2870_reg_fops
= {
330 .read
= aat2870_reg_read_file
,
331 .write
= aat2870_reg_write_file
,
334 static void aat2870_init_debugfs(struct aat2870_data
*aat2870
)
336 aat2870
->dentry_root
= debugfs_create_dir("aat2870", NULL
);
337 if (!aat2870
->dentry_root
) {
338 dev_warn(aat2870
->dev
,
339 "Failed to create debugfs root directory\n");
343 aat2870
->dentry_reg
= debugfs_create_file("regs", 0644,
344 aat2870
->dentry_root
,
345 aat2870
, &aat2870_reg_fops
);
346 if (!aat2870
->dentry_reg
)
347 dev_warn(aat2870
->dev
,
348 "Failed to create debugfs register file\n");
352 static inline void aat2870_init_debugfs(struct aat2870_data
*aat2870
)
355 #endif /* CONFIG_DEBUG_FS */
357 static int aat2870_i2c_probe(struct i2c_client
*client
,
358 const struct i2c_device_id
*id
)
360 struct aat2870_platform_data
*pdata
= dev_get_platdata(&client
->dev
);
361 struct aat2870_data
*aat2870
;
365 aat2870
= devm_kzalloc(&client
->dev
, sizeof(struct aat2870_data
),
370 aat2870
->dev
= &client
->dev
;
371 dev_set_drvdata(aat2870
->dev
, aat2870
);
373 aat2870
->client
= client
;
374 i2c_set_clientdata(client
, aat2870
);
376 aat2870
->reg_cache
= aat2870_regs
;
378 if (pdata
->en_pin
< 0)
379 aat2870
->en_pin
= -1;
381 aat2870
->en_pin
= pdata
->en_pin
;
383 aat2870
->init
= pdata
->init
;
384 aat2870
->uninit
= pdata
->uninit
;
385 aat2870
->read
= aat2870_read
;
386 aat2870
->write
= aat2870_write
;
387 aat2870
->update
= aat2870_update
;
389 mutex_init(&aat2870
->io_lock
);
392 aat2870
->init(aat2870
);
394 if (aat2870
->en_pin
>= 0) {
395 ret
= devm_gpio_request_one(&client
->dev
, aat2870
->en_pin
,
396 GPIOF_OUT_INIT_HIGH
, "aat2870-en");
398 dev_err(&client
->dev
,
399 "Failed to request GPIO %d\n", aat2870
->en_pin
);
404 aat2870_enable(aat2870
);
406 for (i
= 0; i
< pdata
->num_subdevs
; i
++) {
407 for (j
= 0; j
< ARRAY_SIZE(aat2870_devs
); j
++) {
408 if ((pdata
->subdevs
[i
].id
== aat2870_devs
[j
].id
) &&
409 !strcmp(pdata
->subdevs
[i
].name
,
410 aat2870_devs
[j
].name
)) {
411 aat2870_devs
[j
].platform_data
=
412 pdata
->subdevs
[i
].platform_data
;
418 ret
= mfd_add_devices(aat2870
->dev
, 0, aat2870_devs
,
419 ARRAY_SIZE(aat2870_devs
), NULL
, 0, NULL
);
421 dev_err(aat2870
->dev
, "Failed to add subdev: %d\n", ret
);
425 aat2870_init_debugfs(aat2870
);
430 aat2870_disable(aat2870
);
434 #ifdef CONFIG_PM_SLEEP
435 static int aat2870_i2c_suspend(struct device
*dev
)
437 struct i2c_client
*client
= to_i2c_client(dev
);
438 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
440 aat2870_disable(aat2870
);
445 static int aat2870_i2c_resume(struct device
*dev
)
447 struct i2c_client
*client
= to_i2c_client(dev
);
448 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
449 struct aat2870_register
*reg
= NULL
;
452 aat2870_enable(aat2870
);
454 /* restore registers */
455 for (i
= 0; i
< AAT2870_REG_NUM
; i
++) {
456 reg
= &aat2870
->reg_cache
[i
];
458 aat2870
->write(aat2870
, i
, reg
->value
);
463 #endif /* CONFIG_PM_SLEEP */
465 static SIMPLE_DEV_PM_OPS(aat2870_pm_ops
, aat2870_i2c_suspend
,
468 static const struct i2c_device_id aat2870_i2c_id_table
[] = {
473 static struct i2c_driver aat2870_i2c_driver
= {
476 .pm
= &aat2870_pm_ops
,
477 .suppress_bind_attrs
= true,
479 .probe
= aat2870_i2c_probe
,
480 .id_table
= aat2870_i2c_id_table
,
483 static int __init
aat2870_init(void)
485 return i2c_add_driver(&aat2870_i2c_driver
);
487 subsys_initcall(aat2870_init
);