diff options
Diffstat (limited to 'drivers/mfd/da9052-i2c.c')
-rw-r--r-- | drivers/mfd/da9052-i2c.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c new file mode 100644 index 000000000000..44b97c70a61f --- /dev/null +++ b/drivers/mfd/da9052-i2c.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * I2C access for DA9052 PMICs. | ||
3 | * | ||
4 | * Copyright(c) 2011 Dialog Semiconductor Ltd. | ||
5 | * | ||
6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/input.h> | ||
18 | #include <linux/mfd/core.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/err.h> | ||
21 | |||
22 | #include <linux/mfd/da9052/da9052.h> | ||
23 | #include <linux/mfd/da9052/reg.h> | ||
24 | |||
25 | static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) | ||
26 | { | ||
27 | int reg_val, ret; | ||
28 | |||
29 | ret = regmap_read(da9052->regmap, DA9052_CONTROL_B_REG, ®_val); | ||
30 | if (ret < 0) | ||
31 | return ret; | ||
32 | |||
33 | if (reg_val & DA9052_CONTROL_B_WRITEMODE) { | ||
34 | reg_val &= ~DA9052_CONTROL_B_WRITEMODE; | ||
35 | ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG, | ||
36 | reg_val); | ||
37 | if (ret < 0) | ||
38 | return ret; | ||
39 | } | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int __devinit da9052_i2c_probe(struct i2c_client *client, | ||
45 | const struct i2c_device_id *id) | ||
46 | { | ||
47 | struct da9052 *da9052; | ||
48 | int ret; | ||
49 | |||
50 | da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); | ||
51 | if (!da9052) | ||
52 | return -ENOMEM; | ||
53 | |||
54 | if (!i2c_check_functionality(client->adapter, | ||
55 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
56 | dev_info(&client->dev, "Error in %s:i2c_check_functionality\n", | ||
57 | __func__); | ||
58 | ret = -ENODEV; | ||
59 | goto err; | ||
60 | } | ||
61 | |||
62 | da9052->dev = &client->dev; | ||
63 | da9052->chip_irq = client->irq; | ||
64 | |||
65 | i2c_set_clientdata(client, da9052); | ||
66 | |||
67 | da9052->regmap = regmap_init_i2c(client, &da9052_regmap_config); | ||
68 | if (IS_ERR(da9052->regmap)) { | ||
69 | ret = PTR_ERR(da9052->regmap); | ||
70 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | ||
71 | ret); | ||
72 | goto err; | ||
73 | } | ||
74 | |||
75 | ret = da9052_i2c_enable_multiwrite(da9052); | ||
76 | if (ret < 0) | ||
77 | goto err; | ||
78 | |||
79 | ret = da9052_device_init(da9052, id->driver_data); | ||
80 | if (ret != 0) | ||
81 | goto err; | ||
82 | |||
83 | return 0; | ||
84 | |||
85 | err: | ||
86 | kfree(da9052); | ||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | static int da9052_i2c_remove(struct i2c_client *client) | ||
91 | { | ||
92 | struct da9052 *da9052 = i2c_get_clientdata(client); | ||
93 | |||
94 | da9052_device_exit(da9052); | ||
95 | kfree(da9052); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static struct i2c_device_id da9052_i2c_id[] = { | ||
101 | {"da9052", DA9052}, | ||
102 | {"da9053-aa", DA9053_AA}, | ||
103 | {"da9053-ba", DA9053_BA}, | ||
104 | {"da9053-bb", DA9053_BB}, | ||
105 | {} | ||
106 | }; | ||
107 | |||
108 | static struct i2c_driver da9052_i2c_driver = { | ||
109 | .probe = da9052_i2c_probe, | ||
110 | .remove = da9052_i2c_remove, | ||
111 | .id_table = da9052_i2c_id, | ||
112 | .driver = { | ||
113 | .name = "da9052", | ||
114 | .owner = THIS_MODULE, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static int __init da9052_i2c_init(void) | ||
119 | { | ||
120 | int ret; | ||
121 | |||
122 | ret = i2c_add_driver(&da9052_i2c_driver); | ||
123 | if (ret != 0) { | ||
124 | pr_err("DA9052 I2C registration failed %d\n", ret); | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | subsys_initcall(da9052_i2c_init); | ||
131 | |||
132 | static void __exit da9052_i2c_exit(void) | ||
133 | { | ||
134 | i2c_del_driver(&da9052_i2c_driver); | ||
135 | } | ||
136 | module_exit(da9052_i2c_exit); | ||
137 | |||
138 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
139 | MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC"); | ||
140 | MODULE_LICENSE("GPL"); | ||