// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Marvell 88E6xxx Switch Global 2 Scratch & Misc Registers support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
 * Copyright (c) 2017 National Instruments
 *      Brandon Streiff <brandon.streiff@ni.com>
 */

#include "chip.h"
#include "global2.h"

/* Offset 0x1A: Scratch and Misc. Register */
static int mv88e6xxx_g2_scratch_read(struct mv88e6xxx_chip *chip, int reg,
				     u8 *data)
{
	u16 value;
	int err;

	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
				 reg << 8);
	if (err)
		return err;

	err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, &value);
	if (err)
		return err;

	*data = (value & MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK);

	return 0;
}

static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg,
				      u8 data)
{
	u16 value = (reg << 8) | data;

	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
				  MV88E6XXX_G2_SCRATCH_MISC_UPDATE | value);
}

/**
 * mv88e6xxx_g2_scratch_get_bit - get a bit
 * @chip: chip private data
 * @base_reg: base of scratch bits
 * @offset: index of bit within the register
 * @set: is bit set?
 */
static int mv88e6xxx_g2_scratch_get_bit(struct mv88e6xxx_chip *chip,
					int base_reg, unsigned int offset,
					int *set)
{
	int reg = base_reg + (offset / 8);
	u8 mask = (1 << (offset & 0x7));
	u8 val;
	int err;

	err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
	if (err)
		return err;

	*set = !!(mask & val);

	return 0;
}

/**
 * mv88e6xxx_g2_scratch_set_bit - set (or clear) a bit
 * @chip: chip private data
 * @base_reg: base of scratch bits
 * @offset: index of bit within the register
 * @set: should this bit be set?
 *
 * Helper function for dealing with the direction and data registers.
 */
static int mv88e6xxx_g2_scratch_set_bit(struct mv88e6xxx_chip *chip,
					int base_reg, unsigned int offset,
					int set)
{
	int reg = base_reg + (offset / 8);
	u8 mask = (1 << (offset & 0x7));
	u8 val;
	int err;

	err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
	if (err)
		return err;

	if (set)
		val |= mask;
	else
		val &= ~mask;

	return mv88e6xxx_g2_scratch_write(chip, reg, val);
}

/**
 * mv88e6352_g2_scratch_gpio_get_data - get data on gpio pin
 * @chip: chip private data
 * @pin: gpio index
 *
 * Return: 0 for low, 1 for high, negative error
 */
static int mv88e6352_g2_scratch_gpio_get_data(struct mv88e6xxx_chip *chip,
					      unsigned int pin)
{
	int val = 0;
	int err;

	err = mv88e6xxx_g2_scratch_get_bit(chip,
					   MV88E6352_G2_SCRATCH_GPIO_DATA0,
					   pin, &val);
	if (err)
		return err;

	return val;
}

/**
 * mv88e6352_g2_scratch_gpio_set_data - set data on gpio pin
 * @chip: chip private data
 * @pin: gpio index
 * @value: value to set
 */
static int mv88e6352_g2_scratch_gpio_set_data(struct mv88e6xxx_chip *chip,
					      unsigned int pin, int value)
{
	u8 mask = (1 << (pin & 0x7));
	int offset = (pin / 8);
	int reg;

	reg = MV88E6352_G2_SCRATCH_GPIO_DATA0 + offset;

	if (value)
		chip->gpio_data[offset] |= mask;
	else
		chip->gpio_data[offset] &= ~mask;

	return mv88e6xxx_g2_scratch_write(chip, reg, chip->gpio_data[offset]);
}

/**
 * mv88e6352_g2_scratch_gpio_get_dir - get direction of gpio pin
 * @chip: chip private data
 * @pin: gpio index
 *
 * Return: 0 for output, 1 for input (same as GPIOF_DIR_XXX).
 */
static int mv88e6352_g2_scratch_gpio_get_dir(struct mv88e6xxx_chip *chip,
					     unsigned int pin)
{
	int val = 0;
	int err;

	err = mv88e6xxx_g2_scratch_get_bit(chip,
					   MV88E6352_G2_SCRATCH_GPIO_DIR0,
					   pin, &val);
	if (err)
		return err;

	return val;
}

/**
 * mv88e6352_g2_scratch_gpio_set_dir - set direction of gpio pin
 * @chip: chip private data
 * @pin: gpio index
 * @input: should the gpio be an input, or an output?
 */
static int mv88e6352_g2_scratch_gpio_set_dir(struct mv88e6xxx_chip *chip,
					     unsigned int pin, bool input)
{
	int value = (input ? MV88E6352_G2_SCRATCH_GPIO_DIR_IN :
			     MV88E6352_G2_SCRATCH_GPIO_DIR_OUT);

	return mv88e6xxx_g2_scratch_set_bit(chip,
					    MV88E6352_G2_SCRATCH_GPIO_DIR0,
					    pin, value);
}

/**
 * mv88e6352_g2_scratch_gpio_get_pctl - get pin control setting
 * @chip: chip private data
 * @pin: gpio index
 * @func: function number
 *
 * Note that the function numbers themselves may vary by chipset.
 */
static int mv88e6352_g2_scratch_gpio_get_pctl(struct mv88e6xxx_chip *chip,
					      unsigned int pin, int *func)
{
	int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
	int offset = (pin & 0x1) ? 4 : 0;
	u8 mask = (0x7 << offset);
	int err;
	u8 val;

	err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
	if (err)
		return err;

	*func = (val & mask) >> offset;

	return 0;
}

/**
 * mv88e6352_g2_scratch_gpio_set_pctl - set pin control setting
 * @chip: chip private data
 * @pin: gpio index
 * @func: function number
 */
static int mv88e6352_g2_scratch_gpio_set_pctl(struct mv88e6xxx_chip *chip,
					      unsigned int pin, int func)
{
	int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
	int offset = (pin & 0x1) ? 4 : 0;
	u8 mask = (0x7 << offset);
	int err;
	u8 val;

	err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
	if (err)
		return err;

	val = (val & ~mask) | ((func & mask) << offset);

	return mv88e6xxx_g2_scratch_write(chip, reg, val);
}

const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
	.get_data = mv88e6352_g2_scratch_gpio_get_data,
	.set_data = mv88e6352_g2_scratch_gpio_set_data,
	.get_dir = mv88e6352_g2_scratch_gpio_get_dir,
	.set_dir = mv88e6352_g2_scratch_gpio_set_dir,
	.get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
	.set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
};

/**
 * mv88e6xxx_g2_scratch_gpio_set_smi - set gpio muxing for external smi
 * @chip: chip private data
 * @external: set mux for external smi, or free for gpio usage
 *
 * Some mv88e6xxx models have GPIO pins that may be configured as
 * an external SMI interface, or they may be made free for other
 * GPIO uses.
 */
int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
				      bool external)
{
	int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
	int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
	int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
	bool no_cpu;
	u8 p0_mode;
	int err;
	u8 val;

	err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
	if (err)
		return err;

	p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;

	if (p0_mode == 0x01 || p0_mode == 0x02)
		return -EBUSY;

	err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
	if (err)
		return err;

	no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);

	err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
	if (err)
		return err;

	/* NO_CPU being 0 inverts the meaning of the bit */
	if (!no_cpu)
		external = !external;

	if (external)
		val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
	else
		val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;

	return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
}
