From 84430deb6286f57cd7baf56eea1b899ae775e1d0 Mon Sep 17 00:00:00 2001 From: Shenwei Wang Date: Mon, 11 Jan 2021 17:41:41 -0600 Subject: [PATCH] MLK-25166-1 gpio: gpio-scu: gpio driver over scu fw misc api This is a gpio driver to control the PINs which are managed by scu fw. Signed-off-by: Shenwei Wang --- drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-scu.c | 137 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 drivers/gpio/gpio-scu.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 69f8e6587c3c..d282d269fed9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -427,6 +427,12 @@ config GPIO_MXC select GPIO_GENERIC select GENERIC_IRQ_CHIP +config GPIO_SCU + def_bool y + depends on IMX_SCU + help + Say Y here to enable the imx8 gpio over SCFW MISC API + config GPIO_MXS def_bool y depends on ARCH_MXS || COMPILE_TEST diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index f5b82f272b42..da843d1861ef 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -129,6 +129,7 @@ obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o +obj-$(CONFIG_GPIO_SCU) += gpio-scu.o obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o obj-$(CONFIG_GPIO_SL28CPLD) += gpio-sl28cpld.o diff --git a/drivers/gpio/gpio-scu.c b/drivers/gpio/gpio-scu.c new file mode 100644 index 000000000000..5fb2d8b72653 --- /dev/null +++ b/drivers/gpio/gpio-scu.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021 NXP + * + * The driver exports a standard gpiochip interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PIN_NUMBER 8 + +struct imxscfw { + struct mutex lock; + struct imx_sc_ipc *handle; + struct gpio_chip chip; + struct device *dev; +}; + +static unsigned int sc_arr[] = { + IMX_SC_R_BOARD_R0, + IMX_SC_R_BOARD_R1, + IMX_SC_R_BOARD_R2, + IMX_SC_R_BOARD_R3, + IMX_SC_R_BOARD_R4, + IMX_SC_R_BOARD_R5, + IMX_SC_R_BOARD_R6, //R6 is MII select + IMX_SC_R_BOARD_R7, +}; + +static int imxscfw_get(struct gpio_chip *chip, unsigned int offset) +{ + struct imxscfw *scu = gpiochip_get_data(chip); + int err = -EINVAL, level = 0; + + if (offset >= sizeof(sc_arr)/sizeof(unsigned int)) + return err; + + mutex_lock(&scu->lock); + + /* to read PIN state via scu api */ + err = imx_sc_misc_get_control(scu->handle, sc_arr[offset], + 0, &level); + mutex_unlock(&scu->lock); + + if (err) { + pr_err("%s: failed %d\n", __func__, err); + return -EINVAL; + } + + return level; +} + +static void imxscfw_set(struct gpio_chip *chip, unsigned int offset, int value) +{ + struct imxscfw *scu = gpiochip_get_data(chip); + int err; + + if (offset >= sizeof(sc_arr)/sizeof(unsigned int)) + return; + + mutex_lock(&scu->lock); + + /* to set PIN output level via scu api */ + err = imx_sc_misc_set_control(scu->handle, sc_arr[offset], 0, value); + + mutex_unlock(&scu->lock); + + if (err) + pr_err("%s: failed %d\n", __func__, err); + + +} + +static int imx_scu_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct imxscfw *port; + struct gpio_chip *gc; + int ret; + + port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + ret = imx_scu_get_handle(&port->handle); + if (ret) + return ret; + + mutex_init(&port->lock); + gc = &port->chip; + gc->of_node = np; + gc->parent = dev; + gc->label = "imx-scu-gpio"; + gc->ngpio = PIN_NUMBER; + gc->base = of_alias_get_id(np, "gpio") * 32; + + gc->get = imxscfw_get; + gc->set = imxscfw_set; + + platform_set_drvdata(pdev, port); + + ret = devm_gpiochip_add_data(dev, gc, port); + + return ret; +} + +static const struct of_device_id imx_scu_gpio_dt_ids[] = { + { .compatible = "fsl,imx-scu-gpio" }, + { /* sentinel */ } +}; + +static struct platform_driver imx_scu_gpio_driver = { + .driver = { + .name = "gpio-imx-scu", + .of_match_table = imx_scu_gpio_dt_ids, + }, + .probe = imx_scu_gpio_probe, +}; + +static int __init _imx_scu_gpio_init(void) +{ + return platform_driver_register(&imx_scu_gpio_driver); +} + +subsys_initcall_sync(_imx_scu_gpio_init); + +MODULE_AUTHOR("Shenwei Wang"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("NXP GPIO over SCU-MISC API, i.MX8"); -- 2.17.1