xref: /linux/drivers/gpio/gpio-ath79.c (revision a4cdb556cae05cd3e7b602b3a44c01420c4e2258)
1 /*
2  *  Atheros AR71XX/AR724X/AR913X GPIO API support
3  *
4  *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7  *
8  *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
9  *
10  *  This program is free software; you can redistribute it and/or modify it
11  *  under the terms of the GNU General Public License version 2 as published
12  *  by the Free Software Foundation.
13  */
14 
15 #include <linux/gpio/driver.h>
16 #include <linux/platform_data/gpio-ath79.h>
17 #include <linux/of_device.h>
18 
19 #include <asm/mach-ath79/ar71xx_regs.h>
20 
21 struct ath79_gpio_ctrl {
22 	struct gpio_chip chip;
23 	void __iomem *base;
24 	spinlock_t lock;
25 };
26 
27 #define to_ath79_gpio_ctrl(c) container_of(c, struct ath79_gpio_ctrl, chip)
28 
29 static void ath79_gpio_set_value(struct gpio_chip *chip,
30 				unsigned gpio, int value)
31 {
32 	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
33 
34 	if (value)
35 		__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_SET);
36 	else
37 		__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_CLEAR);
38 }
39 
40 static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
41 {
42 	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
43 
44 	return (__raw_readl(ctrl->base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
45 }
46 
47 static int ath79_gpio_direction_input(struct gpio_chip *chip,
48 				       unsigned offset)
49 {
50 	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
51 	unsigned long flags;
52 
53 	spin_lock_irqsave(&ctrl->lock, flags);
54 
55 	__raw_writel(
56 		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
57 		ctrl->base + AR71XX_GPIO_REG_OE);
58 
59 	spin_unlock_irqrestore(&ctrl->lock, flags);
60 
61 	return 0;
62 }
63 
64 static int ath79_gpio_direction_output(struct gpio_chip *chip,
65 					unsigned offset, int value)
66 {
67 	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
68 	unsigned long flags;
69 
70 	spin_lock_irqsave(&ctrl->lock, flags);
71 
72 	if (value)
73 		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
74 	else
75 		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
76 
77 	__raw_writel(
78 		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
79 		ctrl->base + AR71XX_GPIO_REG_OE);
80 
81 	spin_unlock_irqrestore(&ctrl->lock, flags);
82 
83 	return 0;
84 }
85 
86 static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
87 {
88 	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
89 	unsigned long flags;
90 
91 	spin_lock_irqsave(&ctrl->lock, flags);
92 
93 	__raw_writel(
94 		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
95 		ctrl->base + AR71XX_GPIO_REG_OE);
96 
97 	spin_unlock_irqrestore(&ctrl->lock, flags);
98 
99 	return 0;
100 }
101 
102 static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
103 					int value)
104 {
105 	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
106 	unsigned long flags;
107 
108 	spin_lock_irqsave(&ctrl->lock, flags);
109 
110 	if (value)
111 		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
112 	else
113 		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);
114 
115 	__raw_writel(
116 		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
117 		ctrl->base + AR71XX_GPIO_REG_OE);
118 
119 	spin_unlock_irqrestore(&ctrl->lock, flags);
120 
121 	return 0;
122 }
123 
124 static const struct gpio_chip ath79_gpio_chip = {
125 	.label			= "ath79",
126 	.get			= ath79_gpio_get_value,
127 	.set			= ath79_gpio_set_value,
128 	.direction_input	= ath79_gpio_direction_input,
129 	.direction_output	= ath79_gpio_direction_output,
130 	.base			= 0,
131 };
132 
133 static const struct of_device_id ath79_gpio_of_match[] = {
134 	{ .compatible = "qca,ar7100-gpio" },
135 	{ .compatible = "qca,ar9340-gpio" },
136 	{},
137 };
138 
139 static int ath79_gpio_probe(struct platform_device *pdev)
140 {
141 	struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data;
142 	struct device_node *np = pdev->dev.of_node;
143 	struct ath79_gpio_ctrl *ctrl;
144 	struct resource *res;
145 	u32 ath79_gpio_count;
146 	bool oe_inverted;
147 	int err;
148 
149 	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
150 	if (!ctrl)
151 		return -ENOMEM;
152 
153 	if (np) {
154 		err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
155 		if (err) {
156 			dev_err(&pdev->dev, "ngpios property is not valid\n");
157 			return err;
158 		}
159 		if (ath79_gpio_count >= 32) {
160 			dev_err(&pdev->dev, "ngpios must be less than 32\n");
161 			return -EINVAL;
162 		}
163 		oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
164 	} else if (pdata) {
165 		ath79_gpio_count = pdata->ngpios;
166 		oe_inverted = pdata->oe_inverted;
167 	} else {
168 		dev_err(&pdev->dev, "No DT node or platform data found\n");
169 		return -EINVAL;
170 	}
171 
172 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
173 	ctrl->base = devm_ioremap_nocache(
174 		&pdev->dev, res->start, resource_size(res));
175 	if (!ctrl->base)
176 		return -ENOMEM;
177 
178 	spin_lock_init(&ctrl->lock);
179 	memcpy(&ctrl->chip, &ath79_gpio_chip, sizeof(ctrl->chip));
180 	ctrl->chip.dev = &pdev->dev;
181 	ctrl->chip.ngpio = ath79_gpio_count;
182 	if (oe_inverted) {
183 		ctrl->chip.direction_input = ar934x_gpio_direction_input;
184 		ctrl->chip.direction_output = ar934x_gpio_direction_output;
185 	}
186 
187 	err = gpiochip_add(&ctrl->chip);
188 	if (err) {
189 		dev_err(&pdev->dev,
190 			"cannot add AR71xx GPIO chip, error=%d", err);
191 		return err;
192 	}
193 
194 	return 0;
195 }
196 
197 static struct platform_driver ath79_gpio_driver = {
198 	.driver = {
199 		.name = "ath79-gpio",
200 		.of_match_table	= ath79_gpio_of_match,
201 	},
202 	.probe = ath79_gpio_probe,
203 };
204 
205 module_platform_driver(ath79_gpio_driver);
206