/* Copyright (c) 2010-2011, 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.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <mach/msm_smd.h>
#include <mach/qdsp6v2/apr_tal.h>

static char *svc_names[APR_DEST_MAX][APR_CLIENT_MAX] = {
	{
		"apr_audio_svc",
		"apr_voice_svc",
	},
	{
		"apr_audio_svc",
		"apr_voice_svc",
	},
};

struct apr_svc_ch_dev apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX];

int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, int len)
{
	int w_len;
	unsigned long flags;


	spin_lock_irqsave(&apr_ch->w_lock, flags);
	if (smd_write_avail(apr_ch->ch) < len) {
		spin_unlock_irqrestore(&apr_ch->w_lock, flags);
		return -EAGAIN;
	}

	w_len = smd_write(apr_ch->ch, data, len);
	spin_unlock_irqrestore(&apr_ch->w_lock, flags);
	pr_debug("apr_tal:w_len = %d\n", w_len);

	if (w_len != len) {
		pr_err("apr_tal: Error in write\n");
		return -ENETRESET;
	}
	return w_len;
}

int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data, int len)
{
	int rc = 0, retries = 0;

	if (!apr_ch->ch)
		return -EINVAL;

	do {
		if (rc == -EAGAIN)
			udelay(50);

		rc = __apr_tal_write(apr_ch, data, len);
	} while (rc == -EAGAIN && retries++ < 300);

	if (rc == -EAGAIN)
		pr_err("apr_tal: TIMEOUT for write\n");

	return rc;
}

static void apr_tal_notify(void *priv, unsigned event)
{
	struct apr_svc_ch_dev *apr_ch = priv;
	int len, r_len, sz;
	int pkt_cnt = 0;
	unsigned long flags;

	pr_debug("event = %d\n", event);
	switch (event) {
	case SMD_EVENT_DATA:
		pkt_cnt = 0;
		spin_lock_irqsave(&apr_ch->lock, flags);
check_pending:
		len = smd_read_avail(apr_ch->ch);
		if (len < 0) {
			pr_err("apr_tal: Invalid Read Event :%d\n", len);
			spin_unlock_irqrestore(&apr_ch->lock, flags);
			return;
		}
		sz = smd_cur_packet_size(apr_ch->ch);
		if (sz < 0) {
			pr_debug("pkt size is zero\n");
			spin_unlock_irqrestore(&apr_ch->lock, flags);
			return;
		}
		if (!len && !sz && !pkt_cnt)
			goto check_write_avail;
		if (!len) {
			pr_debug("len = %d pkt_cnt = %d\n", len, pkt_cnt);
			spin_unlock_irqrestore(&apr_ch->lock, flags);
			return;
		}
		r_len = smd_read_from_cb(apr_ch->ch, apr_ch->data, len);
		if (len != r_len) {
			pr_err("apr_tal: Invalid Read\n");
			spin_unlock_irqrestore(&apr_ch->lock, flags);
			return;
		}
		pkt_cnt++;
		pr_debug("%d %d %d\n", len, sz, pkt_cnt);
		if (apr_ch->func)
			apr_ch->func(apr_ch->data, r_len, apr_ch->priv);
		goto check_pending;
check_write_avail:
		if (smd_write_avail(apr_ch->ch))
			wake_up(&apr_ch->wait);
		spin_unlock_irqrestore(&apr_ch->lock, flags);
		break;
	case SMD_EVENT_OPEN:
		pr_debug("apr_tal: SMD_EVENT_OPEN\n");
		apr_ch->smd_state = 1;
		wake_up(&apr_ch->wait);
		break;
	case SMD_EVENT_CLOSE:
		pr_debug("apr_tal: SMD_EVENT_CLOSE\n");
		break;
	}
}

struct apr_svc_ch_dev *apr_tal_open(uint32_t svc, uint32_t dest,
				uint32_t dl, apr_svc_cb_fn func, void *priv)
{
	int rc;

	if ((svc >= APR_CLIENT_MAX) || (dest >= APR_DEST_MAX) ||
						(dl >= APR_DL_MAX)) {
		pr_err("apr_tal: Invalid params\n");
		return NULL;
	}

	if (apr_svc_ch[dl][dest][svc].ch) {
		pr_err("apr_tal: This channel alreday openend\n");
		return NULL;
	}

	mutex_lock(&apr_svc_ch[dl][dest][svc].m_lock);
	if (!apr_svc_ch[dl][dest][svc].dest_state) {
		rc = wait_event_timeout(apr_svc_ch[dl][dest][svc].dest,
			apr_svc_ch[dl][dest][svc].dest_state,
				msecs_to_jiffies(APR_OPEN_TIMEOUT_MS));
		if (rc == 0) {
			pr_err("apr_tal:open timeout\n");
			mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);
			return NULL;
		}
		pr_debug("apr_tal:Wakeup done\n");
		apr_svc_ch[dl][dest][svc].dest_state = 0;
	}
	rc = smd_named_open_on_edge(svc_names[dest][svc], dest,
			&apr_svc_ch[dl][dest][svc].ch,
			&apr_svc_ch[dl][dest][svc],
			apr_tal_notify);
	if (rc < 0) {
		pr_err("apr_tal: smd_open failed %s\n",
					svc_names[dest][svc]);
		mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);
		return NULL;
	}
	rc = wait_event_timeout(apr_svc_ch[dl][dest][svc].wait,
		(apr_svc_ch[dl][dest][svc].smd_state == 1), 5 * HZ);
	if (rc == 0) {
		pr_err("apr_tal:TIMEOUT for OPEN event\n");
		mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);
		apr_tal_close(&apr_svc_ch[dl][dest][svc]);
		return NULL;
	}
	if (!apr_svc_ch[dl][dest][svc].dest_state) {
		apr_svc_ch[dl][dest][svc].dest_state = 1;
		pr_debug("apr_tal:Waiting for apr svc init\n");
		msleep(200);
		pr_debug("apr_tal:apr svc init done\n");
	}
	apr_svc_ch[dl][dest][svc].smd_state = 0;

	apr_svc_ch[dl][dest][svc].func = func;
	apr_svc_ch[dl][dest][svc].priv = priv;
	mutex_unlock(&apr_svc_ch[dl][dest][svc].m_lock);

	return &apr_svc_ch[dl][dest][svc];
}

int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
{
	int r;

	if (!apr_ch->ch)
		return -EINVAL;

	mutex_lock(&apr_ch->m_lock);
	r = smd_close(apr_ch->ch);
	apr_ch->ch = NULL;
	apr_ch->func = NULL;
	apr_ch->priv = NULL;
	mutex_unlock(&apr_ch->m_lock);
	return r;
}

static int apr_smd_probe(struct platform_device *pdev)
{
	int dest;
	int clnt;

	if (pdev->id == APR_DEST_MODEM) {
		pr_info("apr_tal:Modem Is Up\n");
		dest = APR_DEST_MODEM;
		clnt = APR_CLIENT_VOICE;
		apr_svc_ch[APR_DL_SMD][dest][clnt].dest_state = 1;
		wake_up(&apr_svc_ch[APR_DL_SMD][dest][clnt].dest);
	} else if (pdev->id == APR_DEST_QDSP6) {
		pr_info("apr_tal:Q6 Is Up\n");
		dest = APR_DEST_QDSP6;
		clnt = APR_CLIENT_AUDIO;
		apr_svc_ch[APR_DL_SMD][dest][clnt].dest_state = 1;
		wake_up(&apr_svc_ch[APR_DL_SMD][dest][clnt].dest);
	} else
		pr_err("apr_tal:Invalid Dest Id: %d\n", pdev->id);

	return 0;
}

static struct platform_driver apr_q6_driver = {
	.probe = apr_smd_probe,
	.driver = {
		.name = "apr_audio_svc",
		.owner = THIS_MODULE,
	},
};

static struct platform_driver apr_modem_driver = {
	.probe = apr_smd_probe,
	.driver = {
		.name = "apr_voice_svc",
		.owner = THIS_MODULE,
	},
};

static int __init apr_tal_init(void)
{
	int i, j, k;

	for (i = 0; i < APR_DL_MAX; i++)
		for (j = 0; j < APR_DEST_MAX; j++)
			for (k = 0; k < APR_CLIENT_MAX; k++) {
				init_waitqueue_head(&apr_svc_ch[i][j][k].wait);
				init_waitqueue_head(&apr_svc_ch[i][j][k].dest);
				spin_lock_init(&apr_svc_ch[i][j][k].lock);
				spin_lock_init(&apr_svc_ch[i][j][k].w_lock);
				mutex_init(&apr_svc_ch[i][j][k].m_lock);
			}
	platform_driver_register(&apr_q6_driver);
	platform_driver_register(&apr_modem_driver);
	return 0;
}
device_initcall(apr_tal_init);
