import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / ssw / ssw_generic_v2 / sim_switch.c
1
2 #include <ssw.h>
3 #include <mach/mt_ccci_common.h>
4 #include "cust_gpio_usage.h"
5 /*--------------Feature option---------------*/
6 #define __ENABLE_SSW_SYSFS 1
7
8 /*--------------SIM mode list----------------*/
9 #define SINGLE_TALK_MDSYS (0x1)
10 #define SINGLE_TALK_MDSYS_LITE (0x2)
11 #define DUAL_TALK (0x3)
12 #define DUAL_TALK_SWAP (0x4)
13
14 /*----------------variable define-----------------*/
15 unsigned int sim_mode_curr = SINGLE_TALK_MDSYS;
16
17 struct mutex sim_switch_mutex;
18
19 static int set_sim_gpio(unsigned int mode);
20
21 static int get_current_ssw_mode(void){ return sim_mode_curr; }
22
23
24 unsigned int get_sim_switch_type(void)
25 {
26 printk("[ccci/ssw]SSW_GENERIC_V2\n");
27 return SSW_INTERN;
28 }
29 EXPORT_SYMBOL(get_sim_switch_type);
30
31 /*---------------------------------------------------------------------------*/
32 /*define sysfs entry for configuring debug level and sysrq*/
33 ssize_t ssw_attr_show(struct kobject *kobj, struct attribute *attr, char *buffer);
34 ssize_t ssw_attr_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t size);
35 ssize_t ssw_mode_show(struct kobject *kobj, char *page);
36 ssize_t ssw_mode_store(struct kobject *kobj, const char *page, size_t size);
37
38 struct sysfs_ops ssw_sysfs_ops = {
39 .show = ssw_attr_show,
40 .store = ssw_attr_store,
41 };
42
43 struct ssw_sys_entry {
44 struct attribute attr;
45 ssize_t (*show)(struct kobject *kobj, char *page);
46 ssize_t (*store)(struct kobject *kobj, const char *page, size_t size);
47 };
48
49 static struct ssw_sys_entry mode_entry = {
50 { .name = "mode", .mode = S_IRUGO | S_IWUSR }, // remove .owner = NULL,
51 ssw_mode_show,
52 ssw_mode_store,
53 };
54
55 struct attribute *ssw_attributes[] = {
56 &mode_entry.attr,
57 NULL,
58 };
59
60 struct kobj_type ssw_ktype = {
61 .sysfs_ops = &ssw_sysfs_ops,
62 .default_attrs = ssw_attributes,
63 };
64
65 static struct ssw_sysobj_t {
66 struct kobject kobj;
67 } ssw_sysobj;
68
69
70 int ssw_sysfs_init(void)
71 {
72 struct ssw_sysobj_t *obj = &ssw_sysobj;
73
74 memset(&obj->kobj, 0x00, sizeof(obj->kobj));
75
76 obj->kobj.parent = kernel_kobj;
77 if (kobject_init_and_add(&obj->kobj, &ssw_ktype, NULL, "mtk_ssw")) {
78 kobject_put(&obj->kobj);
79 return -ENOMEM;
80 }
81 kobject_uevent(&obj->kobj, KOBJ_ADD);
82
83 return 0;
84 }
85
86 ssize_t ssw_attr_show(struct kobject *kobj, struct attribute *attr, char *buffer)
87 {
88 struct ssw_sys_entry *entry = container_of(attr, struct ssw_sys_entry, attr);
89 return entry->show(kobj, buffer);
90 }
91
92 ssize_t ssw_attr_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t size)
93 {
94 struct ssw_sys_entry *entry = container_of(attr, struct ssw_sys_entry, attr);
95 return entry->store(kobj, buffer, size);
96 }
97
98 ssize_t ssw_mode_show(struct kobject *kobj, char *buffer)
99 {
100 int remain = PAGE_SIZE;
101 int len;
102 char *ptr = buffer;
103
104 len = scnprintf(ptr, remain, "0x%x\n", get_current_ssw_mode());
105 ptr += len;
106 remain -= len;
107 SSW_DBG("ssw_mode_show\n");
108
109 return (PAGE_SIZE-remain);
110 }
111 ssize_t ssw_mode_store(struct kobject *kobj, const char *buffer, size_t size)
112 {
113 unsigned int mode;
114 int res = sscanf(buffer, "%x", &mode);
115 unsigned int type;
116
117 if (res != 1)
118 {
119 SSW_DBG("%s: expect 1 numbers\n", __FUNCTION__);
120 }
121 else
122 {
123 SSW_DBG("ssw_mode_store %x\n", mode);
124 //Switch sim mode
125 type = (mode&0xFFFF0000)>>16;
126 mode = mode&0x0000FFFF;
127 if(type == 0) { // Internal
128 SSW_DBG("Internal sim switch: %d-->%d\n", sim_mode_curr, mode);
129 if ((sim_mode_curr != mode) && (SSW_SUCCESS == set_sim_gpio(mode)))
130 {
131 sim_mode_curr = mode;
132 }
133 }
134 }
135 return size;
136 }
137 /*---------------------------------------------------------------------------*/
138
139 /*************************************************************************/
140 /* sim switch hardware operation */
141 /* */
142 /*************************************************************************/
143
144 static int set_sim_gpio(unsigned int mode)
145 {
146 SSW_DBG("set_sim_gpio: %d\n", mode);
147 switch(mode)
148 {
149 case SINGLE_TALK_MDSYS:
150 //SIM1=> MD1 SIM1IF
151 mt_set_gpio_mode(GPIO_SIM1_SCLK,1);
152 mt_set_gpio_mode(GPIO_SIM1_SRST,1);
153 mt_set_gpio_mode(GPIO_SIM1_SIO ,1);
154 //SIM2=> MD1 SIM2IF
155 mt_set_gpio_mode(GPIO_SIM2_SCLK,1);
156 mt_set_gpio_mode(GPIO_SIM2_SRST,1);
157 mt_set_gpio_mode(GPIO_SIM2_SIO ,1);
158 break;
159 case SINGLE_TALK_MDSYS_LITE:
160 //SIM1=> MD2 SIM1IF
161 mt_set_gpio_mode(GPIO_SIM1_SCLK,2);
162 mt_set_gpio_mode(GPIO_SIM1_SRST,2);
163 mt_set_gpio_mode(GPIO_SIM1_SIO ,2);
164 //SIM2=> MD2 SIM2IF
165 mt_set_gpio_mode(GPIO_SIM2_SCLK,2);
166 mt_set_gpio_mode(GPIO_SIM2_SRST,2);
167 mt_set_gpio_mode(GPIO_SIM2_SIO ,2);
168 break;
169 case DUAL_TALK:
170 //SIM1=> MD1 SIM1IF
171 mt_set_gpio_mode(GPIO_SIM1_SCLK,1);
172 mt_set_gpio_mode(GPIO_SIM1_SRST,1);
173 mt_set_gpio_mode(GPIO_SIM1_SIO ,1);
174 //SIM2=> MD2 SIM2IF
175 mt_set_gpio_mode(GPIO_SIM2_SCLK,2);
176 mt_set_gpio_mode(GPIO_SIM2_SRST,2);
177 mt_set_gpio_mode(GPIO_SIM2_SIO ,2);
178 break;
179 case DUAL_TALK_SWAP:
180 //SIM1=> MD2 SIM1IF
181 mt_set_gpio_mode(GPIO_SIM1_SCLK,2);
182 mt_set_gpio_mode(GPIO_SIM1_SRST,2);
183 mt_set_gpio_mode(GPIO_SIM1_SIO ,2);
184 //SIM2=> MD1 SIM2IF
185 mt_set_gpio_mode(GPIO_SIM2_SCLK,1);
186 mt_set_gpio_mode(GPIO_SIM2_SRST,1);
187 mt_set_gpio_mode(GPIO_SIM2_SIO ,1);
188 break;
189 default:
190 SSW_DBG("[Error] Invalid Mode(%d)", mode);
191 return SSW_INVALID_PARA;
192 }
193
194 SSW_DBG("mode(%d),SIM1(sclk=%d, srst=%d , sio=%d) SIM2(sclk=%d, srst=%d , sio=%d)\n", mode,\
195 mt_get_gpio_mode(GPIO_SIM1_SCLK),mt_get_gpio_mode(GPIO_SIM1_SRST),mt_get_gpio_mode(GPIO_SIM1_SIO), \
196 mt_get_gpio_mode(GPIO_SIM2_SCLK),mt_get_gpio_mode(GPIO_SIM2_SRST),mt_get_gpio_mode(GPIO_SIM2_SIO));
197
198 return SSW_SUCCESS;
199 }
200
201
202 int switch_sim_mode(int id, char *buf, unsigned int len)
203 {
204 unsigned int mode = *((unsigned int *)buf);
205 unsigned int type = (mode&0xFFFF0000)>>16;
206 SSW_DBG("switch_sim_mode:mode=0x%x, type=%d\n", mode, type);
207 mode = mode&0x0000FFFF;
208 mutex_lock(&sim_switch_mutex);
209 if(type == 0) { // Internal
210 SSW_DBG("Internal sim switch: %d --> %d\n", sim_mode_curr, mode);
211 if ((sim_mode_curr != mode) && (SSW_SUCCESS == set_sim_gpio(mode)))
212 {
213 sim_mode_curr = mode;
214 }
215 }
216 mutex_unlock(&sim_switch_mutex);
217 SSW_DBG("sim switch sim_mode_curr(%d)OK\n", sim_mode_curr);
218
219 return 0;
220
221 }
222 EXPORT_SYMBOL(switch_sim_mode);
223
224 //To decide sim mode according to compile option
225 static int get_sim_mode_init(void)
226 {
227 unsigned int sim_mode = 0;
228 unsigned int md1_enable, md2_enable = 0;
229 md1_enable = get_modem_is_enabled(MD_SYS1);
230 md2_enable = get_modem_is_enabled(MD_SYS2);
231
232 if (md1_enable)
233 {
234 sim_mode = SINGLE_TALK_MDSYS;
235 if (md2_enable)
236 sim_mode = DUAL_TALK;
237 }
238 else if (md2_enable)
239 {
240 sim_mode = SINGLE_TALK_MDSYS_LITE;
241 }
242 return sim_mode;
243 }
244
245 //sim switch hardware initial
246 static int sim_switch_init(void)
247 {
248 SSW_DBG("sim_switch_init\n");
249 // init sim1
250 mt_set_gpio_dir(GPIO_SIM1_SCLK, 1);
251 mt_set_gpio_dir(GPIO_SIM1_SRST, 1);
252 mt_set_gpio_pull_enable(GPIO_SIM1_SIO, 1);
253 mt_set_gpio_pull_select(GPIO_SIM1_SIO, 1);
254 mt_set_gpio_dir(GPIO_SIM1_SIO, 0);
255 // init sim2
256 mt_set_gpio_dir(GPIO_SIM2_SCLK, 1);
257 mt_set_gpio_dir(GPIO_SIM2_SRST, 1);
258 mt_set_gpio_pull_enable(GPIO_SIM2_SIO, 1);
259 mt_set_gpio_pull_select(GPIO_SIM2_SIO, 1);
260 mt_set_gpio_dir(GPIO_SIM2_SIO, 0);
261 SSW_DBG("SIM1 sclk= en=%d,dir=%d,in=%d,out=%d\n", \
262 mt_get_gpio_pull_enable(GPIO_SIM1_SCLK),mt_get_gpio_dir(GPIO_SIM1_SCLK),mt_get_gpio_in(GPIO_SIM1_SCLK),mt_get_gpio_out(GPIO_SIM1_SCLK));
263 SSW_DBG("SIM1 srst= en=%d,dir=%d,in=%d,out=%d\n", \
264 mt_get_gpio_pull_enable(GPIO_SIM1_SRST),mt_get_gpio_dir(GPIO_SIM1_SRST),mt_get_gpio_in(GPIO_SIM1_SRST),mt_get_gpio_out(GPIO_SIM1_SRST));
265 SSW_DBG("SIM1 sio= en=%d,dir=%d,in=%d,out=%d\n", \
266 mt_get_gpio_pull_enable(GPIO_SIM1_SIO),mt_get_gpio_dir(GPIO_SIM1_SIO),mt_get_gpio_in(GPIO_SIM1_SIO),mt_get_gpio_out(GPIO_SIM1_SIO));
267
268 SSW_DBG("SIM2 sclk= en=%d,dir=%d,in=%d,out=%d\n", \
269 mt_get_gpio_pull_enable(GPIO_SIM2_SCLK),mt_get_gpio_dir(GPIO_SIM2_SCLK),mt_get_gpio_in(GPIO_SIM2_SCLK),mt_get_gpio_out(GPIO_SIM2_SCLK));
270 SSW_DBG("SIM2 srst= en=%d,dir=%d,in=%d,out=%d\n", \
271 mt_get_gpio_pull_enable(GPIO_SIM2_SRST),mt_get_gpio_dir(GPIO_SIM2_SRST),mt_get_gpio_in(GPIO_SIM2_SRST),mt_get_gpio_out(GPIO_SIM2_SRST));
272 SSW_DBG("SIM2 sio= en=%d,dir=%d,in=%d,out=%d\n", \
273 mt_get_gpio_pull_enable(GPIO_SIM2_SIO),mt_get_gpio_dir(GPIO_SIM2_SIO),mt_get_gpio_in(GPIO_SIM2_SIO),mt_get_gpio_out(GPIO_SIM2_SIO));
274
275 sim_mode_curr = get_sim_mode_init();
276 if (SSW_SUCCESS != set_sim_gpio(sim_mode_curr))
277 {
278 SSW_DBG("sim_switch_init fail \n");
279 return SSW_INVALID_PARA;
280 }
281 return 0;
282 }
283
284
285 static int sim_switch_probe(struct platform_device *dev)
286 {
287 SSW_DBG("Enter sim_switch_probe\n");
288 return 0;
289 }
290
291 static int sim_switch_remove(struct platform_device *dev)
292 {
293 //SSW_DBG("sim_switch_remove \n");
294 return 0;
295 }
296
297 static void sim_switch_shutdown(struct platform_device *dev)
298 {
299 //SSW_DBG("sim_switch_shutdown \n");
300 }
301
302 static int sim_switch_suspend(struct platform_device *dev, pm_message_t state)
303 {
304 //SSW_DBG("sim_switch_suspend \n");
305 return 0;
306 }
307
308 static int sim_switch_resume(struct platform_device *dev)
309 {
310 //SSW_DBG("sim_switch_resume \n");
311 return 0;
312 }
313
314
315 static struct platform_driver sim_switch_driver =
316 {
317 .driver = {
318 .name = "sim-switch",
319 },
320 .probe = sim_switch_probe,
321 .remove = sim_switch_remove,
322 .shutdown = sim_switch_shutdown,
323 .suspend = sim_switch_suspend,
324 .resume = sim_switch_resume,
325 };
326
327
328 static int __init sim_switch_driver_init(void)
329 {
330 int ret = 0;
331
332 SSW_DBG("sim_switch_driver_init\n");
333 ret = platform_driver_register(&sim_switch_driver);
334 if (ret) {
335 SSW_DBG("ssw_driver register fail(%d)\n", ret);
336 return ret;
337 }
338
339 mutex_init(&sim_switch_mutex);
340
341 #if __ENABLE_SSW_SYSFS
342 ssw_sysfs_init();
343 #endif
344
345 sim_switch_init();
346
347 return ret;
348 }
349
350
351 static void __exit sim_switch_driver_exit(void)
352 {
353 return;
354 }
355
356
357 module_init(sim_switch_driver_init);
358 module_exit(sim_switch_driver_exit);
359
360
361 MODULE_DESCRIPTION("MTK SIM Switch Driver");
362 MODULE_AUTHOR("MTK");
363 MODULE_LICENSE("GPL");