// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
 * (http://www.friendlyarm.com)
 */

#include <config.h>
#include <common.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/clk.h>
#include <i2c.h>
#include <pwm.h>

#include <irq_func.h>

#include <asm/arch/nexell.h>
#include <asm/arch/nx_gpio.h>

#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC	1000000000L
#endif

#define SAMPLE_BPS		9600
#define SAMPLE_IN_US	101		/* (1000000 / BPS) */

#define REQ_INFO		0x60U
#define REQ_BL			0x80U

#define BUS_I2C			0x18
#define ONEWIRE_I2C_BUS		2
#define ONEWIRE_I2C_ADDR	0x2f

static int bus_type = -1;
static int lcd_id = -1;
static unsigned short lcd_fwrev;
static int current_brightness = -1;
#if CONFIG_IS_ENABLED(DM_I2C)
static struct udevice *i2c_dev;
#endif

/* debug */
#if (0)
#define DBGOUT(msg...)	do { printf("onewire: " msg); } while (0)
#else
#define DBGOUT(msg...)	do {} while (0)
#endif

/* based on web page from http://lfh1986.blogspot.com */
static unsigned char crc8_ow(unsigned int v, unsigned int len)
{
	unsigned char crc = 0xACU;

	while (len--) {
		if ((crc & 0x80U) != 0) {
			crc <<= 1;
			crc ^= 0x7U;
		} else {
			crc <<= 1;
		}
		if ((v & (1U << 31)) != 0)
			crc ^= 0x7U;
		v <<= 1;
	}
	return crc;
}

/* GPIO helpers */
#define __IO_GRP		2	/* GPIOC15 */
#define __IO_IDX		15

static inline void set_pin_as_input(void)
{
	nx_gpio_set_output_enable(__IO_GRP, __IO_IDX, 0);
}

static inline void set_pin_as_output(void)
{
	nx_gpio_set_output_enable(__IO_GRP, __IO_IDX, 1);
}

static inline void set_pin_value(int v)
{
	nx_gpio_set_output_value(__IO_GRP, __IO_IDX, !!v);
}

static inline int get_pin_value(void)
{
	return nx_gpio_get_input_value(__IO_GRP, __IO_IDX);
}

/* Timer helpers */
#define PWM_CH				3
#define PWM_TCON			(PHY_BASEADDR_PWM + 0x08)
#define PWM_TCON_START		(1 << 16)
#define PWM_TINT_CSTAT		(PHY_BASEADDR_PWM + 0x44)

static int onewire_init_timer(void)
{
	int period_ns = NSEC_PER_SEC / SAMPLE_BPS;

	/* range: 1080~1970 */
	period_ns -= 1525;

	return pwm_config(PWM_CH, period_ns >> 1, period_ns);
}

static void wait_one_tick(void)
{
	unsigned int tcon;

	tcon = readl(PWM_TCON);
	tcon |= PWM_TCON_START;
	writel(tcon, PWM_TCON);

	while (1) {
		if (readl(PWM_TINT_CSTAT) & (1 << (5 + PWM_CH)))
			break;
	}

	writel((1 << (5 + PWM_CH)), PWM_TINT_CSTAT);

	tcon &= ~PWM_TCON_START;
	writel(tcon, PWM_TCON);
}

/* Session handler */
static int onewire_session(unsigned char req, unsigned char res[])
{
	unsigned int Req;
	unsigned int *Res;
	int ints = disable_interrupts();
	int i;
	int ret;

	Req = (req << 24) | (crc8_ow(req << 24, 8) << 16);
	Res = (unsigned int *)res;

	set_pin_value(1);
	set_pin_as_output();
	for (i = 0; i < 60; i++)
		wait_one_tick();

	set_pin_value(0);
	for (i = 0; i < 2; i++)
		wait_one_tick();

	for (i = 0; i < 16; i++) {
		int v = !!(Req & (1U << 31));

		Req <<= 1;
		set_pin_value(v);
		wait_one_tick();
	}

	wait_one_tick();
	set_pin_as_input();
	wait_one_tick();
	for (i = 0; i < 32; i++) {
		(*Res) <<= 1;
		(*Res) |= get_pin_value();
		wait_one_tick();
	}
	set_pin_value(1);
	set_pin_as_output();

	if (ints)
		enable_interrupts();

	ret = crc8_ow(*Res, 24) == res[0];
	DBGOUT("req = %02X, res = %02X%02X%02X%02X, ret = %d\n",
	       req, res[3], res[2], res[1], res[0], ret);

	return ret;
}

static int onewire_i2c_do_request(unsigned char req, unsigned char *buf)
{
	unsigned char tx[4];
	int ret;

	tx[0] = req;
	tx[1] = crc8_ow(req << 24, 8);

#if CONFIG_IS_ENABLED(DM_I2C)
	if (dm_i2c_write(i2c_dev, 0, tx, 2))
		return -EIO;

	if (!buf)
		return 0;

	if (dm_i2c_read(i2c_dev, 0, buf, 4))
		return -EIO;
#else
	if (i2c_write(ONEWIRE_I2C_ADDR, 0, 0, tx, 2))
		return -EIO;

	if (!buf) /* NO READ */
		return 0;

	if (i2c_read(ONEWIRE_I2C_ADDR, 0, 0, buf, 4))
		return -EIO;
#endif

	ret = crc8_ow((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8), 24);
	DBGOUT("req = %02X, res = %02X%02X%02X%02X, ret = %02x\n",
	       req, buf[0], buf[1], buf[2], buf[3], ret);

	return (ret == buf[3]) ? 0 : -EIO;
}

static void onewire_i2c_init(void)
{
	unsigned char buf[4];
	int ret;

#if CONFIG_IS_ENABLED(DM_I2C)
	ret = i2c_get_chip_for_busnum(ONEWIRE_I2C_BUS,
				      ONEWIRE_I2C_ADDR, 0, &i2c_dev);
#else
	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
	i2c_set_bus_num(ONEWIRE_I2C_BUS);

	ret = i2c_probe(ONEWIRE_I2C_ADDR);
#endif
	if (ret)
		return;

	ret = onewire_i2c_do_request(REQ_INFO, buf);
	if (!ret) {
		lcd_id = buf[0];
		lcd_fwrev = buf[1] * 0x100 + buf[2];
		bus_type = BUS_I2C;
	}
}

void onewire_init(void)
{
	/* GPIO, Pull-off */
	nx_gpio_set_pad_function(__IO_GRP, __IO_IDX, 1);
	nx_gpio_set_pull_mode(__IO_GRP, __IO_IDX, 2);

	onewire_init_timer();
	onewire_i2c_init();
}

int onewire_get_info(unsigned char *lcd, unsigned short *fw_ver)
{
	unsigned char res[4];
	int i;

	if (bus_type == BUS_I2C && lcd_id > 0) {
		*lcd = lcd_id;
		*fw_ver = lcd_fwrev;
		return 0;
	}

	for (i = 0; i < 3; i++) {
		if (onewire_session(REQ_INFO, res)) {
			*lcd = res[3];
			*fw_ver = res[2] * 0x100 + res[1];
			lcd_id = *lcd;
			DBGOUT("lcd = %d, fw_ver = %x\n", *lcd, *fw_ver);
			return 0;
		}
	}

	/* LCD unknown or not connected */
	*lcd = 0;
	*fw_ver = -1;

	return -1;
}

int onewire_get_lcd_id(void)
{
	return lcd_id;
}

int onewire_set_backlight(int brightness)
{
	unsigned char res[4];
	int i;

	if (brightness == current_brightness)
		return 0;

	if (brightness > 127)
		brightness = 127;
	else if (brightness < 0)
		brightness = 0;

	if (bus_type == BUS_I2C) {
		onewire_i2c_do_request((REQ_BL | brightness), NULL);
		current_brightness = brightness;
		return 0;
	}

	for (i = 0; i < 3; i++) {
		if (onewire_session((REQ_BL | brightness), res)) {
			current_brightness = brightness;
			return 0;
		}
	}

	return -1;
}
