blob: 2bba14e6e57f4710322962c4a23754fd853c4184 [file] [log] [blame]
Christophe Leroy0ee1ff82024-04-12 12:01:25 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2024 CS GROUP France
4 * Christophe Leroy <christophe.leroy@csgroup.eu>
5 */
6
7#include <asm/io.h>
8#include <dm.h>
9#include <mapmem.h>
10#include <asm/gpio.h>
11#include <malloc.h>
12
13#include "../common/common.h"
14
15struct mcr3000_spi_gpio_plat {
16 ulong addr;
17};
18
19struct mcr3000_spi_gpio_data {
20 void __iomem *base;
21};
22
23static int mcr3000_spi_gpio_set_value(struct udevice *dev, uint gpio, int value)
24{
25 struct mcr3000_spi_gpio_data *data = dev_get_priv(dev);
26
27 if (value)
28 clrsetbits_be16(data->base, 7 << 5, (gpio & 7) << 5);
29 else
30 clrbits_be16(data->base, 7 << 5);
31
32 return 0;
33}
34
35static int mcr3000_spi_gpio_get_value(struct udevice *dev, uint gpio)
36{
37 struct mcr3000_spi_gpio_data *data = dev_get_priv(dev);
38
39 return gpio == ((in_be16(data->base) >> 5) & 7);
40}
41
42static int mcr3000_spi_gpio_direction_input(struct udevice *dev, uint gpio)
43{
44 return 0;
45}
46
47static int mcr3000_spi_gpio_get_function(struct udevice *dev, uint gpio)
48{
49 return GPIOF_OUTPUT;
50}
51
52static int mcr3000_spi_gpio_ofdata_to_platdata(struct udevice *dev)
53{
54 struct mcr3000_spi_gpio_plat *plat = dev_get_plat(dev);
55 fdt_addr_t addr;
56 u32 reg[2];
57
58 dev_read_u32_array(dev, "reg", reg, 2);
59 addr = dev_translate_address(dev, reg);
60
61 plat->addr = addr;
62
63 return 0;
64}
65
66static int mcr3000_spi_gpio_probe(struct udevice *dev)
67{
68 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
69 struct mcr3000_spi_gpio_data *data = dev_get_priv(dev);
70 struct mcr3000_spi_gpio_plat *plat = dev_get_plat(dev);
71 char name[32], *str;
72
73 data->base = map_sysmem(plat->addr, 2);
74
75 snprintf(name, sizeof(name), "CHIPSELECT@%lx_", plat->addr);
76 str = strdup(name);
77
78 if (!str)
79 return -ENOMEM;
80
81 uc_priv->bank_name = str;
82 uc_priv->gpio_count = 16;
83
84 return 0;
85}
86
87static const struct dm_gpio_ops gpio_mcr3000_spi_ops = {
88 .get_value = mcr3000_spi_gpio_get_value,
89 .set_value = mcr3000_spi_gpio_set_value,
90 .direction_input = mcr3000_spi_gpio_direction_input,
91 .direction_output = mcr3000_spi_gpio_set_value,
92 .get_function = mcr3000_spi_gpio_get_function,
93};
94
95static const struct udevice_id mcr3000_spi_gpio_ids[] = {
96 { .compatible = "s3k,mcr3000-cpld-csspi"},
97 { /* sentinel */ }
98};
99
100U_BOOT_DRIVER(mcr3000_spi_gpio) = {
101 .name = "mcr3000_spi_chipselect",
102 .id = UCLASS_GPIO,
103 .ops = &gpio_mcr3000_spi_ops,
104 .of_to_plat = mcr3000_spi_gpio_ofdata_to_platdata,
105 .plat_auto = sizeof(struct mcr3000_spi_gpio_plat),
106 .of_match = mcr3000_spi_gpio_ids,
107 .probe = mcr3000_spi_gpio_probe,
108 .priv_auto = sizeof(struct mcr3000_spi_gpio_data),
109};