/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
 * drivers/irblaster/aml_irblaster.c
 *
 * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
 *
 */

#include <asm/arch/io.h>
#include <asm/cpu_id.h>
#include <common.h>
#include <config.h>
#include <command.h>
#include <amlogic/aml_irblaster.h>
#include <asm/arch/secure_apb.h>

static struct aml_irblaster_drv_s irblaster_driver;
const char *protocol_name[] = {
	"NEC",
};

/*NEC key value*/
#define NEC_HEADER	9000
#define NEC_IDLE	4500
const static int  NEC_END[] = {
	560,
	560
};
const static int NEC_ONE[] = {
	560,
	1690
};
const static int NEC_ZERO[] = {
	560,
	560
};

static void get_nec_data(unsigned int value)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();
	unsigned int num = 0;
	int index;
	unsigned int *pdata = drv->windows;
	pdata[num++] = NEC_HEADER;
	pdata[num++] = NEC_IDLE;
	/*low bit first*/
	for (index = 0; index < 32; index++) {
		if (value & (0x01 << index)) {
			pdata[num++] = NEC_ONE[0];
			pdata[num++] = NEC_ONE[1];
		} else {
			pdata[num++] = NEC_ZERO[0];
			pdata[num++] = NEC_ZERO[1];
		}
	}
	pdata[num++] = NEC_END[0];
	pdata[num++] = NEC_END[1];
	drv->windows_num = num;
	drv->sendvalue = value;
}

static int send_bit(unsigned int hightime, unsigned int lowtime,
	unsigned int cycle)
{
	unsigned int count_delay;
	uint32_t val;
	int n = 0;
	int tb[3] = {
		1, 10, 100
	};

	/*
	AO_IR_BLASTER_ADDR2
	bit12: output level(or modulation enable/disable:1=enable)
	bit[11:10]: Timebase :
				00=1us
				01=10us
				10=100us
				11=Modulator clock
	bit[9:0]: Count of timebase units to delay
	*/

	count_delay = (((hightime + cycle/2) / cycle) - 1) & 0x3ff;
	val = (0x10000 | (1 << 12)) | (3 << 10) | (count_delay << 0);
	writel(val, AO_IR_BLASTER_ADDR2);

	/*
	lowtime<1024,n=0,timebase=1us
	1024<=lowtime<10240,n=1,timebase=10us
	10240<=lowtime,n=2,timebase=100us
	*/
	n = lowtime >> 10;
	if (n > 0 && n < 10)
		n = 1;
	else if (n >= 10)
		n = 2;
	lowtime = (lowtime + (tb[n] >> 1))/tb[n];
	count_delay = (lowtime-1) & 0x3ff;
	val = (0x10000 | (0 << 12)) |
		(n << 10) | (count_delay << 0);
	writel(val, AO_IR_BLASTER_ADDR2);
	return 0;
}

static void send_frame(void)
{
	int i;
	int exp = 0x00;
	unsigned int* pdata;
	unsigned int high_ct, low_ct;
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();
	unsigned int consumerir_cycle = 1000 / (drv->frequency / 1000);

	/*reset*/
	writel(readl(AO_RTI_GEN_CNTL_REG0) | (1 << 23), AO_IR_BLASTER_ADDR2);
	udelay(2);
	writel(readl(AO_RTI_GEN_CNTL_REG0) & ~(1 << 23), AO_IR_BLASTER_ADDR2);

	/*
	1. disable ir blaster
	2. set the modulator_tb = 2'10; mpeg_1uS_tick 1us
	*/
	writel((1 << 2) | (2 << 12) | (1<<2), AO_IR_BLASTER_ADDR0);
	/*
	1. set mod_high_count = 13
	2. set mod_low_count = 13
	3. 60khz 8, 38k-13us, 12
	*/
	high_ct = consumerir_cycle * drv->dutycycle/100;
	low_ct = consumerir_cycle - high_ct;
	writel(((high_ct - 1) << 16) | ((low_ct - 1) << 0),
		AO_IR_BLASTER_ADDR1);

	/* Setting this bit to 1 initializes the output to be high.*/
	writel(readl(AO_IR_BLASTER_ADDR0) & ~(1 << 2), AO_IR_BLASTER_ADDR0);

	/*enable irblaster*/
	writel(readl(AO_IR_BLASTER_ADDR0) | (1 << 0), AO_IR_BLASTER_ADDR0);
#define SEND_BIT_NUM 64
	exp = drv->windows_num / SEND_BIT_NUM;
	pdata = drv->windows;

	while (exp) {
		for (i = 0; i < SEND_BIT_NUM/2; i++) {
			send_bit(*pdata, *(pdata+1), consumerir_cycle);
			pdata += 2;
		}
		while (!(readl(AO_IR_BLASTER_ADDR0) & (1<<24))) ;
		while (readl(AO_IR_BLASTER_ADDR0) & (1<<26)) ;
		/*reset*/
		writel(readl(AO_RTI_GEN_CNTL_REG0) | (1 << 23),
			AO_RTI_GEN_CNTL_REG0);
		udelay(2);
		/*reset*/
		writel(readl(AO_RTI_GEN_CNTL_REG0) & ~(1 << 23),
			AO_RTI_GEN_CNTL_REG0);
		exp--;
	}
	exp = (drv->windows_num % SEND_BIT_NUM) & (~(1));
	for (i = 0; i < exp; ) {
		send_bit(*pdata, *(pdata+1), consumerir_cycle);
		pdata += 2;
		i += 2;
	}
}

extern void irblaster_pinmux_config(void);
static int open(void)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();

	drv->protocol = 0; /*default NEC*/
	drv->frequency = 38000; /*freq 38k*/

	/*pinmux*/
	irblaster_pinmux_config();
	drv->openflag = 1;
	return 0;
}

static int close(void)
{
	return 0;
}

static int send(unsigned int value)
{
	get_nec_data(value);
	send_frame();
	return 0;
}

static void print_windows(void)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();
	int n;
	unsigned int *pdata;

	pdata = drv->windows;
	n = drv->windows_num;
	printf ("sendvalue:%u\n", drv->sendvalue);
	printf ("windows_number:%d\n", n);
	printf ("windows:\n");
	while (n--)
		printf ("%d\n", *pdata++);
}

static int setprotocol(char *name)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();
	int p = 0;
	int size = sizeof(protocol_name) / sizeof(protocol_name[0]);

	for (p = 0; p < size; p++) {
		if (!strcmp(protocol_name[p], name)) {
			drv->protocol = p;
			return 0;
		}
	}
	return CMD_RET_USAGE;
}

static const char *getprocotol(void)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();
	int size = sizeof(protocol_name) / sizeof(protocol_name[0]);

	if (drv->protocol >= size)
		return NULL;
	return protocol_name[drv->protocol];
}

static int setfrequency(unsigned int freq)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();

	if (freq < 20000 || freq > 60000) {
		printf("20000<freq<60000\n");
		return CMD_RET_USAGE;
	}
	drv->frequency = freq;
	return 0;
}

static unsigned int getfrequency(void)
{
	struct aml_irblaster_drv_s *drv = aml_irblaster_get_driver();

	return drv->frequency;
}

unsigned char ci_nec_fe01[] = {
	0x01,
	0x02,
	0x03,
	0x04,
	0x05,
	0x06,
	0x07,
	0x08,
	0x09,
	0x0a,
	0x1F,
	0x15,
	0x16,
	0x0c,
	0x0d,
	0x0e,
	0x0f,
	0x11,
	0x1c,
	0x1b,
	0x19,
	0x1a,
	0x1d,
	0x17,
	0x49,
	0x43,
	0x12,
	0x14,
	0x18,
	0x59,
	0x5a,
	0x42,
	0x44,
	0x1e,
	0x4b,
	0x58,
	0x46,
	0x40,
	0x38,
	0x57,
	0x5b,
	0x54,
	0x4c,
	0x4e,
	0x55,
	0x53,
	0x52,
	0x39,
	0x41,
	0x0b,
	0x00,
	0x13
};

static int loop_test(unsigned int times)
{
	unsigned int framecode;
	int n, cnt = 0;
	int size = ARRAY_SIZE(ci_nec_fe01);

	printf("test loop...\n");
	for ( ; times--; ) {
		printf("times=%d\n", cnt++);
		for (n = 0; n < size; n++) {
			framecode = 0xfe01 | ((~ci_nec_fe01[n] & 0xff) << 24) |
				(ci_nec_fe01[n] << 16);
			printf("0x%x\n", framecode);
			get_nec_data(framecode);
			send_frame();
			mdelay(500);
		}
	}
	return 0;
}

int read_reg(volatile unsigned int *addr, unsigned int length)
{
	int n;
	int value;

	printf("read_reg\n");
	for (n = 0; n < length; n++) {
		value = readl(addr);
		printf("0x%p=0x%x\n", addr, value);
		++addr;
	}
	return 0;
}

int write_reg(volatile unsigned int *addr, unsigned int value)
{
	writel(value, addr);
	printf("0x%p=0x%x", addr, value);
	return 0;
}

static struct aml_irblaster_drv_s irblaster_driver = {
	.frequency = 38000,
	.dutycycle = 50,
	.protocol = 0,
	.windows_num = 0,
	.openflag = 0,
	.open = open,
	.close = close,
	.send = send,
	.setprotocol = setprotocol,
	.getprocotol = getprocotol,
	.setfrequency = setfrequency,
	.getfrequency = getfrequency,
	.test = loop_test,
	.print_windows = print_windows,
	.read_reg = read_reg,
	.write_reg = write_reg,
};

struct aml_irblaster_drv_s *aml_irblaster_get_driver(void)
{
	return &irblaster_driver;
}
