mfd: fusb302: change to host when connect type-c to standard-a cable
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rt5025-i2c.c
1 /* drivers/mfd/rt5025-i2c.c
2  * I2C Driver for Richtek RT5025
3  * Multi function device - multi functional baseband PMIC
4  *
5  * Copyright (C) 2014 Richtek Technology Corp.
6  * Author: CY Huang <cy_huang@richtek.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 version 2 as
10  * published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  */
13
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/i2c.h>
17 #include <linux/mfd/rt5025.h>
18
19 static inline int rt5025_read_device(struct i2c_client *i2c,
20                                       int reg, int bytes, void *dest)
21 {
22         int ret;
23
24         if (bytes > 1) {
25                 ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
26         } else {
27                 ret = i2c_smbus_read_byte_data(i2c, reg);
28                 if (ret < 0)
29                         return ret;
30                 *(unsigned char *)dest = (unsigned char)ret;
31         }
32         return ret;
33 }
34
35 int rt5025_reg_block_read(struct i2c_client *i2c, \
36                         int reg, int bytes, void *dest)
37 {
38         return rt5025_read_device(i2c, reg, bytes, dest);
39 }
40 EXPORT_SYMBOL(rt5025_reg_block_read);
41
42 static inline int rt5025_write_device(struct i2c_client *i2c,
43                                       int reg, int bytes, void *dest)
44 {
45         int ret;
46
47         if (bytes > 1) {
48                 ret = i2c_smbus_write_i2c_block_data(i2c, reg, bytes, dest);
49         } else {
50                 ret = i2c_smbus_write_byte_data(i2c, reg, *(u8 *)dest);
51                 if (ret < 0)
52                         return ret;
53         }
54         return ret;
55 }
56
57 int rt5025_reg_block_write(struct i2c_client *i2c, \
58                         int reg, int bytes, void *dest)
59 {
60         return rt5025_write_device(i2c, reg, bytes, dest);
61 }
62 EXPORT_SYMBOL(rt5025_reg_block_write);
63
64 int rt5025_reg_read(struct i2c_client *i2c, int reg)
65 {
66         int ret;
67
68         RTINFO("I2C Read (client : 0x%x) reg = 0x%x\n",
69                 (unsigned int) i2c, (unsigned int) reg);
70         ret = i2c_smbus_read_byte_data(i2c, reg);
71         return ret;
72 }
73 EXPORT_SYMBOL(rt5025_reg_read);
74
75 int rt5025_reg_write(struct i2c_client *i2c, int reg, unsigned char data)
76 {
77         int ret;
78
79         RTINFO("I2C Write (client : 0x%x) reg = 0x%x, data = 0x%x\n",
80                 (unsigned int) i2c, (unsigned int) reg, (unsigned int) data);
81         ret = i2c_smbus_write_byte_data(i2c, reg, data);
82         return ret;
83 }
84 EXPORT_SYMBOL(rt5025_reg_write);
85
86 int rt5025_assign_bits(struct i2c_client *i2c, int reg,
87                 unsigned char mask, unsigned char data)
88 {
89         unsigned char value;
90         int ret;
91
92         ret = rt5025_read_device(i2c, reg, 1, &value);
93
94         if (ret < 0)
95                 goto out;
96         value &= ~mask;
97         value |= (data&mask);
98         ret = i2c_smbus_write_byte_data(i2c, reg, value);
99 out:
100         return ret;
101 }
102 EXPORT_SYMBOL(rt5025_assign_bits);
103
104 int rt5025_set_bits(struct i2c_client *i2c, int reg,
105                 unsigned char mask)
106 {
107         return rt5025_assign_bits(i2c, reg, mask, mask);
108 }
109 EXPORT_SYMBOL(rt5025_set_bits);
110
111 int rt5025_clr_bits(struct i2c_client *i2c, int reg,
112                 unsigned char mask)
113 {
114         return rt5025_assign_bits(i2c, reg, mask, 0);
115 }
116 EXPORT_SYMBOL(rt5025_clr_bits);
117
118 static int rt_parse_dt(struct rt5025_chip *chip, struct device *dev)
119 {
120         return 0;
121 }
122
123 static int rt_parse_pdata(struct rt5025_chip *chip, struct device *dev)
124 {
125         return 0;
126 }
127
128 static int rt5025_i2c_probe(struct i2c_client *client,
129         const struct i2c_device_id *id)
130 {
131         struct rt5025_platform_data *pdata = client->dev.platform_data;
132         struct rt5025_chip *chip;
133         bool use_dt = client->dev.of_node;
134         int ret = 0;
135         u8 val = 0;
136
137         chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
138         if (!chip)
139                 return -ENOMEM;
140
141         if (use_dt) {
142                 rt_parse_dt(chip, &client->dev);
143         } else {
144                 if (!pdata) {
145                         ret = -EINVAL;
146                         goto err_init;
147                 }
148                 rt_parse_pdata(chip, &client->dev);
149         }
150
151         chip->i2c = client;
152         chip->dev = &client->dev;
153         mutex_init(&chip->io_lock);
154         i2c_set_clientdata(client, chip);
155         /* off event */
156         rt5025_read_device(client, 0x20, 1, &val);
157         RTINFO("off event = %d\n", val);
158
159         rt5025_read_device(client, 0x00, 1, &val);
160         if (val != 0x81) {
161                 dev_info(&client->dev, "The PMIC is not RT5025\n");
162                 return -ENODEV;
163         }
164
165         ret = rt5025_core_init(chip, pdata);
166         if (ret < 0) {
167                 dev_err(&client->dev, "rt5025_core_init_fail\n");
168                 goto err_init;
169         }
170
171         dev_info(&client->dev, "driver successfully probed\n");
172         if (pdata && pdata->pre_init) {
173                 ret = pdata->pre_init(chip);
174                 if (ret != 0)
175                         dev_err(chip->dev, "pre_init() failed: %d\n", ret);
176         }
177
178         if (pdata && pdata->post_init) {
179                 ret = pdata->post_init();
180                 if (ret != 0)
181                         dev_err(chip->dev, "post_init() failed: %d\n", ret);
182         }
183         return 0;
184 err_init:
185         return ret;
186
187 }
188
189 static int rt5025_i2c_remove(struct i2c_client *client)
190 {
191         struct rt5025_chip *chip = i2c_get_clientdata(client);
192
193         rt5025_core_deinit(chip);
194         dev_info(&client->dev, "%s\n", __func__);
195         return 0;
196 }
197
198 static int rt5025_i2c_suspend(struct device *dev)
199 {
200         struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
201         struct rt5025_chip *chip = i2c_get_clientdata(i2c);
202
203         RTINFO("\n");
204         chip->suspend = 1;
205         return 0;
206 }
207
208 static int rt5025_i2c_resume(struct device *dev)
209 {
210         struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
211         struct rt5025_chip *chip = i2c_get_clientdata(i2c);
212
213         RTINFO("\n");
214         chip->suspend = 0;
215         return 0;
216 }
217
218 static const struct dev_pm_ops rt5025_pm_ops = {
219         .suspend = rt5025_i2c_suspend,
220         .resume =  rt5025_i2c_resume,
221 };
222
223 static const struct i2c_device_id rt5025_id_table[] = {
224         { RT5025_DEV_NAME, 0 },
225         { },
226 };
227 MODULE_DEVICE_TABLE(i2c, rt5025_id_table);
228
229 static struct of_device_id rt_match_table[] = {
230         { .compatible = "rt,rt5025",},
231         {},
232 };
233
234 static struct i2c_driver rt5025_i2c_driver = {
235         .driver = {
236                 .name   = RT5025_DEV_NAME,
237                 .owner  = THIS_MODULE,
238                  .pm = &rt5025_pm_ops,
239                 .of_match_table = rt_match_table,
240         },
241         .probe          = rt5025_i2c_probe,
242         .remove         = rt5025_i2c_remove,
243         .id_table       = rt5025_id_table,
244 };
245
246 static int rt5025_i2c_init(void)
247 {
248         return i2c_add_driver(&rt5025_i2c_driver);
249 }
250 subsys_initcall_sync(rt5025_i2c_init);
251
252 static void rt5025_i2c_exit(void)
253 {
254         i2c_del_driver(&rt5025_i2c_driver);
255 }
256 module_exit(rt5025_i2c_exit);
257
258 MODULE_LICENSE("GPL");
259 MODULE_DESCRIPTION("I2C Driver for Richtek RT5025");
260 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com>");
261 MODULE_VERSION(RT5025_DRV_VER);