mfd: fusb302: change to host when connect type-c to standard-a cable
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / rt5036-core.c
1 /*
2  *  drivers/mfd/rt5036-core.c
3  *  Driver for Richtek RT5036 Core PMIC
4  *
5  *  Copyright (C) 2014 Richtek Technology Corp.
6  *  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/version.h>
17 #include <linux/mfd/core.h>
18
19 #include <linux/mfd/rt5036/rt5036.h>
20
21 #ifdef CONFIG_REGULATOR_RT5036
22 #ifdef CONFIG_OF
23 #define RT5036_BUCKVR_DEVS(_id, _idx)                           \
24 {                                                               \
25         .name           = RT5036_DEV_NAME "-regulator",         \
26         .num_resources  = 0,                                    \
27         .of_compatible  = "rt," RT5036_DEV_NAME "-dcdc" #_idx, \
28         .id             = RT5036_ID_##_id,                      \
29 }
30
31 #define RT5036_LDOVR_DEVS(_id, _idx)                            \
32 {                                                               \
33         .name           = RT5036_DEV_NAME "-regulator",         \
34         .num_resources  = 0,                                    \
35         .of_compatible  = "rt," RT5036_DEV_NAME "-ldo" #_idx,   \
36         .id             = RT5036_ID_##_id,                      \
37 }
38
39 #define RT5036_LSWVR_DEVS(_id, _idx)                            \
40 {                                                               \
41         .name = RT5036_DEV_NAME "-regulator",                   \
42         .num_resources = 0,                                     \
43         .of_compatible  = "rt," RT5036_DEV_NAME "-lsw" #_idx,   \
44         .id             = RT5036_ID_##_id,                      \
45 }
46 #else
47 #define RT5036_BUCKVR_DEVS(_id, _idx)                           \
48 {                                                               \
49         .name           = RT5036_DEV_NAME "-regulator",         \
50         .num_resources  = 0,                                    \
51         .id             = RT5036_ID_##_id,                      \
52 }
53
54 #define RT5036_LDOVR_DEVS(_id, _idx)                            \
55 {                                                               \
56         .name           = RT5036_DEV_NAME "-regulator",         \
57         .num_resources  = 0,                                    \
58         .id             = RT5036_ID_##_id,                      \
59 }
60
61 #define RT5036_LSWVR_DEVS(_id, _idx)                            \
62 {                                                               \
63         .name = RT5036_DEV_NAME "-regulator",                   \
64         .num_resources = 0,                                     \
65         .id             = RT5036_ID_##_id,                      \
66 }
67 #endif /* #ifdef CONFIG_OF */
68
69 static struct mfd_cell regulator_devs[] = {
70         RT5036_BUCKVR_DEVS(DCDC1, 1),
71         RT5036_BUCKVR_DEVS(DCDC2, 2),
72         RT5036_BUCKVR_DEVS(DCDC3, 3),
73         RT5036_BUCKVR_DEVS(DCDC4, 4),
74         RT5036_LDOVR_DEVS(LDO1, 1),
75         RT5036_LDOVR_DEVS(LDO2, 2),
76         RT5036_LDOVR_DEVS(LDO3, 3),
77         RT5036_LDOVR_DEVS(LDO4, 4),
78         RT5036_LSWVR_DEVS(LSW1, 1),
79         RT5036_LSWVR_DEVS(LSW2, 2),
80 };
81 #endif /* CONFIG_REGULATOR_RT5036 */
82
83 #ifdef CONFIG_CHARGER_RT5036
84 static struct mfd_cell chg_devs[] = {
85         {
86          .name = RT5036_DEV_NAME "-charger",
87          .id = -1,
88          .num_resources = 0,
89 #ifdef CONFIG_OF
90          .of_compatible = "rt," RT5036_DEV_NAME "-charger",
91 #endif /*#ifdef CONFIG_OF */
92          },
93 };
94 #endif /* CONFIG_CHARGER_RT5036 */
95
96 #ifdef CONFIG_RTC_RT5036
97 static struct mfd_cell rtc_devs[] = {
98         {
99          .name = RT5036_DEV_NAME "-rtc",
100          .id = -1,
101          .num_resources = 0,
102 #ifdef CONFIG_OF
103          .of_compatible = "rt," RT5036_DEV_NAME "-rtc",
104 #endif /*#ifdef CONFIG_OF */
105          },
106 };
107 #endif /* CONFIG_RTC_RT5036 */
108
109 #ifdef CONFIG_MISC_RT5036
110 static struct mfd_cell misc_devs[] = {
111         {
112          .name = RT5036_DEV_NAME "-misc",
113          .id = -1,
114          .num_resources = 0,
115 #ifdef CONFIG_OF
116          .of_compatible = "rt," RT5036_DEV_NAME "-misc",
117 #endif /*#ifdef CONFIG_OF */
118          },
119 };
120 #endif /* CONFIG_MISC_RT5036 */
121
122 #ifdef CONFIG_IRQ_RT5036
123 static struct mfd_cell irq_devs[] = {
124         {
125          .name = RT5036_DEV_NAME "-irq",
126          .id = -1,
127          .num_resources = 0,
128 #ifdef CONFIG_OF
129          .of_compatible = "rt," RT5036_DEV_NAME "-irq",
130 #endif /*#ifdef CONFIG_OF */
131          },
132 };
133 #endif /* CONFIG_IRQ_RT5036 */
134
135 #ifdef CONFIG_DEBUG_RT5036
136 static struct mfd_cell debug_devs[] = {
137         {
138          .name = RT5036_DEV_NAME "-debug",
139          .id = -1,
140          .num_resources = 0,
141 #ifdef CONFIG_OF
142          .of_compatible = "rt," RT5036_DEV_NAME "-debug",
143 #endif /*#ifdef CONFIG_OF */
144          },
145 };
146 #endif /* CONFIG_DEBUG_RT5036 */
147
148 int rt5036_core_init(struct device *dev,
149                                struct rt5036_platform_data *pdata)
150 {
151         int ret = 0;
152
153         RTINFO("Start to initialize all device\n");
154 #ifdef CONFIG_REGULATOR_RT5036
155         if (dev->of_node || (pdata && pdata->regulator[0])) {
156                 RTINFO("mfd add regulators dev\n");
157 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
158                 ret = mfd_add_devices(dev, 0, &regulator_devs[0],
159                                       ARRAY_SIZE(regulator_devs),
160                                       NULL, 0, NULL);
161 #else
162                 ret = mfd_add_devices(dev, 0, &regulator_devs[0],
163                                       ARRAY_SIZE(regulator_devs), NULL, 0);
164 #endif /* LINUX_VERSION_CODE>=KERNL_VERSION(3,6,0) */
165                 if (ret < 0) {
166                         dev_err(dev, "Failed to add regulator subdev\n");
167                         goto out_dev;
168                 }
169         }
170 #endif /* CONFIG_REGULATOR_RT5036 */
171
172 #ifdef CONFIG_CHARGER_RT5036
173         if (dev->of_node || (pdata && pdata->chg_pdata)) {
174                 RTINFO("mfd add charger dev\n");
175 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
176                 ret = mfd_add_devices(dev, 0, &chg_devs[0],
177                                       ARRAY_SIZE(chg_devs), NULL, 0, NULL);
178 #else
179                 ret = mfd_add_devices(dev, 0, &chg_devs[0],
180                                       ARRAY_SIZE(chg_devs), NULL, 0);
181 #endif /* LINUX_VERSION_CODE>=KERNL_VERSION(3,6,0) */
182                 if (ret < 0) {
183                         dev_err(dev, "Failed to add charger subdev\n");
184                         goto out_dev;
185                 }
186         }
187 #endif /* CONFIG_CHARGER_RT5036 */
188
189 #ifdef CONFIG_RTC_RT5036
190         if (dev->of_node || pdata) {
191                 RTINFO("mfd add rtc dev\n");
192 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
193                 ret = mfd_add_devices(dev, 0, &rtc_devs[0],
194                                       ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
195 #else
196                 ret = mfd_add_devices(dev, 0, &rtc_devs[0],
197                                       ARRAY_SIZE(rtc_devs), NULL, 0);
198 #endif /* LINUX_VERSION_CODE>=KERNL_VERSION(3,6,0) */
199                 if (ret < 0) {
200                         dev_err(dev, "Failed to add rtc subdev\n");
201                         goto out_dev;
202                 }
203         }
204 #endif /* CONFIG_RTC_RT5036 */
205
206 #ifdef CONFIG_MISC_RT5036
207         if (dev->of_node || (pdata && pdata->misc_pdata)) {
208                 RTINFO("mfd add misc dev\n");
209 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
210                 ret = mfd_add_devices(dev, 0, &misc_devs[0],
211                                       ARRAY_SIZE(misc_devs), NULL, 0, NULL);
212 #else
213                 ret = mfd_add_devices(dev, 0, &misc_devs[0],
214                                       ARRAY_SIZE(misc_devs), NULL, 0);
215 #endif /* LINUX_VERSION_CODE>=KERNL_VERSION(3,6,0) */
216                 if (ret < 0) {
217                         dev_err(dev, "Failed to add misc subdev\n");
218                         goto out_dev;
219                 }
220         }
221 #endif /* CONFIG_MISC_RT5036 */
222
223 #ifdef CONFIG_IRQ_RT5036
224         if (dev->of_node || (pdata && pdata->irq_pdata)) {
225                 RTINFO("mfd add irq dev\n");
226 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
227                 ret = mfd_add_devices(dev, 0, &irq_devs[0],
228                                       ARRAY_SIZE(irq_devs), NULL, 0, NULL);
229 #else
230                 ret = mfd_add_devices(dev, 0, &irq_devs[0],
231                                       ARRAY_SIZE(irq_devs), NULL, 0);
232 #endif /* LINUX_VERSION_CODE>=KERNL_VERSION(3,6,0) */
233                 if (ret < 0) {
234                         dev_err(dev, "Failed to add irq subdev\n");
235                         goto out_dev;
236                 }
237         }
238 #endif /* CONFIG_IRQ_RT5036 */
239
240 #ifdef CONFIG_DEBUG_RT5036
241         RTINFO("mfd add debug dev\n");
242 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
243         ret = mfd_add_devices(dev, 0, &debug_devs[0],
244                               ARRAY_SIZE(debug_devs), NULL, 0, NULL);
245 #else
246         ret = mfd_add_devices(dev, 0, &debug_devs[0],
247                               ARRAY_SIZE(debug_devs), NULL, 0);
248 #endif /* LINUX_VERSION_CODE>=KERNL_VERSION(3,6,0) */
249         if (ret < 0) {
250                 dev_err(dev, "Failed to add debug subdev\n");
251                 goto out_dev;
252         }
253 #endif /* CONFIG_DEBUG_RT5036 */
254
255         RTINFO("Initialize all device successfully\n");
256         return ret;
257 out_dev:
258         mfd_remove_devices(dev);
259         return ret;
260 }
261 EXPORT_SYMBOL(rt5036_core_init);
262
263 int rt5036_core_deinit(struct device *dev)
264 {
265         mfd_remove_devices(dev);
266         return 0;
267 }
268 EXPORT_SYMBOL(rt5036_core_deinit);