rk2928 add phonepad support
[firefly-linux-kernel-4.4.55.git] / drivers / misc / bp / chips / mi700.c
1 /* drivers/misc/bp/chips/mi700.c\r
2  *\r
3  * Copyright (C) 2012-2015 ROCKCHIP.\r
4  * Author: luowei <lw@rock-chips.com>\r
5  *\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
9  *\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
14  *\r
15  */\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
39 \r
40 #include <linux/bp-auto.h>\r
41          \r
42          \r
43 #if 0\r
44 #define DBG(x...)  printk(x)\r
45 #else\r
46 #define DBG(x...)\r
47 #endif\r
48 \r
49 \r
50 /****************operate according to bp chip:start************/\r
51 static int bp_active(struct bp_private_data *bp, int enable)\r
52 {       \r
53         int result = 0;\r
54         if(enable)\r
55         {\r
56                 printk("mi700 power on \n");\r
57                 gpio_set_value(bp->ops->bp_reset, GPIO_LOW);\r
58                 msleep(100);
59                 gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);\r
60                 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);\r
61                 msleep(1000);
62                 gpio_set_value(bp->ops->bp_en, GPIO_LOW);\r
63                 msleep(700);
64                 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);\r
65         }\r
66         else\r
67         {\r
68                 printk("mi700 power off \n");           \r
69 \r
70                 gpio_set_value(bp->ops->bp_en, GPIO_LOW);\r
71                 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);\r
72                 msleep(2500);
73                 gpio_set_value(bp->ops->bp_en, GPIO_LOW);\r
74         }\r
75         \r
76         return result;\r
77 }\r
78 \r
79 static void  ap_wake_bp_work(struct work_struct *work)\r
80 {\r
81         return;\r
82 }\r
83 static int bp_wake_ap(struct bp_private_data *bp)\r
84 {\r
85         int result = 0;\r
86         \r
87         bp->suspend_status = 0;\r
88         wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);\r
89         \r
90         return result;\r
91 }\r
92 static int bp_init(struct bp_private_data *bp)\r
93 {\r
94         int result = 0; \r
95         //if(bp->ops->active)\r
96         //      bp->ops->active(bp, 1); \r
97         INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);\r
98         return result;\r
99 }\r
100 \r
101 static int bp_reset(struct bp_private_data *bp)\r
102 {\r
103         printk("ioctrl mi700 reset !!! \n");\r
104         gpio_set_value(bp->ops->bp_reset, GPIO_LOW);\r
105         msleep(100);\r
106         gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);\r
107         msleep(100);\r
108         gpio_set_value(bp->ops->bp_en, GPIO_HIGH);\r
109         msleep(1000);\r
110         gpio_set_value(bp->ops->bp_en, GPIO_LOW);\r
111         msleep(700);\r
112         gpio_set_value(bp->ops->bp_en, GPIO_HIGH);\r
113         return 0;\r
114 }\r
115 static int bp_shutdown(struct bp_private_data *bp)\r
116 {\r
117         int result = 0;\r
118         \r
119         if(bp->ops->active)\r
120                 bp->ops->active(bp, 0);\r
121         \r
122         cancel_delayed_work_sync(&bp->wakeup_work);     \r
123                 \r
124         return result;\r
125 }\r
126 static int bp_suspend(struct bp_private_data *bp)\r
127 {       \r
128         int result = 0;\r
129         \r
130         if(!bp->suspend_status)\r
131         {\r
132                 bp->suspend_status = 1;\r
133                 //gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);\r
134         }\r
135         \r
136         return result;\r
137 }\r
138 static int bp_resume(struct bp_private_data *bp)\r
139 {\r
140         \r
141         bp->suspend_status = 0; \r
142         //gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);     \r
143         \r
144         \r
145         return 0;\r
146 }\r
147 \r
148 \r
149 struct bp_operate bp_mi700_ops = {\r
150 #if defined(CONFIG_ARCH_RK2928)\r
151         .name                   = "mi700",\r
152         .bp_id                  = BP_ID_MI700,\r
153         .bp_bus                 = BP_BUS_TYPE_USB,              \r
154         .bp_pid                 = 0,    \r
155         .bp_vid                 = 0,    \r
156         .bp_power               = BP_UNKNOW_DATA,       // 3g_power\r
157         .bp_en                  = BP_UNKNOW_DATA,       // 3g_en\r
158         .bp_reset                       = BP_UNKNOW_DATA,\r
159         .ap_ready               = BP_UNKNOW_DATA,       //\r
160         .bp_ready               = BP_UNKNOW_DATA,\r
161         .ap_wakeup_bp   = BP_UNKNOW_DATA,\r
162         .bp_wakeup_ap   = BP_UNKNOW_DATA,       //\r
163         .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
164         .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
165         .trig                           = IRQF_TRIGGER_FALLING,\r
166 \r
167         .active                 = bp_active,\r
168         .init                           = bp_init,\r
169         .reset                  = bp_reset,\r
170         .ap_wake_bp             = NULL,\r
171         .bp_wake_ap             = bp_wake_ap,\r
172         .shutdown               = bp_shutdown,\r
173         .read_status            = NULL,\r
174         .write_status           = NULL,\r
175         .suspend                = bp_suspend,\r
176         .resume                 = bp_resume,\r
177         .misc_name              = NULL,\r
178         .private_miscdev        = NULL,\r
179 #elif defined(CONFIG_ARCH_RK30)\r
180         .name                   = "mi700",\r
181         .bp_id                  = BP_ID_MI700,\r
182         .bp_bus                 = BP_BUS_TYPE_USB,              \r
183         .bp_pid                 = 0,    \r
184         .bp_vid                 = 0,    \r
185         .bp_power               = BP_UNKNOW_DATA,       // 3g_power\r
186         .bp_en                  = BP_UNKNOW_DATA,       // 3g_en\r
187         .bp_reset                       = BP_UNKNOW_DATA,\r
188         .ap_ready               = BP_UNKNOW_DATA,       //\r
189         .bp_ready               = BP_UNKNOW_DATA,\r
190         .ap_wakeup_bp   = BP_UNKNOW_DATA,\r
191         .bp_wakeup_ap   = BP_UNKNOW_DATA,       //\r
192         .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
193         .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
194         .trig                           = IRQF_TRIGGER_FALLING,\r
195 \r
196         .active                 = bp_active,\r
197         .init                           = bp_init,\r
198         .reset                  = bp_reset,\r
199         .ap_wake_bp             = NULL,\r
200         .bp_wake_ap             = bp_wake_ap,\r
201         .shutdown               = bp_shutdown,\r
202         .read_status            = NULL,\r
203         .write_status           = NULL,\r
204         .suspend                = bp_suspend,\r
205         .resume                 = bp_resume,\r
206         .misc_name              = NULL,\r
207         .private_miscdev        = NULL,\r
208 #else\r
209         .name                   = "mi700",\r
210         .bp_id                  = BP_ID_MI700,\r
211         .bp_bus                 = BP_BUS_TYPE_USB,              \r
212         .bp_pid                 = 0,    \r
213         .bp_vid                 = 0,    \r
214         .bp_power               = BP_UNKNOW_DATA,       // 3g_power\r
215         .bp_en                  = BP_UNKNOW_DATA,       // 3g_en\r
216         .bp_reset                       = BP_UNKNOW_DATA,\r
217         .ap_ready               = BP_UNKNOW_DATA,       //\r
218         .bp_ready               = BP_UNKNOW_DATA,\r
219         .ap_wakeup_bp   = BP_UNKNOW_DATA,\r
220         .bp_wakeup_ap   = BP_UNKNOW_DATA,       //\r
221         .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
222         .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
223         .trig                           = IRQF_TRIGGER_FALLING,\r
224 \r
225         .active                 = bp_active,\r
226         .init                           = bp_init,\r
227         .reset                  = bp_reset,\r
228         .ap_wake_bp             = NULL,\r
229         .bp_wake_ap             = bp_wake_ap,\r
230         .shutdown               = bp_shutdown,\r
231         .read_status            = NULL,\r
232         .write_status           = NULL,\r
233         .suspend                = bp_suspend,\r
234         .resume                 = bp_resume,\r
235         .misc_name              = NULL,\r
236         .private_miscdev        = NULL,\r
237 #endif\r
238 };\r
239 \r
240 /****************operate according to bp chip:end************/\r
241 \r
242 //function name should not be changed\r
243 static struct bp_operate *bp_get_ops(void)\r
244 {\r
245         return &bp_mi700_ops;\r
246 }\r
247 \r
248 static int __init bp_mi700_init(void)\r
249 {\r
250         struct bp_operate *ops = bp_get_ops();\r
251         int result = 0;\r
252         result = bp_register_slave(NULL, NULL, bp_get_ops);\r
253         if(result)\r
254         {       \r
255                 return result;\r
256         }\r
257         \r
258         if(ops->private_miscdev)\r
259         {\r
260                 result = misc_register(ops->private_miscdev);\r
261                 if (result < 0) {\r
262                         printk("%s:misc_register err\n",__func__);\r
263                         return result;\r
264                 }\r
265         }\r
266         \r
267         DBG("%s\n",__func__);\r
268         return result;\r
269 }\r
270 \r
271 static void __exit bp_mi700_exit(void)\r
272 {\r
273         //struct bp_operate *ops = bp_get_ops();\r
274         bp_unregister_slave(NULL, NULL, bp_get_ops);\r
275 }\r
276 \r
277 \r
278 subsys_initcall(bp_mi700_init);\r
279 module_exit(bp_mi700_exit);\r
280 \r