// SPDX-License-Identifier: GPL-2.0
/*
 * PCF8575 I2C GPIO EXPANDER DRIVER
 *
 * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
 *
 * Vignesh R <vigneshr@ti.com>
 *
 *
 * Driver for TI PCF-8575 16-bit I2C gpio expander. Based on
 * gpio-pcf857x Linux Kernel(v4.7) driver.
 *
 * Copyright (C) 2007 David Brownell
 *
 * Add support for 8 bit expanders - like pca8574
 * Copyright (C) 2021 Lukasz Majewski - DENX Software Engineering
 *
 */

#include <dm.h>
#include <i2c.h>
#include <log.h>
#include <asm-generic/gpio.h>
#include <asm/global_data.h>
#include <linux/bitops.h>

DECLARE_GLOBAL_DATA_PTR;

struct pcf8575_chip {
	/* NOTE:  these chips have strange "quasi-bidirectional" I/O pins.
	 * We can't actually know whether a pin is configured (a) as output
	 * and driving the signal low, or (b) as input and reporting a low
	 * value ... without knowing the last value written since the chip
	 * came out of reset (if any).  We can't read the latched output.
	 * In short, the only reliable solution for setting up pin direction
	 * is to do it explicitly.
	 *
	 * Using "out" avoids that trouble.  When left initialized to zero,
	 * our software copy of the "latch" then matches the chip's all-ones
	 * reset state.  Otherwise it flags pins to be driven low.
	 */
	unsigned int out;	/* software latch */
};

/* Read/Write to I/O expander */

static int pcf8575_i2c_write(struct udevice *dev, unsigned int word)
{
	struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
	u8 buf[2] = { word & 0xff, word >> 8, };
	int ret;

	ret = dm_i2c_write(dev, 0, buf, dev_get_driver_data(dev));
	if (ret)
		printf("%s i2c write failed to addr %x\n", __func__,
		       chip->chip_addr);

	return ret;
}

static int pcf8575_i2c_read(struct udevice *dev)
{
	struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
	u8 buf[2] = {0x00, 0x00};
	int ret;

	ret = dm_i2c_read(dev, 0, buf, dev_get_driver_data(dev));
	if (ret) {
		printf("%s i2c read failed from addr %x\n", __func__,
		       chip->chip_addr);
		return ret;
	}

	return (buf[1] << 8) | buf[0];
}

static int pcf8575_direction_input(struct udevice *dev, unsigned offset)
{
	struct pcf8575_chip *plat = dev_get_plat(dev);
	int status;

	plat->out |= BIT(offset);
	status = pcf8575_i2c_write(dev, plat->out);

	return status;
}

static int pcf8575_direction_output(struct udevice *dev,
				    unsigned int offset, int value)
{
	struct pcf8575_chip *plat = dev_get_plat(dev);
	int ret;

	if (value)
		plat->out |= BIT(offset);
	else
		plat->out &= ~BIT(offset);

	ret = pcf8575_i2c_write(dev, plat->out);

	return ret;
}

static int pcf8575_get_value(struct udevice *dev, unsigned int offset)
{
	int             value;

	value = pcf8575_i2c_read(dev);

	return (value < 0) ? value : ((value & BIT(offset)) >> offset);
}

static int pcf8575_set_value(struct udevice *dev, unsigned int offset,
			     int value)
{
	return pcf8575_direction_output(dev, offset, value);
}

static int pcf8575_ofdata_plat(struct udevice *dev)
{
	struct pcf8575_chip *plat = dev_get_plat(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	int n_latch;

	/*
	 * Number of pins depends on the expander device and is specified
	 * in the struct udevice_id (as in the Linue kernel).
	 */
	uc_priv->gpio_count = dev_get_driver_data(dev) * 8;
	uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
					 "gpio-bank-name", NULL);
	if (!uc_priv->bank_name)
		uc_priv->bank_name = fdt_get_name(gd->fdt_blob,
						  dev_of_offset(dev), NULL);

	n_latch = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
				  "lines-initial-states", 0);
	plat->out = ~n_latch;

	return 0;
}

static int pcf8575_gpio_probe(struct udevice  *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);

	debug("%s GPIO controller with %d gpios probed\n",
	      uc_priv->bank_name, uc_priv->gpio_count);

	return 0;
}

static const struct dm_gpio_ops pcf8575_gpio_ops = {
	.direction_input	= pcf8575_direction_input,
	.direction_output	= pcf8575_direction_output,
	.get_value		= pcf8575_get_value,
	.set_value		= pcf8575_set_value,
};

static const struct udevice_id pcf8575_gpio_ids[] = {
	{ .compatible = "nxp,pcf8575", .data = 2 },
	{ .compatible = "ti,pcf8575", .data = 2 },
	{ .compatible = "nxp,pca8574", .data = 1 },
	{ }
};

U_BOOT_DRIVER(gpio_pcf8575) = {
	.name	= "gpio_pcf8575",
	.id	= UCLASS_GPIO,
	.ops	= &pcf8575_gpio_ops,
	.of_match = pcf8575_gpio_ids,
	.of_to_plat = pcf8575_ofdata_plat,
	.probe	= pcf8575_gpio_probe,
	.plat_auto	= sizeof(struct pcf8575_chip),
};
