1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Take drivers/gpio/gpio-74x164.c as reference. 4 * 5 * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver 6 * 7 * Copyright (C) 2016 Peng Fan <van.freenix@gmail.com> 8 * 9 */ 10 11 #include <common.h> 12 #include <errno.h> 13 #include <dm.h> 14 #include <fdtdec.h> 15 #include <malloc.h> 16 #include <asm/gpio.h> 17 #include <asm/io.h> 18 #include <dt-bindings/gpio/gpio.h> 19 #include <spi.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 /* 24 * struct gen_74x164_chip - Data for 74Hx164 25 * 26 * @oe: OE pin 27 * @nregs: number of registers 28 * @buffer: buffer for chained chips 29 */ 30 #define GEN_74X164_NUMBER_GPIOS 8 31 32 struct gen_74x164_priv { 33 struct gpio_desc oe; 34 u32 nregs; 35 /* 36 * Since the nregs are chained, every byte sent will make 37 * the previous byte shift to the next register in the 38 * chain. Thus, the first byte sent will end up in the last 39 * register at the end of the transfer. So, to have a logical 40 * numbering, store the bytes in reverse order. 41 */ 42 u8 *buffer; 43 }; 44 45 static int gen_74x164_write_conf(struct udevice *dev) 46 { 47 struct gen_74x164_priv *priv = dev_get_priv(dev); 48 int ret; 49 50 ret = dm_spi_claim_bus(dev); 51 if (ret) 52 return ret; 53 54 ret = dm_spi_xfer(dev, priv->nregs * 8, priv->buffer, NULL, 55 SPI_XFER_BEGIN | SPI_XFER_END); 56 57 dm_spi_release_bus(dev); 58 59 return ret; 60 } 61 62 static int gen_74x164_get_value(struct udevice *dev, unsigned offset) 63 { 64 struct gen_74x164_priv *priv = dev_get_priv(dev); 65 uint bank = priv->nregs - 1 - offset / 8; 66 uint pin = offset % 8; 67 68 return (priv->buffer[bank] >> pin) & 0x1; 69 } 70 71 static int gen_74x164_set_value(struct udevice *dev, unsigned offset, 72 int value) 73 { 74 struct gen_74x164_priv *priv = dev_get_priv(dev); 75 uint bank = priv->nregs - 1 - offset / 8; 76 uint pin = offset % 8; 77 int ret; 78 79 if (value) 80 priv->buffer[bank] |= 1 << pin; 81 else 82 priv->buffer[bank] &= ~(1 << pin); 83 84 ret = gen_74x164_write_conf(dev); 85 if (ret) 86 return ret; 87 88 return 0; 89 } 90 91 static int gen_74x164_direction_input(struct udevice *dev, unsigned offset) 92 { 93 return -ENOSYS; 94 } 95 96 static int gen_74x164_direction_output(struct udevice *dev, unsigned offset, 97 int value) 98 { 99 return gen_74x164_set_value(dev, offset, value); 100 } 101 102 static int gen_74x164_get_function(struct udevice *dev, unsigned offset) 103 { 104 return GPIOF_OUTPUT; 105 } 106 107 static int gen_74x164_xlate(struct udevice *dev, struct gpio_desc *desc, 108 struct ofnode_phandle_args *args) 109 { 110 desc->offset = args->args[0]; 111 desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; 112 113 return 0; 114 } 115 116 static const struct dm_gpio_ops gen_74x164_ops = { 117 .direction_input = gen_74x164_direction_input, 118 .direction_output = gen_74x164_direction_output, 119 .get_value = gen_74x164_get_value, 120 .set_value = gen_74x164_set_value, 121 .get_function = gen_74x164_get_function, 122 .xlate = gen_74x164_xlate, 123 }; 124 125 static int gen_74x164_probe(struct udevice *dev) 126 { 127 struct gen_74x164_priv *priv = dev_get_priv(dev); 128 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 129 char *str, name[32]; 130 int ret; 131 const void *fdt = gd->fdt_blob; 132 int node = dev_of_offset(dev); 133 134 snprintf(name, sizeof(name), "%s_", dev->name); 135 str = strdup(name); 136 if (!str) 137 return -ENOMEM; 138 139 /* 140 * See Linux kernel: 141 * Documentation/devicetree/bindings/gpio/gpio-74x164.txt 142 */ 143 priv->nregs = fdtdec_get_int(fdt, node, "registers-number", 1); 144 priv->buffer = calloc(priv->nregs, sizeof(u8)); 145 if (!priv->buffer) { 146 ret = -ENOMEM; 147 goto free_str; 148 } 149 150 ret = fdtdec_get_byte_array(fdt, node, "registers-default", 151 priv->buffer, priv->nregs); 152 if (ret) 153 dev_dbg(dev, "No registers-default property\n"); 154 155 ret = gpio_request_by_name(dev, "oe-gpios", 0, &priv->oe, 156 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 157 if (ret) { 158 dev_dbg(dev, "No oe-pins property\n"); 159 } 160 161 uc_priv->bank_name = str; 162 uc_priv->gpio_count = priv->nregs * 8; 163 164 ret = gen_74x164_write_conf(dev); 165 if (ret) 166 goto free_buf; 167 168 dev_dbg(dev, "%s is ready\n", dev->name); 169 170 return 0; 171 172 free_buf: 173 free(priv->buffer); 174 free_str: 175 free(str); 176 return ret; 177 } 178 179 static const struct udevice_id gen_74x164_ids[] = { 180 { .compatible = "fairchild,74hc595" }, 181 { } 182 }; 183 184 U_BOOT_DRIVER(74x164) = { 185 .name = "74x164", 186 .id = UCLASS_GPIO, 187 .ops = &gen_74x164_ops, 188 .probe = gen_74x164_probe, 189 .priv_auto_alloc_size = sizeof(struct gen_74x164_priv), 190 .of_match = gen_74x164_ids, 191 }; 192