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