From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gregory CLEMENT Date: Sat, 08 Dec 2018 10:00:58 +0100 Subject: [U-Boot] [PATCH v2] gpio: mscc-bitbang-spi: Add a simple gpio driver for bitbgang spi In-Reply-To: <20181009120842.22090-1-gregory.clement@bootlin.com> (Gregory CLEMENT's message of "Tue, 9 Oct 2018 14:08:42 +0200") References: <20181009120842.22090-1-gregory.clement@bootlin.com> Message-ID: <878t10v1dh.fsf@bootlin.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi, On mar., oct. 09 2018, Gregory CLEMENT wrote: > The VCore III SoCs such as the Luton but also the Ocelot can remap an SPI > flash directly in memory. However, for writing in the flash the > communication has to be done by software. > > Each of the signal used for the SPI are exposed in a single register. In > order to be able to use the soft-spi driver, the management of this pin > is done through this simple gpio driver. > > Even if the main purpose of this driver is to be used by soft-spi, it can > still be used as a normal gpio driver but with limitation: for example > the first pin can't be used as output. > > Signed-off-by: Gregory CLEMENT > --- > Changelog: > v1 -> v2: > - use const and static when needed > - fix style > - use dev_remap_addr I sent this version 2 months ago and addressed all the comments, how could we going further ? Thanks, Gregory > > drivers/gpio/Kconfig | 7 ++ > drivers/gpio/Makefile | 1 + > drivers/gpio/gpio-mscc-bitbang-spi.c | 122 +++++++++++++++++++++++++++ > 3 files changed, 130 insertions(+) > create mode 100644 drivers/gpio/gpio-mscc-bitbang-spi.c > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 5cd8b34400..947a59cce3 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -99,6 +99,13 @@ config LPC32XX_GPIO > help > Support for the LPC32XX GPIO driver. > > +config MSCC_BITBANG_SPI_GPIO > + bool "Microsemi bitbang spi GPIO driver" > + depends on DM_GPIO && SOC_VCOREIII > + help > + Support controlling the GPIO used for SPI bitbang by software. Can > + be used by the VCoreIII SoCs, but it was mainly useful for Luton. > + > config MSM_GPIO > bool "Qualcomm GPIO driver" > depends on DM_GPIO > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index f186120684..2085dd3cba 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -58,3 +58,4 @@ obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o > obj-$(CONFIG_MSM_GPIO) += msm_gpio.o > obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o > obj-$(CONFIG_PM8916_GPIO) += pm8916_gpio.o > +obj-$(CONFIG_MSCC_BITBANG_SPI_GPIO) += gpio-mscc-bitbang-spi.o > diff --git a/drivers/gpio/gpio-mscc-bitbang-spi.c b/drivers/gpio/gpio-mscc-bitbang-spi.c > new file mode 100644 > index 0000000000..b675f9052c > --- /dev/null > +++ b/drivers/gpio/gpio-mscc-bitbang-spi.c > @@ -0,0 +1,122 @@ > +// SPDX-License-Identifier: (GPL-2.0 OR MIT) > +/* > + * Microsemi SoCs pinctrl driver > + * > + * Author: > + * License: Dual MIT/GPL > + * Copyright (c) 2018 Microsemi Corporation > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +enum { > + SDI, > + CS0, > + CS1, > + CS2, > + CS3, > + SDO, > + SCK > +}; > + > +static const int pinmap[] = { 0, 5, 6, 7, 8, 10, 12 }; > + > +#define SW_SPI_CSn_OE 0x1E /* bits 1 to 4 */ > +#define SW_SPI_CS0_OE BIT(1) > +#define SW_SPI_SDO_OE BIT(9) > +#define SW_SPI_SCK_OE BIT(11) > +#define SW_PIN_CTRL_MODE BIT(13) > + > +struct mscc_bb_spi_gpio { > + void __iomem *regs; > + u32 cache_val; > +}; > + > +static int mscc_bb_spi_gpio_set(struct udevice *dev, unsigned oft, int val) > +{ > + struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); > + > + if (val) > + gpio->cache_val |= BIT(pinmap[oft]); > + else > + gpio->cache_val &= ~BIT(pinmap[oft]); > + > + writel(gpio->cache_val, gpio->regs); > + > + return 0; > +} > + > +static int mscc_bb_spi_gpio_direction_output(struct udevice *dev, unsigned oft, > + int val) > +{ > + if (oft == 0) { > + pr_err("SW_SPI_DSI can't be used as output\n"); > + return -ENOTSUPP; > + } > + > + mscc_bb_spi_gpio_set(dev, oft, val); > + > + return 0; > +} > + > +static int mscc_bb_spi_gpio_direction_input(struct udevice *dev, unsigned oft) > +{ > + return 0; > +} > + > +static int mscc_bb_spi_gpio_get(struct udevice *dev, unsigned int oft) > +{ > + struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); > + u32 val = readl(gpio->regs); > + > + return !!(val & BIT(pinmap[oft])); > +} > + > +static const struct dm_gpio_ops mscc_bb_spi_gpio_ops = { > + .direction_output = mscc_bb_spi_gpio_direction_output, > + .direction_input = mscc_bb_spi_gpio_direction_input, > + .set_value = mscc_bb_spi_gpio_set, > + .get_value = mscc_bb_spi_gpio_get, > +}; > + > +static int mscc_bb_spi_gpio_probe(struct udevice *dev) > +{ > + struct mscc_bb_spi_gpio *gpio = dev_get_priv(dev); > + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); > + > + gpio->regs = dev_remap_addr(dev); > + if (!gpio->regs) > + return -EINVAL; > + > + uc_priv->bank_name = dev->name; > + uc_priv->gpio_count = ARRAY_SIZE(pinmap); > + /* > + * Enable software mode to control the SPI pin, enables the > + * output mode for most of the pin and initialize the cache > + * value in the same time > + */ > + > + gpio->cache_val = SW_PIN_CTRL_MODE | SW_SPI_SCK_OE | SW_SPI_SDO_OE | > + SW_SPI_CS0_OE; > + writel(gpio->cache_val, gpio->regs); > + > + return 0; > +} > + > +static const struct udevice_id mscc_bb_spi_gpio_ids[] = { > + {.compatible = "mscc,spi-bitbang-gpio"}, > + {} > +}; > + > +U_BOOT_DRIVER(gpio_mscc_bb_spi) = { > + .name = "gpio-mscc-spi-bitbang", > + .id = UCLASS_GPIO, > + .ops = &mscc_bb_spi_gpio_ops, > + .probe = mscc_bb_spi_gpio_probe, > + .of_match = of_match_ptr(mscc_bb_spi_gpio_ids), > + .priv_auto_alloc_size = sizeof(struct mscc_bb_spi_gpio), > +}; > -- > 2.19.1 > -- Gregory Clement, Bootlin Embedded Linux and Kernel engineering http://bootlin.com