c7b0460c24f91d29eb01717114d8c9afdda8e54f
[firefly-linux-kernel-4.4.55.git] / drivers / misc / bp / chips / mtk6250.c
1 /* drivers/misc/bp/chips/mt6250.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("<-----mt6250 power on-------->\n");     \r
57                 gpio_set_value(bp->ops->bp_power, GPIO_HIGH);\r
58                 msleep(100);\r
59                 gpio_set_value(bp->ops->bp_en,GPIO_HIGH);\r
60                 mdelay(100);\r
61                 gpio_set_value(bp->ops->bp_reset, GPIO_LOW);\r
62                 mdelay(2500);\r
63                 gpio_set_value(bp->ops->bp_en,GPIO_LOW);\r
64         }\r
65         else\r
66         {\r
67                 printk("<-----mt6250 power on-------->\n");\r
68                 gpio_set_value(bp->ops->bp_en, GPIO_LOW);\r
69                 msleep(2500);\r
70                 gpio_set_value(bp->ops->bp_en, GPIO_HIGH);\r
71                 msleep(500);\r
72                 gpio_set_value(bp->ops->bp_reset, GPIO_HIGH); \r
73                 gpio_set_value(bp->ops->bp_power, GPIO_LOW);\r
74         }\r
75         \r
76         return result;\r
77 }\r
78 static void  ap_wake_bp_work(struct work_struct *work)\r
79 {\r
80         return;\r
81 }\r
82 static int bp_wake_ap(struct bp_private_data *bp)\r
83 {\r
84         int result = 0;\r
85         \r
86         bp->suspend_status = 0;         \r
87         wake_lock_timeout(&bp->bp_wakelock, 10 * HZ);\r
88         \r
89         return result;\r
90 }\r
91 static int bp_init(struct bp_private_data *bp)\r
92 {\r
93         int result = 0;\r
94         if(bp->pdata->gpio_valid ==0){          \r
95                 \r
96         }\r
97         gpio_direction_output(bp->ops->bp_power, GPIO_LOW);\r
98         gpio_direction_output(bp->ops->bp_reset, GPIO_HIGH);\r
99         gpio_direction_output(bp->ops->bp_en, GPIO_LOW);\r
100         gpio_direction_output(bp->ops->ap_ready, GPIO_LOW);\r
101         gpio_direction_output(bp->ops->ap_wakeup_bp, GPIO_HIGH);   \r
102         //gpio_direction_input(bp->ops->bp_ready);      \r
103         gpio_direction_input(bp->ops->bp_wakeup_ap);\r
104         gpio_pull_updown(bp->ops->bp_wakeup_ap, 1);     \r
105         \r
106         //if(bp->ops->active)\r
107                 //bp->ops->active(bp, 1);       \r
108         INIT_DELAYED_WORK(&bp->wakeup_work, ap_wake_bp_work);\r
109         return result;\r
110 }\r
111 \r
112 static int bp_reset(struct bp_private_data *bp)\r
113 {\r
114         printk("ioctrl mt6250 reset !!! \n");\r
115         gpio_set_value(bp->ops->bp_reset, GPIO_HIGH);\r
116         msleep(2000);\r
117         gpio_set_value(bp->ops->bp_reset, GPIO_LOW);    \r
118         return 0;\r
119 }\r
120 static int bp_shutdown(struct bp_private_data *bp)\r
121 {\r
122         int result = 0;\r
123         \r
124         if(bp->ops->active)\r
125                 bp->ops->active(bp, 0);\r
126         \r
127         cancel_delayed_work_sync(&bp->wakeup_work);     \r
128                 \r
129         return result;\r
130 }\r
131 static int bp_suspend(struct bp_private_data *bp)\r
132 {       \r
133         int result = 0;\r
134         \r
135         bp->suspend_status = 1;\r
136         gpio_set_value(bp->ops->ap_ready, GPIO_HIGH);\r
137         gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);\r
138 \r
139         \r
140         \r
141         return result;\r
142 }\r
143 static int bp_resume(struct bp_private_data *bp)\r
144 {\r
145         \r
146         bp->suspend_status = 0; \r
147         gpio_set_value(bp->ops->ap_ready, GPIO_LOW);\r
148         gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_HIGH);\r
149         msleep(100);    \r
150         gpio_set_value(bp->ops->ap_wakeup_bp, GPIO_LOW);        \r
151         \r
152         return 0;\r
153 }\r
154 \r
155 \r
156 struct bp_operate bp_mt6250_ops = {\r
157         .name                   = "mt6250",\r
158         .bp_id                  = BP_ID_MT6250,\r
159         .bp_bus                 = BP_BUS_TYPE_UART,             \r
160         .bp_pid                 = 0,    \r
161         .bp_vid                 = 0,    \r
162         .bp_power               = BP_UNKNOW_DATA,       // RK2928_PIN3_PC2,     // 3g_power\r
163         .bp_en                  = BP_UNKNOW_DATA,       // RK2928_PIN3_PC5,//BP_UNKNOW_DATA,    // 3g_en\r
164         .bp_reset                       = BP_UNKNOW_DATA,       // RK2928_PIN0_PB6,\r
165         .ap_ready               = BP_UNKNOW_DATA,       // RK2928_PIN0_PD0,     //\r
166         .bp_ready               = BP_UNKNOW_DATA,       // RK2928_PIN0_PD6,\r
167         .ap_wakeup_bp   = BP_UNKNOW_DATA,       // RK2928_PIN3_PC4,\r
168         .bp_wakeup_ap   = BP_UNKNOW_DATA,       // RK2928_PIN3_PC3,     //\r
169         .bp_assert              = BP_UNKNOW_DATA,\r
170         .bp_uart_en             = BP_UNKNOW_DATA,       //EINT9\r
171         .bp_usb_en              = BP_UNKNOW_DATA,       //W_disable\r
172         .trig                           = IRQF_TRIGGER_FALLING,\r
173 \r
174         .active                 = bp_active,\r
175         .init                           = bp_init,\r
176         .reset                  = bp_reset,\r
177         .ap_wake_bp             = NULL,\r
178         .bp_wake_ap             = bp_wake_ap,\r
179         .shutdown               = bp_shutdown,\r
180         .read_status            = NULL,\r
181         .write_status           = NULL,\r
182         .suspend                = bp_suspend,\r
183         .resume                 = bp_resume,\r
184         .misc_name              = NULL,\r
185         .private_miscdev        = NULL,\r
186 };\r
187 \r
188 /****************operate according to bp chip:end************/\r
189 \r
190 //function name should not be changed\r
191 static struct bp_operate *bp_get_ops(void)\r
192 {\r
193         return &bp_mt6250_ops;\r
194 }\r
195 \r
196 static int __init bp_mt6250_init(void)\r
197 {\r
198         struct bp_operate *ops = bp_get_ops();\r
199         int result = 0;\r
200         result = bp_register_slave(NULL, NULL, bp_get_ops);\r
201         if(result)\r
202         {       \r
203                 return result;\r
204         }\r
205         \r
206         if(ops->private_miscdev)\r
207         {\r
208                 result = misc_register(ops->private_miscdev);\r
209                 if (result < 0) {\r
210                         printk("%s:misc_register err\n",__func__);\r
211                         return result;\r
212                 }\r
213         }\r
214         \r
215         DBG("%s\n",__func__);\r
216         return result;\r
217 }\r
218 \r
219 static void __exit bp_mt6250_exit(void)\r
220 {\r
221         //struct bp_operate *ops = bp_get_ops();\r
222         bp_unregister_slave(NULL, NULL, bp_get_ops);\r
223 }\r
224 \r
225 \r
226 subsys_initcall(bp_mt6250_init);\r
227 module_exit(bp_mt6250_exit);\r
228 \r