1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * CLPS711X GPIO driver |
4 | * |
5 | * Copyright (C) 2012,2013 Alexander Shiyan <shc_work@mail.ru> |
6 | */ |
7 | |
8 | #include <linux/err.h> |
9 | #include <linux/module.h> |
10 | #include <linux/gpio/driver.h> |
11 | #include <linux/platform_device.h> |
12 | |
13 | static int clps711x_gpio_probe(struct platform_device *pdev) |
14 | { |
15 | struct device_node *np = pdev->dev.of_node; |
16 | void __iomem *dat, *dir; |
17 | struct gpio_chip *gc; |
18 | int err, id; |
19 | |
20 | if (!np) |
21 | return -ENODEV; |
22 | |
23 | id = of_alias_get_id(np, stem: "gpio" ); |
24 | if ((id < 0) || (id > 4)) |
25 | return -ENODEV; |
26 | |
27 | gc = devm_kzalloc(dev: &pdev->dev, size: sizeof(*gc), GFP_KERNEL); |
28 | if (!gc) |
29 | return -ENOMEM; |
30 | |
31 | dat = devm_platform_ioremap_resource(pdev, index: 0); |
32 | if (IS_ERR(ptr: dat)) |
33 | return PTR_ERR(ptr: dat); |
34 | |
35 | dir = devm_platform_ioremap_resource(pdev, index: 1); |
36 | if (IS_ERR(ptr: dir)) |
37 | return PTR_ERR(ptr: dir); |
38 | |
39 | switch (id) { |
40 | case 3: |
41 | /* PORTD is inverted logic for direction register */ |
42 | err = bgpio_init(gc, dev: &pdev->dev, sz: 1, dat, NULL, NULL, |
43 | NULL, dirin: dir, flags: 0); |
44 | break; |
45 | default: |
46 | err = bgpio_init(gc, dev: &pdev->dev, sz: 1, dat, NULL, NULL, |
47 | dirout: dir, NULL, flags: 0); |
48 | break; |
49 | } |
50 | |
51 | if (err) |
52 | return err; |
53 | |
54 | switch (id) { |
55 | case 4: |
56 | /* PORTE is 3 lines only */ |
57 | gc->ngpio = 3; |
58 | break; |
59 | default: |
60 | break; |
61 | } |
62 | |
63 | gc->base = -1; |
64 | gc->owner = THIS_MODULE; |
65 | platform_set_drvdata(pdev, data: gc); |
66 | |
67 | return devm_gpiochip_add_data(&pdev->dev, gc, NULL); |
68 | } |
69 | |
70 | static const struct of_device_id clps711x_gpio_ids[] = { |
71 | { .compatible = "cirrus,ep7209-gpio" }, |
72 | { } |
73 | }; |
74 | MODULE_DEVICE_TABLE(of, clps711x_gpio_ids); |
75 | |
76 | static struct platform_driver clps711x_gpio_driver = { |
77 | .driver = { |
78 | .name = "clps711x-gpio" , |
79 | .of_match_table = clps711x_gpio_ids, |
80 | }, |
81 | .probe = clps711x_gpio_probe, |
82 | }; |
83 | module_platform_driver(clps711x_gpio_driver); |
84 | |
85 | MODULE_LICENSE("GPL" ); |
86 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>" ); |
87 | MODULE_DESCRIPTION("CLPS711X GPIO driver" ); |
88 | MODULE_ALIAS("platform:clps711x-gpio" ); |
89 | |