/* Copyright (c) 2016, 2018, The Linux Foundation. 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 version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#define pr_fmt(fmt)	"%s: " fmt, __func__

#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/iopoll.h>
#include <linux/types.h>
#include <linux/extcon.h>
#include <linux/gcd.h>

#include "mdss_hdmi_audio.h"
#include "mdss_hdmi_util.h"

#define HDMI_AUDIO_INFO_FRAME_PACKET_HEADER 0x84
#define HDMI_AUDIO_INFO_FRAME_PACKET_VERSION 0x1
#define HDMI_AUDIO_INFO_FRAME_PACKET_LENGTH 0x0A

#define HDMI_KHZ_TO_HZ 1000
#define HDMI_MHZ_TO_HZ 1000000
#define HDMI_ACR_N_MULTIPLIER 128
#define DEFAULT_AUDIO_SAMPLE_RATE_HZ 48000

/* Supported HDMI Audio channels */
enum hdmi_audio_channels {
	AUDIO_CHANNEL_2 = 2,
	AUDIO_CHANNEL_3,
	AUDIO_CHANNEL_4,
	AUDIO_CHANNEL_5,
	AUDIO_CHANNEL_6,
	AUDIO_CHANNEL_7,
	AUDIO_CHANNEL_8,
};

/* parameters for clock regeneration */
struct hdmi_audio_acr {
	u32 n;
	u32 cts;
};

enum hdmi_audio_sample_rates {
	AUDIO_SAMPLE_RATE_32KHZ,
	AUDIO_SAMPLE_RATE_44_1KHZ,
	AUDIO_SAMPLE_RATE_48KHZ,
	AUDIO_SAMPLE_RATE_88_2KHZ,
	AUDIO_SAMPLE_RATE_96KHZ,
	AUDIO_SAMPLE_RATE_176_4KHZ,
	AUDIO_SAMPLE_RATE_192KHZ,
	AUDIO_SAMPLE_RATE_MAX
};

struct hdmi_audio {
	struct mdss_io_data *io;
	struct msm_hdmi_audio_setup_params params;
	struct extcon_dev sdev;
	u32 pclk;
	bool ack_enabled;
	bool audio_ack_enabled;
	atomic_t ack_pending;
};

static void hdmi_audio_get_audio_sample_rate(u32 *sample_rate_hz)
{
	u32 rate = *sample_rate_hz;

	switch (rate) {
	case 32000:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_32KHZ;
		break;
	case 44100:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_44_1KHZ;
		break;
	case 48000:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_48KHZ;
		break;
	case 88200:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_88_2KHZ;
		break;
	case 96000:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_96KHZ;
		break;
	case 176400:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_176_4KHZ;
		break;
	case 192000:
		*sample_rate_hz = AUDIO_SAMPLE_RATE_192KHZ;
		break;
	default:
		pr_debug("%d unchanged\n", rate);
		break;
	}
}

static void hdmi_audio_get_acr_param(u32 pclk, u32 fs,
	struct hdmi_audio_acr *acr)
{
	u32 div, mul;

	if (!acr) {
		pr_err("invalid data\n");
		return;
	}

	/*
	 * as per HDMI specification, N/CTS = (128*fs)/pclk.
	 * get the ratio using this formula.
	 */
	acr->n = HDMI_ACR_N_MULTIPLIER * fs;
	acr->cts = pclk;

	/* get the greatest common divisor for the ratio */
	div = gcd(acr->n, acr->cts);

	/* get the n and cts values wrt N/CTS formula */
	acr->n /= div;
	acr->cts /= div;

	/*
	 * as per HDMI specification, 300 <= 128*fs/N <= 1500
	 * with a target of 128*fs/N = 1000. To get closest
	 * value without truncating fractional values, find
	 * the corresponding multiplier
	 */
	mul = ((HDMI_ACR_N_MULTIPLIER * fs / HDMI_KHZ_TO_HZ)
		+ (acr->n - 1)) / acr->n;

	acr->n *= mul;
	acr->cts *= mul;
}

static void hdmi_audio_acr_enable(struct hdmi_audio *audio)
{
	struct mdss_io_data *io;
	struct hdmi_audio_acr acr;
	struct msm_hdmi_audio_setup_params *params;
	u32 pclk, layout, multiplier = 1, sample_rate;
	u32 acr_pkt_ctl, aud_pkt_ctl2, acr_reg_cts, acr_reg_n;

	if (!audio) {
		pr_err("invalid input\n");
		return;
	}

	io = audio->io;
	params = &audio->params;
	pclk = audio->pclk;
	sample_rate = params->sample_rate_hz;

	hdmi_audio_get_acr_param(pclk * HDMI_KHZ_TO_HZ, sample_rate, &acr);
	hdmi_audio_get_audio_sample_rate(&sample_rate);

	layout = params->num_of_channels == AUDIO_CHANNEL_2 ? 0 : 1;

	pr_debug("n=%u, cts=%u, layout=%u\n", acr.n, acr.cts, layout);

	/* AUDIO_PRIORITY | SOURCE */
	acr_pkt_ctl = BIT(31) | BIT(8);

	switch (sample_rate) {
	case AUDIO_SAMPLE_RATE_44_1KHZ:
		acr_pkt_ctl |= 0x2 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_44_0;
		acr_reg_n = HDMI_ACR_44_1;
		break;
	case AUDIO_SAMPLE_RATE_48KHZ:
		acr_pkt_ctl |= 0x3 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_48_0;
		acr_reg_n = HDMI_ACR_48_1;
		break;
	case AUDIO_SAMPLE_RATE_192KHZ:
		multiplier = 4;
		acr.n >>= 2;

		acr_pkt_ctl |= 0x3 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_48_0;
		acr_reg_n = HDMI_ACR_48_1;
		break;
	case AUDIO_SAMPLE_RATE_176_4KHZ:
		multiplier = 4;
		acr.n >>= 2;

		acr_pkt_ctl |= 0x2 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_44_0;
		acr_reg_n = HDMI_ACR_44_1;
		break;
	case AUDIO_SAMPLE_RATE_96KHZ:
		multiplier = 2;
		acr.n >>= 1;

		acr_pkt_ctl |= 0x3 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_48_0;
		acr_reg_n = HDMI_ACR_48_1;
		break;
	case AUDIO_SAMPLE_RATE_88_2KHZ:
		multiplier = 2;
		acr.n >>= 1;

		acr_pkt_ctl |= 0x2 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_44_0;
		acr_reg_n = HDMI_ACR_44_1;
		break;
	default:
		multiplier = 1;

		acr_pkt_ctl |= 0x1 << 4;
		acr.cts <<= 12;

		acr_reg_cts = HDMI_ACR_32_0;
		acr_reg_n = HDMI_ACR_32_1;
		break;
	}

	aud_pkt_ctl2 = BIT(0) | (layout << 1);

	/* N_MULTIPLE(multiplier) */
	acr_pkt_ctl &= ~(7 << 16);
	acr_pkt_ctl |= (multiplier & 0x7) << 16;

	/* SEND | CONT */
	acr_pkt_ctl |= BIT(0) | BIT(1);

	DSS_REG_W(io, acr_reg_cts, acr.cts);
	DSS_REG_W(io, acr_reg_n, acr.n);
	DSS_REG_W(io, HDMI_ACR_PKT_CTRL, acr_pkt_ctl);
	DSS_REG_W(io, HDMI_AUDIO_PKT_CTRL2, aud_pkt_ctl2);
}

static void hdmi_audio_acr_setup(struct hdmi_audio *audio, bool on)
{
	if (on)
		hdmi_audio_acr_enable(audio);
	else
		DSS_REG_W(audio->io, HDMI_ACR_PKT_CTRL, 0);
}

static void hdmi_audio_infoframe_setup(struct hdmi_audio *audio, bool enabled)
{
	struct mdss_io_data *io = NULL;
	u32 channels, channel_allocation, level_shift, down_mix, layout;
	u32 hdmi_debug_reg = 0, audio_info_0_reg = 0, audio_info_1_reg = 0;
	u32 audio_info_ctrl_reg, aud_pck_ctrl_2_reg;
	u32 check_sum, sample_present;

	if (!audio) {
		pr_err("invalid input\n");
		return;
	}

	io = audio->io;
	if (!io->base) {
		pr_err("core io not inititalized\n");
		return;
	}

	audio_info_ctrl_reg = DSS_REG_R(io, HDMI_INFOFRAME_CTRL0);
	audio_info_ctrl_reg &= ~0xF0;

	if (!enabled)
		goto end;

	channels           = audio->params.num_of_channels - 1;
	channel_allocation = audio->params.channel_allocation;
	level_shift        = audio->params.level_shift;
	down_mix           = audio->params.down_mix;
	sample_present     = audio->params.sample_present;

	layout = audio->params.num_of_channels == AUDIO_CHANNEL_2 ? 0 : 1;
	aud_pck_ctrl_2_reg = BIT(0) | (layout << 1);
	DSS_REG_W(io, HDMI_AUDIO_PKT_CTRL2, aud_pck_ctrl_2_reg);

	audio_info_1_reg |= channel_allocation & 0xFF;
	audio_info_1_reg |= ((level_shift & 0xF) << 11);
	audio_info_1_reg |= ((down_mix & 0x1) << 15);

	check_sum = 0;
	check_sum += HDMI_AUDIO_INFO_FRAME_PACKET_HEADER;
	check_sum += HDMI_AUDIO_INFO_FRAME_PACKET_VERSION;
	check_sum += HDMI_AUDIO_INFO_FRAME_PACKET_LENGTH;
	check_sum += channels;
	check_sum += channel_allocation;
	check_sum += (level_shift & 0xF) << 3 | (down_mix & 0x1) << 7;
	check_sum &= 0xFF;
	check_sum = (u8) (256 - check_sum);

	audio_info_0_reg |= check_sum & 0xFF;
	audio_info_0_reg |= ((channels & 0x7) << 8);

	/* Enable Audio InfoFrame Transmission */
	audio_info_ctrl_reg |= 0xF0;

	if (layout) {
		/* Set the Layout bit */
		hdmi_debug_reg |= BIT(4);

		/* Set the Sample Present bits */
		hdmi_debug_reg |= sample_present & 0xF;
	}
end:
	DSS_REG_W(io, HDMI_DEBUG, hdmi_debug_reg);
	DSS_REG_W(io, HDMI_AUDIO_INFO0, audio_info_0_reg);
	DSS_REG_W(io, HDMI_AUDIO_INFO1, audio_info_1_reg);
	DSS_REG_W(io, HDMI_INFOFRAME_CTRL0, audio_info_ctrl_reg);
}

static int hdmi_audio_on(void *ctx, u32 pclk,
	struct msm_hdmi_audio_setup_params *params)
{
	struct hdmi_audio *audio = ctx;
	int rc = 0;

	if (!audio) {
		pr_err("invalid input\n");
		rc = -EINVAL;
		goto end;
	}

	audio->pclk = pclk;
	audio->params = *params;

	if (!audio->params.num_of_channels) {
		audio->params.sample_rate_hz = DEFAULT_AUDIO_SAMPLE_RATE_HZ;
		audio->params.num_of_channels = AUDIO_CHANNEL_2;
	}

	hdmi_audio_acr_setup(audio, true);
	hdmi_audio_infoframe_setup(audio, true);

	pr_debug("HDMI Audio: Enabled\n");
end:
	return rc;
}

static void hdmi_audio_off(void *ctx)
{
	struct hdmi_audio *audio = ctx;

	if (!audio) {
		pr_err("invalid input\n");
		return;
	}

	hdmi_audio_infoframe_setup(audio, false);
	hdmi_audio_acr_setup(audio, false);

	pr_debug("HDMI Audio: Disabled\n");
}

static void hdmi_audio_notify(void *ctx, int val)
{
	struct hdmi_audio *audio = ctx;
	int state = 0;
	bool switched;

	if (!audio) {
		pr_err("invalid input\n");
		return;
	}

	state = audio->sdev.state;
	if (state == val)
		return;

	if (audio->ack_enabled &&
		atomic_read(&audio->ack_pending)) {
		pr_err("%s ack pending, not notifying %s\n",
			state ? "connect" : "disconnect",
			val ? "connect" : "disconnect");
		return;
	}

	extcon_set_state_sync(&audio->sdev, 0, val);
	switched = audio->sdev.state != state;

	if (audio->ack_enabled && switched)
		atomic_set(&audio->ack_pending, 1);

	pr_debug("audio %s %s\n", switched ? "switched to" : "same as",
		audio->sdev.state ? "HDMI" : "SPKR");
}

static void hdmi_audio_ack(void *ctx, u32 ack, u32 hpd)
{
	struct hdmi_audio *audio = ctx;
	u32 ack_hpd;

	if (!audio) {
		pr_err("invalid input\n");
		return;
	}

	if (ack & AUDIO_ACK_SET_ENABLE) {
		audio->ack_enabled = ack & AUDIO_ACK_ENABLE ?
			true : false;

		pr_debug("audio ack feature %s\n",
			audio->ack_enabled ? "enabled" : "disabled");
		return;
	}

	if (!audio->ack_enabled)
		return;

	atomic_set(&audio->ack_pending, 0);

	ack_hpd = ack & AUDIO_ACK_CONNECT;

	pr_debug("acknowledging %s\n",
		ack_hpd ? "connect" : "disconnect");

	if (ack_hpd != hpd) {
		pr_debug("unbalanced audio state, ack %d, hpd %d\n",
			ack_hpd, hpd);

		hdmi_audio_notify(ctx, hpd);
	}
}

static void hdmi_audio_reset(void *ctx)
{
	struct hdmi_audio *audio = ctx;

	if (!audio) {
		pr_err("invalid input\n");
		return;
	}

	atomic_set(&audio->ack_pending, 0);
}

static void hdmi_audio_status(void *ctx, struct hdmi_audio_status *status)
{
	struct hdmi_audio *audio = ctx;

	if (!audio || !status) {
		pr_err("invalid input\n");
		return;
	}

	status->ack_enabled = audio->ack_enabled;
	status->ack_pending = atomic_read(&audio->ack_pending);
	status->switched = audio->sdev.state;
}

/**
 * hdmi_audio_register() - audio registeration function
 * @data: registeration initialization data
 *
 * This API configures audio module for client to use HDMI audio.
 * Provides audio functionalities which client can call.
 * Initializes internal data structures.
 *
 * Return: pointer to audio data that client needs to pass on
 * calling audio functions.
 */
void *hdmi_audio_register(struct hdmi_audio_init_data *data)
{
	struct hdmi_audio *audio = NULL;
	int rc = 0;

	if (!data)
		goto end;

	audio = kzalloc(sizeof(*audio), GFP_KERNEL);
	if (!audio)
		goto end;

	audio->sdev.name = "hdmi_audio";
	rc = extcon_dev_register(&audio->sdev);
	if (rc) {
		pr_err("audio switch registration failed\n");
		kzfree(audio);
		goto end;
	}

	audio->io = data->io;

	data->ops->on     = hdmi_audio_on;
	data->ops->off    = hdmi_audio_off;
	data->ops->notify = hdmi_audio_notify;
	data->ops->ack    = hdmi_audio_ack;
	data->ops->reset  = hdmi_audio_reset;
	data->ops->status = hdmi_audio_status;
end:
	return audio;
}

/**
 * hdmi_audio_unregister() - unregister audio module
 * @ctx: audio module's data
 *
 * Delete audio module's instance and allocated resources
 */
void hdmi_audio_unregister(void *ctx)
{
	struct hdmi_audio *audio = ctx;

	if (audio) {
		extcon_dev_unregister(&audio->sdev);
		kfree(ctx);
	}
}
