1 /* drivers/misc/bp/chips/u5501.c
\r
3 * Copyright (C) 2012-2015 ROCKCHIP.
\r
4 * Author: luowei <lw@rock-chips.com>
\r
6 * This software is licensed under the terms of the GNU General Public
\r
7 * License version 2, as published by the Free Software Foundation, and
\r
8 * may be copied, distributed, and modified under those terms.
\r
10 * This program is distributed in the hope that it will be useful,
\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 * GNU General Public License for more details.
\r
16 #include <linux/module.h>
\r
17 #include <linux/kernel.h>
\r
18 #include <linux/i2c.h>
\r
19 #include <linux/irq.h>
\r
20 #include <linux/gpio.h>
\r
21 #include <linux/input.h>
\r
22 #include <linux/platform_device.h>
\r
23 #include <linux/fs.h>
\r
24 #include <linux/uaccess.h>
\r
25 #include <linux/miscdevice.h>
\r
26 #include <linux/circ_buf.h>
\r
27 #include <linux/interrupt.h>
\r
28 #include <linux/miscdevice.h>
\r
29 #include <mach/iomux.h>
\r
30 #include <mach/gpio.h>
\r
31 #include <asm/gpio.h>
\r
32 #include <linux/delay.h>
\r
33 #include <linux/poll.h>
\r
34 #include <linux/wait.h>
\r
35 #include <linux/wakelock.h>
\r
36 #include <linux/workqueue.h>
\r
37 #include <linux/slab.h>
\r
38 #include <linux/earlysuspend.h>
\r
40 #include <linux/bp-auto.h>
\r
44 #define DBG(x...) printk(x)
\r
50 /****************operate according to bp chip:start************/
\r
51 static int bp_active(struct bp_private_data *bp, int enable)
\r
56 // gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
\r
58 gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
\r
60 gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
\r
61 gpio_set_value(bp->ops->bp_en, GPIO_LOW);
\r
63 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
\r
65 gpio_set_value(bp->ops->bp_en, GPIO_LOW);
\r
66 gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
\r
70 // gpio_direction_output(bp->ops->bp_power, GPIO_LOW);
\r
71 gpio_set_value(bp->ops->bp_en, GPIO_LOW);
\r
72 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
\r
74 gpio_set_value(bp->ops->bp_en, GPIO_LOW);
\r
80 static int ap_wake_bp(struct bp_private_data *bp, int wake)
\r
84 gpio_set_value(bp->ops->ap_wakeup_bp, wake);
\r
90 static void ap_wake_bp_work(struct work_struct *work)
\r
92 struct delayed_work *wakeup_work = container_of(work, struct delayed_work, work);
\r
93 struct bp_private_data *bp = container_of(wakeup_work, struct bp_private_data, wakeup_work);
\r
95 if(bp->suspend_status)
\r
97 if(bp->ops->ap_wake_bp)
\r
98 bp->ops->ap_wake_bp(bp, 0);
\r
99 bp->suspend_status = 0;
\r
103 if(bp->ops->ap_wake_bp)
\r
104 bp->ops->ap_wake_bp(bp, 1);
\r
109 static int bp_init(struct bp_private_data *bp)
\r
112 gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
\r
113 gpio_set_value(bp->ops->bp_power, GPIO_HIGH);
\r
115 //if(bp->ops->active)
\r
116 // bp->ops->active(bp, 1);
\r
117 gpio_direction_input(bp->ops->bp_wakeup_ap);
\r
118 gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);
\r
119 gpio_direction_output(bp->ops->bp_reset, GPIO_LOW);
\r
120 gpio_direction_output(bp->ops->bp_en, GPIO_LOW);
\r
121 gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_LOW);
\r
122 INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);
\r
126 static int bp_reset(struct bp_private_data *bp)
\r
128 // gpio_direction_output(bp->ops->bp_power, GPIO_HIGH);
\r
130 gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);
\r
132 gpio_set_value(bp->ops->bp_reset, GPIO_LOW);
\r
133 gpio_set_value(bp->ops->bp_en, GPIO_LOW);
\r
135 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);
\r
137 gpio_set_value(bp->ops->bp_en, GPIO_LOW);
\r
138 gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
\r
143 static int bp_wake_ap(struct bp_private_data *bp)
\r
147 bp->suspend_status = 0;
\r
148 wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);
\r
154 static int bp_shutdown(struct bp_private_data *bp)
\r
158 if(bp->ops->active)
\r
159 bp->ops->active(bp, 0);
\r
160 gpio_set_value(bp->ops->bp_power, GPIO_LOW);
\r
161 cancel_delayed_work_sync(&bp->wakeup_work);
\r
168 static int bp_suspend(struct bp_private_data *bp)
\r
171 printk("<-----u5501 bp_suspend-------->\n");
\r
172 #if defined(CONFIG_ARCH_RK29)
\r
173 rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
\r
174 #elif defined(CONFIG_SOC_RK3066)
\r
175 rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_GPIO1A7);
\r
178 if(!bp->suspend_status)
\r
180 bp->suspend_status = 1;
\r
181 gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);
\r
183 #if defined(CONFIG_ARCH_RK2928)
\r
184 rk29_mux_api_set(GPIO1B1_SPI_TXD_UART1_SOUT_NAME, GPIO1B_GPIO1B1);
\r
185 gpio_set_value(RK2928_PIN1_PB1, GPIO_LOW);
\r
186 #elif defined(CONFIG_SOC_RK3066)
\r
187 rk30_mux_api_set(GPIO1A5_UART1SOUT_SPI0CLK_NAME, GPIO1A_GPIO1A5);
\r
188 gpio_set_value(RK30_PIN1_PA5, GPIO_LOW);
\r
196 static int bp_resume(struct bp_private_data *bp)
\r
198 #if defined(CONFIG_ARCH_RK29)
\r
199 rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
\r
200 #elif defined(CONFIG_SOC_RK3066)
\r
201 rk30_mux_api_set(GPIO1A7_UART1RTSN_SPI0TXD_NAME, GPIO1A_UART1_RTS_N);
\r
204 #if defined(CONFIG_ARCH_RK2928)
\r
205 rk29_mux_api_set(GPIO1B1_SPI_TXD_UART1_SOUT_NAME, GPIO1B_UART1_SOUT);
\r
206 #elif defined(CONFIG_SOC_RK3066)
\r
207 rk30_mux_api_set(GPIO1A5_UART1SOUT_SPI0CLK_NAME, GPIO1A_UART1_SOUT);
\r
209 //bp->suspend_status = 0;
\r
210 //gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);
\r
211 schedule_delayed_work(&bp->wakeup_work, 4*HZ);
\r
218 struct bp_operate bp_u5501_ops = {
\r
219 #if defined(CONFIG_ARCH_RK2928)
\r
221 .bp_id = BP_ID_U5501,
\r
222 .bp_bus = BP_BUS_TYPE_USB_UART,
\r
225 .bp_power = RK2928_PIN3_PC2, // 3g_power
\r
226 .bp_en = BP_UNKNOW_DATA, // 3g_en
\r
227 .bp_reset = RK2928_PIN1_PA3,
\r
228 .ap_ready = BP_UNKNOW_DATA, //
\r
229 .bp_ready = BP_UNKNOW_DATA,
\r
230 .ap_wakeup_bp = RK2928_PIN3_PC4,
\r
231 .bp_wakeup_ap = RK2928_PIN3_PC3, //
\r
232 .bp_uart_en = BP_UNKNOW_DATA, //EINT9
\r
233 .bp_usb_en = BP_UNKNOW_DATA, //W_disable
\r
234 .trig = IRQF_TRIGGER_FALLING,
\r
236 .active = bp_active,
\r
239 .ap_wake_bp = ap_wake_bp,
\r
240 .bp_wake_ap = bp_wake_ap,
\r
241 .shutdown = bp_shutdown,
\r
242 .read_status = NULL,
\r
243 .write_status = NULL,
\r
244 .suspend = bp_suspend,
\r
245 .resume = bp_resume,
\r
247 .private_miscdev = NULL,
\r
248 #elif defined(CONFIG_ARCH_RK30)
\r
250 .bp_id = BP_ID_U5501,
\r
251 .bp_bus = BP_BUS_TYPE_USB_UART,
\r
254 .bp_power = BP_UNKNOW_DATA,//RK2928_PIN3_PC2, // 3g_power
\r
255 .bp_en = BP_UNKNOW_DATA, // 3g_en
\r
256 .bp_reset = BP_UNKNOW_DATA,//RK2928_PIN1_PA3,
\r
257 .ap_ready = BP_UNKNOW_DATA, //
\r
258 .bp_ready = BP_UNKNOW_DATA,
\r
259 .ap_wakeup_bp = BP_UNKNOW_DATA,//RK2928_PIN3_PC4,
\r
260 .bp_wakeup_ap = BP_UNKNOW_DATA,//RK2928_PIN3_PC3, //
\r
261 .bp_uart_en = BP_UNKNOW_DATA, //EINT9
\r
262 .bp_usb_en = BP_UNKNOW_DATA, //W_disable
\r
263 .trig = IRQF_TRIGGER_FALLING,
\r
265 .active = bp_active,
\r
268 .ap_wake_bp = ap_wake_bp,
\r
269 .bp_wake_ap = bp_wake_ap,
\r
270 .shutdown = bp_shutdown,
\r
271 .read_status = NULL,
\r
272 .write_status = NULL,
\r
273 .suspend = bp_suspend,
\r
274 .resume = bp_resume,
\r
276 .private_miscdev = NULL,
\r
279 .bp_id = BP_ID_U5501,
\r
280 .bp_bus = BP_BUS_TYPE_USB_UART,
\r
283 .bp_power = BP_UNKNOW_DATA,//RK2928_PIN3_PC2, // 3g_power
\r
284 .bp_en = BP_UNKNOW_DATA, // 3g_en
\r
285 .bp_reset = BP_UNKNOW_DATA,//RK2928_PIN1_PA3,
\r
286 .ap_ready = BP_UNKNOW_DATA, //
\r
287 .bp_ready = BP_UNKNOW_DATA,
\r
288 .ap_wakeup_bp = BP_UNKNOW_DATA,//RK2928_PIN3_PC4,
\r
289 .bp_wakeup_ap = BP_UNKNOW_DATA,//RK2928_PIN3_PC3, //
\r
290 .bp_uart_en = BP_UNKNOW_DATA, //EINT9
\r
291 .bp_usb_en = BP_UNKNOW_DATA, //W_disable
\r
292 .trig = IRQF_TRIGGER_FALLING,
\r
294 .active = bp_active,
\r
297 .ap_wake_bp = ap_wake_bp,
\r
298 .bp_wake_ap = bp_wake_ap,
\r
299 .shutdown = bp_shutdown,
\r
300 .read_status = NULL,
\r
301 .write_status = NULL,
\r
302 .suspend = bp_suspend,
\r
303 .resume = bp_resume,
\r
305 .private_miscdev = NULL,
\r
309 /****************operate according to bp chip:end************/
\r
311 //function name should not be changed
\r
312 static struct bp_operate *bp_get_ops(void)
\r
314 return &bp_u5501_ops;
\r
317 static int __init bp_u5501_init(void)
\r
319 struct bp_operate *ops = bp_get_ops();
\r
321 result = bp_register_slave(NULL, NULL, bp_get_ops);
\r
327 if(ops->private_miscdev)
\r
329 result = misc_register(ops->private_miscdev);
\r
331 printk("%s:misc_register err\n",__func__);
\r
336 DBG("%s\n",__func__);
\r
340 static void __exit bp_u5501_exit(void)
\r
342 //struct bp_operate *ops = bp_get_ops();
\r
343 bp_unregister_slave(NULL, NULL, bp_get_ops);
\r
347 subsys_initcall(bp_u5501_init);
\r
348 module_exit(bp_u5501_exit);
\r