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/module.h>
24 #include <linux/init.h>
25 #include <linux/debugfs.h>
26 #include <linux/slab.h>
27 #include <linux/uaccess.h>
28 #include <linux/i2c.h>
29 #include <linux/delay.h>
30 #include <linux/gpio.h>
31 #include <linux/mfd/core.h>
32 #include <linux/mfd/aat2870.h>
33 #include <linux/regulator/machine.h>
35 static struct aat2870_register aat2870_regs
[AAT2870_REG_NUM
] = {
36 /* readable, writeable, value */
37 { 0, 1, 0x00 }, /* 0x00 AAT2870_BL_CH_EN */
38 { 0, 1, 0x16 }, /* 0x01 AAT2870_BLM */
39 { 0, 1, 0x16 }, /* 0x02 AAT2870_BLS */
40 { 0, 1, 0x56 }, /* 0x03 AAT2870_BL1 */
41 { 0, 1, 0x56 }, /* 0x04 AAT2870_BL2 */
42 { 0, 1, 0x56 }, /* 0x05 AAT2870_BL3 */
43 { 0, 1, 0x56 }, /* 0x06 AAT2870_BL4 */
44 { 0, 1, 0x56 }, /* 0x07 AAT2870_BL5 */
45 { 0, 1, 0x56 }, /* 0x08 AAT2870_BL6 */
46 { 0, 1, 0x56 }, /* 0x09 AAT2870_BL7 */
47 { 0, 1, 0x56 }, /* 0x0A AAT2870_BL8 */
48 { 0, 1, 0x00 }, /* 0x0B AAT2870_FLR */
49 { 0, 1, 0x03 }, /* 0x0C AAT2870_FM */
50 { 0, 1, 0x03 }, /* 0x0D AAT2870_FS */
51 { 0, 1, 0x10 }, /* 0x0E AAT2870_ALS_CFG0 */
52 { 0, 1, 0x06 }, /* 0x0F AAT2870_ALS_CFG1 */
53 { 0, 1, 0x00 }, /* 0x10 AAT2870_ALS_CFG2 */
54 { 1, 0, 0x00 }, /* 0x11 AAT2870_AMB */
55 { 0, 1, 0x00 }, /* 0x12 AAT2870_ALS0 */
56 { 0, 1, 0x00 }, /* 0x13 AAT2870_ALS1 */
57 { 0, 1, 0x00 }, /* 0x14 AAT2870_ALS2 */
58 { 0, 1, 0x00 }, /* 0x15 AAT2870_ALS3 */
59 { 0, 1, 0x00 }, /* 0x16 AAT2870_ALS4 */
60 { 0, 1, 0x00 }, /* 0x17 AAT2870_ALS5 */
61 { 0, 1, 0x00 }, /* 0x18 AAT2870_ALS6 */
62 { 0, 1, 0x00 }, /* 0x19 AAT2870_ALS7 */
63 { 0, 1, 0x00 }, /* 0x1A AAT2870_ALS8 */
64 { 0, 1, 0x00 }, /* 0x1B AAT2870_ALS9 */
65 { 0, 1, 0x00 }, /* 0x1C AAT2870_ALSA */
66 { 0, 1, 0x00 }, /* 0x1D AAT2870_ALSB */
67 { 0, 1, 0x00 }, /* 0x1E AAT2870_ALSC */
68 { 0, 1, 0x00 }, /* 0x1F AAT2870_ALSD */
69 { 0, 1, 0x00 }, /* 0x20 AAT2870_ALSE */
70 { 0, 1, 0x00 }, /* 0x21 AAT2870_ALSF */
71 { 0, 1, 0x00 }, /* 0x22 AAT2870_SUB_SET */
72 { 0, 1, 0x00 }, /* 0x23 AAT2870_SUB_CTRL */
73 { 0, 1, 0x00 }, /* 0x24 AAT2870_LDO_AB */
74 { 0, 1, 0x00 }, /* 0x25 AAT2870_LDO_CD */
75 { 0, 1, 0x00 }, /* 0x26 AAT2870_LDO_EN */
78 static struct mfd_cell aat2870_devs
[] = {
80 .name
= "aat2870-backlight",
82 .pdata_size
= sizeof(struct aat2870_bl_platform_data
),
85 .name
= "aat2870-regulator",
86 .id
= AAT2870_ID_LDOA
,
87 .pdata_size
= sizeof(struct regulator_init_data
),
90 .name
= "aat2870-regulator",
91 .id
= AAT2870_ID_LDOB
,
92 .pdata_size
= sizeof(struct regulator_init_data
),
95 .name
= "aat2870-regulator",
96 .id
= AAT2870_ID_LDOC
,
97 .pdata_size
= sizeof(struct regulator_init_data
),
100 .name
= "aat2870-regulator",
101 .id
= AAT2870_ID_LDOD
,
102 .pdata_size
= sizeof(struct regulator_init_data
),
106 static int __aat2870_read(struct aat2870_data
*aat2870
, u8 addr
, u8
*val
)
110 if (addr
>= AAT2870_REG_NUM
) {
111 dev_err(aat2870
->dev
, "Invalid address, 0x%02x\n", addr
);
115 if (!aat2870
->reg_cache
[addr
].readable
) {
116 *val
= aat2870
->reg_cache
[addr
].value
;
120 ret
= i2c_master_send(aat2870
->client
, &addr
, 1);
126 ret
= i2c_master_recv(aat2870
->client
, val
, 1);
133 dev_dbg(aat2870
->dev
, "read: addr=0x%02x, val=0x%02x\n", addr
, *val
);
137 static int __aat2870_write(struct aat2870_data
*aat2870
, u8 addr
, u8 val
)
142 if (addr
>= AAT2870_REG_NUM
) {
143 dev_err(aat2870
->dev
, "Invalid address, 0x%02x\n", addr
);
147 if (!aat2870
->reg_cache
[addr
].writeable
) {
148 dev_err(aat2870
->dev
, "Address 0x%02x is not writeable\n",
155 ret
= i2c_master_send(aat2870
->client
, msg
, 2);
161 aat2870
->reg_cache
[addr
].value
= val
;
163 dev_dbg(aat2870
->dev
, "write: addr=0x%02x, val=0x%02x\n", addr
, val
);
167 static int aat2870_read(struct aat2870_data
*aat2870
, u8 addr
, u8
*val
)
171 mutex_lock(&aat2870
->io_lock
);
172 ret
= __aat2870_read(aat2870
, addr
, val
);
173 mutex_unlock(&aat2870
->io_lock
);
178 static int aat2870_write(struct aat2870_data
*aat2870
, u8 addr
, u8 val
)
182 mutex_lock(&aat2870
->io_lock
);
183 ret
= __aat2870_write(aat2870
, addr
, val
);
184 mutex_unlock(&aat2870
->io_lock
);
189 static int aat2870_update(struct aat2870_data
*aat2870
, u8 addr
, u8 mask
,
196 mutex_lock(&aat2870
->io_lock
);
198 ret
= __aat2870_read(aat2870
, addr
, &old_val
);
202 new_val
= (old_val
& ~mask
) | (val
& mask
);
203 change
= old_val
!= new_val
;
205 ret
= __aat2870_write(aat2870
, addr
, new_val
);
208 mutex_unlock(&aat2870
->io_lock
);
213 static inline void aat2870_enable(struct aat2870_data
*aat2870
)
215 if (aat2870
->en_pin
>= 0)
216 gpio_set_value(aat2870
->en_pin
, 1);
218 aat2870
->is_enable
= 1;
221 static inline void aat2870_disable(struct aat2870_data
*aat2870
)
223 if (aat2870
->en_pin
>= 0)
224 gpio_set_value(aat2870
->en_pin
, 0);
226 aat2870
->is_enable
= 0;
229 #ifdef CONFIG_DEBUG_FS
230 static ssize_t
aat2870_dump_reg(struct aat2870_data
*aat2870
, char *buf
)
236 count
+= sprintf(buf
, "aat2870 registers\n");
237 for (addr
= 0; addr
< AAT2870_REG_NUM
; addr
++) {
238 count
+= sprintf(buf
+ count
, "0x%02x: ", addr
);
239 if (count
>= PAGE_SIZE
- 1)
242 ret
= aat2870
->read(aat2870
, addr
, &val
);
244 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
247 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
248 "<read fail: %d>", ret
);
250 if (count
>= PAGE_SIZE
- 1)
253 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "\n");
254 if (count
>= PAGE_SIZE
- 1)
258 /* Truncate count; min() would cause a warning */
259 if (count
>= PAGE_SIZE
)
260 count
= PAGE_SIZE
- 1;
265 static ssize_t
aat2870_reg_read_file(struct file
*file
, char __user
*user_buf
,
266 size_t count
, loff_t
*ppos
)
268 struct aat2870_data
*aat2870
= file
->private_data
;
272 buf
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
276 ret
= aat2870_dump_reg(aat2870
, buf
);
278 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, ret
);
285 static ssize_t
aat2870_reg_write_file(struct file
*file
,
286 const char __user
*user_buf
, size_t count
,
289 struct aat2870_data
*aat2870
= file
->private_data
;
293 unsigned long addr
, val
;
296 buf_size
= min(count
, (size_t)(sizeof(buf
)-1));
297 if (copy_from_user(buf
, user_buf
, buf_size
)) {
298 dev_err(aat2870
->dev
, "Failed to copy from user\n");
303 while (*start
== ' ')
306 ret
= kstrtoul(start
, 16, &addr
);
310 if (addr
>= AAT2870_REG_NUM
) {
311 dev_err(aat2870
->dev
, "Invalid address, 0x%lx\n", addr
);
315 while (*start
== ' ')
318 ret
= kstrtoul(start
, 16, &val
);
322 ret
= aat2870
->write(aat2870
, (u8
)addr
, (u8
)val
);
329 static const struct file_operations aat2870_reg_fops
= {
331 .read
= aat2870_reg_read_file
,
332 .write
= aat2870_reg_write_file
,
335 static void aat2870_init_debugfs(struct aat2870_data
*aat2870
)
337 aat2870
->dentry_root
= debugfs_create_dir("aat2870", NULL
);
338 if (!aat2870
->dentry_root
) {
339 dev_warn(aat2870
->dev
,
340 "Failed to create debugfs root directory\n");
344 aat2870
->dentry_reg
= debugfs_create_file("regs", 0644,
345 aat2870
->dentry_root
,
346 aat2870
, &aat2870_reg_fops
);
347 if (!aat2870
->dentry_reg
)
348 dev_warn(aat2870
->dev
,
349 "Failed to create debugfs register file\n");
352 static void aat2870_uninit_debugfs(struct aat2870_data
*aat2870
)
354 debugfs_remove_recursive(aat2870
->dentry_root
);
357 static inline void aat2870_init_debugfs(struct aat2870_data
*aat2870
)
361 static inline void aat2870_uninit_debugfs(struct aat2870_data
*aat2870
)
364 #endif /* CONFIG_DEBUG_FS */
366 static int aat2870_i2c_probe(struct i2c_client
*client
,
367 const struct i2c_device_id
*id
)
369 struct aat2870_platform_data
*pdata
= dev_get_platdata(&client
->dev
);
370 struct aat2870_data
*aat2870
;
374 aat2870
= devm_kzalloc(&client
->dev
, sizeof(struct aat2870_data
),
379 aat2870
->dev
= &client
->dev
;
380 dev_set_drvdata(aat2870
->dev
, aat2870
);
382 aat2870
->client
= client
;
383 i2c_set_clientdata(client
, aat2870
);
385 aat2870
->reg_cache
= aat2870_regs
;
387 if (pdata
->en_pin
< 0)
388 aat2870
->en_pin
= -1;
390 aat2870
->en_pin
= pdata
->en_pin
;
392 aat2870
->init
= pdata
->init
;
393 aat2870
->uninit
= pdata
->uninit
;
394 aat2870
->read
= aat2870_read
;
395 aat2870
->write
= aat2870_write
;
396 aat2870
->update
= aat2870_update
;
398 mutex_init(&aat2870
->io_lock
);
401 aat2870
->init(aat2870
);
403 if (aat2870
->en_pin
>= 0) {
404 ret
= devm_gpio_request_one(&client
->dev
, aat2870
->en_pin
,
405 GPIOF_OUT_INIT_HIGH
, "aat2870-en");
407 dev_err(&client
->dev
,
408 "Failed to request GPIO %d\n", aat2870
->en_pin
);
413 aat2870_enable(aat2870
);
415 for (i
= 0; i
< pdata
->num_subdevs
; i
++) {
416 for (j
= 0; j
< ARRAY_SIZE(aat2870_devs
); j
++) {
417 if ((pdata
->subdevs
[i
].id
== aat2870_devs
[j
].id
) &&
418 !strcmp(pdata
->subdevs
[i
].name
,
419 aat2870_devs
[j
].name
)) {
420 aat2870_devs
[j
].platform_data
=
421 pdata
->subdevs
[i
].platform_data
;
427 ret
= mfd_add_devices(aat2870
->dev
, 0, aat2870_devs
,
428 ARRAY_SIZE(aat2870_devs
), NULL
, 0, NULL
);
430 dev_err(aat2870
->dev
, "Failed to add subdev: %d\n", ret
);
434 aat2870_init_debugfs(aat2870
);
439 aat2870_disable(aat2870
);
443 static int aat2870_i2c_remove(struct i2c_client
*client
)
445 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
447 aat2870_uninit_debugfs(aat2870
);
449 mfd_remove_devices(aat2870
->dev
);
450 aat2870_disable(aat2870
);
452 aat2870
->uninit(aat2870
);
457 #ifdef CONFIG_PM_SLEEP
458 static int aat2870_i2c_suspend(struct device
*dev
)
460 struct i2c_client
*client
= to_i2c_client(dev
);
461 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
463 aat2870_disable(aat2870
);
468 static int aat2870_i2c_resume(struct device
*dev
)
470 struct i2c_client
*client
= to_i2c_client(dev
);
471 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
472 struct aat2870_register
*reg
= NULL
;
475 aat2870_enable(aat2870
);
477 /* restore registers */
478 for (i
= 0; i
< AAT2870_REG_NUM
; i
++) {
479 reg
= &aat2870
->reg_cache
[i
];
481 aat2870
->write(aat2870
, i
, reg
->value
);
486 #endif /* CONFIG_PM_SLEEP */
488 static SIMPLE_DEV_PM_OPS(aat2870_pm_ops
, aat2870_i2c_suspend
,
491 static const struct i2c_device_id aat2870_i2c_id_table
[] = {
495 MODULE_DEVICE_TABLE(i2c
, aat2870_i2c_id_table
);
497 static struct i2c_driver aat2870_i2c_driver
= {
500 .pm
= &aat2870_pm_ops
,
502 .probe
= aat2870_i2c_probe
,
503 .remove
= aat2870_i2c_remove
,
504 .id_table
= aat2870_i2c_id_table
,
507 static int __init
aat2870_init(void)
509 return i2c_add_driver(&aat2870_i2c_driver
);
511 subsys_initcall(aat2870_init
);
513 static void __exit
aat2870_exit(void)
515 i2c_del_driver(&aat2870_i2c_driver
);
517 module_exit(aat2870_exit
);
519 MODULE_DESCRIPTION("Core support for the AnalogicTech AAT2870");
520 MODULE_LICENSE("GPL");
521 MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");