/*
 * siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
 *
 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.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; 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/module.h>

#include <asm/clock.h>
#include <asm/siu.h>

#include <sound/control.h>
#include <sound/soc.h>

#include "siu.h"

/* Board specifics */
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
# define SIU_MAX_VOLUME		0x1000
#else
# define SIU_MAX_VOLUME		0x7fff
#endif

#define PRAM_SIZE	0x2000
#define XRAM_SIZE	0x800
#define YRAM_SIZE	0x800

#define XRAM_OFFSET	0x4000
#define YRAM_OFFSET	0x6000
#define REG_OFFSET	0xc000

#define PLAYBACK_ENABLED	1
#define CAPTURE_ENABLED		2

#define VOLUME_CAPTURE		0
#define VOLUME_PLAYBACK		1
#define DFLT_VOLUME_LEVEL	0x08000800

/*
 * SPDIF is only available on port A and on some SIU implementations it is only
 * available for input. Due to the lack of hardware to test it, SPDIF is left
 * disabled in this driver version
 */
struct format_flag {
	u32	i2s;
	u32	pcm;
	u32	spdif;
	u32	mask;
};

struct port_flag {
	struct format_flag	playback;
	struct format_flag	capture;
};

struct siu_info *siu_i2s_data;

static struct port_flag siu_flags[SIU_PORT_NUM] = {
	[SIU_PORT_A] = {
		.playback = {
			.i2s	= 0x50000000,
			.pcm	= 0x40000000,
			.spdif	= 0x80000000,	/* not on all SIU versions */
			.mask	= 0xd0000000,
		},
		.capture = {
			.i2s	= 0x05000000,
			.pcm	= 0x04000000,
			.spdif	= 0x08000000,
			.mask	= 0x0d000000,
		},
	},
	[SIU_PORT_B] = {
		.playback = {
			.i2s	= 0x00500000,
			.pcm	= 0x00400000,
			.spdif	= 0,		/* impossible - turn off */
			.mask	= 0x00500000,
		},
		.capture = {
			.i2s	= 0x00050000,
			.pcm	= 0x00040000,
			.spdif	= 0,		/* impossible - turn off */
			.mask	= 0x00050000,
		},
	},
};

static void siu_dai_start(struct siu_port *port_info)
{
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;

	dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);

	/* Issue software reset to siu */
	siu_write32(base + SIU_SRCTL, 0);

	/* Wait for the reset to take effect */
	udelay(1);

	port_info->stfifo = 0;
	port_info->trdat = 0;

	/* portA, portB, SIU operate */
	siu_write32(base + SIU_SRCTL, 0x301);

	/* portA=256fs, portB=256fs */
	siu_write32(base + SIU_CKCTL, 0x40400000);

	/* portA's BRG does not divide SIUCKA */
	siu_write32(base + SIU_BRGASEL, 0);
	siu_write32(base + SIU_BRRA, 0);

	/* portB's BRG divides SIUCKB by half */
	siu_write32(base + SIU_BRGBSEL, 1);
	siu_write32(base + SIU_BRRB, 0);

	siu_write32(base + SIU_IFCTL, 0x44440000);

	/* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
	siu_write32(base + SIU_SFORM, 0x0c0c0000);

	/*
	 * Volume levels: looks like the DSP firmware implements volume controls
	 * differently from what's described in the datasheet
	 */
	siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
	siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
}

static void siu_dai_stop(struct siu_port *port_info)
{
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;

	/* SIU software reset */
	siu_write32(base + SIU_SRCTL, 0);
}

static void siu_dai_spbAselect(struct siu_port *port_info)
{
	struct siu_info *info = siu_i2s_data;
	struct siu_firmware *fw = &info->fw;
	u32 *ydef = fw->yram0;
	u32 idx;

	/* path A use */
	if (!info->port_id)
		idx = 1;		/* portA */
	else
		idx = 2;		/* portB */

	ydef[0] = (fw->spbpar[idx].ab1a << 16) |
		(fw->spbpar[idx].ab0a << 8) |
		(fw->spbpar[idx].dir << 7) | 3;
	ydef[1] = fw->yram0[1];	/* 0x03000300 */
	ydef[2] = (16 / 2) << 24;
	ydef[3] = fw->yram0[3];	/* 0 */
	ydef[4] = fw->yram0[4];	/* 0 */
	ydef[7] = fw->spbpar[idx].event;
	port_info->stfifo |= fw->spbpar[idx].stfifo;
	port_info->trdat |= fw->spbpar[idx].trdat;
}

static void siu_dai_spbBselect(struct siu_port *port_info)
{
	struct siu_info *info = siu_i2s_data;
	struct siu_firmware *fw = &info->fw;
	u32 *ydef = fw->yram0;
	u32 idx;

	/* path B use */
	if (!info->port_id)
		idx = 7;		/* portA */
	else
		idx = 8;		/* portB */

	ydef[5] = (fw->spbpar[idx].ab1a << 16) |
		(fw->spbpar[idx].ab0a << 8) | 1;
	ydef[6] = fw->spbpar[idx].event;
	port_info->stfifo |= fw->spbpar[idx].stfifo;
	port_info->trdat |= fw->spbpar[idx].trdat;
}

static void siu_dai_open(struct siu_stream *siu_stream)
{
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;
	u32 srctl, ifctl;

	srctl = siu_read32(base + SIU_SRCTL);
	ifctl = siu_read32(base + SIU_IFCTL);

	switch (info->port_id) {
	case SIU_PORT_A:
		/* portA operates */
		srctl |= 0x200;
		ifctl &= ~0xc2;
		break;
	case SIU_PORT_B:
		/* portB operates */
		srctl |= 0x100;
		ifctl &= ~0x31;
		break;
	}

	siu_write32(base + SIU_SRCTL, srctl);
	/* Unmute and configure portA */
	siu_write32(base + SIU_IFCTL, ifctl);
}

/*
 * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
 * packing is supported
 */
static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
{
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;
	u32 dpak;

	dpak = siu_read32(base + SIU_DPAK);

	switch (info->port_id) {
	case SIU_PORT_A:
		dpak &= ~0xc0000000;
		break;
	case SIU_PORT_B:
		dpak &= ~0x00c00000;
		break;
	}

	siu_write32(base + SIU_DPAK, dpak);
}

static int siu_dai_spbstart(struct siu_port *port_info)
{
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;
	struct siu_firmware *fw = &info->fw;
	u32 *ydef = fw->yram0;
	int cnt;
	u32 __iomem *add;
	u32 *ptr;

	/* Load SPB Program in PRAM */
	ptr = fw->pram0;
	add = info->pram;
	for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
		siu_write32(add, *ptr);

	ptr = fw->pram1;
	add = info->pram + (0x0100 / sizeof(u32));
	for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
		siu_write32(add, *ptr);

	/* XRAM initialization */
	add = info->xram;
	for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
		siu_write32(add, 0);

	/* YRAM variable area initialization */
	add = info->yram;
	for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
		siu_write32(add, ydef[cnt]);

	/* YRAM FIR coefficient area initialization */
	add = info->yram + (0x0200 / sizeof(u32));
	for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
		siu_write32(add, fw->yram_fir_coeff[cnt]);

	/* YRAM IIR coefficient area initialization */
	add = info->yram + (0x0600 / sizeof(u32));
	for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
		siu_write32(add, 0);

	siu_write32(base + SIU_TRDAT, port_info->trdat);
	port_info->trdat = 0x0;


	/* SPB start condition: software */
	siu_write32(base + SIU_SBACTIV, 0);
	/* Start SPB */
	siu_write32(base + SIU_SBCTL, 0xc0000000);
	/* Wait for program to halt */
	cnt = 0x10000;
	while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
		cpu_relax();

	if (!cnt)
		return -EBUSY;

	/* SPB program start address setting */
	siu_write32(base + SIU_SBPSET, 0x00400000);
	/* SPB hardware start(FIFOCTL source) */
	siu_write32(base + SIU_SBACTIV, 0xc0000000);

	return 0;
}

static void siu_dai_spbstop(struct siu_port *port_info)
{
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;

	siu_write32(base + SIU_SBACTIV, 0);
	/* SPB stop */
	siu_write32(base + SIU_SBCTL, 0);

	port_info->stfifo = 0;
}

/*		API functions		*/

/* Playback and capture hardware properties are identical */
static struct snd_pcm_hardware siu_dai_pcm_hw = {
	.info			= SNDRV_PCM_INFO_INTERLEAVED,
	.formats		= SNDRV_PCM_FMTBIT_S16,
	.rates			= SNDRV_PCM_RATE_8000_48000,
	.rate_min		= 8000,
	.rate_max		= 48000,
	.channels_min		= 2,
	.channels_max		= 2,
	.buffer_bytes_max	= SIU_BUFFER_BYTES_MAX,
	.period_bytes_min	= SIU_PERIOD_BYTES_MIN,
	.period_bytes_max	= SIU_PERIOD_BYTES_MAX,
	.periods_min		= SIU_PERIODS_MIN,
	.periods_max		= SIU_PERIODS_MAX,
};

static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
			       struct snd_ctl_elem_info *uinfo)
{
	struct siu_port *port_info = snd_kcontrol_chip(kctrl);

	dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = SIU_MAX_VOLUME;

	return 0;
}

static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct siu_port *port_info = snd_kcontrol_chip(kctrl);
	struct device *dev = port_info->pcm->card->dev;
	u32 vol;

	dev_dbg(dev, "%s\n", __func__);

	switch (kctrl->private_value) {
	case VOLUME_PLAYBACK:
		/* Playback is always on port 0 */
		vol = port_info->playback.volume;
		ucontrol->value.integer.value[0] = vol & 0xffff;
		ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
		break;
	case VOLUME_CAPTURE:
		/* Capture is always on port 1 */
		vol = port_info->capture.volume;
		ucontrol->value.integer.value[0] = vol & 0xffff;
		ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
		break;
	default:
		dev_err(dev, "%s() invalid private_value=%ld\n",
			__func__, kctrl->private_value);
		return -EINVAL;
	}

	return 0;
}

static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct siu_port *port_info = snd_kcontrol_chip(kctrl);
	struct device *dev = port_info->pcm->card->dev;
	struct siu_info *info = siu_i2s_data;
	u32 __iomem *base = info->reg;
	u32 new_vol;
	u32 cur_vol;

	dev_dbg(dev, "%s\n", __func__);

	if (ucontrol->value.integer.value[0] < 0 ||
	    ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
	    ucontrol->value.integer.value[1] < 0 ||
	    ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
		return -EINVAL;

	new_vol = ucontrol->value.integer.value[0] |
		ucontrol->value.integer.value[1] << 16;

	/* See comment above - DSP firmware implementation */
	switch (kctrl->private_value) {
	case VOLUME_PLAYBACK:
		/* Playback is always on port 0 */
		cur_vol = port_info->playback.volume;
		siu_write32(base + SIU_SBDVCA, new_vol);
		port_info->playback.volume = new_vol;
		break;
	case VOLUME_CAPTURE:
		/* Capture is always on port 1 */
		cur_vol = port_info->capture.volume;
		siu_write32(base + SIU_SBDVCB, new_vol);
		port_info->capture.volume = new_vol;
		break;
	default:
		dev_err(dev, "%s() invalid private_value=%ld\n",
			__func__, kctrl->private_value);
		return -EINVAL;
	}

	if (cur_vol != new_vol)
		return 1;

	return 0;
}

static struct snd_kcontrol_new playback_controls = {
	.iface		= SNDRV_CTL_ELEM_IFACE_MIXER,
	.name		= "PCM Playback Volume",
	.index		= 0,
	.info		= siu_dai_info_volume,
	.get		= siu_dai_get_volume,
	.put		= siu_dai_put_volume,
	.private_value	= VOLUME_PLAYBACK,
};

static struct snd_kcontrol_new capture_controls = {
	.iface		= SNDRV_CTL_ELEM_IFACE_MIXER,
	.name		= "PCM Capture Volume",
	.index		= 0,
	.info		= siu_dai_info_volume,
	.get		= siu_dai_get_volume,
	.put		= siu_dai_put_volume,
	.private_value	= VOLUME_CAPTURE,
};

int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
{
	struct device *dev = card->dev;
	struct snd_kcontrol *kctrl;
	int ret;

	*port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
	if (!*port_info)
		return -ENOMEM;

	dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);

	(*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
	(*port_info)->capture.volume = DFLT_VOLUME_LEVEL;

	/*
	 * Add mixer support. The SPB is used to change the volume. Both
	 * ports use the same SPB. Therefore, we only register one
	 * control instance since it will be used by both channels.
	 * In error case we continue without controls.
	 */
	kctrl = snd_ctl_new1(&playback_controls, *port_info);
	ret = snd_ctl_add(card, kctrl);
	if (ret < 0)
		dev_err(dev,
			"failed to add playback controls %p port=%d err=%d\n",
			kctrl, port, ret);

	kctrl = snd_ctl_new1(&capture_controls, *port_info);
	ret = snd_ctl_add(card, kctrl);
	if (ret < 0)
		dev_err(dev,
			"failed to add capture controls %p port=%d err=%d\n",
			kctrl, port, ret);

	return 0;
}

void siu_free_port(struct siu_port *port_info)
{
	kfree(port_info);
}

static int siu_dai_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
	struct snd_pcm_runtime *rt = substream->runtime;
	struct siu_port	*port_info = siu_port_info(substream);
	int ret;

	dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
		info->port_id, port_info);

	snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);

	ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
	if (unlikely(ret < 0))
		return ret;

	siu_dai_start(port_info);

	return 0;
}

static void siu_dai_shutdown(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai)
{
	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
	struct siu_port	*port_info = siu_port_info(substream);

	dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
		info->port_id, port_info);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		port_info->play_cap &= ~PLAYBACK_ENABLED;
	else
		port_info->play_cap &= ~CAPTURE_ENABLED;

	/* Stop the siu if the other stream is not using it */
	if (!port_info->play_cap) {
		/* during stmread or stmwrite ? */
		if (WARN_ON(port_info->playback.rw_flg || port_info->capture.rw_flg))
			return;
		siu_dai_spbstop(port_info);
		siu_dai_stop(port_info);
	}
}

/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
static int siu_dai_prepare(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
	struct snd_pcm_runtime *rt = substream->runtime;
	struct siu_port *port_info = siu_port_info(substream);
	struct siu_stream *siu_stream;
	int self, ret;

	dev_dbg(substream->pcm->card->dev,
		"%s: port %d, active streams %lx, %d channels\n",
		__func__, info->port_id, port_info->play_cap, rt->channels);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		self = PLAYBACK_ENABLED;
		siu_stream = &port_info->playback;
	} else {
		self = CAPTURE_ENABLED;
		siu_stream = &port_info->capture;
	}

	/* Set up the siu if not already done */
	if (!port_info->play_cap) {
		siu_stream->rw_flg = 0;	/* stream-data transfer flag */

		siu_dai_spbAselect(port_info);
		siu_dai_spbBselect(port_info);

		siu_dai_open(siu_stream);

		siu_dai_pcmdatapack(siu_stream);

		ret = siu_dai_spbstart(port_info);
		if (ret < 0)
			goto fail;
	} else {
		ret = 0;
	}

	port_info->play_cap |= self;

fail:
	return ret;
}

/*
 * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
 * capture, however, the current API sets the bus format globally for a DAI.
 */
static int siu_dai_set_fmt(struct snd_soc_dai *dai,
			   unsigned int fmt)
{
	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
	u32 __iomem *base = info->reg;
	u32 ifctl;

	dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
		__func__, fmt, info->port_id);

	if (info->port_id < 0)
		return -ENODEV;

	/* Here select between I2S / PCM / SPDIF */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		ifctl = siu_flags[info->port_id].playback.i2s |
			siu_flags[info->port_id].capture.i2s;
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		ifctl = siu_flags[info->port_id].playback.pcm |
			siu_flags[info->port_id].capture.pcm;
		break;
	/* SPDIF disabled - see comment at the top */
	default:
		return -EINVAL;
	}

	ifctl |= ~(siu_flags[info->port_id].playback.mask |
		   siu_flags[info->port_id].capture.mask) &
		siu_read32(base + SIU_IFCTL);
	siu_write32(base + SIU_IFCTL, ifctl);

	return 0;
}

static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
			      unsigned int freq, int dir)
{
	struct clk *siu_clk, *parent_clk;
	char *siu_name, *parent_name;
	int ret;

	if (dir != SND_SOC_CLOCK_IN)
		return -EINVAL;

	dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);

	switch (clk_id) {
	case SIU_CLKA_PLL:
		siu_name = "siua_clk";
		parent_name = "pll_clk";
		break;
	case SIU_CLKA_EXT:
		siu_name = "siua_clk";
		parent_name = "siumcka_clk";
		break;
	case SIU_CLKB_PLL:
		siu_name = "siub_clk";
		parent_name = "pll_clk";
		break;
	case SIU_CLKB_EXT:
		siu_name = "siub_clk";
		parent_name = "siumckb_clk";
		break;
	default:
		return -EINVAL;
	}

	siu_clk = clk_get(dai->dev, siu_name);
	if (IS_ERR(siu_clk)) {
		dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__,
			PTR_ERR(siu_clk));
		return PTR_ERR(siu_clk);
	}

	parent_clk = clk_get(dai->dev, parent_name);
	if (IS_ERR(parent_clk)) {
		ret = PTR_ERR(parent_clk);
		dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret);
		goto epclkget;
	}

	ret = clk_set_parent(siu_clk, parent_clk);
	if (ret < 0) {
		dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret);
		goto eclksetp;
	}

	ret = clk_set_rate(siu_clk, freq);
	if (ret < 0)
		dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret);

	/* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */
eclksetp:
	clk_put(parent_clk);
epclkget:
	clk_put(siu_clk);

	return ret;
}

static const struct snd_soc_dai_ops siu_dai_ops = {
	.startup	= siu_dai_startup,
	.shutdown	= siu_dai_shutdown,
	.prepare	= siu_dai_prepare,
	.set_sysclk	= siu_dai_set_sysclk,
	.set_fmt	= siu_dai_set_fmt,
};

static struct snd_soc_dai_driver siu_i2s_dai = {
	.name	= "siu-i2s-dai",
	.playback = {
		.channels_min = 2,
		.channels_max = 2,
		.formats = SNDRV_PCM_FMTBIT_S16,
		.rates = SNDRV_PCM_RATE_8000_48000,
	},
	.capture = {
		.channels_min = 2,
		.channels_max = 2,
		.formats = SNDRV_PCM_FMTBIT_S16,
		.rates = SNDRV_PCM_RATE_8000_48000,
	 },
	.ops = &siu_dai_ops,
};

static const struct snd_soc_component_driver siu_i2s_component = {
	.name		= "siu-i2s",
};

static int siu_probe(struct platform_device *pdev)
{
	const struct firmware *fw_entry;
	struct resource *res, *region;
	struct siu_info *info;
	int ret;

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;
	siu_i2s_data = info;
	info->dev = &pdev->dev;

	ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
	if (ret)
		goto ereqfw;

	/*
	 * Loaded firmware is "const" - read only, but we have to modify it in
	 * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
	 */
	memcpy(&info->fw, fw_entry->data, fw_entry->size);

	release_firmware(fw_entry);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENODEV;
		goto egetres;
	}

	region = request_mem_region(res->start, resource_size(res),
				    pdev->name);
	if (!region) {
		dev_err(&pdev->dev, "SIU region already claimed\n");
		ret = -EBUSY;
		goto ereqmemreg;
	}

	ret = -ENOMEM;
	info->pram = ioremap(res->start, PRAM_SIZE);
	if (!info->pram)
		goto emappram;
	info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE);
	if (!info->xram)
		goto emapxram;
	info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE);
	if (!info->yram)
		goto emapyram;
	info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) -
			    REG_OFFSET);
	if (!info->reg)
		goto emapreg;

	dev_set_drvdata(&pdev->dev, info);

	/* register using ARRAY version so we can keep dai name */
	ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component,
					 &siu_i2s_dai, 1);
	if (ret < 0)
		goto edaiinit;

	ret = snd_soc_register_platform(&pdev->dev, &siu_platform);
	if (ret < 0)
		goto esocregp;

	pm_runtime_enable(&pdev->dev);

	return ret;

esocregp:
	snd_soc_unregister_component(&pdev->dev);
edaiinit:
	iounmap(info->reg);
emapreg:
	iounmap(info->yram);
emapyram:
	iounmap(info->xram);
emapxram:
	iounmap(info->pram);
emappram:
	release_mem_region(res->start, resource_size(res));
ereqmemreg:
egetres:
ereqfw:
	kfree(info);

	return ret;
}

static int siu_remove(struct platform_device *pdev)
{
	struct siu_info *info = dev_get_drvdata(&pdev->dev);
	struct resource *res;

	pm_runtime_disable(&pdev->dev);

	snd_soc_unregister_platform(&pdev->dev);
	snd_soc_unregister_component(&pdev->dev);

	iounmap(info->reg);
	iounmap(info->yram);
	iounmap(info->xram);
	iounmap(info->pram);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res)
		release_mem_region(res->start, resource_size(res));
	kfree(info);

	return 0;
}

static struct platform_driver siu_driver = {
	.driver 	= {
		.name	= "siu-pcm-audio",
	},
	.probe		= siu_probe,
	.remove		= siu_remove,
};

module_platform_driver(siu_driver);

MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
MODULE_LICENSE("GPL");
