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 <mach/spi_fpga.h>
17 #include <linux/delay.h>
18 #include <linux/poll.h>
19 #include <linux/wait.h>
20 //#include <linux/android_power.h>
21 //#include <asm/arch/gpio_extend.h>
22 #include <linux/workqueue.h>
23 #include <linux/mtk23d.h>
24 #include <linux/wakelock.h>
25 #include "../mtd/rknand/api_flash.h"
26 #include <linux/slab.h>
28 MODULE_LICENSE("GPL");
32 #define MODEMDBG(x...) printk(x)
34 #define MODEMDBG(fmt,argss...)
36 #define MTK23D_POWEROFF 0X00
37 #define MTK23D_RESET 0x01
38 #define MTK23D_POWERON 0x02
39 #define MTK23D_POWER_HIGH 0x03
40 #define MTK23D_IMEI_READ 0x04
41 //#define BP_POW_EN TCA6424_P02
42 //#define BP_STATUS RK2818_PIN_PH7 //input high bp sleep
43 //#define AP_STATUS RK2818_PIN_PA4 //output high ap sleep
45 //#define BP_RESET TCA6424_P11 //Ryan
47 //#define AP_BP_WAKEUP RK2818_PIN_PF5 //output AP wake up BP used rising edge
48 //#define BP_AP_WAKEUP RK2818_PIN_PE0 //input BP wake up AP
50 static bool bpstatus_irq_enable = false;
51 static bool wakelock_inited;
52 static struct wake_lock mtk23d_wakelock;
57 //struct modem_dev *mt6223d_data = NULL;
58 struct rk2818_23d_data *gpdata = NULL;
60 static int rk29_uart_to_gpio(int uart_id)
63 rk29_mux_api_set(GPIO2B3_UART3SOUT_NAME, GPIO2L_GPIO2B3);
64 rk29_mux_api_set(GPIO2B2_UART3SIN_NAME, GPIO2L_GPIO2B2);
66 gpio_request(RK29_PIN2_PB3, NULL);
67 gpio_request(RK29_PIN2_PB2, NULL);
69 gpio_direction_output(RK29_PIN2_PB3, GPIO_LOW);
70 gpio_direction_output(RK29_PIN2_PB2, GPIO_LOW);
72 else if(uart_id == 2) {
73 rk29_mux_api_set(GPIO2B1_UART2SOUT_NAME, GPIO2L_GPIO2B1);
74 rk29_mux_api_set(GPIO2B0_UART2SIN_NAME, GPIO2L_GPIO2B0);
76 gpio_request(RK29_PIN2_PB1, NULL);
77 gpio_request(RK29_PIN2_PB0, NULL);
79 gpio_direction_output(RK29_PIN2_PB1, GPIO_LOW);
80 gpio_direction_output(RK29_PIN2_PB0, GPIO_LOW);
82 else if(uart_id == 1) {
83 rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_GPIO2A5);
84 rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_GPIO2A4);
86 gpio_request(RK29_PIN2_PA5, NULL);
87 gpio_request(RK29_PIN2_PA4, NULL);
89 gpio_direction_output(RK29_PIN2_PA5, GPIO_LOW);
90 gpio_direction_output(RK29_PIN2_PA4, GPIO_LOW);
92 else if(uart_id == 0){
93 rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_GPIO1B7);
94 gpio_request(RK29_PIN1_PB7, NULL);
95 gpio_direction_output(RK29_PIN1_PB7,GPIO_LOW);
96 gpio_pull_updown(RK29_PIN1_PB7, PullDisable); // ÏÂÀ½ûÖ¹
98 rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_GPIO1B6);
99 gpio_request(RK29_PIN1_PB6, NULL);
100 gpio_direction_output(RK29_PIN1_PB6,GPIO_LOW);
101 gpio_pull_updown(RK29_PIN1_PB6, PullDisable); // ÏÂÀ½ûÖ¹
103 rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
104 gpio_request(RK29_PIN1_PC1, NULL);
105 gpio_direction_output(RK29_PIN1_PC1,GPIO_LOW);
107 rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_GPIO1C0);
108 gpio_request(RK29_PIN1_PC0, NULL);
109 //gpio_direction_input(RK29_PIN1_PC0);
110 gpio_direction_output(RK29_PIN1_PC0,GPIO_LOW);
116 static int rk29_gpio_to_uart(int uart_id)
119 rk29_mux_api_set(GPIO2B3_UART3SOUT_NAME, GPIO2L_UART3_SOUT);
120 rk29_mux_api_set(GPIO2B2_UART3SIN_NAME, GPIO2L_UART3_SIN);
122 gpio_request(RK29_PIN2_PB3, NULL);
123 gpio_request(RK29_PIN2_PB2, NULL);
125 gpio_direction_output(RK29_PIN2_PB3, GPIO_HIGH);
126 gpio_direction_output(RK29_PIN2_PB2, GPIO_HIGH);
128 else if(uart_id == 2) {
129 rk29_mux_api_set(GPIO2B1_UART2SOUT_NAME, GPIO2L_UART2_SOUT);
130 rk29_mux_api_set(GPIO2B0_UART2SIN_NAME, GPIO2L_UART2_SIN);
132 gpio_request(RK29_PIN2_PB1, NULL);
133 gpio_request(RK29_PIN2_PB0, NULL);
135 gpio_direction_output(RK29_PIN2_PB1, GPIO_HIGH);
136 gpio_direction_output(RK29_PIN2_PB0, GPIO_HIGH);
138 else if(uart_id == 1) {
139 rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_UART1_SOUT);
140 rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_UART1_SIN);
142 gpio_request(RK29_PIN2_PA5, NULL);
143 gpio_request(RK29_PIN2_PA4, NULL);
145 gpio_direction_output(RK29_PIN2_PA5, GPIO_HIGH);
146 gpio_direction_output(RK29_PIN2_PA4, GPIO_HIGH);
148 else if(uart_id == 0){
149 rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_UART0_SOUT);
150 rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_UART0_SIN);
151 rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
152 rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_UART0_CTS_N);
159 static int get_bp_statue(struct platform_device *pdev)
161 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
163 if(gpio_get_value(pdata->bp_statue))
168 static void ap_sleep(struct platform_device *pdev)
170 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
172 MODEMDBG("ap sleep!\n");
173 gpio_set_value(pdata->ap_statue,GPIO_HIGH);
175 static void ap_wakeup(struct platform_device *pdev)
177 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
179 MODEMDBG("ap wakeup!\n");
180 gpio_set_value(pdata->ap_statue,GPIO_LOW);
183 static void ap_wakeup_bp(struct platform_device *pdev, int wake)//low to wakeup bp
185 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
186 struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
187 MODEMDBG("ap_wakeup_bp\n");
189 gpio_set_value(pdata->ap_bp_wakeup, wake); // phc
190 //gpio_set_value(RK2818_PIN_PF5, wake);
193 static void bpwakeup_work_func_work(struct work_struct *work)
195 struct modem_dev *bdata = container_of(work, struct modem_dev, work);
197 MODEMDBG("%s\n", __FUNCTION__);
201 static irqreturn_t bpwakeup_work_func(int irq, void *data)
203 struct modem_dev *mt6223d_data = (struct modem_dev *)data;
205 MODEMDBG("bpwakeup_work_func\n");
206 schedule_work(&mt6223d_data->work);
209 static irqreturn_t bp_apwakeup_work_func(int irq, void *data)
211 //struct modem_dev *dev = &mtk23d_misc;
213 MODEMDBG("bp_apwakeup_work_func\n");
214 //wake_up_interruptible(&dev->wakeup);
218 static irqreturn_t BBwakeup_isr(int irq, void *dev_id)
220 struct rk2818_23d_data *pdata = dev_id;
222 MODEMDBG("%s \n", __FUNCTION__);
223 //if(irq != gpio_to_irq(RK29_PIN1_PC0))
225 // printk("irq != gpio_to_irq(RK29_PIN1_PC0) \n");
229 // disable_irq_wake(irq);
231 if(bpstatus_irq_enable == true)
233 MODEMDBG("mtk23d_wakelock 3s \n");
234 wake_lock_timeout(&mtk23d_wakelock, 3 * HZ);
241 int modem_poweron_off(int on_off)
243 struct rk2818_23d_data *pdata = gpdata;
244 int result, error = 0, irq = 0;
248 printk("modem_poweron\n");
250 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH); // power on enable
252 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW); // release reset
254 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW); // power on relase
256 rk29_gpio_to_uart(0);
258 gpio_direction_input(pdata->bp_statue);
259 if(pdata->bp_ap_wakeup) // SDK°åÖУ¬¸Ã¿ÚûÓÐÒý³ö
260 gpio_direction_input(pdata->bp_ap_wakeup);
262 /* ³õʼ»¯BP»½ÐÑAPµÄ¹¦ÄÜ */
263 wakelock_inited = false;
264 irq = gpio_to_irq(pdata->bp_statue);
266 printk("can't get pdata->bp_statue irq \n");
270 error = request_irq(irq, BBwakeup_isr,IRQF_TRIGGER_FALLING, "mtk23d", pdata);
272 printk("mtk23d_probe bp_statue request_irq error!!! \n");
275 if (!wakelock_inited) {
276 wake_lock_init(&mtk23d_wakelock, WAKE_LOCK_SUSPEND, "23d_resume");
277 wakelock_inited = true;
282 printk("modem_poweroff\n");
283 rk29_uart_to_gpio(0);
284 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
286 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
288 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
291 static int power_on =1;
292 static int mtk23d_open(struct inode *inode, struct file *file)
294 struct rk2818_23d_data *pdata = gpdata;
295 //struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
296 struct platform_data *pdev = container_of(pdata, struct device, platform_data);
298 MODEMDBG("modem_open\n");
304 modem_poweron_off(1);
306 device_init_wakeup(&pdev, 1);
311 static int mtk23d_release(struct inode *inode, struct file *file)
313 MODEMDBG("mtk23d_release\n");
315 //gpio_free(pdata->bp_power);
319 //extern char imei_value[16]; // phc, no find 'imei_value' in rk29 project
320 //char imei_value[16] = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5};
322 static int mtk23d_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
324 struct rk2818_23d_data *pdata = gpdata;
326 void __user *argp = (void __user *)arg;
328 char SectorBuffer[512];
330 printk("mtk23d_ioctl\n");
331 ret = down_interruptible(&pdata->power_sem);
333 printk("%s: down power_sem error ret = %d\n", __func__, ret);
340 case MTK23D_POWEROFF:
341 printk("MTK23D_POWEROFF\n");
342 rk29_uart_to_gpio(0);
343 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
345 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
347 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
351 printk("MTK23D_RESET\n");
352 /****power off 23d and uart to gpio***/
353 rk29_uart_to_gpio(0);
354 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
356 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
358 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
360 /****power on 23d***/
362 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
363 rk29_gpio_to_uart(0);
365 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
367 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
371 /****power on 23d***/
372 printk("MTK23D_POWERON\n");
373 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
375 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
376 rk29_gpio_to_uart(0);
378 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
380 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
383 case MTK23D_IMEI_READ:
384 printk("MTK23D_IMEI_READ\n");
386 GetSNSectorInfo(SectorBuffer); // phc,20110624
388 if(copy_to_user(argp, &(SectorBuffer[451]), 16)) // IMEIºó´Ó451Æ«ÒÆ¿ªÊ¼µÄ16bytes£¬µÚÒ»¸öbyteΪ³¤¶È¹Ì¶¨Îª15
390 printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
391 up(&pdata->power_sem);
394 //printk("IMEI:%d %d %d %d\n", SectorBuffer[451], SectorBuffer[452], SectorBuffer[453], SectorBuffer[454]);
400 up(&pdata->power_sem);
405 static struct file_operations mtk23d_fops = {
406 .owner = THIS_MODULE,
408 .release = mtk23d_release,
409 .unlocked_ioctl = mtk23d_ioctl
412 static struct miscdevice mtk23d_misc = {
413 .minor = MISC_DYNAMIC_MINOR,
418 static int mtk23d_probe(struct platform_device *pdev)
420 struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
421 struct modem_dev *mt6223d_data = NULL;
422 int result, error = 0, irq = 0;
424 MODEMDBG("mtk23d_probe\n");
427 pdata->dev = &pdev->dev;
429 mt6223d_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
430 if(NULL == mt6223d_data)
432 printk("failed to request mt6223d_data\n");
435 platform_set_drvdata(pdev, mt6223d_data);
437 result = gpio_request(pdata->bp_statue, "mtk23d");
439 printk("failed to request BP_STATUS gpio\n");
443 result = gpio_request(pdata->ap_statue, "mtk23d");
445 printk("failed to request AP_STATUS gpio\n");
449 result = gpio_request(pdata->ap_bp_wakeup, "mtk23d");
451 printk("failed to request AP_BP_WAKEUP gpio\n");
454 result = gpio_request(pdata->bp_reset, "mtk23d");
456 printk("failed to request BP_RESET gpio\n");
459 result = gpio_request(pdata->bp_power, "mtk23d");
461 printk("failed to request BP_POW_EN gpio\n");
465 if(pdata->bp_ap_wakeup) // SDK°åÖУ¬¸Ã¿ÚûÓÐÒý³ö
467 result = gpio_request(pdata->bp_ap_wakeup, "mtk23d");
469 printk("failed to request BP_AP_WAKEUP gpio\n");
474 #if 1 // GPIO³õʼ»¯£¬²¢ÇÒ·Àֹ©µç
475 rk29_uart_to_gpio(0);
477 /***power off 23d***/
478 gpio_direction_output(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
480 gpio_direction_output(pdata->ap_statue, GPIO_LOW);
481 gpio_direction_output(pdata->ap_bp_wakeup, GPIO_LOW);
482 //gpio_direction_output(pdata->bp_statue,GPIO_LOW);
483 gpio_direction_input(pdata->bp_statue);
484 if(pdata->bp_ap_wakeup) // SDK°åÖУ¬¸Ã¿ÚûÓÐÒý³ö
486 //gpio_direction_output(pdata->bp_ap_wakeup,GPIO_LOW);
487 gpio_direction_input(pdata->bp_ap_wakeup);
491 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
493 //gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
496 INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
497 sema_init(&pdata->power_sem,1);
499 result = misc_register(&mtk23d_misc);
502 MODEMDBG("misc_register err\n");
504 MODEMDBG("mtk23d_probe ok\n");
508 cancel_work_sync(&mt6223d_data->work);
509 gpio_free(pdata->bp_ap_wakeup);
511 gpio_free(pdata->bp_power);
513 gpio_free(pdata->bp_reset);
515 gpio_free(pdata->ap_bp_wakeup);
517 gpio_free(pdata->ap_statue);
519 gpio_free(pdata->bp_statue);
526 int mtk23d_suspend(struct platform_device *pdev)
529 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
531 MODEMDBG("%s \n", __FUNCTION__);
533 //enable_irq_wake(irq);
535 ap_wakeup_bp(pdev, 0);
537 irq = gpio_to_irq(pdata->bp_statue);
539 printk("can't get pdata->bp_statue irq \n");
543 printk("enable pdata->bp_statue irq_wake!! \n");
544 bpstatus_irq_enable = true;
545 enable_irq_wake(irq);
551 int mtk23d_resume(struct platform_device *pdev)
553 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
556 MODEMDBG("%s \n", __FUNCTION__);
558 irq = gpio_to_irq(pdata->bp_statue);
561 printk("disable pdata->bp_statue irq_wake!! \n");
562 bpstatus_irq_enable = false;
563 disable_irq_wake(irq);
567 ap_wakeup_bp(pdev, 1);
572 void mtk23d_shutdown(struct platform_device *pdev, pm_message_t state)
574 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
575 struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
577 MODEMDBG("%s \n", __FUNCTION__);
579 modem_poweron_off(0); // power down
581 cancel_work_sync(&mt6223d_data->work);
582 gpio_free(pdata->bp_ap_wakeup);
583 gpio_free(pdata->bp_power);
584 gpio_free(pdata->bp_reset);
585 gpio_free(pdata->ap_bp_wakeup);
586 gpio_free(pdata->ap_statue);
587 gpio_free(pdata->bp_statue);
591 static struct platform_driver mtk23d_driver = {
592 .probe = mtk23d_probe,
593 .shutdown = mtk23d_shutdown,
594 .suspend = mtk23d_suspend,
595 .resume = mtk23d_resume,
598 .owner = THIS_MODULE,
602 static int __init mtk23d_init(void)
604 MODEMDBG("mtk23d_init ret=%d\n");
605 return platform_driver_register(&mtk23d_driver);
608 static void __exit mtk23d_exit(void)
610 MODEMDBG("mtk23d_exit\n");
611 platform_driver_unregister(&mtk23d_driver);
614 module_init(mtk23d_init);
615 //late_initcall_sync(mtk23d_init);
616 module_exit(mtk23d_exit);