• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Toumaz Xenif TZ1090 PDC GPIO handling.
3  *
4  * Copyright (C) 2012-2013 Imagination Technologies Ltd.
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 version 2 as
8  * published by the Free Software Foundation.
9  */
10 
11 #include <linux/bitops.h>
12 #include <linux/gpio.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/of_irq.h>
16 #include <linux/pinctrl/consumer.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
19 #include <linux/syscore_ops.h>
20 #include <asm/global_lock.h>
21 
22 /* Register offsets from SOC_GPIO_CONTROL0 */
23 #define REG_SOC_GPIO_CONTROL0	0x00
24 #define REG_SOC_GPIO_CONTROL1	0x04
25 #define REG_SOC_GPIO_CONTROL2	0x08
26 #define REG_SOC_GPIO_CONTROL3	0x0c
27 #define REG_SOC_GPIO_STATUS	0x80
28 
29 /* PDC GPIOs go after normal GPIOs */
30 #define GPIO_PDC_BASE		90
31 #define GPIO_PDC_NGPIO		7
32 
33 /* Out of PDC gpios, only syswakes have irqs */
34 #define GPIO_PDC_IRQ_FIRST	2
35 #define GPIO_PDC_NIRQ		3
36 
37 /**
38  * struct tz1090_pdc_gpio - GPIO bank private data
39  * @chip:	Generic GPIO chip for GPIO bank
40  * @reg:	Base of registers, offset for this GPIO bank
41  * @irq:	IRQ numbers for Syswake GPIOs
42  *
43  * This is the main private data for the PDC GPIO driver. It encapsulates a
44  * gpio_chip, and the callbacks for the gpio_chip can access the private data
45  * with the to_pdc() macro below.
46  */
47 struct tz1090_pdc_gpio {
48 	struct gpio_chip chip;
49 	void __iomem *reg;
50 	int irq[GPIO_PDC_NIRQ];
51 };
52 
53 /* Register accesses into the PDC MMIO area */
54 
pdc_write(struct tz1090_pdc_gpio * priv,unsigned int reg_offs,unsigned int data)55 static inline void pdc_write(struct tz1090_pdc_gpio *priv, unsigned int reg_offs,
56 		      unsigned int data)
57 {
58 	writel(data, priv->reg + reg_offs);
59 }
60 
pdc_read(struct tz1090_pdc_gpio * priv,unsigned int reg_offs)61 static inline unsigned int pdc_read(struct tz1090_pdc_gpio *priv,
62 			     unsigned int reg_offs)
63 {
64 	return readl(priv->reg + reg_offs);
65 }
66 
67 /* Generic GPIO interface */
68 
tz1090_pdc_gpio_direction_input(struct gpio_chip * chip,unsigned int offset)69 static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip,
70 					   unsigned int offset)
71 {
72 	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
73 	u32 value;
74 	int lstat;
75 
76 	__global_lock2(lstat);
77 	value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
78 	value |= BIT(offset);
79 	pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
80 	__global_unlock2(lstat);
81 
82 	return 0;
83 }
84 
tz1090_pdc_gpio_direction_output(struct gpio_chip * chip,unsigned int offset,int output_value)85 static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip,
86 					    unsigned int offset,
87 					    int output_value)
88 {
89 	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
90 	u32 value;
91 	int lstat;
92 
93 	__global_lock2(lstat);
94 	/* EXT_POWER doesn't seem to have an output value bit */
95 	if (offset < 6) {
96 		value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
97 		if (output_value)
98 			value |= BIT(offset);
99 		else
100 			value &= ~BIT(offset);
101 		pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
102 	}
103 
104 	value = pdc_read(priv, REG_SOC_GPIO_CONTROL1);
105 	value &= ~BIT(offset);
106 	pdc_write(priv, REG_SOC_GPIO_CONTROL1, value);
107 	__global_unlock2(lstat);
108 
109 	return 0;
110 }
111 
tz1090_pdc_gpio_get(struct gpio_chip * chip,unsigned int offset)112 static int tz1090_pdc_gpio_get(struct gpio_chip *chip, unsigned int offset)
113 {
114 	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
115 	return !!(pdc_read(priv, REG_SOC_GPIO_STATUS) & BIT(offset));
116 }
117 
tz1090_pdc_gpio_set(struct gpio_chip * chip,unsigned int offset,int output_value)118 static void tz1090_pdc_gpio_set(struct gpio_chip *chip, unsigned int offset,
119 				int output_value)
120 {
121 	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
122 	u32 value;
123 	int lstat;
124 
125 	/* EXT_POWER doesn't seem to have an output value bit */
126 	if (offset >= 6)
127 		return;
128 
129 	__global_lock2(lstat);
130 	value = pdc_read(priv, REG_SOC_GPIO_CONTROL0);
131 	if (output_value)
132 		value |= BIT(offset);
133 	else
134 		value &= ~BIT(offset);
135 	pdc_write(priv, REG_SOC_GPIO_CONTROL0, value);
136 	__global_unlock2(lstat);
137 }
138 
tz1090_pdc_gpio_to_irq(struct gpio_chip * chip,unsigned int offset)139 static int tz1090_pdc_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
140 {
141 	struct tz1090_pdc_gpio *priv = gpiochip_get_data(chip);
142 	unsigned int syswake = offset - GPIO_PDC_IRQ_FIRST;
143 	int irq;
144 
145 	/* only syswakes have irqs */
146 	if (syswake >= GPIO_PDC_NIRQ)
147 		return -EINVAL;
148 
149 	irq = priv->irq[syswake];
150 	if (!irq)
151 		return -EINVAL;
152 
153 	return irq;
154 }
155 
tz1090_pdc_gpio_probe(struct platform_device * pdev)156 static int tz1090_pdc_gpio_probe(struct platform_device *pdev)
157 {
158 	struct device_node *np = pdev->dev.of_node;
159 	struct resource *res_regs;
160 	struct tz1090_pdc_gpio *priv;
161 	unsigned int i;
162 
163 	if (!np) {
164 		dev_err(&pdev->dev, "must be instantiated via devicetree\n");
165 		return -ENOENT;
166 	}
167 
168 	res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
169 	if (!res_regs) {
170 		dev_err(&pdev->dev, "cannot find registers resource\n");
171 		return -ENOENT;
172 	}
173 
174 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
175 	if (!priv) {
176 		dev_err(&pdev->dev, "unable to allocate driver data\n");
177 		return -ENOMEM;
178 	}
179 
180 	/* Ioremap the registers */
181 	priv->reg = devm_ioremap(&pdev->dev, res_regs->start,
182 				 resource_size(res_regs));
183 	if (!priv->reg) {
184 		dev_err(&pdev->dev, "unable to ioremap registers\n");
185 		return -ENOMEM;
186 	}
187 
188 	/* Set up GPIO chip */
189 	priv->chip.label		= "tz1090-pdc-gpio";
190 	priv->chip.parent		= &pdev->dev;
191 	priv->chip.direction_input	= tz1090_pdc_gpio_direction_input;
192 	priv->chip.direction_output	= tz1090_pdc_gpio_direction_output;
193 	priv->chip.get			= tz1090_pdc_gpio_get;
194 	priv->chip.set			= tz1090_pdc_gpio_set;
195 	priv->chip.free			= gpiochip_generic_free;
196 	priv->chip.request		= gpiochip_generic_request;
197 	priv->chip.to_irq		= tz1090_pdc_gpio_to_irq;
198 	priv->chip.of_node		= np;
199 
200 	/* GPIO numbering */
201 	priv->chip.base			= GPIO_PDC_BASE;
202 	priv->chip.ngpio		= GPIO_PDC_NGPIO;
203 
204 	/* Map the syswake irqs */
205 	for (i = 0; i < GPIO_PDC_NIRQ; ++i)
206 		priv->irq[i] = irq_of_parse_and_map(np, i);
207 
208 	/* Add the GPIO bank */
209 	gpiochip_add_data(&priv->chip, priv);
210 
211 	return 0;
212 }
213 
214 static struct of_device_id tz1090_pdc_gpio_of_match[] = {
215 	{ .compatible = "img,tz1090-pdc-gpio" },
216 	{ },
217 };
218 
219 static struct platform_driver tz1090_pdc_gpio_driver = {
220 	.driver = {
221 		.name		= "tz1090-pdc-gpio",
222 		.of_match_table	= tz1090_pdc_gpio_of_match,
223 	},
224 	.probe		= tz1090_pdc_gpio_probe,
225 };
226 
tz1090_pdc_gpio_init(void)227 static int __init tz1090_pdc_gpio_init(void)
228 {
229 	return platform_driver_register(&tz1090_pdc_gpio_driver);
230 }
231 subsys_initcall(tz1090_pdc_gpio_init);
232