/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
* *
This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* *
This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* *
You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
Description:
*/

#include <amlogic/aml_led.h>

#define LED_DEFAULT_PWM_FREQ 100000
#define FIN_FREQ (24 * 1000)
#define DUTY_MAX 1024

static struct aml_led pwm_led;
static unsigned int ledmode = -1;

static int pwm_calc(int duty, unsigned int pwm_freq, unsigned int *setting)
{
	unsigned int div;
	unsigned int pwm_cnt;
	unsigned int pwm_lo, pwm_hi;

	if (duty < 0)
		duty = 0;
	else if (duty > DUTY_MAX)
		duty = DUTY_MAX;

	for (div = 0; div < 0x7f; div++) {
		pwm_cnt = FIN_FREQ * 1000 / (pwm_freq * (div + 1)) - 2;
		if (pwm_cnt <= 0xffff)
			break;
	}

	if (duty == 0) {
		pwm_hi = 0;
		pwm_lo = pwm_cnt;
	}
	else if (duty == DUTY_MAX) {
		pwm_hi = pwm_cnt;
		pwm_lo = 0;
	}
	else {
		pwm_hi = pwm_cnt * duty;
		pwm_hi /= DUTY_MAX;
		pwm_lo = pwm_cnt - pwm_hi;
	}

	setting[0] = div;
	setting[1] = pwm_lo;
	setting[2] = pwm_hi;
	return 0;
}

/*
static void pled_gpio_ctrl(int on)
{
	unsigned int value;

	value = readl(AO_RTI_PIN_MUX_REG);
	value &= ~(3<<19);
	writel(value, AO_RTI_PIN_MUX_REG);
	value = readl(AO_GPIO_O_EN_N);
	value &= ~((1<<11)|(1<<27));
#ifdef CONFIG_LED_PWM_INVERT
	on = !on;
#endif
	value |= (on<<27);
	//printf("on=%d, value=0x%x\n", on, value);
	writel(value, AO_GPIO_O_EN_N);
}
*/

static void pled_mux_to_pwm(void)
{
	unsigned int value;
	// GPIOAO_11 mux as PWM_AO_A
	value = readl(AO_RTI_PIN_MUX_REG);
	value |= (1<<19);
	value &= ~(1<<20);
	writel(value, AO_RTI_PIN_MUX_REG);
}

static void pled_set_brightness(int brightness)
{
	unsigned int value;
	unsigned int setting[3] = {0};

#ifdef CONFIG_LED_PWM_INVERT
	brightness = DUTY_MAX - brightness;
#endif
	pwm_calc(brightness, LED_DEFAULT_PWM_FREQ, &setting[0]);

	value = readl(AO_PWM_MISC_REG_AB);
	// clk div
	value &= ~(0x7f<<8);
	value |= (setting[0]<<8);
	//clk enable
	value |= 1<<15;
	writel(value, AO_PWM_MISC_REG_AB);
	// duty cycle
	writel((setting[2] << 16) | setting[1], AO_PWM_PWM_A);

	// enable PWM_AO_A
	value = readl(AO_PWM_MISC_REG_AB);
	value |= 0x3;
	writel(value, AO_PWM_MISC_REG_AB);
}

static struct coord breath_inflections[]= {
	{0, 0},
	{1000, 80},
	{2000, 256},
	{2500, 512},
	{3000, 1024},
	{3200, 1024},
	{4200, 512},
	{5200, 256},
	{7200, 80},
	{9200, 0},
	{9400, 0},
};

struct aml_led_config pled_config = {
	.off_brightness = 0,
	.on_brightness = DUTY_MAX,
	.flash_off_brightness = 0,
	.flash_off_time = 350,
	.flash_on_brightness = DUTY_MAX,
	.flash_on_time = 400,
	.breath_inflections = breath_inflections,
	.breath_inflections_num = 11,
	.set_brightness = pled_set_brightness,
};

/*
 * for suspend
 */
void pled_suspend_init(void)
{
	if (ledmode == -1)
		return;
	pled_mux_to_pwm();
	aml_led_init(&pwm_led, &pled_config);
	//if (lwm_get_suspend(ledmode) == SHUTDOWN_MODE)
		aml_led_event(&pwm_led, LED_EVENT_FLASH, 3);
	if (lwm_get_standby(ledmode) == LWM_ON)
		aml_led_event(&pwm_led, LED_EVENT_ON, 0);
	else if(lwm_get_standby(ledmode) == LWM_FLASH)
		aml_led_event(&pwm_led, LED_EVENT_FLASH, 0);
	else if(lwm_get_standby(ledmode) == LWM_BREATH)
		aml_led_event(&pwm_led, LED_EVENT_BREATH, 0);
	else
		aml_led_event(&pwm_led, LED_EVENT_OFF, 0);
}

void pled_suspend_timer_proc(void)
{
	if (ledmode == -1)
		return;
	aml_led_timer_proc(&pwm_led);
}

/*
 * for scp
 */
static void pled_scp_init(int mode)
{
	ledmode = mode;
	pled_mux_to_pwm();
}

static void pled_scp_timer_proc(int count)
{
	int mod = 2;

	if (lwm_get_suspend(ledmode) == RECOVERY_MODE)
		mod = 3;
	if (count%mod)
		pled_set_brightness(pled_config.flash_on_brightness);
	else
		pled_set_brightness(pled_config.flash_off_brightness);
}

struct scp_led pwm_scp_led = {
	.count = 0,
	.init = pled_scp_init,
	.timer_proc = pled_scp_timer_proc,
};
