// SPDX-License-Identifier: GPL-2.0-only
/*
 * Support for viafb GPIO ports.
 *
 * Copyright 2009 Jonathan Corbet <corbet@lwn.net>
 */

#include <linux/spinlock.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/platform_device.h>
#include <linux/via-core.h>
#include <linux/export.h>
#include "via-gpio.h"

/*
 * The ports we know about.  Note that the port-25 gpios are not
 * mentioned in the datasheet.
 */

struct viafb_gpio {
	char *vg_name;	/* Data sheet name */
	u16 vg_io_port;
	u8  vg_port_index;
	int  vg_mask_shift;
};

static struct viafb_gpio viafb_all_gpios[] = {
	{
		.vg_name = "VGPIO0",  /* Guess - not in datasheet */
		.vg_io_port = VIASR,
		.vg_port_index = 0x25,
		.vg_mask_shift = 1
	},
	{
		.vg_name = "VGPIO1",
		.vg_io_port = VIASR,
		.vg_port_index = 0x25,
		.vg_mask_shift = 0
	},
	{
		.vg_name = "VGPIO2",  /* aka DISPCLKI0 */
		.vg_io_port = VIASR,
		.vg_port_index = 0x2c,
		.vg_mask_shift = 1
	},
	{
		.vg_name = "VGPIO3",  /* aka DISPCLKO0 */
		.vg_io_port = VIASR,
		.vg_port_index = 0x2c,
		.vg_mask_shift = 0
	},
	{
		.vg_name = "VGPIO4",  /* DISPCLKI1 */
		.vg_io_port = VIASR,
		.vg_port_index = 0x3d,
		.vg_mask_shift = 1
	},
	{
		.vg_name = "VGPIO5",  /* DISPCLKO1 */
		.vg_io_port = VIASR,
		.vg_port_index = 0x3d,
		.vg_mask_shift = 0
	},
};

#define VIAFB_NUM_GPIOS ARRAY_SIZE(viafb_all_gpios)

/*
 * This structure controls the active GPIOs, which may be a subset
 * of those which are known.
 */

struct viafb_gpio_cfg {
	struct gpio_chip gpio_chip;
	struct viafb_dev *vdev;
	struct viafb_gpio *active_gpios[VIAFB_NUM_GPIOS];
	const char *gpio_names[VIAFB_NUM_GPIOS];
};

/*
 * GPIO access functions
 */
static void via_gpio_set(struct gpio_chip *chip, unsigned int nr,
			 int value)
{
	struct viafb_gpio_cfg *cfg = gpiochip_get_data(chip);
	u8 reg;
	struct viafb_gpio *gpio;
	unsigned long flags;

	spin_lock_irqsave(&cfg->vdev->reg_lock, flags);
	gpio = cfg->active_gpios[nr];
	reg = via_read_reg(VIASR, gpio->vg_port_index);
	reg |= 0x40 << gpio->vg_mask_shift;  /* output enable */
	if (value)
		reg |= 0x10 << gpio->vg_mask_shift;
	else
		reg &= ~(0x10 << gpio->vg_mask_shift);
	via_write_reg(VIASR, gpio->vg_port_index, reg);
	spin_unlock_irqrestore(&cfg->vdev->reg_lock, flags);
}

static int via_gpio_dir_out(struct gpio_chip *chip, unsigned int nr,
			    int value)
{
	via_gpio_set(chip, nr, value);
	return 0;
}

/*
 * Set the input direction.  I'm not sure this is right; we should
 * be able to do input without disabling output.
 */
static int via_gpio_dir_input(struct gpio_chip *chip, unsigned int nr)
{
	struct viafb_gpio_cfg *cfg = gpiochip_get_data(chip);
	struct viafb_gpio *gpio;
	unsigned long flags;

	spin_lock_irqsave(&cfg->vdev->reg_lock, flags);
	gpio = cfg->active_gpios[nr];
	via_write_reg_mask(VIASR, gpio->vg_port_index, 0,
			0x40 << gpio->vg_mask_shift);
	spin_unlock_irqrestore(&cfg->vdev->reg_lock, flags);
	return 0;
}

static int via_gpio_get(struct gpio_chip *chip, unsigned int nr)
{
	struct viafb_gpio_cfg *cfg = gpiochip_get_data(chip);
	u8 reg;
	struct viafb_gpio *gpio;
	unsigned long flags;

	spin_lock_irqsave(&cfg->vdev->reg_lock, flags);
	gpio = cfg->active_gpios[nr];
	reg = via_read_reg(VIASR, gpio->vg_port_index);
	spin_unlock_irqrestore(&cfg->vdev->reg_lock, flags);
	return !!(reg & (0x04 << gpio->vg_mask_shift));
}


static struct viafb_gpio_cfg viafb_gpio_config = {
	.gpio_chip = {
		.label = "VIAFB onboard GPIO",
		.owner = THIS_MODULE,
		.direction_output = via_gpio_dir_out,
		.set = via_gpio_set,
		.direction_input = via_gpio_dir_input,
		.get = via_gpio_get,
		.base = -1,
		.ngpio = 0,
		.can_sleep = 0
	}
};

/*
 * Manage the software enable bit.
 */
static void viafb_gpio_enable(struct viafb_gpio *gpio)
{
	via_write_reg_mask(VIASR, gpio->vg_port_index, 0x02, 0x02);
}

static void viafb_gpio_disable(struct viafb_gpio *gpio)
{
	via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02);
}

#ifdef CONFIG_PM

static int viafb_gpio_suspend(void *private)
{
	return 0;
}

static int viafb_gpio_resume(void *private)
{
	int i;

	for (i = 0; i < viafb_gpio_config.gpio_chip.ngpio; i += 2)
		viafb_gpio_enable(viafb_gpio_config.active_gpios[i]);
	return 0;
}

static struct viafb_pm_hooks viafb_gpio_pm_hooks = {
	.suspend = viafb_gpio_suspend,
	.resume = viafb_gpio_resume
};
#endif /* CONFIG_PM */

static struct gpiod_lookup_table viafb_gpio_table = {
	.dev_id = "viafb-camera",
	.table = {
		GPIO_LOOKUP("via-gpio", 2, "VGPIO2", GPIO_ACTIVE_LOW),
		GPIO_LOOKUP("via-gpio", 3, "VGPIO3", GPIO_ACTIVE_HIGH),
		{ }
	},
};

/*
 * Platform device stuff.
 */
static int viafb_gpio_probe(struct platform_device *platdev)
{
	struct viafb_dev *vdev = platdev->dev.platform_data;
	struct via_port_cfg *port_cfg = vdev->port_cfg;
	int i, ngpio = 0, ret;
	struct viafb_gpio *gpio;
	unsigned long flags;

	/*
	 * Set up entries for all GPIOs which have been configured to
	 * operate as such (as opposed to as i2c ports).
	 */
	for (i = 0; i < VIAFB_NUM_PORTS; i++) {
		if (port_cfg[i].mode != VIA_MODE_GPIO)
			continue;
		for (gpio = viafb_all_gpios;
		     gpio < viafb_all_gpios + VIAFB_NUM_GPIOS; gpio++)
			if (gpio->vg_port_index == port_cfg[i].ioport_index) {
				viafb_gpio_config.active_gpios[ngpio] = gpio;
				viafb_gpio_config.gpio_names[ngpio] =
					gpio->vg_name;
				ngpio++;
			}
	}
	viafb_gpio_config.gpio_chip.ngpio = ngpio;
	viafb_gpio_config.gpio_chip.names = viafb_gpio_config.gpio_names;
	viafb_gpio_config.vdev = vdev;
	if (ngpio == 0) {
		printk(KERN_INFO "viafb: no GPIOs configured\n");
		return 0;
	}
	/*
	 * Enable the ports.  They come in pairs, with a single
	 * enable bit for both.
	 */
	spin_lock_irqsave(&viafb_gpio_config.vdev->reg_lock, flags);
	for (i = 0; i < ngpio; i += 2)
		viafb_gpio_enable(viafb_gpio_config.active_gpios[i]);
	spin_unlock_irqrestore(&viafb_gpio_config.vdev->reg_lock, flags);
	/*
	 * Get registered.
	 */
	viafb_gpio_config.gpio_chip.base = -1;  /* Dynamic */
	viafb_gpio_config.gpio_chip.label = "via-gpio";
	ret = gpiochip_add_data(&viafb_gpio_config.gpio_chip,
				&viafb_gpio_config);
	if (ret) {
		printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret);
		viafb_gpio_config.gpio_chip.ngpio = 0;
	}

	gpiod_add_lookup_table(&viafb_gpio_table);

#ifdef CONFIG_PM
	viafb_pm_register(&viafb_gpio_pm_hooks);
#endif
	return ret;
}


static void viafb_gpio_remove(struct platform_device *platdev)
{
	unsigned long flags;
	int i;

#ifdef CONFIG_PM
	viafb_pm_unregister(&viafb_gpio_pm_hooks);
#endif

	/*
	 * Get unregistered.
	 */
	if (viafb_gpio_config.gpio_chip.ngpio > 0) {
		gpiochip_remove(&viafb_gpio_config.gpio_chip);
	}
	/*
	 * Disable the ports.
	 */
	spin_lock_irqsave(&viafb_gpio_config.vdev->reg_lock, flags);
	for (i = 0; i < viafb_gpio_config.gpio_chip.ngpio; i += 2)
		viafb_gpio_disable(viafb_gpio_config.active_gpios[i]);
	viafb_gpio_config.gpio_chip.ngpio = 0;
	spin_unlock_irqrestore(&viafb_gpio_config.vdev->reg_lock, flags);
}

static struct platform_driver via_gpio_driver = {
	.driver = {
		.name = "viafb-gpio",
	},
	.probe = viafb_gpio_probe,
	.remove = viafb_gpio_remove,
};

int viafb_gpio_init(void)
{
	return platform_driver_register(&via_gpio_driver);
}

void viafb_gpio_exit(void)
{
	platform_driver_unregister(&via_gpio_driver);
}
