1 // SPDX-License-Identifier: GPL-2.0+
3 * Take drivers/gpio/gpio-74x164.c as reference.
5 * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
7 * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
18 #include <dm/device_compat.h>
19 #include <dt-bindings/gpio/gpio.h>
22 DECLARE_GLOBAL_DATA_PTR
;
25 * struct gen_74x164_chip - Data for 74Hx164
28 * @nregs: number of registers
29 * @buffer: buffer for chained chips
31 #define GEN_74X164_NUMBER_GPIOS 8
33 struct gen_74x164_priv
{
37 * Since the nregs are chained, every byte sent will make
38 * the previous byte shift to the next register in the
39 * chain. Thus, the first byte sent will end up in the last
40 * register at the end of the transfer. So, to have a logical
41 * numbering, store the bytes in reverse order.
46 static int gen_74x164_write_conf(struct udevice
*dev
)
48 struct gen_74x164_priv
*priv
= dev_get_priv(dev
);
51 ret
= dm_spi_claim_bus(dev
);
55 ret
= dm_spi_xfer(dev
, priv
->nregs
* 8, priv
->buffer
, NULL
,
56 SPI_XFER_BEGIN
| SPI_XFER_END
);
58 dm_spi_release_bus(dev
);
63 static int gen_74x164_get_value(struct udevice
*dev
, unsigned offset
)
65 struct gen_74x164_priv
*priv
= dev_get_priv(dev
);
66 uint bank
= priv
->nregs
- 1 - offset
/ 8;
67 uint pin
= offset
% 8;
69 return (priv
->buffer
[bank
] >> pin
) & 0x1;
72 static int gen_74x164_set_value(struct udevice
*dev
, unsigned offset
,
75 struct gen_74x164_priv
*priv
= dev_get_priv(dev
);
76 uint bank
= priv
->nregs
- 1 - offset
/ 8;
77 uint pin
= offset
% 8;
81 priv
->buffer
[bank
] |= 1 << pin
;
83 priv
->buffer
[bank
] &= ~(1 << pin
);
85 ret
= gen_74x164_write_conf(dev
);
92 static int gen_74x164_direction_input(struct udevice
*dev
, unsigned offset
)
97 static int gen_74x164_direction_output(struct udevice
*dev
, unsigned offset
,
100 return gen_74x164_set_value(dev
, offset
, value
);
103 static int gen_74x164_get_function(struct udevice
*dev
, unsigned offset
)
108 static int gen_74x164_xlate(struct udevice
*dev
, struct gpio_desc
*desc
,
109 struct ofnode_phandle_args
*args
)
111 desc
->offset
= args
->args
[0];
112 desc
->flags
= args
->args
[1] & GPIO_ACTIVE_LOW
? GPIOD_ACTIVE_LOW
: 0;
117 static const struct dm_gpio_ops gen_74x164_ops
= {
118 .direction_input
= gen_74x164_direction_input
,
119 .direction_output
= gen_74x164_direction_output
,
120 .get_value
= gen_74x164_get_value
,
121 .set_value
= gen_74x164_set_value
,
122 .get_function
= gen_74x164_get_function
,
123 .xlate
= gen_74x164_xlate
,
126 static int gen_74x164_probe(struct udevice
*dev
)
128 struct gen_74x164_priv
*priv
= dev_get_priv(dev
);
129 struct gpio_dev_priv
*uc_priv
= dev_get_uclass_priv(dev
);
132 const void *fdt
= gd
->fdt_blob
;
133 int node
= dev_of_offset(dev
);
135 snprintf(name
, sizeof(name
), "%s_", dev
->name
);
142 * Documentation/devicetree/bindings/gpio/gpio-74x164.txt
144 priv
->nregs
= fdtdec_get_int(fdt
, node
, "registers-number", 1);
145 priv
->buffer
= calloc(priv
->nregs
, sizeof(u8
));
151 ret
= fdtdec_get_byte_array(fdt
, node
, "registers-default",
152 priv
->buffer
, priv
->nregs
);
154 dev_dbg(dev
, "No registers-default property\n");
156 ret
= gpio_request_by_name(dev
, "oe-gpios", 0, &priv
->oe
,
157 GPIOD_IS_OUT
| GPIOD_IS_OUT_ACTIVE
);
159 dev_dbg(dev
, "No oe-pins property\n");
162 uc_priv
->bank_name
= str
;
163 uc_priv
->gpio_count
= priv
->nregs
* 8;
165 ret
= gen_74x164_write_conf(dev
);
169 dev_dbg(dev
, "%s is ready\n", dev
->name
);
180 static const struct udevice_id gen_74x164_ids
[] = {
181 { .compatible
= "fairchild,74hc595" },
185 U_BOOT_DRIVER(74x164
) = {
188 .ops
= &gen_74x164_ops
,
189 .probe
= gen_74x164_probe
,
190 .priv_auto_alloc_size
= sizeof(struct gen_74x164_priv
),
191 .of_match
= gen_74x164_ids
,