1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/drivers/mfd/aat2870-core.c
5 * Copyright (c) 2011, NVIDIA Corporation.
6 * Author: Jin Park <jinyoungp@nvidia.com>
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/debugfs.h>
12 #include <linux/slab.h>
13 #include <linux/uaccess.h>
14 #include <linux/i2c.h>
15 #include <linux/delay.h>
16 #include <linux/gpio.h>
17 #include <linux/mfd/core.h>
18 #include <linux/mfd/aat2870.h>
19 #include <linux/regulator/machine.h>
21 static struct aat2870_register aat2870_regs
[AAT2870_REG_NUM
] = {
22 /* readable, writeable, value */
23 { 0, 1, 0x00 }, /* 0x00 AAT2870_BL_CH_EN */
24 { 0, 1, 0x16 }, /* 0x01 AAT2870_BLM */
25 { 0, 1, 0x16 }, /* 0x02 AAT2870_BLS */
26 { 0, 1, 0x56 }, /* 0x03 AAT2870_BL1 */
27 { 0, 1, 0x56 }, /* 0x04 AAT2870_BL2 */
28 { 0, 1, 0x56 }, /* 0x05 AAT2870_BL3 */
29 { 0, 1, 0x56 }, /* 0x06 AAT2870_BL4 */
30 { 0, 1, 0x56 }, /* 0x07 AAT2870_BL5 */
31 { 0, 1, 0x56 }, /* 0x08 AAT2870_BL6 */
32 { 0, 1, 0x56 }, /* 0x09 AAT2870_BL7 */
33 { 0, 1, 0x56 }, /* 0x0A AAT2870_BL8 */
34 { 0, 1, 0x00 }, /* 0x0B AAT2870_FLR */
35 { 0, 1, 0x03 }, /* 0x0C AAT2870_FM */
36 { 0, 1, 0x03 }, /* 0x0D AAT2870_FS */
37 { 0, 1, 0x10 }, /* 0x0E AAT2870_ALS_CFG0 */
38 { 0, 1, 0x06 }, /* 0x0F AAT2870_ALS_CFG1 */
39 { 0, 1, 0x00 }, /* 0x10 AAT2870_ALS_CFG2 */
40 { 1, 0, 0x00 }, /* 0x11 AAT2870_AMB */
41 { 0, 1, 0x00 }, /* 0x12 AAT2870_ALS0 */
42 { 0, 1, 0x00 }, /* 0x13 AAT2870_ALS1 */
43 { 0, 1, 0x00 }, /* 0x14 AAT2870_ALS2 */
44 { 0, 1, 0x00 }, /* 0x15 AAT2870_ALS3 */
45 { 0, 1, 0x00 }, /* 0x16 AAT2870_ALS4 */
46 { 0, 1, 0x00 }, /* 0x17 AAT2870_ALS5 */
47 { 0, 1, 0x00 }, /* 0x18 AAT2870_ALS6 */
48 { 0, 1, 0x00 }, /* 0x19 AAT2870_ALS7 */
49 { 0, 1, 0x00 }, /* 0x1A AAT2870_ALS8 */
50 { 0, 1, 0x00 }, /* 0x1B AAT2870_ALS9 */
51 { 0, 1, 0x00 }, /* 0x1C AAT2870_ALSA */
52 { 0, 1, 0x00 }, /* 0x1D AAT2870_ALSB */
53 { 0, 1, 0x00 }, /* 0x1E AAT2870_ALSC */
54 { 0, 1, 0x00 }, /* 0x1F AAT2870_ALSD */
55 { 0, 1, 0x00 }, /* 0x20 AAT2870_ALSE */
56 { 0, 1, 0x00 }, /* 0x21 AAT2870_ALSF */
57 { 0, 1, 0x00 }, /* 0x22 AAT2870_SUB_SET */
58 { 0, 1, 0x00 }, /* 0x23 AAT2870_SUB_CTRL */
59 { 0, 1, 0x00 }, /* 0x24 AAT2870_LDO_AB */
60 { 0, 1, 0x00 }, /* 0x25 AAT2870_LDO_CD */
61 { 0, 1, 0x00 }, /* 0x26 AAT2870_LDO_EN */
64 static struct mfd_cell aat2870_devs
[] = {
66 .name
= "aat2870-backlight",
68 .pdata_size
= sizeof(struct aat2870_bl_platform_data
),
71 .name
= "aat2870-regulator",
72 .id
= AAT2870_ID_LDOA
,
73 .pdata_size
= sizeof(struct regulator_init_data
),
76 .name
= "aat2870-regulator",
77 .id
= AAT2870_ID_LDOB
,
78 .pdata_size
= sizeof(struct regulator_init_data
),
81 .name
= "aat2870-regulator",
82 .id
= AAT2870_ID_LDOC
,
83 .pdata_size
= sizeof(struct regulator_init_data
),
86 .name
= "aat2870-regulator",
87 .id
= AAT2870_ID_LDOD
,
88 .pdata_size
= sizeof(struct regulator_init_data
),
92 static int __aat2870_read(struct aat2870_data
*aat2870
, u8 addr
, u8
*val
)
96 if (addr
>= AAT2870_REG_NUM
) {
97 dev_err(aat2870
->dev
, "Invalid address, 0x%02x\n", addr
);
101 if (!aat2870
->reg_cache
[addr
].readable
) {
102 *val
= aat2870
->reg_cache
[addr
].value
;
106 ret
= i2c_master_send(aat2870
->client
, &addr
, 1);
112 ret
= i2c_master_recv(aat2870
->client
, val
, 1);
119 dev_dbg(aat2870
->dev
, "read: addr=0x%02x, val=0x%02x\n", addr
, *val
);
123 static int __aat2870_write(struct aat2870_data
*aat2870
, u8 addr
, u8 val
)
128 if (addr
>= AAT2870_REG_NUM
) {
129 dev_err(aat2870
->dev
, "Invalid address, 0x%02x\n", addr
);
133 if (!aat2870
->reg_cache
[addr
].writeable
) {
134 dev_err(aat2870
->dev
, "Address 0x%02x is not writeable\n",
141 ret
= i2c_master_send(aat2870
->client
, msg
, 2);
147 aat2870
->reg_cache
[addr
].value
= val
;
149 dev_dbg(aat2870
->dev
, "write: addr=0x%02x, val=0x%02x\n", addr
, val
);
153 static int aat2870_read(struct aat2870_data
*aat2870
, u8 addr
, u8
*val
)
157 mutex_lock(&aat2870
->io_lock
);
158 ret
= __aat2870_read(aat2870
, addr
, val
);
159 mutex_unlock(&aat2870
->io_lock
);
164 static int aat2870_write(struct aat2870_data
*aat2870
, u8 addr
, u8 val
)
168 mutex_lock(&aat2870
->io_lock
);
169 ret
= __aat2870_write(aat2870
, addr
, val
);
170 mutex_unlock(&aat2870
->io_lock
);
175 static int aat2870_update(struct aat2870_data
*aat2870
, u8 addr
, u8 mask
,
182 mutex_lock(&aat2870
->io_lock
);
184 ret
= __aat2870_read(aat2870
, addr
, &old_val
);
188 new_val
= (old_val
& ~mask
) | (val
& mask
);
189 change
= old_val
!= new_val
;
191 ret
= __aat2870_write(aat2870
, addr
, new_val
);
194 mutex_unlock(&aat2870
->io_lock
);
199 static inline void aat2870_enable(struct aat2870_data
*aat2870
)
201 if (aat2870
->en_pin
>= 0)
202 gpio_set_value(aat2870
->en_pin
, 1);
204 aat2870
->is_enable
= 1;
207 static inline void aat2870_disable(struct aat2870_data
*aat2870
)
209 if (aat2870
->en_pin
>= 0)
210 gpio_set_value(aat2870
->en_pin
, 0);
212 aat2870
->is_enable
= 0;
215 #ifdef CONFIG_DEBUG_FS
216 static ssize_t
aat2870_dump_reg(struct aat2870_data
*aat2870
, char *buf
)
222 count
+= sprintf(buf
, "aat2870 registers\n");
223 for (addr
= 0; addr
< AAT2870_REG_NUM
; addr
++) {
224 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "0x%02x: ", addr
);
225 if (count
>= PAGE_SIZE
- 1)
228 ret
= aat2870
->read(aat2870
, addr
, &val
);
230 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
233 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
,
234 "<read fail: %d>", ret
);
236 if (count
>= PAGE_SIZE
- 1)
239 count
+= snprintf(buf
+ count
, PAGE_SIZE
- count
, "\n");
240 if (count
>= PAGE_SIZE
- 1)
244 /* Truncate count; min() would cause a warning */
245 if (count
>= PAGE_SIZE
)
246 count
= PAGE_SIZE
- 1;
251 static ssize_t
aat2870_reg_read_file(struct file
*file
, char __user
*user_buf
,
252 size_t count
, loff_t
*ppos
)
254 struct aat2870_data
*aat2870
= file
->private_data
;
258 buf
= kmalloc(PAGE_SIZE
, GFP_KERNEL
);
262 ret
= aat2870_dump_reg(aat2870
, buf
);
264 ret
= simple_read_from_buffer(user_buf
, count
, ppos
, buf
, ret
);
271 static ssize_t
aat2870_reg_write_file(struct file
*file
,
272 const char __user
*user_buf
, size_t count
,
275 struct aat2870_data
*aat2870
= file
->private_data
;
279 unsigned long addr
, val
;
282 buf_size
= min(count
, (size_t)(sizeof(buf
)-1));
283 if (copy_from_user(buf
, user_buf
, buf_size
)) {
284 dev_err(aat2870
->dev
, "Failed to copy from user\n");
289 while (*start
== ' ')
292 ret
= kstrtoul(start
, 16, &addr
);
296 if (addr
>= AAT2870_REG_NUM
) {
297 dev_err(aat2870
->dev
, "Invalid address, 0x%lx\n", addr
);
301 while (*start
== ' ')
304 ret
= kstrtoul(start
, 16, &val
);
308 ret
= aat2870
->write(aat2870
, (u8
)addr
, (u8
)val
);
315 static const struct file_operations aat2870_reg_fops
= {
317 .read
= aat2870_reg_read_file
,
318 .write
= aat2870_reg_write_file
,
321 static void aat2870_init_debugfs(struct aat2870_data
*aat2870
)
323 aat2870
->dentry_root
= debugfs_create_dir("aat2870", NULL
);
325 debugfs_create_file("regs", 0644, aat2870
->dentry_root
, aat2870
,
330 static inline void aat2870_init_debugfs(struct aat2870_data
*aat2870
)
333 #endif /* CONFIG_DEBUG_FS */
335 static int aat2870_i2c_probe(struct i2c_client
*client
)
337 struct aat2870_platform_data
*pdata
= dev_get_platdata(&client
->dev
);
338 struct aat2870_data
*aat2870
;
342 aat2870
= devm_kzalloc(&client
->dev
, sizeof(struct aat2870_data
),
347 aat2870
->dev
= &client
->dev
;
348 aat2870
->client
= client
;
349 i2c_set_clientdata(client
, aat2870
);
351 aat2870
->reg_cache
= aat2870_regs
;
353 if (pdata
->en_pin
< 0)
354 aat2870
->en_pin
= -1;
356 aat2870
->en_pin
= pdata
->en_pin
;
358 aat2870
->init
= pdata
->init
;
359 aat2870
->uninit
= pdata
->uninit
;
360 aat2870
->read
= aat2870_read
;
361 aat2870
->write
= aat2870_write
;
362 aat2870
->update
= aat2870_update
;
364 mutex_init(&aat2870
->io_lock
);
367 aat2870
->init(aat2870
);
369 if (aat2870
->en_pin
>= 0) {
370 ret
= devm_gpio_request_one(&client
->dev
, aat2870
->en_pin
,
371 GPIOF_OUT_INIT_HIGH
, "aat2870-en");
373 dev_err(&client
->dev
,
374 "Failed to request GPIO %d\n", aat2870
->en_pin
);
379 aat2870_enable(aat2870
);
381 for (i
= 0; i
< pdata
->num_subdevs
; i
++) {
382 for (j
= 0; j
< ARRAY_SIZE(aat2870_devs
); j
++) {
383 if ((pdata
->subdevs
[i
].id
== aat2870_devs
[j
].id
) &&
384 !strcmp(pdata
->subdevs
[i
].name
,
385 aat2870_devs
[j
].name
)) {
386 aat2870_devs
[j
].platform_data
=
387 pdata
->subdevs
[i
].platform_data
;
393 ret
= mfd_add_devices(aat2870
->dev
, 0, aat2870_devs
,
394 ARRAY_SIZE(aat2870_devs
), NULL
, 0, NULL
);
396 dev_err(aat2870
->dev
, "Failed to add subdev: %d\n", ret
);
400 aat2870_init_debugfs(aat2870
);
405 aat2870_disable(aat2870
);
409 static int aat2870_i2c_suspend(struct device
*dev
)
411 struct i2c_client
*client
= to_i2c_client(dev
);
412 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
414 aat2870_disable(aat2870
);
419 static int aat2870_i2c_resume(struct device
*dev
)
421 struct i2c_client
*client
= to_i2c_client(dev
);
422 struct aat2870_data
*aat2870
= i2c_get_clientdata(client
);
423 struct aat2870_register
*reg
= NULL
;
426 aat2870_enable(aat2870
);
428 /* restore registers */
429 for (i
= 0; i
< AAT2870_REG_NUM
; i
++) {
430 reg
= &aat2870
->reg_cache
[i
];
432 aat2870
->write(aat2870
, i
, reg
->value
);
438 static DEFINE_SIMPLE_DEV_PM_OPS(aat2870_pm_ops
, aat2870_i2c_suspend
,
441 static const struct i2c_device_id aat2870_i2c_id_table
[] = {
446 static struct i2c_driver aat2870_i2c_driver
= {
449 .pm
= pm_sleep_ptr(&aat2870_pm_ops
),
450 .suppress_bind_attrs
= true,
452 .probe
= aat2870_i2c_probe
,
453 .id_table
= aat2870_i2c_id_table
,
456 static int __init
aat2870_init(void)
458 return i2c_add_driver(&aat2870_i2c_driver
);
460 subsys_initcall(aat2870_init
);