tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / arch / arm / mach-sc / sec-switch.c
1 /*
2  * arch/arm/mach-sc/sec-switch.c
3  *
4  * c source file supporting MUIC common platform device register
5  *
6  * Copyright (C) 2014 Samsung Electronics
7  * tyung.kim <tyung.kim@samsung.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  *
23  */
24
25 #include <linux/platform_device.h>
26 #include <linux/device.h>
27 #include <linux/kernel.h>
28 #include <linux/err.h>
29 #include <linux/power_supply.h>
30 #include <linux/module.h>
31 #include <linux/usb/gadget.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/mfd/sm5701_core.h>
34
35 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
36 #include <linux/i2c/ist30xxc.h>
37 #endif
38
39 #ifdef CONFIG_TOUCHSCREEN_ZINITIX_BT432
40 #include <linux/i2c/zinitix_ts.h>
41 #endif
42
43 #ifdef CONFIG_MFD_SM5504
44 #include <linux/mfd/sm5504.h>
45 #endif
46
47 #ifdef CONFIG_SWITCH
48 #include <linux/switch.h>
49 static struct switch_dev switch_dock = {
50         .name = "dock",
51 };
52
53 static struct switch_dev switch_usb = {
54         .name = "usb_cable",
55 };
56
57 static struct switch_dev switch_otg = {
58         .name = "otg",
59 };
60
61 static struct switch_dev switch_jig = {
62         .name = "jig_cable",
63 };
64 #endif /* CONFIG_SWITCH */
65
66 extern struct class *sec_class;
67 struct device *switch_device;
68 EXPORT_SYMBOL(switch_device);
69
70 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
71 struct tsp_callbacks *ist30xxc_charger_callbacks;
72 void ist30xxc_tsp_charger_infom(int cable_type)
73 {
74         if (ist30xxc_charger_callbacks && ist30xxc_charger_callbacks->inform_charger)
75                 ist30xxc_charger_callbacks->inform_charger(ist30xxc_charger_callbacks, cable_type);
76 }
77 #endif
78
79 #ifdef CONFIG_TOUCHSCREEN_ZINITIX_BT432
80 struct tsp_callbacks *zinitix_charger_callbacks;
81 void zinitix_tsp_charger_infom(int cable_type)
82 {
83         if (zinitix_charger_callbacks && zinitix_charger_callbacks->inform_charger)
84                 zinitix_charger_callbacks->inform_charger(zinitix_charger_callbacks, cable_type);
85 }
86 void zinitix_tsp_register_callback(struct tsp_callbacks *cb)
87 {
88         zinitix_charger_callbacks = cb;
89         pr_info("%s\n", __func__);
90 }
91 #endif
92
93 static void muic_init_cb(void)
94 {
95 #ifdef CONFIG_SWITCH
96         int ret;
97         pr_info("func:%s\n", __func__);
98
99         ret = switch_dev_register(&switch_dock);
100         if (ret < 0)
101                 pr_err("%s Failed to register dock switch(%d)\n", __func__, ret);
102
103         ret = switch_dev_register(&switch_usb);
104         if (ret < 0)
105                 pr_err("%s Failed to register usb switch(%d)\n", __func__, ret);
106
107         ret = switch_dev_register(&switch_otg);
108         if (ret < 0)
109                 pr_err("%s Failed to register otg switch(%d)\n", __func__, ret);
110
111         ret = switch_dev_register(&switch_jig);
112         if (ret < 0)
113                 pr_err("%s Failed to register jig switch(%d)\n", __func__, ret);
114 #endif
115 }
116
117 extern void usb_notify_cb(int plug_in);
118
119 static void muic_usb_cb(u8 attached)
120 {
121         pr_info("%s: usb_mode:%d\n", __func__, attached);
122
123         usb_notify_cb(attached);
124
125 #ifdef CONFIG_SWITCH
126         switch_set_state(&switch_usb, attached);
127 #endif
128         return;
129 }
130
131 static void muic_otg_cb(u8 attached)
132 {
133         pr_info("%s: otg_mode:%d\n", __func__, attached);
134
135
136
137 #ifdef CONFIG_SWITCH
138         switch_set_state(&switch_otg, attached);
139 #endif
140
141 #ifdef CONFIG_MFD_SM5504
142         if (attached) {
143                 SM5701_set_bstout(SM5701_BSTOUT_5P0);
144                 SM5701_set_operationmode(SM5701_OPERATIONMODE_OTG_ON);
145         }
146         else {
147                 SM5701_set_bstout(SM5701_BSTOUT_4P5);
148                 SM5701_clear_operationmode(SM5701_OPERATIONMODE_OTG_ON);
149         }
150 #endif
151
152         return;
153 }
154
155 #ifdef CONFIG_TOUCHSCREEN_IST30XXB
156 void charger_enable(int enable);
157 #endif
158
159 bool is_jig_on;
160 #ifdef CONFIG_MFD_SM5504
161 extern int current_cable_type;
162 #endif
163
164 static void muic_charger_cb(int cable_type)
165 {
166         struct power_supply *psy = power_supply_get_by_name("battery");
167         union  power_supply_propval value;
168
169         pr_info("%s: cable type (0x%02x)\n", __func__, cable_type);
170
171 #ifdef CONFIG_TOUCHSCREEN_ZINITIX_BT432
172         zinitix_tsp_charger_infom(cable_type);
173 #endif
174
175 #ifdef CONFIG_MFD_SM5504
176         switch (cable_type) {
177                 case MUIC_SM5504_CABLE_TYPE_NONE:
178                 case MUIC_SM5504_CABLE_TYPE_UNKNOWN:
179                         current_cable_type = POWER_SUPPLY_TYPE_BATTERY;
180                         is_jig_on = false;
181 #ifdef CONFIG_TOUCHSCREEN_IST30XXB
182                         charger_enable(0);
183 #endif
184 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
185                         ist30xxc_tsp_charger_infom(0);
186 #endif
187                         break;
188                 case MUIC_SM5504_CABLE_TYPE_USB:
189                 case MUIC_SM5504_CABLE_TYPE_CDP:
190                 case MUIC_SM5504_CABLE_TYPE_L_USB:
191                 case MUIC_SM5504_CABLE_TYPE_0x15:
192                 case MUIC_SM5504_CABLE_TYPE_TYPE1_CHARGER:
193                         current_cable_type = POWER_SUPPLY_TYPE_USB;
194                         is_jig_on = false;
195 #ifdef CONFIG_TOUCHSCREEN_IST30XXB
196                         charger_enable(1);
197 #endif
198 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
199                         ist30xxc_tsp_charger_infom(1);
200 #endif
201                         break;
202                 case MUIC_SM5504_CABLE_TYPE_REGULAR_TA:
203                 case MUIC_SM5504_CABLE_TYPE_ATT_TA:
204                         current_cable_type = POWER_SUPPLY_TYPE_MAINS;
205                         is_jig_on = false;
206 #ifdef CONFIG_TOUCHSCREEN_IST30XXB
207                         charger_enable(1);
208 #endif
209 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
210                         ist30xxc_tsp_charger_infom(1);
211 #endif
212                         break;
213                 case MUIC_SM5504_CABLE_TYPE_OTG:
214 #if 0 /*def CONFIG_MACH_KIRAN*/
215                         current_cable_type = POWER_SUPPLY_TYPE_USB;
216                         is_jig_on = false;
217 #else
218                         goto skip;
219 #endif
220                 case MUIC_SM5504_CABLE_TYPE_JIG_UART_OFF_WITH_VBUS:
221                 case MUIC_SM5504_CABLE_TYPE_JIG_UART_ON_WITH_VBUS:
222                         current_cable_type = POWER_SUPPLY_TYPE_UARTOFF;
223                         is_jig_on = true;
224                         break;
225                 case MUIC_SM5504_CABLE_TYPE_JIG_UART_OFF:
226                 case MUIC_SM5504_CABLE_TYPE_JIG_UART_ON:
227                         current_cable_type = POWER_SUPPLY_TYPE_BATTERY;
228                         is_jig_on = true;
229                         break;
230                 case MUIC_SM5504_CABLE_TYPE_JIG_USB_ON:
231                 case MUIC_SM5504_CABLE_TYPE_JIG_USB_OFF:
232                         current_cable_type = POWER_SUPPLY_TYPE_USB;
233                         is_jig_on = true;
234 #ifdef CONFIG_TOUCHSCREEN_IST30XXB
235                         charger_enable(1);
236 #endif
237 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
238                         ist30xxc_tsp_charger_infom(1);
239 #endif
240                         break;
241                 case MUIC_SM5504_CABLE_TYPE_0x1A:
242                 case MUIC_SM5504_CABLE_TYPE_UART:
243                         current_cable_type = POWER_SUPPLY_TYPE_MAINS;
244                         is_jig_on = false;
245 #ifdef CONFIG_TOUCHSCREEN_IST30XXB
246                         charger_enable(1);
247 #endif
248 #ifdef CONFIG_TOUCHSCREEN_IMAGIS_IST30XXC
249                         ist30xxc_tsp_charger_infom(1);
250 #endif
251                         break;
252                 default:
253                         pr_err("%s: invalid type for charger:%d\n",
254                                         __func__, cable_type);
255                         current_cable_type = POWER_SUPPLY_TYPE_UNKNOWN;
256                         goto skip;
257         }
258
259         if (!psy || !psy->set_property)
260                 pr_err("%s: fail to get battery psy\n", __func__);
261         else {
262                 value.intval = current_cable_type;
263                 psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value);
264         }
265 #endif
266
267 skip:
268         return;
269 }
270
271 static void muic_dock_cb(u8 type)
272 {
273         pr_info("%s: type: %d\n", __func__, type);
274
275 #ifdef CONFIG_SWITCH
276         switch_set_state(&switch_dock, type);
277 #endif
278 }
279
280 bool is_jig_attached;
281 int muic_get_jig_state(void)
282 {
283         return is_jig_attached;
284 }
285 EXPORT_SYMBOL(muic_get_jig_state);
286
287 static void muic_set_jig_state(u8 attached)
288 {
289         pr_info("%s: attached: %d\n", __func__, attached);
290         is_jig_attached = !!attached;
291
292 #ifdef CONFIG_SWITCH
293         switch_set_state(&switch_jig, !!attached);
294 #endif
295 }
296
297 struct sec_switch_data switch_data = {
298         .init_cb = muic_init_cb,
299         .dock_cb = muic_dock_cb,
300         .usb_cb  = muic_usb_cb,
301         .otg_cb  = muic_otg_cb,
302         .cable_chg_cb = muic_charger_cb,
303         .set_jig_state_cb = muic_set_jig_state,
304 };
305
306 static int __init sec_switch_init(void)
307 {
308         if (!sec_class) {
309                 pr_err("%s: sec_class is null\n", __func__);
310                 return -ENODEV;
311         }
312
313         switch_device = device_create(sec_class, NULL, 0, NULL, "switch");
314         if (IS_ERR(switch_device)) {
315                 pr_err("%s: Failed to create device(switch)!\n", __func__);
316                 return -ENODEV;
317         }
318
319         return 0;
320 };
321
322 device_initcall(sec_switch_init);