cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

siu_dai.c (19669B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
      4//
      5// Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
      6// Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
      7
      8#include <linux/delay.h>
      9#include <linux/firmware.h>
     10#include <linux/pm_runtime.h>
     11#include <linux/slab.h>
     12#include <linux/module.h>
     13
     14#include <asm/clock.h>
     15#include <asm/siu.h>
     16
     17#include <sound/control.h>
     18#include <sound/soc.h>
     19
     20#include "siu.h"
     21
     22/* Board specifics */
     23#if defined(CONFIG_CPU_SUBTYPE_SH7722)
     24# define SIU_MAX_VOLUME		0x1000
     25#else
     26# define SIU_MAX_VOLUME		0x7fff
     27#endif
     28
     29#define PRAM_SIZE	0x2000
     30#define XRAM_SIZE	0x800
     31#define YRAM_SIZE	0x800
     32
     33#define XRAM_OFFSET	0x4000
     34#define YRAM_OFFSET	0x6000
     35#define REG_OFFSET	0xc000
     36
     37#define PLAYBACK_ENABLED	1
     38#define CAPTURE_ENABLED		2
     39
     40#define VOLUME_CAPTURE		0
     41#define VOLUME_PLAYBACK		1
     42#define DFLT_VOLUME_LEVEL	0x08000800
     43
     44/*
     45 * SPDIF is only available on port A and on some SIU implementations it is only
     46 * available for input. Due to the lack of hardware to test it, SPDIF is left
     47 * disabled in this driver version
     48 */
     49struct format_flag {
     50	u32	i2s;
     51	u32	pcm;
     52	u32	spdif;
     53	u32	mask;
     54};
     55
     56struct port_flag {
     57	struct format_flag	playback;
     58	struct format_flag	capture;
     59};
     60
     61struct siu_info *siu_i2s_data;
     62
     63static struct port_flag siu_flags[SIU_PORT_NUM] = {
     64	[SIU_PORT_A] = {
     65		.playback = {
     66			.i2s	= 0x50000000,
     67			.pcm	= 0x40000000,
     68			.spdif	= 0x80000000,	/* not on all SIU versions */
     69			.mask	= 0xd0000000,
     70		},
     71		.capture = {
     72			.i2s	= 0x05000000,
     73			.pcm	= 0x04000000,
     74			.spdif	= 0x08000000,
     75			.mask	= 0x0d000000,
     76		},
     77	},
     78	[SIU_PORT_B] = {
     79		.playback = {
     80			.i2s	= 0x00500000,
     81			.pcm	= 0x00400000,
     82			.spdif	= 0,		/* impossible - turn off */
     83			.mask	= 0x00500000,
     84		},
     85		.capture = {
     86			.i2s	= 0x00050000,
     87			.pcm	= 0x00040000,
     88			.spdif	= 0,		/* impossible - turn off */
     89			.mask	= 0x00050000,
     90		},
     91	},
     92};
     93
     94static void siu_dai_start(struct siu_port *port_info)
     95{
     96	struct siu_info *info = siu_i2s_data;
     97	u32 __iomem *base = info->reg;
     98
     99	dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
    100
    101	/* Issue software reset to siu */
    102	siu_write32(base + SIU_SRCTL, 0);
    103
    104	/* Wait for the reset to take effect */
    105	udelay(1);
    106
    107	port_info->stfifo = 0;
    108	port_info->trdat = 0;
    109
    110	/* portA, portB, SIU operate */
    111	siu_write32(base + SIU_SRCTL, 0x301);
    112
    113	/* portA=256fs, portB=256fs */
    114	siu_write32(base + SIU_CKCTL, 0x40400000);
    115
    116	/* portA's BRG does not divide SIUCKA */
    117	siu_write32(base + SIU_BRGASEL, 0);
    118	siu_write32(base + SIU_BRRA, 0);
    119
    120	/* portB's BRG divides SIUCKB by half */
    121	siu_write32(base + SIU_BRGBSEL, 1);
    122	siu_write32(base + SIU_BRRB, 0);
    123
    124	siu_write32(base + SIU_IFCTL, 0x44440000);
    125
    126	/* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
    127	siu_write32(base + SIU_SFORM, 0x0c0c0000);
    128
    129	/*
    130	 * Volume levels: looks like the DSP firmware implements volume controls
    131	 * differently from what's described in the datasheet
    132	 */
    133	siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
    134	siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
    135}
    136
    137static void siu_dai_stop(struct siu_port *port_info)
    138{
    139	struct siu_info *info = siu_i2s_data;
    140	u32 __iomem *base = info->reg;
    141
    142	/* SIU software reset */
    143	siu_write32(base + SIU_SRCTL, 0);
    144}
    145
    146static void siu_dai_spbAselect(struct siu_port *port_info)
    147{
    148	struct siu_info *info = siu_i2s_data;
    149	struct siu_firmware *fw = &info->fw;
    150	u32 *ydef = fw->yram0;
    151	u32 idx;
    152
    153	/* path A use */
    154	if (!info->port_id)
    155		idx = 1;		/* portA */
    156	else
    157		idx = 2;		/* portB */
    158
    159	ydef[0] = (fw->spbpar[idx].ab1a << 16) |
    160		(fw->spbpar[idx].ab0a << 8) |
    161		(fw->spbpar[idx].dir << 7) | 3;
    162	ydef[1] = fw->yram0[1];	/* 0x03000300 */
    163	ydef[2] = (16 / 2) << 24;
    164	ydef[3] = fw->yram0[3];	/* 0 */
    165	ydef[4] = fw->yram0[4];	/* 0 */
    166	ydef[7] = fw->spbpar[idx].event;
    167	port_info->stfifo |= fw->spbpar[idx].stfifo;
    168	port_info->trdat |= fw->spbpar[idx].trdat;
    169}
    170
    171static void siu_dai_spbBselect(struct siu_port *port_info)
    172{
    173	struct siu_info *info = siu_i2s_data;
    174	struct siu_firmware *fw = &info->fw;
    175	u32 *ydef = fw->yram0;
    176	u32 idx;
    177
    178	/* path B use */
    179	if (!info->port_id)
    180		idx = 7;		/* portA */
    181	else
    182		idx = 8;		/* portB */
    183
    184	ydef[5] = (fw->spbpar[idx].ab1a << 16) |
    185		(fw->spbpar[idx].ab0a << 8) | 1;
    186	ydef[6] = fw->spbpar[idx].event;
    187	port_info->stfifo |= fw->spbpar[idx].stfifo;
    188	port_info->trdat |= fw->spbpar[idx].trdat;
    189}
    190
    191static void siu_dai_open(struct siu_stream *siu_stream)
    192{
    193	struct siu_info *info = siu_i2s_data;
    194	u32 __iomem *base = info->reg;
    195	u32 srctl, ifctl;
    196
    197	srctl = siu_read32(base + SIU_SRCTL);
    198	ifctl = siu_read32(base + SIU_IFCTL);
    199
    200	switch (info->port_id) {
    201	case SIU_PORT_A:
    202		/* portA operates */
    203		srctl |= 0x200;
    204		ifctl &= ~0xc2;
    205		break;
    206	case SIU_PORT_B:
    207		/* portB operates */
    208		srctl |= 0x100;
    209		ifctl &= ~0x31;
    210		break;
    211	}
    212
    213	siu_write32(base + SIU_SRCTL, srctl);
    214	/* Unmute and configure portA */
    215	siu_write32(base + SIU_IFCTL, ifctl);
    216}
    217
    218/*
    219 * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
    220 * packing is supported
    221 */
    222static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
    223{
    224	struct siu_info *info = siu_i2s_data;
    225	u32 __iomem *base = info->reg;
    226	u32 dpak;
    227
    228	dpak = siu_read32(base + SIU_DPAK);
    229
    230	switch (info->port_id) {
    231	case SIU_PORT_A:
    232		dpak &= ~0xc0000000;
    233		break;
    234	case SIU_PORT_B:
    235		dpak &= ~0x00c00000;
    236		break;
    237	}
    238
    239	siu_write32(base + SIU_DPAK, dpak);
    240}
    241
    242static int siu_dai_spbstart(struct siu_port *port_info)
    243{
    244	struct siu_info *info = siu_i2s_data;
    245	u32 __iomem *base = info->reg;
    246	struct siu_firmware *fw = &info->fw;
    247	u32 *ydef = fw->yram0;
    248	int cnt;
    249	u32 __iomem *add;
    250	u32 *ptr;
    251
    252	/* Load SPB Program in PRAM */
    253	ptr = fw->pram0;
    254	add = info->pram;
    255	for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
    256		siu_write32(add, *ptr);
    257
    258	ptr = fw->pram1;
    259	add = info->pram + (0x0100 / sizeof(u32));
    260	for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
    261		siu_write32(add, *ptr);
    262
    263	/* XRAM initialization */
    264	add = info->xram;
    265	for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
    266		siu_write32(add, 0);
    267
    268	/* YRAM variable area initialization */
    269	add = info->yram;
    270	for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
    271		siu_write32(add, ydef[cnt]);
    272
    273	/* YRAM FIR coefficient area initialization */
    274	add = info->yram + (0x0200 / sizeof(u32));
    275	for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
    276		siu_write32(add, fw->yram_fir_coeff[cnt]);
    277
    278	/* YRAM IIR coefficient area initialization */
    279	add = info->yram + (0x0600 / sizeof(u32));
    280	for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
    281		siu_write32(add, 0);
    282
    283	siu_write32(base + SIU_TRDAT, port_info->trdat);
    284	port_info->trdat = 0x0;
    285
    286
    287	/* SPB start condition: software */
    288	siu_write32(base + SIU_SBACTIV, 0);
    289	/* Start SPB */
    290	siu_write32(base + SIU_SBCTL, 0xc0000000);
    291	/* Wait for program to halt */
    292	cnt = 0x10000;
    293	while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
    294		cpu_relax();
    295
    296	if (!cnt)
    297		return -EBUSY;
    298
    299	/* SPB program start address setting */
    300	siu_write32(base + SIU_SBPSET, 0x00400000);
    301	/* SPB hardware start(FIFOCTL source) */
    302	siu_write32(base + SIU_SBACTIV, 0xc0000000);
    303
    304	return 0;
    305}
    306
    307static void siu_dai_spbstop(struct siu_port *port_info)
    308{
    309	struct siu_info *info = siu_i2s_data;
    310	u32 __iomem *base = info->reg;
    311
    312	siu_write32(base + SIU_SBACTIV, 0);
    313	/* SPB stop */
    314	siu_write32(base + SIU_SBCTL, 0);
    315
    316	port_info->stfifo = 0;
    317}
    318
    319/*		API functions		*/
    320
    321/* Playback and capture hardware properties are identical */
    322static const struct snd_pcm_hardware siu_dai_pcm_hw = {
    323	.info			= SNDRV_PCM_INFO_INTERLEAVED,
    324	.formats		= SNDRV_PCM_FMTBIT_S16,
    325	.rates			= SNDRV_PCM_RATE_8000_48000,
    326	.rate_min		= 8000,
    327	.rate_max		= 48000,
    328	.channels_min		= 2,
    329	.channels_max		= 2,
    330	.buffer_bytes_max	= SIU_BUFFER_BYTES_MAX,
    331	.period_bytes_min	= SIU_PERIOD_BYTES_MIN,
    332	.period_bytes_max	= SIU_PERIOD_BYTES_MAX,
    333	.periods_min		= SIU_PERIODS_MIN,
    334	.periods_max		= SIU_PERIODS_MAX,
    335};
    336
    337static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
    338			       struct snd_ctl_elem_info *uinfo)
    339{
    340	struct siu_port *port_info = snd_kcontrol_chip(kctrl);
    341
    342	dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
    343
    344	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    345	uinfo->count = 2;
    346	uinfo->value.integer.min = 0;
    347	uinfo->value.integer.max = SIU_MAX_VOLUME;
    348
    349	return 0;
    350}
    351
    352static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
    353			      struct snd_ctl_elem_value *ucontrol)
    354{
    355	struct siu_port *port_info = snd_kcontrol_chip(kctrl);
    356	struct device *dev = port_info->pcm->card->dev;
    357	u32 vol;
    358
    359	dev_dbg(dev, "%s\n", __func__);
    360
    361	switch (kctrl->private_value) {
    362	case VOLUME_PLAYBACK:
    363		/* Playback is always on port 0 */
    364		vol = port_info->playback.volume;
    365		ucontrol->value.integer.value[0] = vol & 0xffff;
    366		ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
    367		break;
    368	case VOLUME_CAPTURE:
    369		/* Capture is always on port 1 */
    370		vol = port_info->capture.volume;
    371		ucontrol->value.integer.value[0] = vol & 0xffff;
    372		ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
    373		break;
    374	default:
    375		dev_err(dev, "%s() invalid private_value=%ld\n",
    376			__func__, kctrl->private_value);
    377		return -EINVAL;
    378	}
    379
    380	return 0;
    381}
    382
    383static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
    384			      struct snd_ctl_elem_value *ucontrol)
    385{
    386	struct siu_port *port_info = snd_kcontrol_chip(kctrl);
    387	struct device *dev = port_info->pcm->card->dev;
    388	struct siu_info *info = siu_i2s_data;
    389	u32 __iomem *base = info->reg;
    390	u32 new_vol;
    391	u32 cur_vol;
    392
    393	dev_dbg(dev, "%s\n", __func__);
    394
    395	if (ucontrol->value.integer.value[0] < 0 ||
    396	    ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
    397	    ucontrol->value.integer.value[1] < 0 ||
    398	    ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
    399		return -EINVAL;
    400
    401	new_vol = ucontrol->value.integer.value[0] |
    402		ucontrol->value.integer.value[1] << 16;
    403
    404	/* See comment above - DSP firmware implementation */
    405	switch (kctrl->private_value) {
    406	case VOLUME_PLAYBACK:
    407		/* Playback is always on port 0 */
    408		cur_vol = port_info->playback.volume;
    409		siu_write32(base + SIU_SBDVCA, new_vol);
    410		port_info->playback.volume = new_vol;
    411		break;
    412	case VOLUME_CAPTURE:
    413		/* Capture is always on port 1 */
    414		cur_vol = port_info->capture.volume;
    415		siu_write32(base + SIU_SBDVCB, new_vol);
    416		port_info->capture.volume = new_vol;
    417		break;
    418	default:
    419		dev_err(dev, "%s() invalid private_value=%ld\n",
    420			__func__, kctrl->private_value);
    421		return -EINVAL;
    422	}
    423
    424	if (cur_vol != new_vol)
    425		return 1;
    426
    427	return 0;
    428}
    429
    430static const struct snd_kcontrol_new playback_controls = {
    431	.iface		= SNDRV_CTL_ELEM_IFACE_MIXER,
    432	.name		= "PCM Playback Volume",
    433	.index		= 0,
    434	.info		= siu_dai_info_volume,
    435	.get		= siu_dai_get_volume,
    436	.put		= siu_dai_put_volume,
    437	.private_value	= VOLUME_PLAYBACK,
    438};
    439
    440static const struct snd_kcontrol_new capture_controls = {
    441	.iface		= SNDRV_CTL_ELEM_IFACE_MIXER,
    442	.name		= "PCM Capture Volume",
    443	.index		= 0,
    444	.info		= siu_dai_info_volume,
    445	.get		= siu_dai_get_volume,
    446	.put		= siu_dai_put_volume,
    447	.private_value	= VOLUME_CAPTURE,
    448};
    449
    450int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
    451{
    452	struct device *dev = card->dev;
    453	struct snd_kcontrol *kctrl;
    454	int ret;
    455
    456	*port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
    457	if (!*port_info)
    458		return -ENOMEM;
    459
    460	dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);
    461
    462	(*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
    463	(*port_info)->capture.volume = DFLT_VOLUME_LEVEL;
    464
    465	/*
    466	 * Add mixer support. The SPB is used to change the volume. Both
    467	 * ports use the same SPB. Therefore, we only register one
    468	 * control instance since it will be used by both channels.
    469	 * In error case we continue without controls.
    470	 */
    471	kctrl = snd_ctl_new1(&playback_controls, *port_info);
    472	ret = snd_ctl_add(card, kctrl);
    473	if (ret < 0)
    474		dev_err(dev,
    475			"failed to add playback controls %p port=%d err=%d\n",
    476			kctrl, port, ret);
    477
    478	kctrl = snd_ctl_new1(&capture_controls, *port_info);
    479	ret = snd_ctl_add(card, kctrl);
    480	if (ret < 0)
    481		dev_err(dev,
    482			"failed to add capture controls %p port=%d err=%d\n",
    483			kctrl, port, ret);
    484
    485	return 0;
    486}
    487
    488void siu_free_port(struct siu_port *port_info)
    489{
    490	kfree(port_info);
    491}
    492
    493static int siu_dai_startup(struct snd_pcm_substream *substream,
    494			   struct snd_soc_dai *dai)
    495{
    496	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
    497	struct snd_pcm_runtime *rt = substream->runtime;
    498	struct siu_port	*port_info = siu_port_info(substream);
    499	int ret;
    500
    501	dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
    502		info->port_id, port_info);
    503
    504	snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);
    505
    506	ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
    507	if (unlikely(ret < 0))
    508		return ret;
    509
    510	siu_dai_start(port_info);
    511
    512	return 0;
    513}
    514
    515static void siu_dai_shutdown(struct snd_pcm_substream *substream,
    516			     struct snd_soc_dai *dai)
    517{
    518	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
    519	struct siu_port	*port_info = siu_port_info(substream);
    520
    521	dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
    522		info->port_id, port_info);
    523
    524	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    525		port_info->play_cap &= ~PLAYBACK_ENABLED;
    526	else
    527		port_info->play_cap &= ~CAPTURE_ENABLED;
    528
    529	/* Stop the siu if the other stream is not using it */
    530	if (!port_info->play_cap) {
    531		/* during stmread or stmwrite ? */
    532		if (WARN_ON(port_info->playback.rw_flg || port_info->capture.rw_flg))
    533			return;
    534		siu_dai_spbstop(port_info);
    535		siu_dai_stop(port_info);
    536	}
    537}
    538
    539/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
    540static int siu_dai_prepare(struct snd_pcm_substream *substream,
    541			   struct snd_soc_dai *dai)
    542{
    543	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
    544	struct snd_pcm_runtime *rt = substream->runtime;
    545	struct siu_port *port_info = siu_port_info(substream);
    546	struct siu_stream *siu_stream;
    547	int self, ret;
    548
    549	dev_dbg(substream->pcm->card->dev,
    550		"%s: port %d, active streams %lx, %d channels\n",
    551		__func__, info->port_id, port_info->play_cap, rt->channels);
    552
    553	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
    554		self = PLAYBACK_ENABLED;
    555		siu_stream = &port_info->playback;
    556	} else {
    557		self = CAPTURE_ENABLED;
    558		siu_stream = &port_info->capture;
    559	}
    560
    561	/* Set up the siu if not already done */
    562	if (!port_info->play_cap) {
    563		siu_stream->rw_flg = 0;	/* stream-data transfer flag */
    564
    565		siu_dai_spbAselect(port_info);
    566		siu_dai_spbBselect(port_info);
    567
    568		siu_dai_open(siu_stream);
    569
    570		siu_dai_pcmdatapack(siu_stream);
    571
    572		ret = siu_dai_spbstart(port_info);
    573		if (ret < 0)
    574			goto fail;
    575	} else {
    576		ret = 0;
    577	}
    578
    579	port_info->play_cap |= self;
    580
    581fail:
    582	return ret;
    583}
    584
    585/*
    586 * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
    587 * capture, however, the current API sets the bus format globally for a DAI.
    588 */
    589static int siu_dai_set_fmt(struct snd_soc_dai *dai,
    590			   unsigned int fmt)
    591{
    592	struct siu_info *info = snd_soc_dai_get_drvdata(dai);
    593	u32 __iomem *base = info->reg;
    594	u32 ifctl;
    595
    596	dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
    597		__func__, fmt, info->port_id);
    598
    599	if (info->port_id < 0)
    600		return -ENODEV;
    601
    602	/* Here select between I2S / PCM / SPDIF */
    603	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    604	case SND_SOC_DAIFMT_I2S:
    605		ifctl = siu_flags[info->port_id].playback.i2s |
    606			siu_flags[info->port_id].capture.i2s;
    607		break;
    608	case SND_SOC_DAIFMT_LEFT_J:
    609		ifctl = siu_flags[info->port_id].playback.pcm |
    610			siu_flags[info->port_id].capture.pcm;
    611		break;
    612	/* SPDIF disabled - see comment at the top */
    613	default:
    614		return -EINVAL;
    615	}
    616
    617	ifctl |= ~(siu_flags[info->port_id].playback.mask |
    618		   siu_flags[info->port_id].capture.mask) &
    619		siu_read32(base + SIU_IFCTL);
    620	siu_write32(base + SIU_IFCTL, ifctl);
    621
    622	return 0;
    623}
    624
    625static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
    626			      unsigned int freq, int dir)
    627{
    628	struct clk *siu_clk, *parent_clk;
    629	char *siu_name, *parent_name;
    630	int ret;
    631
    632	if (dir != SND_SOC_CLOCK_IN)
    633		return -EINVAL;
    634
    635	dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);
    636
    637	switch (clk_id) {
    638	case SIU_CLKA_PLL:
    639		siu_name = "siua_clk";
    640		parent_name = "pll_clk";
    641		break;
    642	case SIU_CLKA_EXT:
    643		siu_name = "siua_clk";
    644		parent_name = "siumcka_clk";
    645		break;
    646	case SIU_CLKB_PLL:
    647		siu_name = "siub_clk";
    648		parent_name = "pll_clk";
    649		break;
    650	case SIU_CLKB_EXT:
    651		siu_name = "siub_clk";
    652		parent_name = "siumckb_clk";
    653		break;
    654	default:
    655		return -EINVAL;
    656	}
    657
    658	siu_clk = clk_get(dai->dev, siu_name);
    659	if (IS_ERR(siu_clk)) {
    660		dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__,
    661			PTR_ERR(siu_clk));
    662		return PTR_ERR(siu_clk);
    663	}
    664
    665	parent_clk = clk_get(dai->dev, parent_name);
    666	if (IS_ERR(parent_clk)) {
    667		ret = PTR_ERR(parent_clk);
    668		dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret);
    669		goto epclkget;
    670	}
    671
    672	ret = clk_set_parent(siu_clk, parent_clk);
    673	if (ret < 0) {
    674		dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret);
    675		goto eclksetp;
    676	}
    677
    678	ret = clk_set_rate(siu_clk, freq);
    679	if (ret < 0)
    680		dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret);
    681
    682	/* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */
    683eclksetp:
    684	clk_put(parent_clk);
    685epclkget:
    686	clk_put(siu_clk);
    687
    688	return ret;
    689}
    690
    691static const struct snd_soc_dai_ops siu_dai_ops = {
    692	.startup	= siu_dai_startup,
    693	.shutdown	= siu_dai_shutdown,
    694	.prepare	= siu_dai_prepare,
    695	.set_sysclk	= siu_dai_set_sysclk,
    696	.set_fmt	= siu_dai_set_fmt,
    697};
    698
    699static struct snd_soc_dai_driver siu_i2s_dai = {
    700	.name	= "siu-i2s-dai",
    701	.playback = {
    702		.channels_min = 2,
    703		.channels_max = 2,
    704		.formats = SNDRV_PCM_FMTBIT_S16,
    705		.rates = SNDRV_PCM_RATE_8000_48000,
    706	},
    707	.capture = {
    708		.channels_min = 2,
    709		.channels_max = 2,
    710		.formats = SNDRV_PCM_FMTBIT_S16,
    711		.rates = SNDRV_PCM_RATE_8000_48000,
    712	 },
    713	.ops = &siu_dai_ops,
    714};
    715
    716static int siu_probe(struct platform_device *pdev)
    717{
    718	const struct firmware *fw_entry;
    719	struct resource *res, *region;
    720	struct siu_info *info;
    721	int ret;
    722
    723	info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
    724	if (!info)
    725		return -ENOMEM;
    726	siu_i2s_data = info;
    727	info->dev = &pdev->dev;
    728
    729	ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
    730	if (ret)
    731		return ret;
    732
    733	/*
    734	 * Loaded firmware is "const" - read only, but we have to modify it in
    735	 * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
    736	 */
    737	memcpy(&info->fw, fw_entry->data, fw_entry->size);
    738
    739	release_firmware(fw_entry);
    740
    741	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    742	if (!res)
    743		return -ENODEV;
    744
    745	region = devm_request_mem_region(&pdev->dev, res->start,
    746					 resource_size(res), pdev->name);
    747	if (!region) {
    748		dev_err(&pdev->dev, "SIU region already claimed\n");
    749		return -EBUSY;
    750	}
    751
    752	info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE);
    753	if (!info->pram)
    754		return -ENOMEM;
    755	info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET,
    756				  XRAM_SIZE);
    757	if (!info->xram)
    758		return -ENOMEM;
    759	info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET,
    760				  YRAM_SIZE);
    761	if (!info->yram)
    762		return -ENOMEM;
    763	info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET,
    764			    resource_size(res) - REG_OFFSET);
    765	if (!info->reg)
    766		return -ENOMEM;
    767
    768	dev_set_drvdata(&pdev->dev, info);
    769
    770	/* register using ARRAY version so we can keep dai name */
    771	ret = devm_snd_soc_register_component(&pdev->dev, &siu_component,
    772					      &siu_i2s_dai, 1);
    773	if (ret < 0)
    774		return ret;
    775
    776	pm_runtime_enable(&pdev->dev);
    777
    778	return 0;
    779}
    780
    781static int siu_remove(struct platform_device *pdev)
    782{
    783	pm_runtime_disable(&pdev->dev);
    784	return 0;
    785}
    786
    787static struct platform_driver siu_driver = {
    788	.driver 	= {
    789		.name	= "siu-pcm-audio",
    790	},
    791	.probe		= siu_probe,
    792	.remove		= siu_remove,
    793};
    794
    795module_platform_driver(siu_driver);
    796
    797MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
    798MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
    799MODULE_LICENSE("GPL");