/*
 * Copyright (c) 2012, 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/types.h>
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <mach/qdsp6v2/apr.h>
#include <mach/qdsp6v2/apr_tal.h>
#include <mach/qdsp6v2/dsp_debug.h>

static const char *lpass_subsys_name = "adsp";

struct apr_svc *apr_register(char *dest, char *svc_name, apr_fn svc_fn,
			     uint32_t src_port, void *priv)
{
	struct apr_client *client;
	int client_id = 0;
	int svc_idx = 0;
	int svc_id = 0;
	int dest_id = 0;
	int temp_port = 0;
	struct apr_svc *svc = NULL;
	int rc = 0;

	if (!dest || !svc_name || !svc_fn)
		return NULL;

	if (!strncmp(dest, "ADSP", 4))
		dest_id = APR_DEST_QDSP6;
	else if (!strncmp(dest, "MODEM", 5)) {
		dest_id = APR_DEST_MODEM;
	} else {
		pr_err("APR: wrong destination\n");
		goto done;
	}

	if ((dest_id == APR_DEST_QDSP6)) {
		if (apr_get_q6_state() != APR_SUBSYS_LOADED) {
			pr_err("%s: adsp not up\n", __func__);
			return NULL;
		}
		pr_debug("%s: adsp Up\n", __func__);
	} else if ((dest_id == APR_DEST_MODEM) &&
		   (apr_get_modem_state() == APR_SUBSYS_DOWN)) {
		pr_debug("%s: Wait for modem to bootup\n", __func__);
		rc = apr_wait_for_device_up(dest_id);
		if (rc == 0) {
			pr_err("%s: Modem is not Up\n", __func__);
			return NULL;
		}
		pr_debug("%s: modem Up\n", __func__);
	}

	if (apr_get_svc(svc_name, dest_id, &client_id, &svc_idx, &svc_id)) {
		pr_err("%s: apr_get_svc failed\n", __func__);
		goto done;
	}

	/* APRv2 doen't load ADSP image automatically */

	client = apr_get_client(dest_id, client_id);
	mutex_lock(&client->m_lock);
	if (!client->handle) {
		client->handle = apr_tal_open(client_id, dest_id, APR_DL_SMD,
					      apr_cb_func, NULL);
		if (!client->handle) {
			svc = NULL;
			pr_err("APR: Unable to open handle\n");
			mutex_unlock(&client->m_lock);
			goto done;
		}
	}
	mutex_unlock(&client->m_lock);
	svc = &client->svc[svc_idx];
	mutex_lock(&svc->m_lock);
	client->id = client_id;
	if (svc->need_reset) {
		mutex_unlock(&svc->m_lock);
		pr_err("APR: Service needs reset\n");
		goto done;
	}
	svc->priv = priv;
	svc->id = svc_id;
	svc->dest_id = dest_id;
	svc->client_id = client_id;
	if (src_port != 0xFFFFFFFF) {
		temp_port = ((src_port >> 8) * 8) + (src_port & 0xFF);
		pr_debug("port = %d t_port = %d\n", src_port, temp_port);
		if (temp_port >= APR_MAX_PORTS || temp_port < 0) {
			pr_err("APR: temp_port out of bounds\n");
			mutex_unlock(&svc->m_lock);
			return NULL;
		}
		if (!svc->port_cnt && !svc->svc_cnt)
			client->svc_cnt++;
		svc->port_cnt++;
		svc->port_fn[temp_port] = svc_fn;
		svc->port_priv[temp_port] = priv;
	} else {
		if (!svc->fn) {
			if (!svc->port_cnt && !svc->svc_cnt)
				client->svc_cnt++;
			svc->fn = svc_fn;
			if (svc->port_cnt)
				svc->svc_cnt++;
		}
	}

	mutex_unlock(&svc->m_lock);
done:
	return svc;
}

void apr_set_subsys_state(void)
{
	apr_set_q6_state(APR_SUBSYS_DOWN);
	apr_set_modem_state(APR_SUBSYS_UP);
}

const char *apr_get_lpass_subsys_name(void)
{
	return lpass_subsys_name;
}
