ASoC: fsi: Fixup for master mode
This patch add hw_params to snd_soc_dai_ops, because board specific set_rate is needed when FSI was used as master mode. This patch remove fsi_clk_ctrl from fsi_dai_startup, because clock should be disabled before set_rate. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
This commit is contained in:
parent
d78541473d
commit
ccad7b44cc
@ -72,9 +72,41 @@
|
|||||||
#define SH_FSI_OFMT_TDM_DELAY_CH(x) \
|
#define SH_FSI_OFMT_TDM_DELAY_CH(x) \
|
||||||
(SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x))
|
(SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_rate return value
|
||||||
|
*
|
||||||
|
* see ACKMD/BPFMD on
|
||||||
|
* ACK_MD (FSI2)
|
||||||
|
* CKG1 (FSI)
|
||||||
|
*
|
||||||
|
* err: return value < 0
|
||||||
|
*
|
||||||
|
* 0x-00000AB
|
||||||
|
*
|
||||||
|
* A: ACKMD value
|
||||||
|
* B: BPFMD value
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SH_FSI_ACKMD_MASK (0xF << 0)
|
||||||
|
#define SH_FSI_ACKMD_512 (1 << 0)
|
||||||
|
#define SH_FSI_ACKMD_256 (2 << 0)
|
||||||
|
#define SH_FSI_ACKMD_128 (3 << 0)
|
||||||
|
#define SH_FSI_ACKMD_64 (4 << 0)
|
||||||
|
#define SH_FSI_ACKMD_32 (5 << 0)
|
||||||
|
|
||||||
|
#define SH_FSI_BPFMD_MASK (0xF << 4)
|
||||||
|
#define SH_FSI_BPFMD_512 (1 << 4)
|
||||||
|
#define SH_FSI_BPFMD_256 (2 << 4)
|
||||||
|
#define SH_FSI_BPFMD_128 (3 << 4)
|
||||||
|
#define SH_FSI_BPFMD_64 (4 << 4)
|
||||||
|
#define SH_FSI_BPFMD_32 (5 << 4)
|
||||||
|
#define SH_FSI_BPFMD_16 (6 << 4)
|
||||||
|
|
||||||
struct sh_fsi_platform_info {
|
struct sh_fsi_platform_info {
|
||||||
unsigned long porta_flags;
|
unsigned long porta_flags;
|
||||||
unsigned long portb_flags;
|
unsigned long portb_flags;
|
||||||
|
int (*set_rate)(int is_porta, int rate); /* for master mode */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct snd_soc_dai fsi_soc_dai[2];
|
extern struct snd_soc_dai fsi_soc_dai[2];
|
||||||
|
@ -65,6 +65,10 @@
|
|||||||
#define ERR_UNDER 0x00000001
|
#define ERR_UNDER 0x00000001
|
||||||
#define ST_ERR (ERR_OVER | ERR_UNDER)
|
#define ST_ERR (ERR_OVER | ERR_UNDER)
|
||||||
|
|
||||||
|
/* CKG1 */
|
||||||
|
#define ACKMD_MASK 0x00007000
|
||||||
|
#define BPFMD_MASK 0x00000700
|
||||||
|
|
||||||
/* CLK_RST */
|
/* CLK_RST */
|
||||||
#define B_CLK 0x00000010
|
#define B_CLK 0x00000010
|
||||||
#define A_CLK 0x00000001
|
#define A_CLK 0x00000001
|
||||||
@ -734,12 +738,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
|
|||||||
}
|
}
|
||||||
fsi_reg_write(fsi, reg, data);
|
fsi_reg_write(fsi, reg, data);
|
||||||
|
|
||||||
/*
|
|
||||||
* clear clk reset if master mode
|
|
||||||
*/
|
|
||||||
if (is_master)
|
|
||||||
fsi_clk_ctrl(fsi, 1);
|
|
||||||
|
|
||||||
/* irq clear */
|
/* irq clear */
|
||||||
fsi_irq_disable(fsi, is_play);
|
fsi_irq_disable(fsi, is_play);
|
||||||
fsi_irq_clear_status(fsi);
|
fsi_irq_clear_status(fsi);
|
||||||
@ -786,10 +784,98 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
struct snd_pcm_hw_params *params,
|
||||||
|
struct snd_soc_dai *dai)
|
||||||
|
{
|
||||||
|
struct fsi_priv *fsi = fsi_get_priv(substream);
|
||||||
|
struct fsi_master *master = fsi_get_master(fsi);
|
||||||
|
int (*set_rate)(int is_porta, int rate) = master->info->set_rate;
|
||||||
|
int fsi_ver = master->core->ver;
|
||||||
|
int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* if slave mode, set_rate is not needed */
|
||||||
|
if (!fsi_is_master_mode(fsi, is_play))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* it is error if no set_rate */
|
||||||
|
if (!set_rate)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
/* clock stop */
|
||||||
|
pm_runtime_put_sync(dai->dev);
|
||||||
|
fsi_clk_ctrl(fsi, 0);
|
||||||
|
|
||||||
|
ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
|
||||||
|
if (ret > 0) {
|
||||||
|
u32 data = 0;
|
||||||
|
|
||||||
|
switch (ret & SH_FSI_ACKMD_MASK) {
|
||||||
|
default:
|
||||||
|
/* FALL THROUGH */
|
||||||
|
case SH_FSI_ACKMD_512:
|
||||||
|
data |= (0x0 << 12);
|
||||||
|
break;
|
||||||
|
case SH_FSI_ACKMD_256:
|
||||||
|
data |= (0x1 << 12);
|
||||||
|
break;
|
||||||
|
case SH_FSI_ACKMD_128:
|
||||||
|
data |= (0x2 << 12);
|
||||||
|
break;
|
||||||
|
case SH_FSI_ACKMD_64:
|
||||||
|
data |= (0x3 << 12);
|
||||||
|
break;
|
||||||
|
case SH_FSI_ACKMD_32:
|
||||||
|
if (fsi_ver < 2)
|
||||||
|
dev_err(dai->dev, "unsupported ACKMD\n");
|
||||||
|
else
|
||||||
|
data |= (0x4 << 12);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ret & SH_FSI_BPFMD_MASK) {
|
||||||
|
default:
|
||||||
|
/* FALL THROUGH */
|
||||||
|
case SH_FSI_BPFMD_32:
|
||||||
|
data |= (0x0 << 8);
|
||||||
|
break;
|
||||||
|
case SH_FSI_BPFMD_64:
|
||||||
|
data |= (0x1 << 8);
|
||||||
|
break;
|
||||||
|
case SH_FSI_BPFMD_128:
|
||||||
|
data |= (0x2 << 8);
|
||||||
|
break;
|
||||||
|
case SH_FSI_BPFMD_256:
|
||||||
|
data |= (0x3 << 8);
|
||||||
|
break;
|
||||||
|
case SH_FSI_BPFMD_512:
|
||||||
|
data |= (0x4 << 8);
|
||||||
|
break;
|
||||||
|
case SH_FSI_BPFMD_16:
|
||||||
|
if (fsi_ver < 2)
|
||||||
|
dev_err(dai->dev, "unsupported ACKMD\n");
|
||||||
|
else
|
||||||
|
data |= (0x7 << 8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
|
||||||
|
udelay(10);
|
||||||
|
fsi_clk_ctrl(fsi, 1);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
pm_runtime_get_sync(dai->dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static struct snd_soc_dai_ops fsi_dai_ops = {
|
static struct snd_soc_dai_ops fsi_dai_ops = {
|
||||||
.startup = fsi_dai_startup,
|
.startup = fsi_dai_startup,
|
||||||
.shutdown = fsi_dai_shutdown,
|
.shutdown = fsi_dai_shutdown,
|
||||||
.trigger = fsi_dai_trigger,
|
.trigger = fsi_dai_trigger,
|
||||||
|
.hw_params = fsi_dai_hw_params,
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user