/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright(c) 2016, Analogix Semiconductor.
 *
 * Based on anx7808 driver obtained from chromeos with copyright:
 * Copyright(c) 2013, Google Inc.
 */
#include <linux/regmap.h>

#include <drm/display/drm_dp_helper.h>
#include <drm/drm.h>
#include <drm/drm_print.h>

#include "analogix-i2c-dptx.h"

#define AUX_WAIT_TIMEOUT_MS	15
#define AUX_CH_BUFFER_SIZE	16

static int anx_i2c_dp_clear_bits(struct regmap *map, u8 reg, u8 mask)
{
	return regmap_update_bits(map, reg, mask, 0);
}

static bool anx_dp_aux_op_finished(struct regmap *map_dptx)
{
	unsigned int value;
	int err;

	err = regmap_read(map_dptx, SP_DP_AUX_CH_CTRL2_REG, &value);
	if (err < 0)
		return false;

	return (value & SP_AUX_EN) == 0;
}

static int anx_dp_aux_wait(struct regmap *map_dptx)
{
	unsigned long timeout;
	unsigned int status;
	int err;

	timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1;

	while (!anx_dp_aux_op_finished(map_dptx)) {
		if (time_after(jiffies, timeout)) {
			if (!anx_dp_aux_op_finished(map_dptx)) {
				DRM_ERROR("Timed out waiting AUX to finish\n");
				return -ETIMEDOUT;
			}

			break;
		}

		usleep_range(1000, 2000);
	}

	/* Read the AUX channel access status */
	err = regmap_read(map_dptx, SP_AUX_CH_STATUS_REG, &status);
	if (err < 0) {
		DRM_ERROR("Failed to read from AUX channel: %d\n", err);
		return err;
	}

	if (status & SP_AUX_STATUS) {
		DRM_ERROR("Failed to wait for AUX channel (status: %02x)\n",
			  status);
		return -ETIMEDOUT;
	}

	return 0;
}

static int anx_dp_aux_address(struct regmap *map_dptx, unsigned int addr)
{
	int err;

	err = regmap_write(map_dptx, SP_AUX_ADDR_7_0_REG, addr & 0xff);
	if (err)
		return err;

	err = regmap_write(map_dptx, SP_AUX_ADDR_15_8_REG,
			   (addr & 0xff00) >> 8);
	if (err)
		return err;

	/*
	 * DP AUX CH Address Register #2, only update bits[3:0]
	 * [7:4] RESERVED
	 * [3:0] AUX_ADDR[19:16], Register control AUX CH address.
	 */
	err = regmap_update_bits(map_dptx, SP_AUX_ADDR_19_16_REG,
				 SP_AUX_ADDR_19_16_MASK,
				 (addr & 0xf0000) >> 16);

	if (err)
		return err;

	return 0;
}

ssize_t anx_dp_aux_transfer(struct regmap *map_dptx,
				struct drm_dp_aux_msg *msg)
{
	u8 ctrl1 = msg->request;
	u8 ctrl2 = SP_AUX_EN;
	u8 *buffer = msg->buffer;
	int err;

	/* The DP AUX transmit and receive buffer has 16 bytes. */
	if (WARN_ON(msg->size > AUX_CH_BUFFER_SIZE))
		return -E2BIG;

	/* Zero-sized messages specify address-only transactions. */
	if (msg->size < 1)
		ctrl2 |= SP_ADDR_ONLY;
	else	/* For non-zero-sized set the length field. */
		ctrl1 |= (msg->size - 1) << SP_AUX_LENGTH_SHIFT;

	if ((msg->size > 0) && ((msg->request & DP_AUX_I2C_READ) == 0)) {
		/* When WRITE | MOT write values to data buffer */
		err = regmap_bulk_write(map_dptx,
					SP_DP_BUF_DATA0_REG, buffer,
					msg->size);
		if (err)
			return err;
	}

	/* Write address and request */
	err = anx_dp_aux_address(map_dptx, msg->address);
	if (err)
		return err;

	err = regmap_write(map_dptx, SP_DP_AUX_CH_CTRL1_REG, ctrl1);
	if (err)
		return err;

	/* Start transaction */
	err = regmap_update_bits(map_dptx, SP_DP_AUX_CH_CTRL2_REG,
				 SP_ADDR_ONLY | SP_AUX_EN, ctrl2);
	if (err)
		return err;

	err = anx_dp_aux_wait(map_dptx);
	if (err)
		return err;

	msg->reply = DP_AUX_I2C_REPLY_ACK;

	if ((msg->size > 0) && (msg->request & DP_AUX_I2C_READ)) {
		/* Read values from data buffer */
		err = regmap_bulk_read(map_dptx,
				       SP_DP_BUF_DATA0_REG, buffer,
				       msg->size);
		if (err)
			return err;
	}

	err = anx_i2c_dp_clear_bits(map_dptx, SP_DP_AUX_CH_CTRL2_REG,
				    SP_ADDR_ONLY);
	if (err)
		return err;

	return msg->size;
}
EXPORT_SYMBOL_GPL(anx_dp_aux_transfer);
