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");
31 #define MODEMDBG(x...) printk(x)
33 #define MODEMDBG(fmt,argss...)
37 #define MW_IOCTL_RESET _IO(MW100IO,0X01)
41 #define MW100_RESET 0x01
42 #define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
43 //#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
44 struct rk29_mw100_data *gpdata = NULL;
45 static int bp_wakeup_ap_irq = 0;
47 static struct wake_lock bp_wakelock;
48 static bool bpstatus_irq_enable = false;
51 static void ap_wakeup_bp(struct platform_device *pdev, int wake)
53 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
54 MODEMDBG("ap_wakeup_bp\n");
56 gpio_set_value(pdata->ap_wakeup_bp, wake);
60 static void do_wakeup(struct work_struct *work)
62 MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
63 enable_irq(bp_wakeup_ap_irq);
66 static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
67 static irqreturn_t detect_irq_handler(int irq, void *dev_id)
69 printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
70 wake_lock_timeout(&bp_wakelock, 10 * HZ);
74 int modem_poweron_off(int on_off)
78 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
82 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
87 static int mw100_open(struct inode *inode, struct file *file)
89 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
90 //modem_poweron_off(1);
94 static int mw100_release(struct inode *inode, struct file *file)
96 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
97 //modem_poweron_off(0);
101 static long mw100_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
103 struct rk29_mw100_data *pdata = gpdata;
107 printk("%s::%d--bruins--ioctl mw100 reset\n",__func__,__LINE__);
108 gpio_direction_output(pdata->bp_reset,GPIO_LOW);
110 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
119 static struct file_operations mw100_fops = {
120 .owner = THIS_MODULE,
122 .release = mw100_release,
123 .unlocked_ioctl = mw100_ioctl
126 static struct miscdevice mw100_misc = {
127 .minor = MISC_DYNAMIC_MINOR,
132 static int mw100_probe(struct platform_device *pdev)
134 struct rk29_mw100_data *pdata = gpdata = pdev->dev.platform_data;
135 struct modem_dev *mw100_data = NULL;
138 gpio_request(pdata->bp_power,"bp_power");
139 gpio_request(pdata->bp_reset,"bp_reset");
140 gpio_request(pdata->bp_wakeup_ap,"bp_wakeup_ap");
141 gpio_request(pdata->ap_wakeup_bp,"ap_wakeup_bp");
142 gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
144 #if defined(CONFIG_ARCH_RK29)
145 rk29_mux_api_set(GPIO6C76_CPUTRACEDATA76_NAME, GPIO4H_GPIO6C76);
147 gpio_direction_output(pdata->bp_reset,GPIO_LOW);
149 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
151 gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
152 gpio_direction_output(pdata->ap_wakeup_bp,GPIO_HIGH);
154 gpio_set_value(pdata->bp_power, GPIO_HIGH);
155 gpio_direction_output(pdata->bp_power,GPIO_HIGH);
157 gpio_set_value(pdata->bp_power, GPIO_LOW);
158 gpio_direction_output(pdata->bp_power,GPIO_LOW);
162 /* gpio_set_value(pdata->bp_reset, GPIO_LOW);
163 gpio_direction_output(pdata->bp_reset,GPIO_LOW);
165 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
166 gpio_direction_output(pdata->bp_reset,GPIO_HIGH);
168 mw100_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
169 if(mw100_data == NULL){
170 printk("failed to request mw100_data\n");
173 platform_set_drvdata(pdev, mw100_data);
175 gpio_direction_input(pdata->bp_wakeup_ap);
176 irq = gpio_to_irq(pdata->bp_wakeup_ap);
178 gpio_free(pdata->bp_wakeup_ap);
179 printk("failed to request bp_wakeup_ap\n");
182 bp_wakeup_ap_irq = irq;
184 result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
186 printk("%s: request_irq(%d) failed\n", __func__, irq);
187 gpio_free(pdata->bp_wakeup_ap);
191 enable_irq_wake(bp_wakeup_ap_irq);
193 wake_lock_init(&bp_wakelock, WAKE_LOCK_SUSPEND, "bp_resume");
195 result = misc_register(&mw100_misc);
197 MODEMDBG("misc_register err\n");
201 gpio_free(pdata->bp_wakeup_ap);
207 int mw100_suspend(struct platform_device *pdev, pm_message_t state)
210 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
212 MODEMDBG("%s::%d--\n",__func__,__LINE__);
213 gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
214 irq = gpio_to_irq(pdata->bp_wakeup_ap);
216 printk("can't get pdata->bp_statue irq \n");
220 printk("enable pdata->bp_statue irq_wake!! \n");
221 bpstatus_irq_enable = true;
222 enable_irq_wake(irq);
227 int mw100_resume(struct platform_device *pdev)
229 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
231 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
232 gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
233 irq = gpio_to_irq(pdata->bp_wakeup_ap);
235 printk("enable pdata->bp_statue irq_wake!! \n");
236 disable_irq_wake(irq);
237 bpstatus_irq_enable = false;
242 void mw100_shutdown(struct platform_device *pdev)
244 struct rk29_mw100_data *pdata = pdev->dev.platform_data;
245 struct modem_dev *mw100_data = platform_get_drvdata(pdev);
247 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
248 gpio_set_value(pdata->bp_power, GPIO_HIGH);
250 gpio_free(pdata->modem_power_en);
251 gpio_free(pdata->bp_power);
252 gpio_free(pdata->bp_reset);
253 gpio_free(pdata->ap_wakeup_bp);
254 gpio_free(pdata->bp_wakeup_ap);
258 static struct platform_driver mw100_driver = {
259 .probe = mw100_probe,
260 .shutdown = mw100_shutdown,
261 .suspend = mw100_suspend,
262 .resume = mw100_resume,
265 .owner = THIS_MODULE,
269 static int __init mw100_init(void)
271 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
272 return platform_driver_register(&mw100_driver);
275 static void __exit mw100_exit(void)
277 MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
278 platform_driver_unregister(&mw100_driver);
281 module_init(mw100_init);
283 module_exit(mw100_exit);