// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
 *
 * Original author:
 * Ben Collins <bcollins@ubuntu.com>
 *
 * Additional work by:
 * John Brooks <john.brooks@bluecherry.net>
 */

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/uaccess.h>

#include "solo6x10.h"

static void solo_gpio_mode(struct solo_dev *solo_dev,
			   unsigned int port_mask, unsigned int mode)
{
	int port;
	unsigned int ret;

	ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_0);

	/* To set gpio */
	for (port = 0; port < 16; port++) {
		if (!((1 << port) & port_mask))
			continue;

		ret &= (~(3 << (port << 1)));
		ret |= ((mode & 3) << (port << 1));
	}

	solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_0, ret);

	/* To set extended gpio - sensor */
	ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1);

	for (port = 0; port < 16; port++) {
		if (!((1UL << (port + 16)) & port_mask))
			continue;

		if (!mode)
			ret &= ~(1UL << port);
		else
			ret |= 1UL << port;
	}

	/* Enable GPIO[31:16] */
	ret |= 0xffff0000;

	solo_reg_write(solo_dev, SOLO_GPIO_CONFIG_1, ret);
}

static void solo_gpio_set(struct solo_dev *solo_dev, unsigned int value)
{
	solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT,
		       solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) | value);
}

static void solo_gpio_clear(struct solo_dev *solo_dev, unsigned int value)
{
	solo_reg_write(solo_dev, SOLO_GPIO_DATA_OUT,
		       solo_reg_read(solo_dev, SOLO_GPIO_DATA_OUT) & ~value);
}

static void solo_gpio_config(struct solo_dev *solo_dev)
{
	/* Video reset */
	solo_gpio_mode(solo_dev, 0x30, 1);
	solo_gpio_clear(solo_dev, 0x30);
	udelay(100);
	solo_gpio_set(solo_dev, 0x30);
	udelay(100);

	/* Warning: Don't touch the next line unless you're sure of what
	 * you're doing: first four gpio [0-3] are used for video. */
	solo_gpio_mode(solo_dev, 0x0f, 2);

	/* We use bit 8-15 of SOLO_GPIO_CONFIG_0 for relay purposes */
	solo_gpio_mode(solo_dev, 0xff00, 1);

	/* Initially set relay status to 0 */
	solo_gpio_clear(solo_dev, 0xff00);

	/* Set input pins direction */
	solo_gpio_mode(solo_dev, 0xffff0000, 0);
}

#ifdef CONFIG_GPIOLIB
/* Pins 0-7 are not exported, because it seems from code above they are
 * used for internal purposes. So offset 0 corresponds to pin 8, therefore
 * offsets 0-7 are relay GPIOs, 8-23 - input GPIOs.
 */
static int solo_gpiochip_get_direction(struct gpio_chip *chip,
				       unsigned int offset)
{
	int ret, mode;
	struct solo_dev *solo_dev = gpiochip_get_data(chip);

	if (offset < 8) {
		ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_0);
		mode = 3 & (ret >> ((offset + 8) * 2));
	} else {
		ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1);
		mode =  1 & (ret >> (offset - 8));
	}

	if (!mode)
		return 1;
	else if (mode == 1)
		return 0;

	return -1;
}

static int solo_gpiochip_direction_input(struct gpio_chip *chip,
					 unsigned int offset)
{
	return -1;
}

static int solo_gpiochip_direction_output(struct gpio_chip *chip,
					  unsigned int offset, int value)
{
	return -1;
}

static int solo_gpiochip_get(struct gpio_chip *chip,
						unsigned int offset)
{
	int ret;
	struct solo_dev *solo_dev = gpiochip_get_data(chip);

	ret = solo_reg_read(solo_dev, SOLO_GPIO_DATA_IN);

	return 1 & (ret >> (offset + 8));
}

static void solo_gpiochip_set(struct gpio_chip *chip,
						unsigned int offset, int value)
{
	struct solo_dev *solo_dev = gpiochip_get_data(chip);

	if (value)
		solo_gpio_set(solo_dev, 1 << (offset + 8));
	else
		solo_gpio_clear(solo_dev, 1 << (offset + 8));
}
#endif

int solo_gpio_init(struct solo_dev *solo_dev)
{
#ifdef CONFIG_GPIOLIB
	int ret;
#endif

	solo_gpio_config(solo_dev);
#ifdef CONFIG_GPIOLIB
	solo_dev->gpio_dev.label = SOLO6X10_NAME"_gpio";
	solo_dev->gpio_dev.parent = &solo_dev->pdev->dev;
	solo_dev->gpio_dev.owner = THIS_MODULE;
	solo_dev->gpio_dev.base = -1;
	solo_dev->gpio_dev.ngpio = 24;
	solo_dev->gpio_dev.can_sleep = 0;

	solo_dev->gpio_dev.get_direction = solo_gpiochip_get_direction;
	solo_dev->gpio_dev.direction_input = solo_gpiochip_direction_input;
	solo_dev->gpio_dev.direction_output = solo_gpiochip_direction_output;
	solo_dev->gpio_dev.get = solo_gpiochip_get;
	solo_dev->gpio_dev.set = solo_gpiochip_set;

	ret = gpiochip_add_data(&solo_dev->gpio_dev, solo_dev);

	if (ret) {
		solo_dev->gpio_dev.label = NULL;
		return -1;
	}
#endif
	return 0;
}

void solo_gpio_exit(struct solo_dev *solo_dev)
{
#ifdef CONFIG_GPIOLIB
	if (solo_dev->gpio_dev.label) {
		gpiochip_remove(&solo_dev->gpio_dev);
		solo_dev->gpio_dev.label = NULL;
	}
#endif
	solo_gpio_clear(solo_dev, 0x30);
	solo_gpio_config(solo_dev);
}
