/*
 *   intelmid_pvt.h - Intel Sound card driver for MID
 *
 *  Copyright (C) 2008-10 Intel Corp
 *  Authors:	Harsha Priya <priya.harsha@intel.com>
 *		Vinod Koul <vinod.koul@intel.com>
 *		KP Jeeja <jeeja.kp@intel.com>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  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; version 2 of the License.
 *
 *  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.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * ALSA driver for Intel MID sound card chipset - holding private functions
 */
#include <linux/io.h>
#include <asm/intel_scu_ipc.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include "jack.h"
#include "intel_sst.h"
#include "intel_sst_ioctl.h"
#include "intelmid_snd_control.h"
#include "intelmid.h"


void period_elapsed(void *mad_substream)
{
	struct snd_pcm_substream *substream = mad_substream;
	struct mad_stream_pvt *stream;



	if (!substream || !substream->runtime)
		return;
	stream = substream->runtime->private_data;
	if (!stream)
		return;

	if (stream->stream_status != RUNNING)
		return;
	pr_debug("sst: calling period elapsed\n");
	snd_pcm_period_elapsed(substream);
	return;
}


int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream)
{
	struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
	struct mad_stream_pvt *stream = substream->runtime->private_data;
	struct snd_sst_stream_params param = {{{0,},},};
	struct snd_sst_params str_params = {0};
	int ret_val;

	/* set codec params and inform SST driver the same */

	param.uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
	param.uc.pcm_params.num_chan = (u8) substream->runtime->channels;
	param.uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
	param.uc.pcm_params.reserved = 0;
	param.uc.pcm_params.sfreq = substream->runtime->rate;
	param.uc.pcm_params.ring_buffer_size =
					snd_pcm_lib_buffer_bytes(substream);
	param.uc.pcm_params.period_count = substream->runtime->period_size;
	param.uc.pcm_params.ring_buffer_addr =
				virt_to_phys(substream->runtime->dma_area);
	pr_debug("sst: period_cnt = %d\n", param.uc.pcm_params.period_count);
	pr_debug("sst: sfreq= %d, wd_sz = %d\n",
		 param.uc.pcm_params.sfreq, param.uc.pcm_params.pcm_wd_sz);

	str_params.sparams = param;
	str_params.codec = SST_CODEC_TYPE_PCM;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		str_params.ops = STREAM_OPS_PLAYBACK;
		pr_debug("sst: Playbck stream,Device %d\n", stream->device);
	} else {
		str_params.ops = STREAM_OPS_CAPTURE;
		stream->device = SND_SST_DEVICE_CAPTURE;
		pr_debug("sst: Capture stream,Device %d\n", stream->device);
	}
	str_params.device_type = stream->device;
	ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_ALLOC,
					&str_params);
	pr_debug("sst: SST_SND_PLAY/CAPTURE ret_val = %x\n",
			ret_val);
	if (ret_val < 0)
		return ret_val;

	stream->stream_info.str_id = ret_val;
	stream->stream_status = INIT;
	stream->stream_info.buffer_ptr = 0;
	pr_debug("sst: str id :  %d\n", stream->stream_info.str_id);

	return ret_val;
}

int snd_intelmad_init_stream(struct snd_pcm_substream *substream)
{
	struct mad_stream_pvt *stream = substream->runtime->private_data;
	struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
	int ret_val;

	pr_debug("sst: setting buffer ptr param\n");
	stream->stream_info.period_elapsed = period_elapsed;
	stream->stream_info.mad_substream = substream;
	stream->stream_info.buffer_ptr = 0;
	stream->stream_info.sfreq = substream->runtime->rate;
	ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_STREAM_INIT,
					&stream->stream_info);
	if (ret_val)
		pr_err("sst: control_set ret error %d\n", ret_val);
	return ret_val;

}


/**
 * sst_sc_reg_access - IPC read/write wrapper
 *
 * @sc_access:  array of data, addresses and mask
 * @type: operation type
 * @num_val: number of reg to opertae on
 *
 * Reads/writes/read-modify operations on registers accessed through SCU (sound
 * card and few SST DSP regsisters that are not accissible to IA)
 */
int sst_sc_reg_access(struct sc_reg_access *sc_access,
					int type, int num_val)
{
	int i, retval = 0;
	if (type == PMIC_WRITE) {
		for (i = 0; i < num_val; i++) {
			retval = intel_scu_ipc_iowrite8(sc_access[i].reg_addr,
							sc_access[i].value);
			if (retval) {
				pr_err("sst: IPC write failed!!! %d\n", retval);
				return retval;
			}
		}
	} else if (type == PMIC_READ) {
		for (i = 0; i < num_val; i++) {
			retval = intel_scu_ipc_ioread8(sc_access[i].reg_addr,
							&(sc_access[i].value));
			if (retval) {
				pr_err("sst: IPC read failed!!!!!%d\n", retval);
				return retval;
			}
		}
	} else {
		for (i = 0; i < num_val; i++) {
			retval = intel_scu_ipc_update_register(
				sc_access[i].reg_addr, sc_access[i].value,
				sc_access[i].mask);
			if (retval) {
				pr_err("sst: IPC Modify failed!!!%d\n", retval);
				return retval;
			}
		}
	}
	return retval;
}
