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>
25 MODULE_LICENSE("GPL");
29 #define MODEMDBG(x...) printk(x)
31 #define MODEMDBG(fmt,argss...)
34 #define MTK23D_RESET 0x01
35 #define MTK23D_POWERON 0x02
36 #define MTK23D_POWER_HIGH 0x03
37 #define MTK23D_IMEI_READ 0x04
38 //#define BP_POW_EN TCA6424_P02
39 //#define BP_STATUS RK2818_PIN_PH7 //input high bp sleep
40 //#define AP_STATUS RK2818_PIN_PA4 //output high ap sleep
42 //#define BP_RESET TCA6424_P11 //Ryan
44 //#define AP_BP_WAKEUP RK2818_PIN_PF5 //output AP wake up BP used rising edge
45 //#define BP_AP_WAKEUP RK2818_PIN_PE0 //input BP wake up AP
50 //struct modem_dev *mt6223d_data = NULL;
51 struct rk2818_23d_data *gpdata = NULL;
53 static int get_bp_statue(struct platform_device *pdev)
55 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
57 if(gpio_get_value(pdata->bp_statue))
62 static void ap_sleep(struct platform_device *pdev)
64 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
66 MODEMDBG("ap sleep!\n");
67 gpio_set_value(pdata->ap_statue,GPIO_HIGH);
69 static void ap_wakeup(struct platform_device *pdev)
71 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
73 MODEMDBG("ap wakeup!\n");
74 gpio_set_value(pdata->ap_statue,GPIO_LOW);
77 static void ap_wakeup_bp(struct platform_device *pdev, int wake)//low to wakeup bp
79 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
80 struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
81 MODEMDBG("ap_wakeup_bp\n");
83 gpio_set_value(pdata->ap_bp_wakeup, wake); // phc
84 //gpio_set_value(RK2818_PIN_PF5, wake);
87 static void bpwakeup_work_func_work(struct work_struct *work)
89 struct modem_dev *bdata = container_of(work, struct modem_dev, work);
91 MODEMDBG("%s\n", __FUNCTION__);
95 static irqreturn_t bpwakeup_work_func(int irq, void *data)
97 struct modem_dev *mt6223d_data = (struct modem_dev *)data;
99 MODEMDBG("bpwakeup_work_func\n");
100 schedule_work(&mt6223d_data->work);
103 static irqreturn_t bp_apwakeup_work_func(int irq, void *data)
105 //struct modem_dev *dev = &mtk23d_misc;
107 MODEMDBG("bp_apwakeup_work_func\n");
108 //wake_up_interruptible(&dev->wakeup);
111 int modem_poweron_off(int on_off)
113 struct rk2818_23d_data *pdata = gpdata;
117 printk("modem_poweron\n");
118 gpio_set_value(gpdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
120 gpio_set_value(gpdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
124 printk("modem_poweroff\n");
125 gpio_set_value(gpdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
127 gpio_set_value(gpdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
130 static int power_on =1;
131 static int mtk23d_open(struct inode *inode, struct file *file)
133 struct rk2818_23d_data *pdata = gpdata;
134 //struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
135 struct platform_data *pdev = container_of(pdata, struct device, platform_data);
137 MODEMDBG("modem_open\n");
143 modem_poweron_off(1);
145 device_init_wakeup(&pdev, 1);
150 static int mtk23d_release(struct inode *inode, struct file *file)
152 MODEMDBG("mtk23d_release\n");
154 //gpio_free(pdata->bp_power);
158 //extern char imei_value[16]; // phc, no find 'imei_value' in rk29 project
159 char imei_value[16] = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5};
161 static int mtk23d_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
163 struct rk2818_23d_data *pdata = gpdata;
165 void __user *argp = (void __user *)arg;
166 printk("mtk23d_ioctl\n");
170 gpio_set_value(gpdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
172 gpio_direction_output(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
174 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
176 gpio_set_value(gpdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
178 case MTK23D_IMEI_READ:
179 if(copy_to_user(argp, &(imei_value[0]), 16))
181 printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
191 static struct file_operations mtk23d_fops = {
192 .owner = THIS_MODULE,
194 .release = mtk23d_release,
195 .ioctl = mtk23d_ioctl
198 static struct miscdevice mtk23d_misc = {
199 .minor = MISC_DYNAMIC_MINOR,
204 static int mtk23d_probe(struct platform_device *pdev)
206 struct rk2818_23d_data *pdata = gpdata = pdev->dev.platform_data;
207 struct modem_dev *mt6223d_data = NULL;
210 MODEMDBG("mtk23d_probe\n");
213 rk29_mux_api_set(GPIO1B7_UART0SOUT_NAME, GPIO1L_GPIO1B7);
214 gpio_request(RK29_PIN1_PB7, NULL);
215 gpio_direction_output(RK29_PIN1_PB7,GPIO_LOW);
216 gpio_pull_updown(RK29_PIN1_PB7, PullDisable); // ÏÂÀ½ûÖ¹
218 rk29_mux_api_set(GPIO1B6_UART0SIN_NAME, GPIO1L_GPIO1B6);
219 gpio_request(RK29_PIN1_PB6, NULL);
220 gpio_direction_output(RK29_PIN1_PB6,GPIO_LOW);
221 gpio_pull_updown(RK29_PIN1_PB6, PullDisable); // ÏÂÀ½ûÖ¹
223 rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
224 gpio_request(RK29_PIN1_PC1, NULL);
225 gpio_direction_output(RK29_PIN1_PC1,GPIO_LOW);
227 rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_GPIO1C0);
228 gpio_request(RK29_PIN1_PC0, NULL);
229 gpio_direction_output(RK29_PIN1_PC0,GPIO_LOW);
234 mt6223d_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
235 if(NULL == mt6223d_data)
237 printk("failed to request mt6223d_data\n");
240 platform_set_drvdata(pdev, mt6223d_data);
242 result = gpio_request(pdata->bp_statue, "mtk23d");
244 printk("failed to request BP_STATUS gpio\n");
248 result = gpio_request(pdata->ap_statue, "mtk23d");
250 printk("failed to request AP_STATUS gpio\n");
254 result = gpio_request(pdata->ap_bp_wakeup, "mtk23d");
256 printk("failed to request AP_BP_WAKEUP gpio\n");
259 result = gpio_request(pdata->bp_reset, "mtk23d");
261 printk("failed to request BP_RESET gpio\n");
264 result = gpio_request(pdata->bp_power, "mtk23d");
266 printk("failed to request BP_POW_EN gpio\n");
271 gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
272 gpio_direction_output(pdata->ap_statue, GPIO_LOW);
273 gpio_direction_output(pdata->ap_bp_wakeup, GPIO_LOW);
275 gpio_direction_output(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
277 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
281 gpio_direction_input(pdata->bp_statue);
283 //rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME, 0);
284 gpio_direction_output(pdata->ap_statue, GPIO_LOW);
286 //rk2818_mux_api_set(GPIOF5_APWM3_DPWM3_NAME,0);
287 gpio_direction_output(pdata->ap_bp_wakeup, GPIO_LOW);
289 //rk2818_mux_api_set(GPIOE_SPI1_FLASH_SEL_NAME, IOMUXA_GPIO1_A3B7);
290 gpio_direction_output(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_LOW:GPIO_HIGH);
292 gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
293 gpio_set_value(pdata->ap_bp_wakeup, GPIO_HIGH);
296 INIT_WORK(&mt6223d_data->work, bpwakeup_work_func_work);
298 result = misc_register(&mtk23d_misc);
301 MODEMDBG("misc_register err\n");
303 MODEMDBG("mtk23d_probe ok\n");
306 cancel_work_sync(&mt6223d_data->work);
307 gpio_free(pdata->bp_ap_wakeup);
309 gpio_free(pdata->bp_power);
311 gpio_free(pdata->bp_reset);
313 gpio_free(pdata->ap_bp_wakeup);
315 gpio_free(pdata->ap_statue);
317 gpio_free(pdata->bp_statue);
324 int mtk23d_suspend(struct platform_device *pdev)
326 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
327 //int irq = gpio_to_irq(pdata->bp_ap_wakeup);
329 MODEMDBG("%s \n", __FUNCTION__);
330 //enable_irq_wake(irq);
332 ap_wakeup_bp(pdev, 0);
336 int mtk23d_resume(struct platform_device *pdev)
338 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
339 //int irq = gpio_to_irq(pdata->bp_ap_wakeup);
341 MODEMDBG("%s \n", __FUNCTION__);
342 //disable_irq_wake(irq);
344 ap_wakeup_bp(pdev, 1);
348 void mtk23d_shutdown(struct platform_device *pdev, pm_message_t state)
350 struct rk2818_23d_data *pdata = pdev->dev.platform_data;
351 struct modem_dev *mt6223d_data = platform_get_drvdata(pdev);
353 MODEMDBG("%s \n", __FUNCTION__);
355 modem_poweron_off(0); // power down
357 cancel_work_sync(&mt6223d_data->work);
358 gpio_free(pdata->bp_ap_wakeup);
359 gpio_free(pdata->bp_power);
360 gpio_free(pdata->bp_reset);
361 gpio_free(pdata->ap_bp_wakeup);
362 gpio_free(pdata->ap_statue);
363 gpio_free(pdata->bp_statue);
367 static struct platform_driver mtk23d_driver = {
368 .probe = mtk23d_probe,
369 .shutdown = mtk23d_shutdown,
370 .suspend = mtk23d_suspend,
371 .resume = mtk23d_resume,
374 .owner = THIS_MODULE,
378 static int __init mtk23d_init(void)
380 MODEMDBG("mtk23d_init ret=%d\n");
381 return platform_driver_register(&mtk23d_driver);
384 static void __exit mtk23d_exit(void)
386 MODEMDBG("mtk23d_exit\n");
387 platform_driver_unregister(&mtk23d_driver);
390 module_init(mtk23d_init);
391 //late_initcall_sync(mtk23d_init);
392 module_exit(mtk23d_exit);