]>
Commit | Line | Data |
---|---|---|
a3b8d4a5 AS |
1 | /* |
2 | * CLPS711X GPIO driver | |
3 | * | |
55fe14ab | 4 | * Copyright (C) 2012,2013 Alexander Shiyan <[email protected]> |
a3b8d4a5 AS |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | */ | |
11 | ||
55fe14ab | 12 | #include <linux/err.h> |
a3b8d4a5 | 13 | #include <linux/module.h> |
0f4630f3 | 14 | #include <linux/gpio/driver.h> |
a3b8d4a5 AS |
15 | #include <linux/platform_device.h> |
16 | ||
55fe14ab | 17 | static int clps711x_gpio_probe(struct platform_device *pdev) |
a3b8d4a5 | 18 | { |
a180132f | 19 | struct device_node *np = pdev->dev.of_node; |
55fe14ab | 20 | void __iomem *dat, *dir; |
0f4630f3 | 21 | struct gpio_chip *gc; |
55fe14ab | 22 | struct resource *res; |
a180132f | 23 | int err, id = np ? of_alias_get_id(np, "gpio") : pdev->id; |
a3b8d4a5 | 24 | |
55fe14ab AS |
25 | if ((id < 0) || (id > 4)) |
26 | return -ENODEV; | |
a3b8d4a5 | 27 | |
0f4630f3 LW |
28 | gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL); |
29 | if (!gc) | |
55fe14ab | 30 | return -ENOMEM; |
a3b8d4a5 | 31 | |
55fe14ab AS |
32 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
33 | dat = devm_ioremap_resource(&pdev->dev, res); | |
34 | if (IS_ERR(dat)) | |
35 | return PTR_ERR(dat); | |
36 | ||
37 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | |
38 | dir = devm_ioremap_resource(&pdev->dev, res); | |
39 | if (IS_ERR(dir)) | |
40 | return PTR_ERR(dir); | |
41 | ||
42 | switch (id) { | |
43 | case 3: | |
44 | /* PORTD is inverted logic for direction register */ | |
0f4630f3 | 45 | err = bgpio_init(gc, &pdev->dev, 1, dat, NULL, NULL, |
55fe14ab AS |
46 | NULL, dir, 0); |
47 | break; | |
48 | default: | |
0f4630f3 | 49 | err = bgpio_init(gc, &pdev->dev, 1, dat, NULL, NULL, |
55fe14ab AS |
50 | dir, NULL, 0); |
51 | break; | |
52 | } | |
a3b8d4a5 | 53 | |
55fe14ab AS |
54 | if (err) |
55 | return err; | |
a3b8d4a5 | 56 | |
55fe14ab AS |
57 | switch (id) { |
58 | case 4: | |
59 | /* PORTE is 3 lines only */ | |
0f4630f3 | 60 | gc->ngpio = 3; |
55fe14ab AS |
61 | break; |
62 | default: | |
63 | break; | |
64 | } | |
d6a2fa04 | 65 | |
0f4630f3 LW |
66 | gc->base = id * 8; |
67 | gc->owner = THIS_MODULE; | |
68 | platform_set_drvdata(pdev, gc); | |
d6a2fa04 | 69 | |
da9d6700 | 70 | return devm_gpiochip_add_data(&pdev->dev, gc, NULL); |
d6a2fa04 AS |
71 | } |
72 | ||
e8b49e07 | 73 | static const struct of_device_id __maybe_unused clps711x_gpio_ids[] = { |
a180132f AS |
74 | { .compatible = "cirrus,clps711x-gpio" }, |
75 | { } | |
76 | }; | |
77 | MODULE_DEVICE_TABLE(of, clps711x_gpio_ids); | |
78 | ||
55fe14ab AS |
79 | static struct platform_driver clps711x_gpio_driver = { |
80 | .driver = { | |
a180132f | 81 | .name = "clps711x-gpio", |
e8b49e07 | 82 | .of_match_table = of_match_ptr(clps711x_gpio_ids), |
55fe14ab AS |
83 | }, |
84 | .probe = clps711x_gpio_probe, | |
a3b8d4a5 | 85 | }; |
55fe14ab | 86 | module_platform_driver(clps711x_gpio_driver); |
a3b8d4a5 | 87 | |
55fe14ab | 88 | MODULE_LICENSE("GPL"); |
a3b8d4a5 AS |
89 | MODULE_AUTHOR("Alexander Shiyan <[email protected]>"); |
90 | MODULE_DESCRIPTION("CLPS711X GPIO driver"); | |
21708c99 | 91 | MODULE_ALIAS("platform:clps711x-gpio"); |