1 #include <linux/module.h>
2 #include <linux/kernel.h>
5 #include <linux/gpio.h>
6 #include <linux/input.h>
7 #include <linux/platform_device.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 <linux/delay.h>
17 #include <linux/poll.h>
18 #include <linux/wait.h>
19 #include <linux/wakelock.h>
20 #include <linux/workqueue.h>
21 #include <linux/mw100.h>
22 #include <mach/iomux.h>
23 #include<linux/ioctl.h>
25 #include <linux/slab.h>
27 MODULE_LICENSE("GPL");
30 #define MODEMDBG(x...) printk(x)
32 #define MODEMDBG(fmt,argss...)
36 #define MW_IOCTL_RESET _IO(MW100IO,0X01)
40 #define MW100_RESET 0x01
41 #define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
42 //#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
43 struct rk29_mw100_data *gpdata = NULL;
44 static int bp_wakeup_ap_irq = 0;
46 static struct wake_lock bp_wakelock;
47 static bool bpstatus_irq_enable = false;
49 static void do_wakeup(struct work_struct *work)
51 enable_irq(bp_wakeup_ap_irq);
54 static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
55 static irqreturn_t detect_irq_handler(int irq, void *dev_id)
57 wake_lock_timeout(&bp_wakelock, 10 * HZ);
62 static int mw100_open(struct inode *inode, struct file *file)
67 static int mw100_release(struct inode *inode, struct file *file)
72 static long mw100_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
74 struct rk29_mw100_data *pdata = gpdata;
78 gpio_direction_output(pdata->bp_reset,GPIO_LOW);
80 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
89 static struct file_operations mw100_fops = {
92 .release = mw100_release,
93 .unlocked_ioctl = mw100_ioctl
96 static struct miscdevice mw100_misc = {
97 .minor = MISC_DYNAMIC_MINOR,
102 static int mw100_probe(struct platform_device *pdev)
104 struct rk29_mw100_data *pdata = gpdata = pdev->dev.platform_data;
105 struct modem_dev *mw100_data = NULL;
108 gpio_request(pdata->bp_power,"bp_power");
109 gpio_request(pdata->bp_reset,"bp_reset");
110 gpio_request(pdata->bp_wakeup_ap,"bp_wakeup_ap");
111 gpio_request(pdata->ap_wakeup_bp,"ap_wakeup_bp");
112 gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
114 gpio_direction_output(pdata->bp_reset,GPIO_LOW);
116 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
118 gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
119 gpio_direction_output(pdata->ap_wakeup_bp,GPIO_HIGH);
121 gpio_set_value(pdata->bp_power, GPIO_HIGH);
122 gpio_direction_output(pdata->bp_power,GPIO_HIGH);
124 gpio_set_value(pdata->bp_power, GPIO_LOW);
125 gpio_direction_output(pdata->bp_power,GPIO_LOW);
127 mw100_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
128 if(mw100_data == NULL){
129 printk("failed to request mw100_data\n");
132 platform_set_drvdata(pdev, mw100_data);
134 gpio_direction_input(pdata->bp_wakeup_ap);
135 irq = gpio_to_irq(pdata->bp_wakeup_ap);
137 gpio_free(pdata->bp_wakeup_ap);
138 printk("failed to request bp_wakeup_ap\n");
141 bp_wakeup_ap_irq = irq;
143 result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
145 printk("%s: request_irq(%d) failed\n", __func__, irq);
146 gpio_free(pdata->bp_wakeup_ap);
150 enable_irq_wake(bp_wakeup_ap_irq);
152 wake_lock_init(&bp_wakelock, WAKE_LOCK_SUSPEND, "bp_resume");
154 result = misc_register(&mw100_misc);
156 MODEMDBG("misc_register err\n");
160 gpio_free(pdata->bp_wakeup_ap);
166 int mw100_suspend(struct platform_device *pdev, pm_message_t state)
169 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
171 gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
172 irq = gpio_to_irq(pdata->bp_wakeup_ap);
174 printk("can't get pdata->bp_statue irq \n");
178 bpstatus_irq_enable = true;
179 enable_irq_wake(irq);
184 int mw100_resume(struct platform_device *pdev)
186 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
188 gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
189 irq = gpio_to_irq(pdata->bp_wakeup_ap);
191 disable_irq_wake(irq);
192 bpstatus_irq_enable = false;
197 void mw100_shutdown(struct platform_device *pdev)
199 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
200 struct modem_dev *mw100_data = platform_get_drvdata(pdev);
202 gpio_set_value(pdata->bp_power, GPIO_HIGH);
204 gpio_free(pdata->modem_power_en);
205 gpio_free(pdata->bp_power);
206 gpio_free(pdata->bp_reset);
207 gpio_free(pdata->ap_wakeup_bp);
208 gpio_free(pdata->bp_wakeup_ap);
212 static struct platform_driver mw100_driver = {
213 .probe = mw100_probe,
214 .shutdown = mw100_shutdown,
215 .suspend = mw100_suspend,
216 .resume = mw100_resume,
219 .owner = THIS_MODULE,
223 static int __init mw100_init(void)
225 return platform_driver_register(&mw100_driver);
228 static void __exit mw100_exit(void)
230 platform_driver_unregister(&mw100_driver);
233 module_init(mw100_init);
235 module_exit(mw100_exit);