// SPDX-License-Identifier: GPL-2.0
/*
 * GPIO latch driver
 *
 *  Copyright (C) 2022 Sascha Hauer <s.hauer@pengutronix.de>
 *
 * This driver implements a GPIO (or better GPO as there is no input)
 * multiplexer based on latches like this:
 *
 * CLK0 ----------------------.        ,--------.
 * CLK1 -------------------.  `--------|>    #0 |
 *                         |           |        |
 * OUT0 ----------------+--|-----------|D0    Q0|-----|<
 * OUT1 --------------+-|--|-----------|D1    Q1|-----|<
 * OUT2 ------------+-|-|--|-----------|D2    Q2|-----|<
 * OUT3 ----------+-|-|-|--|-----------|D3    Q3|-----|<
 * OUT4 --------+-|-|-|-|--|-----------|D4    Q4|-----|<
 * OUT5 ------+-|-|-|-|-|--|-----------|D5    Q5|-----|<
 * OUT6 ----+-|-|-|-|-|-|--|-----------|D6    Q6|-----|<
 * OUT7 --+-|-|-|-|-|-|-|--|-----------|D7    Q7|-----|<
 *        | | | | | | | |  |           `--------'
 *        | | | | | | | |  |
 *        | | | | | | | |  |           ,--------.
 *        | | | | | | | |  `-----------|>    #1 |
 *        | | | | | | | |              |        |
 *        | | | | | | | `--------------|D0    Q0|-----|<
 *        | | | | | | `----------------|D1    Q1|-----|<
 *        | | | | | `------------------|D2    Q2|-----|<
 *        | | | | `--------------------|D3    Q3|-----|<
 *        | | | `----------------------|D4    Q4|-----|<
 *        | | `------------------------|D5    Q5|-----|<
 *        | `--------------------------|D6    Q6|-----|<
 *        `----------------------------|D7    Q7|-----|<
 *                                     `--------'
 *
 * The above is just an example. The actual number of number of latches and
 * the number of inputs per latch is derived from the number of GPIOs given
 * in the corresponding device tree properties.
 */

#include <linux/cleanup.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/delay.h>

#include "gpiolib.h"

struct gpio_latch_priv {
	struct gpio_chip gc;
	struct gpio_descs *clk_gpios;
	struct gpio_descs *latched_gpios;
	int n_latched_gpios;
	unsigned int setup_duration_ns;
	unsigned int clock_duration_ns;
	unsigned long *shadow;
	/*
	 * Depending on whether any of the underlying GPIOs may sleep we either
	 * use a mutex or a spinlock to protect our shadow map.
	 */
	union {
		struct mutex mutex; /* protects @shadow */
		spinlock_t spinlock; /* protects @shadow */
	};
};

static int gpio_latch_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	return GPIO_LINE_DIRECTION_OUT;
}

static int gpio_latch_set_unlocked(struct gpio_latch_priv *priv,
				   int (*set)(struct gpio_desc *desc, int value),
				   unsigned int offset, bool val)
{
	int latch = offset / priv->n_latched_gpios, i, ret;

	assign_bit(offset, priv->shadow, val);

	for (i = 0; i < priv->n_latched_gpios; i++) {
		ret = set(priv->latched_gpios->desc[i],
			  test_bit(latch * priv->n_latched_gpios + i,
				   priv->shadow));
		if (ret)
			return ret;
	}

	ndelay(priv->setup_duration_ns);
	set(priv->clk_gpios->desc[latch], 1);
	ndelay(priv->clock_duration_ns);
	set(priv->clk_gpios->desc[latch], 0);

	return 0;
}

static int gpio_latch_set(struct gpio_chip *gc, unsigned int offset, int val)
{
	struct gpio_latch_priv *priv = gpiochip_get_data(gc);

	guard(spinlock_irqsave)(&priv->spinlock);

	return gpio_latch_set_unlocked(priv, gpiod_set_value, offset, val);
}

static int gpio_latch_set_can_sleep(struct gpio_chip *gc, unsigned int offset, int val)
{
	struct gpio_latch_priv *priv = gpiochip_get_data(gc);

	guard(mutex)(&priv->mutex);

	return gpio_latch_set_unlocked(priv, gpiod_set_value_cansleep, offset, val);
}

static bool gpio_latch_can_sleep(struct gpio_latch_priv *priv, unsigned int n_latches)
{
	int i;

	for (i = 0; i < n_latches; i++)
		if (gpiod_cansleep(priv->clk_gpios->desc[i]))
			return true;

	for (i = 0; i < priv->n_latched_gpios; i++)
		if (gpiod_cansleep(priv->latched_gpios->desc[i]))
			return true;

	return false;
}

/*
 * Some value which is still acceptable to delay in atomic context.
 * If we need to go higher we might have to switch to usleep_range(),
 * but that cannot ne used in atomic context and the driver would have
 * to be adjusted to support that.
 */
#define DURATION_NS_MAX 5000

static int gpio_latch_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct gpio_latch_priv *priv;
	unsigned int n_latches;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->clk_gpios = devm_gpiod_get_array(dev, "clk", GPIOD_OUT_LOW);
	if (IS_ERR(priv->clk_gpios))
		return PTR_ERR(priv->clk_gpios);

	priv->latched_gpios = devm_gpiod_get_array(dev, "latched", GPIOD_OUT_LOW);
	if (IS_ERR(priv->latched_gpios))
		return PTR_ERR(priv->latched_gpios);

	n_latches = priv->clk_gpios->ndescs;
	priv->n_latched_gpios = priv->latched_gpios->ndescs;

	priv->shadow = devm_bitmap_zalloc(dev, n_latches * priv->n_latched_gpios,
					  GFP_KERNEL);
	if (!priv->shadow)
		return -ENOMEM;

	if (gpio_latch_can_sleep(priv, n_latches)) {
		priv->gc.can_sleep = true;
		priv->gc.set_rv = gpio_latch_set_can_sleep;
		mutex_init(&priv->mutex);
	} else {
		priv->gc.can_sleep = false;
		priv->gc.set_rv = gpio_latch_set;
		spin_lock_init(&priv->spinlock);
	}

	device_property_read_u32(dev, "setup-duration-ns",
				 &priv->setup_duration_ns);
	if (priv->setup_duration_ns > DURATION_NS_MAX) {
		dev_warn(dev, "setup-duration-ns too high, limit to %d\n",
			 DURATION_NS_MAX);
		priv->setup_duration_ns = DURATION_NS_MAX;
	}

	device_property_read_u32(dev, "clock-duration-ns",
				 &priv->clock_duration_ns);
	if (priv->clock_duration_ns > DURATION_NS_MAX) {
		dev_warn(dev, "clock-duration-ns too high, limit to %d\n",
			 DURATION_NS_MAX);
		priv->clock_duration_ns = DURATION_NS_MAX;
	}

	priv->gc.get_direction = gpio_latch_get_direction;
	priv->gc.ngpio = n_latches * priv->n_latched_gpios;
	priv->gc.owner = THIS_MODULE;
	priv->gc.base = -1;
	priv->gc.parent = dev;

	platform_set_drvdata(pdev, priv);

	return devm_gpiochip_add_data(dev, &priv->gc, priv);
}

static const struct of_device_id gpio_latch_ids[] = {
	{
		.compatible = "gpio-latch",
	},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, gpio_latch_ids);

static struct platform_driver gpio_latch_driver = {
	.driver	= {
		.name		= "gpio-latch",
		.of_match_table	= gpio_latch_ids,
	},
	.probe	= gpio_latch_probe,
};
module_platform_driver(gpio_latch_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
MODULE_DESCRIPTION("GPIO latch driver");
