1.add mt6229 power on/off on settings for MID
[firefly-linux-kernel-4.4.55.git] / drivers / misc / 3g_module / mu509.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/i2c.h>
4 #include <linux/irq.h>
5 #include <linux/gpio.h>
6 #include <linux/input.h>
7 #include <linux/platform_device.h>
8 #include <linux/fs.h>
9 #include <linux/uaccess.h>
10 #include <linux/miscdevice.h>
11 #include <linux/circ_buf.h>
12 #include <linux/interrupt.h>
13 #include <linux/miscdevice.h>
14 #include <mach/iomux.h>
15 #include <mach/gpio.h>
16 #include <asm/gpio.h>
17 #include <linux/delay.h>
18 #include <linux/poll.h>
19 #include <linux/wait.h>
20 #include <linux/wakelock.h>
21 #include <linux/workqueue.h>
22 #include <linux/mu509.h>
23 #include <linux/slab.h>
24 #include <linux/earlysuspend.h>
25
26 MODULE_LICENSE("GPL");
27
28 #define DEBUG
29 #ifdef DEBUG
30 #define MODEMDBG(x...) printk(x)
31 #else
32 #define MODEMDBG(fmt,argss...)
33 #endif
34 #define SLEEP 1
35 #define READY 0
36 static struct wake_lock modem_wakelock;
37 #define IRQ_BB_WAKEUP_AP_TRIGGER    IRQF_TRIGGER_FALLING
38 //#define IRQ_BB_WAKEUP_AP_TRIGGER    IRQF_TRIGGER_RISING
39 #define MU509_RESET 0x01
40 struct rk29_mu509_data *gpdata = NULL;
41 struct class *modem_class = NULL; 
42 static int do_wakeup_irq = 0;
43 static int modem_status;
44 int suspend_int =0;
45 static void ap_wakeup_bp(struct platform_device *pdev, int wake)
46 {
47         struct rk29_mu509_data *pdata = pdev->dev.platform_data;
48
49         gpio_set_value(pdata->ap_wakeup_bp, wake);  
50
51 }
52 extern void rk28_send_wakeup_key(void);
53
54 static void do_wakeup(struct work_struct *work)
55 {
56       if(suspend_int)
57          {
58              gpio_set_value(gpdata->ap_wakeup_bp, 0);
59              suspend_int = 0;
60          }
61
62 }
63
64 static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
65 static irqreturn_t detect_irq_handler(int irq, void *dev_id)
66 {
67     if(do_wakeup_irq)
68     {
69         do_wakeup_irq = 0;
70   //      MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
71         wake_lock_timeout(&modem_wakelock, 10 * HZ);
72         schedule_delayed_work(&wakeup_work, 2*HZ);
73     }
74     return IRQ_HANDLED;
75 }
76 static int modem_poweron_off(int on_off)
77 {
78         struct rk29_mu509_data *pdata = gpdata;         
79   if(on_off)
80   {
81                 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
82                 msleep(100);
83                 gpio_set_value(pdata->bp_reset, GPIO_LOW);
84                 gpio_set_value(pdata->bp_power, GPIO_LOW);
85                 msleep(1000);
86                 gpio_set_value(pdata->bp_power, GPIO_HIGH);
87                 msleep(700);
88                 gpio_set_value(pdata->bp_power, GPIO_LOW);
89                 gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
90   }
91   else
92   {
93                 gpio_set_value(pdata->bp_power, GPIO_LOW);
94                 gpio_set_value(pdata->bp_power, GPIO_HIGH);
95                 msleep(2500);
96                 gpio_set_value(pdata->bp_power, GPIO_LOW);
97   }
98   return 0;
99 }
100 static int mu509_open(struct inode *inode, struct file *file)
101 {
102         struct rk29_mu509_data *pdata = gpdata;
103         device_init_wakeup(pdata->dev, 1);
104         return 0;
105 }
106
107 static int mu509_release(struct inode *inode, struct file *file)
108 {
109         return 0;
110 }
111
112 static long mu509_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
113 {
114         struct rk29_mu509_data *pdata = gpdata;
115         switch(cmd)
116         {
117                 case MU509_RESET:                                       
118                         gpio_set_value(pdata->bp_reset, GPIO_HIGH);
119                         msleep(100);
120                         gpio_set_value(pdata->bp_reset, GPIO_LOW);
121                         msleep(100);
122                         gpio_set_value(pdata->bp_power, GPIO_LOW);
123                         msleep(1000);
124                         gpio_set_value(pdata->bp_power, GPIO_HIGH);
125                         msleep(700);
126                         gpio_set_value(pdata->bp_power, GPIO_LOW);
127                         gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
128                         break;
129                 default:
130                         break;
131         }
132         return 0;
133 }
134
135 static struct file_operations mu509_fops = {
136         .owner = THIS_MODULE,
137         .open = mu509_open,
138         .release = mu509_release,
139         .unlocked_ioctl = mu509_ioctl
140 };
141
142 static struct miscdevice mu509_misc = {
143         .minor = MISC_DYNAMIC_MINOR,
144         .name = MODEM_NAME,
145         .fops = &mu509_fops
146 };
147 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
148 static ssize_t modem_status_read(struct class *cls, struct class_attribute *attr, char *_buf)
149 #else
150 static ssize_t modem_status_read(struct class *cls, char *_buf)
151 #endif
152 {
153
154         return sprintf(_buf, "%d\n", modem_status);
155         
156 }
157 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
158 static ssize_t modem_status_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
159 #else
160 static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)
161 #endif
162 {
163     int new_state = simple_strtoul(_buf, NULL, 16);
164    if(new_state == modem_status) return _count;
165    if (new_state == 1){
166      printk("%s, c(%d), open modem \n", __FUNCTION__, new_state);
167          modem_poweron_off(1);
168    }else if(new_state == 0){
169      printk("%s, c(%d), close modem \n", __FUNCTION__, new_state);
170          modem_poweron_off(0);
171    }else{
172      printk("%s, invalid parameter \n", __FUNCTION__);
173    }
174         modem_status = new_state;
175     return _count; 
176 }
177 static CLASS_ATTR(modem_status, 0777, modem_status_read, modem_status_write);
178 static void rk29_early_suspend(struct early_suspend *h)
179 {
180                  
181 }
182 static void rk29_early_resume(struct early_suspend *h)
183 {
184          if(suspend_int)
185         {
186         gpio_set_value(gpdata->ap_wakeup_bp, 0);
187          suspend_int = 0;
188         }
189 }
190
191 static struct early_suspend mu509_early_suspend = {
192                  .suspend = rk29_early_suspend,
193                   .resume = rk29_early_resume,
194                   .level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1,
195           };
196 static int mu509_probe(struct platform_device *pdev)
197 {
198         struct rk29_mu509_data *pdata = gpdata = pdev->dev.platform_data;
199         struct modem_dev *mu509_data = NULL;
200         int result, irq = 0;    
201         
202         pdata->dev = &pdev->dev;
203         if(pdata->io_init)
204                 pdata->io_init();
205
206    printk("******** mu509_probe_mu509_probe*********\n");       
207
208                 #if 0   
209                         rk30_mux_api_set(GPIO1A1_UART0SOUT_NAME, GPIO1A_GPIO1A4);       
210                                     result = gpio_request(RK30_PIN1_PA4, "uart1_sout");                 
211                                         if (result < 0) {       
212                                                         
213                                 printk("%s: gpio_request( uart1_sout ) failed\n", __func__);    
214                                 
215                                 }       
216                                 else {
217                 printk("******* uart0_sout low ( %s ) 88 ********\n", __FUNCTION__);
218                         gpio_set_value(RK30_PIN1_PA4, GPIO_LOW);  // Make sure the uart1_rx of MU509 is low for usb autosuspend 
219                         
220                         }               
221    
222           #endif        
223
224
225         mu509_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
226         if(mu509_data == NULL)
227         {
228                 printk("failed to request mu509_data\n");
229                 goto err0;
230         }
231         platform_set_drvdata(pdev, mu509_data); 
232         result = gpio_request(pdata->modem_power_en,"modem_power_en");
233         if(result){
234                         printk("failed to request modem_power_en gpio\n");
235                         goto err1;
236                 }
237         gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
238         result = gpio_request(pdata->bp_power,"modem_power");
239   if(result){
240                 printk("failed to request modem_power gpio\n");
241                         goto err2;
242         }
243
244         
245         register_early_suspend(&mu509_early_suspend);
246         
247         result = gpio_request(pdata->ap_wakeup_bp, "mu509");
248         if (result) {
249                 printk("failed to request AP_BP_WAKEUP gpio\n");
250                 goto err3;
251         }       
252         irq     = gpio_to_irq(pdata->bp_wakeup_ap);
253         enable_irq_wake(irq);
254         if(irq < 0)
255         {
256                 gpio_free(pdata->bp_wakeup_ap);
257                 printk("failed to request bp_wakeup_ap\n");
258         }
259         result = gpio_request(pdata->bp_wakeup_ap, "bp_wakeup_ap");
260         if (result < 0) {
261                 printk("%s: gpio_request(%d) failed\n", __func__, pdata->bp_wakeup_ap);
262         }
263         wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
264         gpio_direction_input(pdata->bp_wakeup_ap);
265     gpio_pull_updown(pdata->bp_wakeup_ap, 1);   
266         result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
267         if (result < 0) {
268                 printk("%s: request_irq(%d) failed\n", __func__, irq);
269                 gpio_free(pdata->bp_wakeup_ap);
270                 goto err4;
271         }
272         enable_irq_wake(gpio_to_irq(pdata->bp_wakeup_ap)); 
273         
274         msleep(1000);
275         modem_poweron_off(1);
276         modem_status = 1;
277
278         result = misc_register(&mu509_misc);
279         if(result)
280         {
281                 printk("misc_register err\n");
282         }       
283         return result;
284 err0:
285         kfree(mu509_data);
286 err1:
287         gpio_free(pdata->modem_power_en);
288 err2:
289         gpio_free(pdata->bp_power);
290 err3:
291         gpio_free(pdata->ap_wakeup_bp);
292 err4:
293         cancel_work_sync(&mu509_data->work);
294         gpio_free(pdata->bp_wakeup_ap); 
295         return 0;
296 }
297
298 static int mu509_suspend(struct platform_device *pdev, pm_message_t state)
299 {
300         suspend_int = 1;
301         do_wakeup_irq = 1;
302         ap_wakeup_bp(pdev, 1);
303 #if defined(CONFIG_ARCH_RK29)
304         rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
305 #endif
306 #if defined(CONFIG_ARCH_RK30)
307         rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_GPIO1A7);
308 #endif  
309         return 0;
310 }
311
312 static int mu509_resume(struct platform_device *pdev)
313 {
314 #if defined(CONFIG_ARCH_RK29)
315         rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
316 #endif
317 #if defined(CONFIG_ARCH_RK30)
318         rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_UART1_RTS_N);
319 #endif
320         if(gpio_get_value(gpdata->bp_wakeup_ap))
321         {
322                 schedule_delayed_work(&wakeup_work, 2*HZ);
323         }
324         return 0;
325 }
326
327 static void mu509_shutdown(struct platform_device *pdev)
328 {
329         struct rk29_mu509_data *pdata = pdev->dev.platform_data;
330         struct modem_dev *mu509_data = platform_get_drvdata(pdev);
331         
332         modem_poweron_off(0);
333         gpio_set_value(pdata->modem_power_en, GPIO_LOW);
334
335         if(pdata->io_deinit)
336                 pdata->io_deinit();
337         cancel_work_sync(&mu509_data->work);
338         gpio_free(pdata->modem_power_en);
339         gpio_free(pdata->bp_power);
340         gpio_free(pdata->bp_reset);
341         gpio_free(pdata->ap_wakeup_bp);
342         gpio_free(pdata->bp_wakeup_ap);
343         kfree(mu509_data);
344 }
345
346 static struct platform_driver mu509_driver = {
347         .probe  = mu509_probe,
348         .shutdown       = mu509_shutdown,
349         .suspend        = mu509_suspend,
350         .resume         = mu509_resume,
351         .driver = {
352                 .name   = "mu509",
353                 .owner  = THIS_MODULE,
354         },
355 };
356
357 static int __init mu509_init(void)
358 {
359         int ret ;
360         modem_class = class_create(THIS_MODULE, "rk291x_modem");
361         ret =  class_create_file(modem_class, &class_attr_modem_status);
362         if (ret)
363         {
364                 printk("Fail to class rk291x_modem.\n");
365         }
366         return platform_driver_register(&mu509_driver);
367 }
368
369 static void __exit mu509_exit(void)
370 {
371         platform_driver_unregister(&mu509_driver);
372         class_remove_file(modem_class, &class_attr_modem_status);
373 }
374
375 module_init(mu509_init);
376
377 module_exit(mu509_exit);