Lines Matching +full:sgpio +full:- +full:gpio

1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 * Microsemi SoCs serial gpio driver
12 #include <asm/gpio.h>
44 #define __X(bf, x) (((x) >> (bf).beg) & GENMASK(((bf).end - (bf).beg), 0))
46 #define MSCC_M_CFG_SIO_AUTO_REPEAT(p) BIT(p->props->auto_repeat.beg)
47 #define MSCC_F_CFG_SIO_PORT_WIDTH(p, x) __F(p->props->port_width, x)
48 #define MSCC_M_CFG_SIO_PORT_WIDTH(p) __M(p->props->port_width)
49 #define MSCC_F_CLOCK_SIO_CLK_FREQ(p, x) __F(p->props->clk_freq, x)
50 #define MSCC_M_CLOCK_SIO_CLK_FREQ(p) __M(p->props->clk_freq)
51 #define MSCC_F_PORT_CFG_BIT_SOURCE(p, x) __F(p->props->bit_source, x)
52 #define MSCC_X_PORT_CFG_BIT_SOURCE(p, x) __X(p->props->bit_source, x)
81 u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off]; in sgpio_readl()
89 u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off]; in sgpio_writel()
97 u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off]; in sgpio_clrsetbits()
102 static int mscc_sgpio_direction_input(struct udevice *dev, unsigned int gpio) in mscc_sgpio_direction_input() argument
106 u32 port = gpio % MSCC_SGPIOS_PER_BANK; in mscc_sgpio_direction_input()
107 u32 bit = gpio / MSCC_SGPIOS_PER_BANK; in mscc_sgpio_direction_input()
109 priv->mode[port] |= BIT(bit); in mscc_sgpio_direction_input()
115 unsigned int gpio, int value) in mscc_sgpio_direction_output() argument
118 u32 port = gpio % MSCC_SGPIOS_PER_BANK; in mscc_sgpio_direction_output()
119 u32 bit = gpio / MSCC_SGPIOS_PER_BANK; in mscc_sgpio_direction_output()
129 clrbits_le32(&priv->mode[port], BIT(bit)); in mscc_sgpio_direction_output()
134 static int mscc_sgpio_get_function(struct udevice *dev, unsigned int gpio) in mscc_sgpio_get_function() argument
137 u32 port = gpio % MSCC_SGPIOS_PER_BANK; in mscc_sgpio_get_function()
138 u32 bit = gpio / MSCC_SGPIOS_PER_BANK; in mscc_sgpio_get_function()
139 u32 val = priv->mode[port] & BIT(bit); in mscc_sgpio_get_function()
148 unsigned int gpio, int value) in mscc_sgpio_set_value() argument
150 return mscc_sgpio_direction_output(dev, gpio, value); in mscc_sgpio_set_value()
153 static int mscc_sgpio_get_value(struct udevice *dev, unsigned int gpio) in mscc_sgpio_get_value() argument
156 u32 port = gpio % MSCC_SGPIOS_PER_BANK; in mscc_sgpio_get_value()
157 u32 bit = gpio / MSCC_SGPIOS_PER_BANK; in mscc_sgpio_get_value()
160 if (mscc_sgpio_get_function(dev, gpio) == GPIOF_INPUT) { in mscc_sgpio_get_value()
169 debug("get: gpio %d, port %d, bit %d, value %d\n", in mscc_sgpio_get_value()
170 gpio, port, bit, ret); in mscc_sgpio_get_value()
179 ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, i, &args); in mscc_sgpio_get_count()
180 while (ret != -ENOENT) { in mscc_sgpio_get_count()
182 ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, in mscc_sgpio_get_count()
201 return -EINVAL; in mscc_sgpio_probe()
209 priv->props = (const struct mscc_sgpio_props *)dev_get_driver_data(dev); in mscc_sgpio_probe()
210 priv->ports = dev_read_u32_default(dev, "mscc,sgpio-ports", 0xFFFFFFFF); in mscc_sgpio_probe()
211 priv->clock = dev_read_u32_default(dev, "mscc,sgpio-frequency", in mscc_sgpio_probe()
213 if (priv->clock <= 0 || priv->clock > div_clock) { in mscc_sgpio_probe()
214 dev_err(dev, "Invalid frequency %d\n", priv->clock); in mscc_sgpio_probe()
215 return -EINVAL; in mscc_sgpio_probe()
218 uc_priv->gpio_count = mscc_sgpio_get_count(dev); in mscc_sgpio_probe()
219 uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", in mscc_sgpio_probe()
220 uc_priv->gpio_count); in mscc_sgpio_probe()
221 if (uc_priv->gpio_count < 1 || uc_priv->gpio_count > in mscc_sgpio_probe()
223 dev_err(dev, "Invalid gpio count %d\n", uc_priv->gpio_count); in mscc_sgpio_probe()
224 return -EINVAL; in mscc_sgpio_probe()
226 priv->bitcount = DIV_ROUND_UP(uc_priv->gpio_count, in mscc_sgpio_probe()
228 debug("probe: gpios = %d, bit-count = %d\n", in mscc_sgpio_probe()
229 uc_priv->gpio_count, priv->bitcount); in mscc_sgpio_probe()
231 priv->regs = (u32 __iomem *)dev_read_addr(dev); in mscc_sgpio_probe()
232 uc_priv->bank_name = "sgpio"; in mscc_sgpio_probe()
236 MSCC_F_CFG_SIO_PORT_WIDTH(priv, priv->bitcount - 1) | in mscc_sgpio_probe()
238 val = div_clock / priv->clock; in mscc_sgpio_probe()
239 debug("probe: div-clock = %d KHz, freq = %d KHz, div = %d\n", in mscc_sgpio_probe()
240 div_clock / 1000, priv->clock / 1000, val); in mscc_sgpio_probe()
247 sgpio_writel(priv, priv->ports, REG_PORT_ENABLE, 0); in mscc_sgpio_probe()
249 debug("probe: sgpio regs = %p\n", priv->regs); in mscc_sgpio_probe()
263 { .compatible = "mscc,luton-sgpio", .data = (ulong)&props_luton },
264 { .compatible = "mscc,ocelot-sgpio", .data = (ulong)&props_ocelot },
269 .name = "mscc-sgpio",