blob: 8dcf3c3f5fa94eec270b0b604c5bd223e282124d [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* Copyright (c) 2013, ZTE-TSP. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/bitmap.h>
15#include <linux/bitops.h>
16#include <linux/gpio.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/irq.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
24
25#include <asm/mach/irq.h>
26
27#include <mach/gpio.h>
28#include <mach/pcu.h>
29#include <mach/irqs.h>
30
31
32static int zx29_gpio_get(struct gpio_chip *chip, unsigned offset)
33{
34 unsigned int gpio=chip->base+offset;
35 int ret=0;
36
37 ret = zx29_gpio_input_data(gpio);
38
39 return ret;
40}
41
42static void zx29_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
43{
44 unsigned int gpio=chip->base+offset;
45
46 zx29_gpio_output_data(gpio,(unsigned int)val);
47}
48
49static int zx29_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
50{
51 unsigned int gpio=chip->base+offset;
52
53 zx29_gpio_set_direction(gpio, GPIO_IN);
54
55 return 0;
56}
57
58static int zx29_gpio_direction_output(struct gpio_chip *chip,
59 unsigned offset,
60 int val)
61{
62 unsigned int gpio=chip->base+offset;
63
64 zx29_gpio_set_direction(gpio, GPIO_OUT);
65 zx29_gpio_output_data(gpio, (unsigned int)val);
66
67 return 0;
68}
69
70
71static int zx29_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
72{
73 unsigned int gpio=chip->base+offset;
74
75 return (zx29_gpio2irq(gpio));
76}
77
78
79static struct gpio_chip zx29_gpio =
80{
81 .base = BASE_GPIO,
82 .ngpio = NGPIO,
83 .direction_input = zx29_gpio_direction_input,
84 .direction_output = zx29_gpio_direction_output,
85 .get = zx29_gpio_get,
86 .set = zx29_gpio_set,
87 .to_irq = zx29_gpio_to_irq,
88 .request = NULL,
89 .free = NULL,
90};
91
92/*
93 * select gpio multiplex function
94 * gpio: gpio number
95 * func: PIN_FUNC_SEL_AON/PIN_FUNC_SEL_PD
96 * according with register defination
97 */
98int zx29_gpio_config(unsigned int gpio, gpio_func_id func )
99{
100 return zx29_gpio_function_sel(gpio, func);
101}
102EXPORT_SYMBOL(zx29_gpio_config);
103
104#if 0
105/*add by shideyou 20130731*/
106static ssize_t ap_ufi_wps_show(struct device *dev,
107 struct device_attribute *attr, char *buf)
108{
109 long value;
110 unsigned int tmp = 0;
111 unsigned int dir = 0;
112
113 struct zx29_gpio_platform_data *pdata = dev->platform_data;
114 dir = zx29_gpio_get_direction(pdata->ufi_wps);
115 tmp = zx29_gpio_function_sel_get(pdata->ufi_wps);
116 tmp = ((tmp>>24)&0x7);
117 if((tmp==0)||(tmp==2)||(tmp==4)||(tmp==6))
118 {
119 value = gpio_get_value(pdata->ufi_wps);
120 if (value < 0)
121 return value;
122
123 if (value)
124 if(dir)
125 strcpy(buf, "input highlevel!\n");
126 else
127 strcpy(buf, "output highlevel!\n");
128 else
129 if(dir)
130 strcpy(buf, "input lowlevel!\n");
131 else
132 strcpy(buf, "output lowlevel!\n");
133 return 18;
134 }
135 else
136 {
137 strcpy(buf, "it is not gpio!\n");
138 return 16;
139 }
140}
141static const DEVICE_ATTR(ap_ufi_wps, 0600, ap_ufi_wps_show, NULL);
142
143static ssize_t ap_ufi_reset_show(struct device *dev,
144 struct device_attribute *attr, char *buf)
145{
146 long value;
147 unsigned int tmp = 0;
148 unsigned int dir = 0;
149
150 struct zx29_gpio_platform_data *pdata = dev->platform_data;
151 dir = zx29_gpio_get_direction(pdata->ufi_resetkey);
152 tmp = zx29_gpio_function_sel_get(pdata->ufi_resetkey);
153 tmp = ((tmp>>24)&0x3);
154 if((tmp==0)||(tmp==2)||(tmp==3))
155 {
156 value = gpio_get_value(pdata->ufi_resetkey);
157 if (value < 0)
158 return value;
159
160 if (value)
161 if(dir)
162 strcpy(buf, "input highlevel!\n");
163 else
164 strcpy(buf, "output highlevel!\n");
165 else
166 if(dir)
167 strcpy(buf, "input lowlevel!\n");
168 else
169 strcpy(buf, "output lowlevel!\n");
170 return 18;
171 }
172 else
173 {
174 strcpy(buf, "it is not gpio!\n");
175 return 16;
176 }
177}
178static const DEVICE_ATTR(ap_ufi_reset, 0600, ap_ufi_reset_show, NULL);
179
180static ssize_t ap_poweron_show(struct device *dev,
181 struct device_attribute *attr, char *buf)
182{
183 long value;
184 unsigned int tmp = 0;
185 unsigned int dir = 0;
186
187 struct zx29_gpio_platform_data *pdata = dev->platform_data;
188 dir = zx29_gpio_get_direction(pdata->power_on_int);
189 tmp = zx29_gpio_function_sel_get(pdata->power_on_int);
190 tmp = ((tmp>>24)&0x7);
191 if((tmp==0)||(tmp==2)||(tmp==3)||(tmp==4)||(tmp==6))
192 {
193 value = gpio_get_value(pdata->power_on_int);
194 if (value < 0)
195 return value;
196
197 if (value)
198 if(dir)
199 strcpy(buf, "input highlevel!\n");
200 else
201 strcpy(buf, "output highlevel!\n");
202 else
203 if(dir)
204 strcpy(buf, "input lowlevel!\n");
205 else
206 strcpy(buf, "output lowlevel!\n");
207 return 18;
208 }
209 else
210 {
211 strcpy(buf, "it is not gpio!\n");
212 return 16;
213 }
214}
215static const DEVICE_ATTR(ap_poweron, 0600, ap_poweron_show, NULL);
216
217static ssize_t ap_wifi_hostwake_show(struct device *dev,
218 struct device_attribute *attr, char *buf)
219{
220 long value;
221 unsigned int tmp = 0;
222 unsigned int dir = 0;
223
224 struct zx29_gpio_platform_data *pdata = dev->platform_data;
225 dir = zx29_gpio_get_direction(pdata->wifi_host_wake);
226 tmp = zx29_gpio_function_sel_get(pdata->wifi_host_wake);
227 tmp = ((tmp>>24)&0x7);
228 if((tmp==0)||(tmp==2)||(tmp==4)||(tmp==6))
229 {
230 value = gpio_get_value(pdata->wifi_host_wake);
231 if (value < 0)
232 return value;
233
234 if (value)
235 if(dir)
236 strcpy(buf, "input highlevel!\n");
237 else
238 strcpy(buf, "output highlevel!\n");
239 else
240 if(dir)
241 strcpy(buf, "input lowlevel!\n");
242 else
243 strcpy(buf, "output lowlevel!\n");
244 return 18;
245 }
246 else
247 {
248 strcpy(buf, "it is not gpio!\n");
249 return 16;
250 }
251
252}
253static const DEVICE_ATTR(ap_wifi_hostwake, 0600, ap_wifi_hostwake_show, NULL);
254
255static ssize_t ap_charger_show(struct device *dev,
256 struct device_attribute *attr, char *buf)
257{
258 long value;
259 unsigned int tmp = 0;
260 unsigned int dir = 0;
261
262 struct zx29_gpio_platform_data *pdata = dev->platform_data;
263 dir = zx29_gpio_get_direction(pdata->charger_pg);
264 tmp = zx29_gpio_function_sel_get(pdata->charger_pg);
265 tmp = ((tmp>>24)&0x3);
266 if((tmp==0)||(tmp==2))
267 {
268 value = gpio_get_value(pdata->charger_pg);
269 if (value < 0)
270 return value;
271
272 if (value)
273 if(dir)
274 strcpy(buf, "input highlevel!\n");
275 else
276 strcpy(buf, "output highlevel!\n");
277 else
278 if(dir)
279 strcpy(buf, "input lowlevel!\n");
280 else
281 strcpy(buf, "output lowlevel!\n");
282 return 18;
283 }
284 else
285 {
286 strcpy(buf, "it is not gpio!\n");
287 return 16;
288 }
289}
290static const DEVICE_ATTR(ap_charger, 0600, ap_charger_show, NULL);
291#endif
292
293static const struct attribute *ap_gpio_attrs[] = {
294#if 0
295 &dev_attr_ap_ufi_reset.attr,
296 &dev_attr_ap_poweron.attr,
297 &dev_attr_ap_ufi_wps.attr,
298 &dev_attr_ap_wifi_hostwake.attr,
299 &dev_attr_ap_charger.attr,
300#endif
301 NULL,
302};
303
304static const struct attribute_group ap_gpio_attr_group = {
305 .attrs = (struct attribute **) ap_gpio_attrs,
306};
307
308static int __init zx29_gpio_probe(struct platform_device *dev)
309{
310 int ret;
311
312 zx29_gpio.label = dev->name;
313 ret = gpiochip_add(&zx29_gpio);
314 if (ret < 0)
315 return ret;
316
317 pr_info("[GPIO]create sysfs interface\n");
318 ret = sysfs_create_group(&dev->dev.kobj, &ap_gpio_attr_group);
319 if (ret)
320 printk(KERN_WARNING "[GPIO]sysfs_create_group ret %d\n", ret);
321
322 return 0;
323}
324
325static int zx29_gpio_remove(struct platform_device *dev)
326{
327 int ret = gpiochip_remove(&zx29_gpio);
328
329 if (ret) {
330 dev_err(&dev->dev, "%s failed, %d\n",
331 "gpiochip_remove()", ret);
332 return ret;
333 }
334
335 return 0;
336}
337
338static struct platform_driver zx29_gpio_driver = {
339 .driver = {
340 .name = "zx29_gpio",
341 .owner = THIS_MODULE,
342 },
343 .probe = zx29_gpio_probe,
344 .remove = __devexit_p(zx29_gpio_remove),
345};
346
347static struct zx29_gpio_platform_data zx29_gpio_data=
348{
349 .ufi_resetkey = GPIO_UFI_RESETKEY,
350 .power_on_int = GPIO_POWER_ON_INT,
351 .ufi_wps = GPIO_UFI_WPS,
352 .wifi_host_wake = GPIO_WIFI_HOST_WAKE,
353 .charger_pg = GPIO_CHARGER_PG,
354};
355
356static struct platform_device zx29_device_gpio =
357{
358 .name = "zx29_gpio",
359 .id = -1,
360 .dev = {
361 .platform_data = &zx29_gpio_data,
362 },
363};
364
365static int __init zx29_gpio_init(void)
366{
367 int rc;
368
369 rc = platform_driver_register(&zx29_gpio_driver);
370 if (!rc) {
371 rc = platform_device_register(&zx29_device_gpio);
372 if (rc)
373 platform_driver_unregister(&zx29_gpio_driver);
374 }
375 if(!rc)
376 pr_info("[GPIO]zx29 GPIO initialized\n");
377
378 return rc;
379}
380
381static void __exit zx29_gpio_exit(void)
382{
383 platform_device_unregister(&zx29_device_gpio);
384 platform_driver_unregister(&zx29_gpio_driver);
385}
386
387postcore_initcall(zx29_gpio_init);
388module_exit(zx29_gpio_exit);