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/sew868.h>
22 #include<linux/ioctl.h>
23 #include<linux/slab.h>
25 MODULE_LICENSE("GPL");
29 #define MODEMDBG(x...) printk(x)
31 #define MODEMDBG(fmt,argss...)
35 #define SEW868_RESET 0x01
36 #define SEW868_POWON 0x02
37 #define SEW868_POWOFF 0x03
38 static struct wake_lock modem_wakelock;
39 #define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING
40 //#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
41 struct rk30_sew868_data *gpdata = NULL;
42 static int do_wakeup_irq = 0;
44 extern void rk28_send_wakeup_key(void);
46 static void do_wakeup(struct work_struct *work)
48 rk28_send_wakeup_key();
51 static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
52 static irqreturn_t detect_irq_handler(int irq, void *dev_id)
54 printk("%s\n", __FUNCTION__);
58 wake_lock_timeout(&modem_wakelock, 10 * HZ);
59 schedule_delayed_work(&wakeup_work, HZ / 10);
63 int modem_poweron_off(int on_off)
65 struct rk30_sew868_data *pdata = gpdata;
68 gpio_direction_output(pdata->bp_sys, GPIO_HIGH);
69 gpio_set_value(pdata->bp_power, GPIO_LOW);
70 msleep(200);//for charge
71 gpio_set_value(pdata->bp_power, GPIO_HIGH);
73 gpio_set_value(pdata->bp_power, GPIO_LOW);
78 gpio_set_value(pdata->bp_power, GPIO_HIGH);
80 gpio_set_value(pdata->bp_power, GPIO_LOW);
81 gpio_set_value(pdata->bp_sys, GPIO_LOW);
83 gpio_set_value(pdata->bp_power, GPIO_LOW);
87 static int sew868_open(struct inode *inode, struct file *file)
92 static int sew868_release(struct inode *inode, struct file *file)
97 static long sew868_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
99 struct rk30_sew868_data *pdata = gpdata;
103 gpio_set_value(pdata->bp_reset, GPIO_HIGH);
105 gpio_set_value(pdata->bp_reset, GPIO_LOW);
107 modem_poweron_off(1);
110 modem_poweron_off(1);
113 modem_poweron_off(0);
121 static struct file_operations sew868_fops = {
122 .owner = THIS_MODULE,
124 .release = sew868_release,
125 .unlocked_ioctl = sew868_ioctl
128 static struct miscdevice sew868_misc = {
129 .minor = MISC_DYNAMIC_MINOR,
134 static int sew868_probe(struct platform_device *pdev)
136 struct rk30_sew868_data *pdata = gpdata = pdev->dev.platform_data;
137 struct modem_dev *sew868_data = NULL;
143 modem_poweron_off(1);
144 sew868_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
145 if(sew868_data == NULL)
147 printk("failed to request sew868_data\n");
150 platform_set_drvdata(pdev, sew868_data);
152 irq = gpio_to_irq(pdata->bp_wakeup_ap);
155 gpio_free(pdata->bp_wakeup_ap);
156 printk("failed to request bp_wakeup_ap\n");
159 wake_lock_init(&modem_wakelock, WAKE_LOCK_SUSPEND, "bp_wakeup_ap");
160 gpio_direction_input(pdata->bp_wakeup_ap);
161 gpio_pull_updown(pdata->bp_wakeup_ap, GPIONormal);
162 result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
164 printk("%s: request_irq(%d) failed\n", __func__, irq);
165 gpio_free(pdata->bp_wakeup_ap);
168 enable_irq_wake(gpio_to_irq(pdata->bp_wakeup_ap));
169 result = misc_register(&sew868_misc);
172 MODEMDBG("misc_register err\n");
177 cancel_work_sync(&sew868_data->work);
183 int sew868_suspend(struct platform_device *pdev, pm_message_t state)
189 int sew868_resume(struct platform_device *pdev)
194 void sew868_shutdown(struct platform_device *pdev)
196 struct rk30_sew868_data *pdata = pdev->dev.platform_data;
197 struct modem_dev *sew868_data = platform_get_drvdata(pdev);
198 modem_poweron_off(0);
201 cancel_work_sync(&sew868_data->work);
205 static struct platform_driver sew868_driver = {
206 .probe = sew868_probe,
207 .shutdown = sew868_shutdown,
208 .suspend = sew868_suspend,
209 .resume = sew868_resume,
212 .owner = THIS_MODULE,
216 static int __init sew868_init(void)
218 return platform_driver_register(&sew868_driver);
221 static void __exit sew868_exit(void)
223 platform_driver_unregister(&sew868_driver);
226 module_init(sew868_init);
228 module_exit(sew868_exit);