Merge branch 'master' of git://git.denx.de/u-boot-socfpga
[oweals/u-boot.git] / drivers / gpio / pca953x_gpio.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Take linux kernel driver drivers/gpio/gpio-pca953x.c for reference.
4  *
5  * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
6  *
7  */
8
9 /*
10  * Note:
11  * The driver's compatible table is borrowed from Linux Kernel,
12  * but now max supported gpio pins is 24 and only PCA953X_TYPE
13  * is supported. PCA957X_TYPE is not supported now.
14  * Also the Polarity Inversion feature is not supported now.
15  *
16  * TODO:
17  * 1. Support PCA957X_TYPE
18  * 2. Support Polarity Inversion
19  */
20
21 #include <common.h>
22 #include <errno.h>
23 #include <dm.h>
24 #include <fdtdec.h>
25 #include <i2c.h>
26 #include <malloc.h>
27 #include <asm/gpio.h>
28 #include <asm/io.h>
29 #include <dt-bindings/gpio/gpio.h>
30
31 #define PCA953X_INPUT           0
32 #define PCA953X_OUTPUT          1
33 #define PCA953X_INVERT          2
34 #define PCA953X_DIRECTION       3
35
36 #define PCA_GPIO_MASK           0x00FF
37 #define PCA_INT                 0x0100
38 #define PCA953X_TYPE            0x1000
39 #define PCA957X_TYPE            0x2000
40 #define PCA_TYPE_MASK           0xF000
41 #define PCA_CHIP_TYPE(x)        ((x) & PCA_TYPE_MASK)
42
43 enum {
44         PCA953X_DIRECTION_IN,
45         PCA953X_DIRECTION_OUT,
46 };
47
48 #define MAX_BANK 5
49 #define BANK_SZ 8
50
51 /*
52  * struct pca953x_info - Data for pca953x
53  *
54  * @dev: udevice structure for the device
55  * @addr: i2c slave address
56  * @invert: Polarity inversion or not
57  * @gpio_count: the number of gpio pins that the device supports
58  * @chip_type: indicate the chip type,PCA953X or PCA957X
59  * @bank_count: the number of banks that the device supports
60  * @reg_output: array to hold the value of output registers
61  * @reg_direction: array to hold the value of direction registers
62  */
63 struct pca953x_info {
64         struct udevice *dev;
65         int addr;
66         int invert;
67         int gpio_count;
68         int chip_type;
69         int bank_count;
70         u8 reg_output[MAX_BANK];
71         u8 reg_direction[MAX_BANK];
72 };
73
74 static int pca953x_write_single(struct udevice *dev, int reg, u8 val,
75                                 int offset)
76 {
77         struct pca953x_info *info = dev_get_platdata(dev);
78         int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
79         int off = offset / BANK_SZ;
80         int ret = 0;
81
82         ret = dm_i2c_write(dev, (reg << bank_shift) + off, &val, 1);
83         if (ret) {
84                 dev_err(dev, "%s error\n", __func__);
85                 return ret;
86         }
87
88         return 0;
89 }
90
91 static int pca953x_read_single(struct udevice *dev, int reg, u8 *val,
92                                int offset)
93 {
94         struct pca953x_info *info = dev_get_platdata(dev);
95         int bank_shift = fls((info->gpio_count - 1) / BANK_SZ);
96         int off = offset / BANK_SZ;
97         int ret;
98         u8 byte;
99
100         ret = dm_i2c_read(dev, (reg << bank_shift) + off, &byte, 1);
101         if (ret) {
102                 dev_err(dev, "%s error\n", __func__);
103                 return ret;
104         }
105
106         *val = byte;
107
108         return 0;
109 }
110
111 static int pca953x_read_regs(struct udevice *dev, int reg, u8 *val)
112 {
113         struct pca953x_info *info = dev_get_platdata(dev);
114         int ret = 0;
115
116         if (info->gpio_count <= 8) {
117                 ret = dm_i2c_read(dev, reg, val, 1);
118         } else if (info->gpio_count <= 16) {
119                 ret = dm_i2c_read(dev, reg << 1, val, info->bank_count);
120         } else if (info->gpio_count <= 24) {
121                 /* Auto increment */
122                 ret = dm_i2c_read(dev, (reg << 2) | 0x80, val,
123                                   info->bank_count);
124         } else if (info->gpio_count == 40) {
125                 /* Auto increment */
126                 ret = dm_i2c_read(dev, (reg << 3) | 0x80, val,
127                                   info->bank_count);
128         } else {
129                 dev_err(dev, "Unsupported now\n");
130                 return -EINVAL;
131         }
132
133         return ret;
134 }
135
136 static int pca953x_write_regs(struct udevice *dev, int reg, u8 *val)
137 {
138         struct pca953x_info *info = dev_get_platdata(dev);
139         int ret = 0;
140
141         if (info->gpio_count <= 8) {
142                 ret = dm_i2c_write(dev, reg, val, 1);
143         } else if (info->gpio_count <= 16) {
144                 ret = dm_i2c_write(dev, reg << 1, val, info->bank_count);
145         } else if (info->gpio_count <= 24) {
146                 /* Auto increment */
147                 ret = dm_i2c_write(dev, (reg << 2) | 0x80, val,
148                                    info->bank_count);
149         } else if (info->gpio_count == 40) {
150                 /* Auto increment */
151                 ret = dm_i2c_write(dev, (reg << 3) | 0x80, val, info->bank_count);
152         } else {
153                 return -EINVAL;
154         }
155
156         return ret;
157 }
158
159 static int pca953x_is_output(struct udevice *dev, int offset)
160 {
161         struct pca953x_info *info = dev_get_platdata(dev);
162
163         int bank = offset / BANK_SZ;
164         int off = offset % BANK_SZ;
165
166         /*0: output; 1: input */
167         return !(info->reg_direction[bank] & (1 << off));
168 }
169
170 static int pca953x_get_value(struct udevice *dev, uint offset)
171 {
172         int ret;
173         u8 val = 0;
174
175         int off = offset % BANK_SZ;
176
177         ret = pca953x_read_single(dev, PCA953X_INPUT, &val, offset);
178         if (ret)
179                 return ret;
180
181         return (val >> off) & 0x1;
182 }
183
184 static int pca953x_set_value(struct udevice *dev, uint offset, int value)
185 {
186         struct pca953x_info *info = dev_get_platdata(dev);
187         int bank = offset / BANK_SZ;
188         int off = offset % BANK_SZ;
189         u8 val;
190         int ret;
191
192         if (value)
193                 val = info->reg_output[bank] | (1 << off);
194         else
195                 val = info->reg_output[bank] & ~(1 << off);
196
197         ret = pca953x_write_single(dev, PCA953X_OUTPUT, val, offset);
198         if (ret)
199                 return ret;
200
201         info->reg_output[bank] = val;
202
203         return 0;
204 }
205
206 static int pca953x_set_direction(struct udevice *dev, uint offset, int dir)
207 {
208         struct pca953x_info *info = dev_get_platdata(dev);
209         int bank = offset / BANK_SZ;
210         int off = offset % BANK_SZ;
211         u8 val;
212         int ret;
213
214         if (dir == PCA953X_DIRECTION_IN)
215                 val = info->reg_direction[bank] | (1 << off);
216         else
217                 val = info->reg_direction[bank] & ~(1 << off);
218
219         ret = pca953x_write_single(dev, PCA953X_DIRECTION, val, offset);
220         if (ret)
221                 return ret;
222
223         info->reg_direction[bank] = val;
224
225         return 0;
226 }
227
228 static int pca953x_direction_input(struct udevice *dev, uint offset)
229 {
230         return pca953x_set_direction(dev, offset, PCA953X_DIRECTION_IN);
231 }
232
233 static int pca953x_direction_output(struct udevice *dev, uint offset, int value)
234 {
235         /* Configure output value. */
236         pca953x_set_value(dev, offset, value);
237
238         /* Configure direction as output. */
239         pca953x_set_direction(dev, offset, PCA953X_DIRECTION_OUT);
240
241         return 0;
242 }
243
244 static int pca953x_get_function(struct udevice *dev, uint offset)
245 {
246         if (pca953x_is_output(dev, offset))
247                 return GPIOF_OUTPUT;
248         else
249                 return GPIOF_INPUT;
250 }
251
252 static int pca953x_xlate(struct udevice *dev, struct gpio_desc *desc,
253                          struct ofnode_phandle_args *args)
254 {
255         desc->offset = args->args[0];
256         desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
257
258         return 0;
259 }
260
261 static const struct dm_gpio_ops pca953x_ops = {
262         .direction_input        = pca953x_direction_input,
263         .direction_output       = pca953x_direction_output,
264         .get_value              = pca953x_get_value,
265         .set_value              = pca953x_set_value,
266         .get_function           = pca953x_get_function,
267         .xlate                  = pca953x_xlate,
268 };
269
270 static int pca953x_probe(struct udevice *dev)
271 {
272         struct pca953x_info *info = dev_get_platdata(dev);
273         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
274         char name[32], label[8], *str;
275         int addr;
276         ulong driver_data;
277         int ret;
278         int size;
279         const u8 *tmp;
280         u8 val[MAX_BANK];
281
282         addr = dev_read_addr(dev);
283         if (addr == 0)
284                 return -ENODEV;
285
286         info->addr = addr;
287
288         driver_data = dev_get_driver_data(dev);
289
290         info->gpio_count = driver_data & PCA_GPIO_MASK;
291         if (info->gpio_count > MAX_BANK * BANK_SZ) {
292                 dev_err(dev, "Max support %d pins now\n", MAX_BANK * BANK_SZ);
293                 return -EINVAL;
294         }
295
296         info->chip_type = PCA_CHIP_TYPE(driver_data);
297         if (info->chip_type != PCA953X_TYPE) {
298                 dev_err(dev, "Only support PCA953X chip type now.\n");
299                 return -EINVAL;
300         }
301
302         info->bank_count = DIV_ROUND_UP(info->gpio_count, BANK_SZ);
303
304         ret = pca953x_read_regs(dev, PCA953X_OUTPUT, info->reg_output);
305         if (ret) {
306                 dev_err(dev, "Error reading output register\n");
307                 return ret;
308         }
309
310         ret = pca953x_read_regs(dev, PCA953X_DIRECTION, info->reg_direction);
311         if (ret) {
312                 dev_err(dev, "Error reading direction register\n");
313                 return ret;
314         }
315
316         tmp = dev_read_prop(dev, "label", &size);
317
318         if (tmp) {
319                 memcpy(label, tmp, sizeof(label) - 1);
320                 label[sizeof(label) - 1] = '\0';
321                 snprintf(name, sizeof(name), "%s@%x_", label, info->addr);
322         } else {
323                 snprintf(name, sizeof(name), "gpio@%x_", info->addr);
324         }
325
326         /* Clear the polarity registers to no invert */
327         memset(val, 0, MAX_BANK);
328         ret = pca953x_write_regs(dev, PCA953X_INVERT, val);
329         if (ret < 0) {
330                 dev_err(dev, "Error writing invert register\n");
331                 return ret;
332         }
333
334         str = strdup(name);
335         if (!str)
336                 return -ENOMEM;
337         uc_priv->bank_name = str;
338         uc_priv->gpio_count = info->gpio_count;
339
340         dev_dbg(dev, "%s is ready\n", str);
341
342         return 0;
343 }
344
345 #define OF_953X(__nrgpio, __int) (ulong)(__nrgpio | PCA953X_TYPE | __int)
346 #define OF_957X(__nrgpio, __int) (ulong)(__nrgpio | PCA957X_TYPE | __int)
347
348 static const struct udevice_id pca953x_ids[] = {
349         { .compatible = "nxp,pca9505", .data = OF_953X(40, PCA_INT), },
350         { .compatible = "nxp,pca9534", .data = OF_953X(8, PCA_INT), },
351         { .compatible = "nxp,pca9535", .data = OF_953X(16, PCA_INT), },
352         { .compatible = "nxp,pca9536", .data = OF_953X(4, 0), },
353         { .compatible = "nxp,pca9537", .data = OF_953X(4, PCA_INT), },
354         { .compatible = "nxp,pca9538", .data = OF_953X(8, PCA_INT), },
355         { .compatible = "nxp,pca9539", .data = OF_953X(16, PCA_INT), },
356         { .compatible = "nxp,pca9554", .data = OF_953X(8, PCA_INT), },
357         { .compatible = "nxp,pca9555", .data = OF_953X(16, PCA_INT), },
358         { .compatible = "nxp,pca9556", .data = OF_953X(8, 0), },
359         { .compatible = "nxp,pca9557", .data = OF_953X(8, 0), },
360         { .compatible = "nxp,pca9574", .data = OF_957X(8, PCA_INT), },
361         { .compatible = "nxp,pca9575", .data = OF_957X(16, PCA_INT), },
362         { .compatible = "nxp,pca9698", .data = OF_953X(40, 0), },
363
364         { .compatible = "maxim,max7310", .data = OF_953X(8, 0), },
365         { .compatible = "maxim,max7312", .data = OF_953X(16, PCA_INT), },
366         { .compatible = "maxim,max7313", .data = OF_953X(16, PCA_INT), },
367         { .compatible = "maxim,max7315", .data = OF_953X(8, PCA_INT), },
368
369         { .compatible = "ti,pca6107", .data = OF_953X(8, PCA_INT), },
370         { .compatible = "ti,tca6408", .data = OF_953X(8, PCA_INT), },
371         { .compatible = "ti,tca6416", .data = OF_953X(16, PCA_INT), },
372         { .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
373         { .compatible = "ti,tca9539", .data = OF_953X(16, PCA_INT), },
374
375         { .compatible = "onsemi,pca9654", .data = OF_953X(8, PCA_INT), },
376
377         { .compatible = "exar,xra1202", .data = OF_953X(8, 0), },
378         { }
379 };
380
381 U_BOOT_DRIVER(pca953x) = {
382         .name           = "pca953x",
383         .id             = UCLASS_GPIO,
384         .ops            = &pca953x_ops,
385         .probe          = pca953x_probe,
386         .platdata_auto_alloc_size = sizeof(struct pca953x_info),
387         .of_match       = pca953x_ids,
388 };