import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpio / mt_gpio_core.c
1 /******************************************************************************
2 * mt_gpio.c - MTKLinux GPIO Device Driver
3 *
4 * Copyright 2008-2009 MediaTek Co.,Ltd.
5 *
6 * DESCRIPTION:
7 * This file provid the other drivers GPIO relative functions
8 *
9 ******************************************************************************/
10
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <generated/autoconf.h>
15 #include <linux/platform_device.h>
16 #include <linux/fs.h>
17 #include <linux/ioctl.h>
18
19 #include <linux/types.h>
20 #include <linux/device.h>
21 #include <linux/slab.h>
22 #include <linux/spinlock.h>
23 #include <linux/cdev.h>
24 #include <asm/uaccess.h>
25 #include <asm/io.h>
26 #include <asm/atomic.h>
27 #include <linux/miscdevice.h>
28 #include <linux/mtgpio.h> /* ioctl cmd */
29
30 #include <mach/mt_typedefs.h>
31
32 #include <mach/mt_gpio.h>
33 #include <mach/mt_gpio_core.h>
34 #include <mach/gpio_const.h>
35
36 /***********************/
37 struct mt_gpio_ops {
38 /* char name[MT_GPIO_MAX_NAME]; */
39 int (*set_dir) (unsigned long pin, unsigned long dir);
40 int (*get_dir) (unsigned long pin);
41 int (*set_pull_enable) (unsigned long pin, unsigned long enable);
42 int (*get_pull_enable) (unsigned long pin);
43 int (*set_smt) (unsigned long pin, unsigned long enable);
44 int (*get_smt) (unsigned long pin);
45 int (*set_ies) (unsigned long pin, unsigned long enable);
46 int (*get_ies) (unsigned long pin);
47 int (*set_pull_select) (unsigned long pin, unsigned long select);
48 int (*get_pull_select) (unsigned long pin);
49 int (*set_inversion) (unsigned long pin, unsigned long enable);
50 int (*get_inversion) (unsigned long pin);
51 int (*set_out) (unsigned long pin, unsigned long output);
52 int (*get_out) (unsigned long pin);
53 int (*get_in) (unsigned long pin);
54 int (*set_mode) (unsigned long pin, unsigned long mode);
55 int (*get_mode) (unsigned long pin);
56 };
57
58 /*---------------------------------------------------------------------------*/
59 static struct mt_gpio_ops mt_base_ops = {
60 .set_dir = mt_set_gpio_dir_base,
61 .get_dir = mt_get_gpio_dir_base,
62 .set_pull_enable = mt_set_gpio_pull_enable_base,
63 .get_pull_enable = mt_get_gpio_pull_enable_base,
64 .set_smt = mt_set_gpio_smt_base,
65 .get_smt = mt_get_gpio_smt_base,
66 .set_ies = mt_set_gpio_ies_base,
67 .get_ies = mt_get_gpio_ies_base,
68 .set_pull_select = mt_set_gpio_pull_select_base,
69 .get_pull_select = mt_get_gpio_pull_select_base,
70 .set_inversion = mt_set_gpio_inversion_base,
71 .get_inversion = mt_get_gpio_inversion_base,
72 .set_out = mt_set_gpio_out_base,
73 .get_out = mt_get_gpio_out_base,
74 .get_in = mt_get_gpio_in_base,
75 .set_mode = mt_set_gpio_mode_base,
76 .get_mode = mt_get_gpio_mode_base,
77 };
78
79 static struct mt_gpio_ops mt_ext_ops = {
80 .set_dir = mt_set_gpio_dir_ext,
81 .get_dir = mt_get_gpio_dir_ext,
82 .set_pull_enable = mt_set_gpio_pull_enable_ext,
83 .get_pull_enable = mt_get_gpio_pull_enable_ext,
84 .set_smt = mt_set_gpio_smt_ext,
85 .get_smt = mt_get_gpio_smt_ext,
86 .set_ies = mt_set_gpio_ies_ext,
87 .get_ies = mt_get_gpio_ies_ext,
88 .set_pull_select = mt_set_gpio_pull_select_ext,
89 .get_pull_select = mt_get_gpio_pull_select_ext,
90 .set_inversion = mt_set_gpio_inversion_ext,
91 .get_inversion = mt_get_gpio_inversion_ext,
92 .set_out = mt_set_gpio_out_ext,
93 .get_out = mt_get_gpio_out_ext,
94 .get_in = mt_get_gpio_in_ext,
95 .set_mode = mt_set_gpio_mode_ext,
96 .get_mode = mt_get_gpio_mode_ext,
97 };
98
99 DEFINE_SPINLOCK(mt_gpio_lock);
100 struct mt_gpio_obj_t {
101 atomic_t ref;
102 dev_t devno;
103 struct class *cls;
104 struct device *dev;
105 struct cdev chrdev;
106 /* spinlock_t lock; */
107 struct miscdevice *misc;
108 struct mt_gpio_ops *base_ops;
109 struct mt_gpio_ops *ext_ops;
110 };
111 static struct mt_gpio_obj_t mt_gpio_obj = {
112 .ref = ATOMIC_INIT(0),
113 .cls = NULL,
114 .dev = NULL,
115 .base_ops = &mt_base_ops,
116 .ext_ops = &mt_ext_ops,
117 /* .lock = __SPIN_LOCK_UNLOCKED(die.lock), */
118 };
119
120 static struct mt_gpio_obj_t *mt_gpio = &mt_gpio_obj;
121
122 #define MT_GPIO_OPS_SET(pin, operation, arg) \
123 ({ unsigned long flags;\
124 u32 retval = 0;\
125 mt_gpio_pin_decrypt(&pin);\
126 spin_lock_irqsave(&mt_gpio_lock, flags);\
127 switch (MT_GPIO_PLACE(pin)) {\
128 case MT_BASE:\
129 if ((mt_gpio->base_ops == NULL) || (mt_gpio->base_ops->operation == NULL)) {\
130 GPIOERR("base access error, null point %d\n", (int)pin);\
131 retval = -ERACCESS;\
132 } else{\
133 retval = mt_gpio->base_ops->operation(pin, arg);\
134 if (retval < 0) \
135 GPIOERR("base operation fail %d\n", (int)retval);\
136 } \
137 break;\
138 case MT_EXT:\
139 if ((mt_gpio->ext_ops == NULL) || (mt_gpio->ext_ops->operation == NULL)) {\
140 GPIOERR("extention access error, null point %d\n", (int)pin);\
141 retval = -ERWRAPPER;\
142 } else{\
143 retval = mt_gpio->ext_ops->operation(pin, arg);\
144 if (retval < 0) \
145 GPIOERR("ext operation fail %d\n", (int)retval);\
146 } \
147 break;\
148 default:\
149 GPIOERR("Parameter error: %d\n", (int)pin);\
150 retval = -ERINVAL;\
151 break;\
152 } \
153 spin_unlock_irqrestore(&mt_gpio_lock, flags);\
154 retval; })
155
156 /* GPIOLOG("%s(%d)\n","operation",pin); */
157 #define MT_GPIO_OPS_GET(pin, operation) \
158 ({ u32 retval = 0;\
159 mt_gpio_pin_decrypt(&pin);\
160 switch (MT_GPIO_PLACE(pin)) {\
161 case MT_BASE:\
162 if ((mt_gpio->base_ops == NULL) || (mt_gpio->base_ops->operation == NULL)) {\
163 GPIOERR("base access error, null point %d\n", (int)pin);\
164 retval = -ERACCESS;\
165 } else{\
166 retval = mt_gpio->base_ops->operation(pin);\
167 if (retval < 0) \
168 GPIOERR("base operation fail %d\n", (int)retval);\
169 } \
170 break;\
171 case MT_EXT:\
172 if ((mt_gpio->ext_ops == NULL) || (mt_gpio->ext_ops->operation == NULL)) {\
173 GPIOERR("extention access error, null point %d\n", (int)pin);\
174 retval = -ERWRAPPER;\
175 } else{\
176 retval = mt_gpio->ext_ops->operation(pin);\
177 if (retval < 0) \
178 GPIOERR("ext operation fail %d\n", (int)retval);\
179 } \
180 break;\
181 default:\
182 GPIOERR("Parameter pin number error: %d\n", (int)pin);\
183 retval = -ERINVAL;\
184 break;\
185 };\
186 retval; })
187
188 int mt_set_gpio_dir(unsigned long pin, unsigned long dir)
189 {
190 /* int ret=0; */
191 if (dir >= GPIO_DIR_MAX) {
192 GPIOERR("Parameter dir error: %d\n", (int)dir);
193 return -ERINVAL;
194 }
195
196 return MT_GPIO_OPS_SET(pin, set_dir, dir);
197 }
198 EXPORT_SYMBOL(mt_set_gpio_dir);
199 /*---------------------------------------------------------------------------*/
200 int mt_get_gpio_dir(unsigned long pin)
201 {
202 return MT_GPIO_OPS_GET(pin, get_dir);
203 }
204 EXPORT_SYMBOL(mt_get_gpio_dir);
205 /*---------------------------------------------------------------------------*/
206 int mt_set_gpio_pull_enable(unsigned long pin, unsigned long enable)
207 {
208 if (enable >= GPIO_PULL_EN_MAX) {
209 GPIOERR("Parameter enable error: %d\n", (int)enable);
210 return -ERINVAL;
211 }
212
213 return MT_GPIO_OPS_SET(pin, set_pull_enable, enable);
214 }
215 EXPORT_SYMBOL(mt_set_gpio_pull_enable);
216 /*---------------------------------------------------------------------------*/
217 int mt_get_gpio_pull_enable(unsigned long pin)
218 {
219 return MT_GPIO_OPS_GET(pin, get_pull_enable);
220 }
221 EXPORT_SYMBOL(mt_get_gpio_pull_enable);
222 /*---------------------------------------------------------------------------*/
223 int mt_set_gpio_smt(unsigned long pin, unsigned long enable)
224 {
225 if (enable >= GPIO_SMT_MAX){
226 GPIOERR("Parameter enable error: %d\n",(int)enable);
227 return -ERINVAL;
228 }
229 return MT_GPIO_OPS_SET(pin,set_smt,enable);
230 }
231 EXPORT_SYMBOL(mt_set_gpio_smt);
232 /*---------------------------------------------------------------------------*/
233 int mt_get_gpio_smt(unsigned long pin)
234 {
235 return MT_GPIO_OPS_GET(pin,get_smt);
236 }
237 EXPORT_SYMBOL(mt_get_gpio_smt);
238 /*---------------------------------------------------------------------------*/
239 int mt_set_gpio_ies(unsigned long pin, unsigned long enable)
240 {
241 if (enable >= GPIO_IES_MAX) {
242 GPIOERR("Parameter enable error: %d\n", (int)enable);
243 return -ERINVAL;
244 }
245 return MT_GPIO_OPS_SET(pin, set_ies, enable);
246 }
247 EXPORT_SYMBOL(mt_set_gpio_ies);
248 /*---------------------------------------------------------------------------*/
249 int mt_get_gpio_ies(unsigned long pin)
250 {
251 return MT_GPIO_OPS_GET(pin, get_ies);
252 }
253 EXPORT_SYMBOL(mt_get_gpio_ies);
254 /*---------------------------------------------------------------------------*/
255 int mt_set_gpio_pull_select(unsigned long pin, unsigned long select)
256 {
257 if (select >= GPIO_PULL_MAX) {
258 GPIOERR("Parameter select error: %d\n", (int)select);
259 return -ERINVAL;
260 }
261 return MT_GPIO_OPS_SET(pin, set_pull_select, select);
262 }
263 EXPORT_SYMBOL(mt_get_gpio_pull_select);
264 /*---------------------------------------------------------------------------*/
265 int mt_get_gpio_pull_select(unsigned long pin)
266 {
267 return MT_GPIO_OPS_GET(pin, get_pull_select);
268 }
269 EXPORT_SYMBOL(mt_set_gpio_pull_select);
270 /*---------------------------------------------------------------------------*/
271 int mt_set_gpio_inversion(unsigned long pin, unsigned long enable)
272 {
273 if (enable >= GPIO_DATA_INV_MAX) {
274 GPIOERR("Parameter enable error: %d\n", (int)enable);
275 return -ERINVAL;
276 }
277 return MT_GPIO_OPS_SET(pin, set_inversion, enable);
278 }
279 EXPORT_SYMBOL(mt_set_gpio_inversion);
280 /*---------------------------------------------------------------------------*/
281 int mt_get_gpio_inversion(unsigned long pin)
282 {
283 return MT_GPIO_OPS_GET(pin, get_inversion);
284 }
285 EXPORT_SYMBOL(mt_get_gpio_inversion);
286 /*---------------------------------------------------------------------------*/
287 int mt_set_gpio_out(unsigned long pin, unsigned long output)
288 {
289 if (output >= GPIO_OUT_MAX) {
290 GPIOERR("Parameter output error: %d\n", (int)output);
291 return -ERINVAL;
292 }
293 return MT_GPIO_OPS_SET(pin, set_out, output);
294 }
295 EXPORT_SYMBOL(mt_set_gpio_out);
296 /*---------------------------------------------------------------------------*/
297 int mt_get_gpio_out(unsigned long pin)
298 {
299 return MT_GPIO_OPS_GET(pin, get_out);
300 }
301 EXPORT_SYMBOL(mt_get_gpio_out);
302 /*---------------------------------------------------------------------------*/
303 int mt_get_gpio_in(unsigned long pin)
304 {
305 return MT_GPIO_OPS_GET(pin, get_in);
306 }
307 EXPORT_SYMBOL(mt_get_gpio_in);
308 /*---------------------------------------------------------------------------*/
309 int mt_set_gpio_mode(unsigned long pin, unsigned long mode)
310 {
311 if (mode >= GPIO_MODE_MAX) {
312 GPIOERR("Parameter mode error: %d\n", (int)mode);
313 return -ERINVAL;
314 }
315 return MT_GPIO_OPS_SET(pin, set_mode, mode);
316 }
317 EXPORT_SYMBOL(mt_set_gpio_mode);
318 /*---------------------------------------------------------------------------*/
319 int mt_get_gpio_mode(unsigned long pin)
320 {
321 return MT_GPIO_OPS_GET(pin, get_mode);
322 }
323 EXPORT_SYMBOL(mt_get_gpio_mode);
324
325 /*****************************************************************************/
326 /* File operation */
327 /*****************************************************************************/
328 static int mt_gpio_open(struct inode *inode, struct file *file)
329 {
330 struct mt_gpio_obj_t *obj = mt_gpio;
331 GPIOFUC();
332
333 if (obj == NULL) {
334 GPIOERR("NULL pointer");
335 return -EFAULT;
336 }
337
338 atomic_inc(&obj->ref);
339 file->private_data = obj;
340 return nonseekable_open(inode, file);
341 }
342
343 /*---------------------------------------------------------------------------*/
344 static int mt_gpio_release(struct inode *inode, struct file *file)
345 {
346 struct mt_gpio_obj_t *obj = mt_gpio;
347
348 GPIOFUC();
349
350 if (obj == NULL) {
351 GPIOERR("NULL pointer");
352 return -EFAULT;
353 }
354
355 atomic_dec(&obj->ref);
356 return RSUCCESS;
357 }
358
359 /*---------------------------------------------------------------------------*/
360 static long mt_gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
361 {
362 struct mt_gpio_obj_t *obj = mt_gpio;
363 long res;
364 unsigned long pin;
365
366 GPIOFUC();
367
368 if (obj == NULL) {
369 GPIOERR("NULL pointer");
370 return -EFAULT;
371 }
372
373 switch (cmd) {
374 case GPIO_IOCQMODE:
375 {
376 pin = (unsigned long)arg;
377 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_get_gpio_mode(pin);
378 break;
379 }
380 case GPIO_IOCTMODE0:
381 {
382 pin = (unsigned long)arg;
383 res =
384 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_mode(pin, GPIO_MODE_00);
385 break;
386 }
387 case GPIO_IOCTMODE1:
388 {
389 pin = (unsigned long)arg;
390 res =
391 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_mode(pin, GPIO_MODE_01);
392 break;
393 }
394 case GPIO_IOCTMODE2:
395 {
396 pin = (unsigned long)arg;
397 res =
398 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_mode(pin, GPIO_MODE_02);
399 break;
400 }
401 case GPIO_IOCTMODE3:
402 {
403 pin = (unsigned long)arg;
404 res =
405 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_mode(pin, GPIO_MODE_03);
406 break;
407 }
408 case GPIO_IOCQDIR:
409 {
410 pin = (unsigned long)arg;
411 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_get_gpio_dir(pin);
412 break;
413 }
414 case GPIO_IOCSDIRIN:
415 {
416 pin = (unsigned long)arg;
417 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_dir(pin, GPIO_DIR_IN);
418 break;
419 }
420 case GPIO_IOCSDIROUT:
421 {
422 pin = (unsigned long)arg;
423 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_dir(pin, GPIO_DIR_OUT);
424 break;
425 }
426 case GPIO_IOCQPULLEN:
427 {
428 pin = (unsigned long)arg;
429 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_get_gpio_pull_enable(pin);
430 break;
431 }
432 case GPIO_IOCSPULLENABLE:
433 {
434 pin = (unsigned long)arg;
435 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_pull_enable(pin, TRUE);
436 break;
437 }
438 case GPIO_IOCSPULLDISABLE:
439 {
440 pin = (unsigned long)arg;
441 res =
442 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_pull_enable(pin, FALSE);
443 break;
444 }
445 case GPIO_IOCQPULL:
446 {
447 pin = (unsigned long)arg;
448 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_get_gpio_pull_select(pin);
449 break;
450 }
451 case GPIO_IOCSPULLDOWN:
452 {
453 pin = (unsigned long)arg;
454 res =
455 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_pull_select(pin,
456 GPIO_PULL_DOWN);
457 break;
458 }
459 case GPIO_IOCSPULLUP:
460 {
461 pin = (unsigned long)arg;
462 res =
463 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_pull_select(pin,
464 GPIO_PULL_UP);
465 break;
466 }
467 case GPIO_IOCQINV:
468 {
469 pin = (unsigned long)arg;
470 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_get_gpio_inversion(pin);
471 break;
472 }
473 case GPIO_IOCSINVENABLE:
474 {
475 pin = (unsigned long)arg;
476 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_inversion(pin, TRUE);
477 break;
478 }
479 case GPIO_IOCSINVDISABLE:
480 {
481 pin = (unsigned long)arg;
482 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_inversion(pin, FALSE);
483 break;
484 }
485 case GPIO_IOCQDATAIN:
486 {
487 pin = (unsigned long)arg;
488 res = GIO_INVALID_OBJ(obj) ? (-EFAULT) : mt_get_gpio_in(pin);
489 break;
490 }
491 case GPIO_IOCQDATAOUT:
492 {
493 pin = (unsigned long)arg;
494 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_get_gpio_out(pin);
495 break;
496 }
497 case GPIO_IOCSDATALOW:
498 {
499 pin = (unsigned long)arg;
500 res =
501 GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_out(pin, GPIO_OUT_ZERO);
502 break;
503 }
504 case GPIO_IOCSDATAHIGH:
505 {
506 pin = (unsigned long)arg;
507 res = GIO_INVALID_OBJ(obj) ? (-EACCES) : mt_set_gpio_out(pin, GPIO_OUT_ONE);
508 break;
509 }
510 default:
511 {
512 res = -EPERM;
513 break;
514 }
515 }
516
517 if (res == -EACCES)
518 GPIOERR(" cmd = 0x%8X, invalid pointer\n", cmd);
519 else if (res < 0)
520 GPIOERR(" cmd = 0x%8X, err = %ld\n", cmd, res);
521 return res;
522 }
523
524 /*---------------------------------------------------------------------------*/
525 static struct file_operations mt_gpio_fops = {
526 .owner = THIS_MODULE,
527 .unlocked_ioctl = mt_gpio_ioctl,
528 #ifdef CONFIG_COMPAT
529 .compat_ioctl = mt_gpio_ioctl,
530 #endif
531 .open = mt_gpio_open,
532 .release = mt_gpio_release,
533 };
534
535 /*----------------------------------------------------------------------------*/
536 static struct miscdevice mt_gpio_device = {
537 .minor = MISC_DYNAMIC_MINOR,
538 .name = "mtgpio",
539 .fops = &mt_gpio_fops,
540 };
541
542 /*---------------------------------------------------------------------------*/
543 static int mt_gpio_probe(struct platform_device *dev)
544 {
545 int err;
546 struct miscdevice *misc = &mt_gpio_device;
547
548 #ifdef CONFIG_OF
549 if (dev->dev.of_node) {
550 /* Setup IO addresses */
551 get_gpio_vbase(dev->dev.of_node);
552 }
553
554 get_io_cfg_vbase();
555 #endif
556 #ifdef CONFIG_MD32_SUPPORT
557 md32_gpio_handle_init();
558 #endif
559
560 /* printk(KERN_ALERT"[GPIO]%5d,<%s> gpio devices probe\n", __LINE__, __func__); */
561 GPIOLOG("Registering GPIO device\n");
562
563 if (!mt_gpio)
564 GPIO_RETERR(-EACCES, "");
565 mt_gpio->misc = misc;
566
567 if ((err = misc_register(misc)))
568 GPIOERR("register gpio\n");
569
570 if ((err = mt_gpio_create_attr(misc->this_device)))
571 GPIOERR("create attribute\n");
572
573 dev_set_drvdata(misc->this_device, mt_gpio);
574
575 return err;
576 }
577
578 /*---------------------------------------------------------------------------*/
579 static int mt_gpio_remove(struct platform_device *dev)
580 {
581 struct mt_gpio_obj_t *obj = platform_get_drvdata(dev);
582 int err;
583
584 if ((err = mt_gpio_delete_attr(obj->misc->this_device)))
585 GPIOERR("delete attr\n");
586
587 if ((err = misc_deregister(obj->misc)))
588 GPIOERR("deregister gpio\n");
589
590 return err;
591 }
592
593 /*---------------------------------------------------------------------------*/
594 #ifdef CONFIG_PM
595 /*---------------------------------------------------------------------------*/
596 static int mtk_gpio_suspend(struct platform_device *pdev, pm_message_t state)
597 {
598 int ret = 0;
599 mt_gpio_suspend();
600 return ret;
601 }
602
603 /*---------------------------------------------------------------------------*/
604 static int mtk_gpio_resume(struct platform_device *pdev)
605 {
606 int ret = 0;
607 mt_gpio_resume();
608 return ret;
609 }
610
611 /*---------------------------------------------------------------------------*/
612 #endif /*CONFIG_PM */
613 /*---------------------------------------------------------------------------*/
614 /*---------------------------------------------------------------------------*/
615 #ifdef CONFIG_OF
616 static const struct of_device_id apgpio_of_ids[] = {
617 { .compatible = "mediatek,GPIO", },
618 {}
619 };
620 #endif
621
622 static struct platform_driver gpio_driver = {
623 .probe = mt_gpio_probe,
624 .remove = mt_gpio_remove,
625 #ifdef CONFIG_PM
626 .suspend = mtk_gpio_suspend,
627 .resume = mtk_gpio_resume,
628 #endif
629 .driver = {
630 .name = GPIO_DEVICE,
631 #ifdef CONFIG_OF
632 .of_match_table = apgpio_of_ids,
633 #endif
634 },
635 };
636
637 #ifdef CONFIG_OF
638 struct device_node *get_gpio_np(void)
639 {
640 gpio_vbase.gpio_regs = NULL;
641 struct device_node *np_gpio;
642 np_gpio = of_find_compatible_node(NULL, NULL, apgpio_of_ids[0].compatible);
643 if(np_gpio == NULL) {
644 GPIOERR("GPIO device node is NULL\n");
645 return NULL;
646 }
647 return np_gpio;
648 }
649 #endif
650
651 /*---------------------------------------------------------------------------*/
652
653 /*---------------------------------------------------------------------------*/
654 static int __init mt_gpio_init(void)
655 {
656 int ret = 0;
657 GPIOLOG("version: %s\n", VERSION);
658
659 ret = platform_driver_register(&gpio_driver);
660 return ret;
661 }
662
663 /*---------------------------------------------------------------------------*/
664 static void __exit mt_gpio_exit(void)
665 {
666 platform_driver_unregister(&gpio_driver);
667 return;
668 }
669
670 /* void gpio_dump_regs(void) */
671 /* { */
672 /* return; */
673 /* } */
674 /*---------------------------------------------------------------------------*/
675 module_init(mt_gpio_init);
676 module_exit(mt_gpio_exit);
677 MODULE_AUTHOR("Ranran <ranran.lu@mediatek.com>");
678 MODULE_DESCRIPTION("MT General Purpose Driver (GPIO) $Revision$");
679 MODULE_LICENSE("GPL");
680 /*---------------------------------------------------------------------------*/