// 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 <asm/arch/pwm.h>
#include <i2c.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 s5p_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;
}
