// SPDX-License-Identifier: GPL-2.0-or-later
/*

    bt8xx GPIO abuser

    Copyright (C) 2008 Michael Buesch <m@bues.ch>

    Please do _only_ contact the people listed _above_ with issues related to this driver.
    All the other people listed below are not related to this driver. Their names
    are only here, because this driver is derived from the bt848 driver.


    Derived from the bt848 driver:

    Copyright (C) 1996,97,98 Ralph  Metzler
			   & Marcus Metzler
    (c) 1999-2002 Gerd Knorr

    some v4l2 code lines are taken from Justin's bttv2 driver which is
    (c) 2000 Justin Schoeman

    V4L1 removal from:
    (c) 2005-2006 Nickolay V. Shmyrev

    Fixes to be fully V4L2 compliant by
    (c) 2006 Mauro Carvalho Chehab

    Cropping and overscan support
    Copyright (C) 2005, 2006 Michael H. Schimek
    Sponsored by OPQ Systems AB

*/

#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>

/* Steal the hardware definitions from the bttv driver. */
#include "../media/pci/bt8xx/bt848.h"


#define BT8XXGPIO_NR_GPIOS		24 /* We have 24 GPIO pins */


struct bt8xxgpio {
	spinlock_t lock;

	void __iomem *mmio;
	struct pci_dev *pdev;
	struct gpio_chip gpio;

#ifdef CONFIG_PM
	u32 saved_outen;
	u32 saved_data;
#endif
};

#define bgwrite(dat, adr)	writel((dat), bg->mmio+(adr))
#define bgread(adr)		readl(bg->mmio+(adr))


static int modparam_gpiobase = -1/* dynamic */;
module_param_named(gpiobase, modparam_gpiobase, int, 0444);
MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");


static int bt8xxgpio_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
{
	struct bt8xxgpio *bg = gpiochip_get_data(gpio);
	u32 outen, data;

	guard(spinlock_irqsave)(&bg->lock);

	data = bgread(BT848_GPIO_DATA);
	data &= ~(1 << nr);
	bgwrite(data, BT848_GPIO_DATA);

	outen = bgread(BT848_GPIO_OUT_EN);
	outen &= ~(1 << nr);
	bgwrite(outen, BT848_GPIO_OUT_EN);

	return 0;
}

static int bt8xxgpio_gpio_get(struct gpio_chip *gpio, unsigned nr)
{
	struct bt8xxgpio *bg = gpiochip_get_data(gpio);
	u32 val;

	guard(spinlock_irqsave)(&bg->lock);

	val = bgread(BT848_GPIO_DATA);

	return !!(val & (1 << nr));
}

static int bt8xxgpio_gpio_direction_output(struct gpio_chip *gpio,
					unsigned nr, int val)
{
	struct bt8xxgpio *bg = gpiochip_get_data(gpio);
	u32 outen, data;

	guard(spinlock_irqsave)(&bg->lock);

	outen = bgread(BT848_GPIO_OUT_EN);
	outen |= (1 << nr);
	bgwrite(outen, BT848_GPIO_OUT_EN);

	data = bgread(BT848_GPIO_DATA);
	if (val)
		data |= (1 << nr);
	else
		data &= ~(1 << nr);
	bgwrite(data, BT848_GPIO_DATA);

	return 0;
}

static int bt8xxgpio_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val)
{
	struct bt8xxgpio *bg = gpiochip_get_data(gpio);
	u32 data;

	guard(spinlock_irqsave)(&bg->lock);

	data = bgread(BT848_GPIO_DATA);
	if (val)
		data |= (1 << nr);
	else
		data &= ~(1 << nr);
	bgwrite(data, BT848_GPIO_DATA);

	return 0;
}

static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
{
	struct gpio_chip *c = &bg->gpio;

	c->label = dev_name(&bg->pdev->dev);
	c->owner = THIS_MODULE;
	c->direction_input = bt8xxgpio_gpio_direction_input;
	c->get = bt8xxgpio_gpio_get;
	c->direction_output = bt8xxgpio_gpio_direction_output;
	c->set_rv = bt8xxgpio_gpio_set;
	c->dbg_show = NULL;
	c->base = modparam_gpiobase;
	c->ngpio = BT8XXGPIO_NR_GPIOS;
	c->can_sleep = false;
}

static int bt8xxgpio_probe(struct pci_dev *dev,
			const struct pci_device_id *pci_id)
{
	struct bt8xxgpio *bg;
	int err;

	bg = devm_kzalloc(&dev->dev, sizeof(struct bt8xxgpio), GFP_KERNEL);
	if (!bg)
		return -ENOMEM;

	bg->pdev = dev;
	spin_lock_init(&bg->lock);

	err = pci_enable_device(dev);
	if (err) {
		dev_err(&dev->dev, "can't enable device.\n");
		return err;
	}
	if (!devm_request_mem_region(&dev->dev, pci_resource_start(dev, 0),
				pci_resource_len(dev, 0),
				"bt8xxgpio")) {
		dev_warn(&dev->dev, "can't request iomem (0x%llx).\n",
		       (unsigned long long)pci_resource_start(dev, 0));
		err = -EBUSY;
		goto err_disable;
	}
	pci_set_master(dev);
	pci_set_drvdata(dev, bg);

	bg->mmio = devm_ioremap(&dev->dev, pci_resource_start(dev, 0), 0x1000);
	if (!bg->mmio) {
		dev_err(&dev->dev, "ioremap() failed\n");
		err = -EIO;
		goto err_disable;
	}

	/* Disable interrupts */
	bgwrite(0, BT848_INT_MASK);

	/* gpio init */
	bgwrite(0, BT848_GPIO_DMA_CTL);
	bgwrite(0, BT848_GPIO_REG_INP);
	bgwrite(0, BT848_GPIO_OUT_EN);

	bt8xxgpio_gpio_setup(bg);
	err = gpiochip_add_data(&bg->gpio, bg);
	if (err) {
		dev_err(&dev->dev, "failed to register GPIOs\n");
		goto err_disable;
	}

	return 0;

err_disable:
	pci_disable_device(dev);

	return err;
}

static void bt8xxgpio_remove(struct pci_dev *pdev)
{
	struct bt8xxgpio *bg = pci_get_drvdata(pdev);

	gpiochip_remove(&bg->gpio);

	bgwrite(0, BT848_INT_MASK);
	bgwrite(~0x0, BT848_INT_STAT);
	bgwrite(0x0, BT848_GPIO_OUT_EN);

	pci_disable_device(pdev);
}

#ifdef CONFIG_PM
static int bt8xxgpio_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct bt8xxgpio *bg = pci_get_drvdata(pdev);

	scoped_guard(spinlock_irqsave, &bg->lock) {
		bg->saved_outen = bgread(BT848_GPIO_OUT_EN);
		bg->saved_data = bgread(BT848_GPIO_DATA);

		bgwrite(0, BT848_INT_MASK);
		bgwrite(~0x0, BT848_INT_STAT);
		bgwrite(0x0, BT848_GPIO_OUT_EN);
	}

	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));

	return 0;
}

static int bt8xxgpio_resume(struct pci_dev *pdev)
{
	struct bt8xxgpio *bg = pci_get_drvdata(pdev);
	int err;

	pci_set_power_state(pdev, PCI_D0);
	err = pci_enable_device(pdev);
	if (err)
		return err;
	pci_restore_state(pdev);

	guard(spinlock_irqsave)(&bg->lock);

	bgwrite(0, BT848_INT_MASK);
	bgwrite(0, BT848_GPIO_DMA_CTL);
	bgwrite(0, BT848_GPIO_REG_INP);
	bgwrite(bg->saved_outen, BT848_GPIO_OUT_EN);
	bgwrite(bg->saved_data & bg->saved_outen,
		BT848_GPIO_DATA);

	return 0;
}
#else
#define bt8xxgpio_suspend NULL
#define bt8xxgpio_resume NULL
#endif /* CONFIG_PM */

static const struct pci_device_id bt8xxgpio_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848) },
	{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849) },
	{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878) },
	{ PCI_DEVICE(PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879) },
	{ 0, },
};
MODULE_DEVICE_TABLE(pci, bt8xxgpio_pci_tbl);

static struct pci_driver bt8xxgpio_pci_driver = {
	.name		= "bt8xxgpio",
	.id_table	= bt8xxgpio_pci_tbl,
	.probe		= bt8xxgpio_probe,
	.remove		= bt8xxgpio_remove,
	.suspend	= bt8xxgpio_suspend,
	.resume		= bt8xxgpio_resume,
};

module_pci_driver(bt8xxgpio_pci_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michael Buesch");
MODULE_DESCRIPTION("Abuse a BT8xx framegrabber card as generic GPIO card");
