Skip to content

Commit

Permalink
ASoC: sh: fsi: Add module/port clock control function
Browse files Browse the repository at this point in the history
The FIFO of each port were always working though it was not used
in current FSI driver.
This patch add module/port clock control function for fixing it.
This patch is also caring suspend/resume.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Simon Horman <simon@horms.net>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Kuninori Morimoto authored and Mark Brown committed Apr 26, 2011
1 parent 106c79e commit 1f5e2a3
Showing 1 changed file with 50 additions and 31 deletions.
81 changes: 50 additions & 31 deletions sound/soc/sh/fsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
#define SE (1 << 0) /* Fix the master clock */

/* CLK_RST */
#define B_CLK 0x00000010
#define A_CLK 0x00000001
#define CRB (1 << 4)
#define CRA (1 << 0)

/* IO SHIFT / MACRO */
#define BI_SHIFT 12
Expand Down Expand Up @@ -187,6 +187,7 @@ struct fsi_master {
u32 saved_iemsk;
u32 saved_imsk;
u32 saved_clk_rst;
u32 saved_soft_rst;
};

/*
Expand Down Expand Up @@ -556,20 +557,45 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
}

/*
* ctrl function
* clock function
*/
#define fsi_module_init(m, d) __fsi_module_clk_ctrl(m, d, 1)
#define fsi_module_kill(m, d) __fsi_module_clk_ctrl(m, d, 0)
static void __fsi_module_clk_ctrl(struct fsi_master *master,
struct device *dev,
int enable)
{
pm_runtime_get_sync(dev);

if (enable) {
/* enable only SR */
fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
} else {
/* clear all registers */
fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
}

pm_runtime_put_sync(dev);
}

static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
#define fsi_port_start(f) __fsi_port_clk_ctrl(f, 1)
#define fsi_port_stop(f) __fsi_port_clk_ctrl(f, 0)
static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int enable)
{
u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
struct fsi_master *master = fsi_get_master(fsi);
u32 soft = fsi_is_port_a(fsi) ? PASR : PBSR;
u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
int is_master = fsi_is_clk_master(fsi);

if (enable)
fsi_master_mask_set(master, CLK_RST, val, val);
else
fsi_master_mask_set(master, CLK_RST, val, 0);
fsi_master_mask_set(master, SOFT_RST, soft, (enable) ? soft : 0);
if (is_master)
fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
}

/*
* ctrl function
*/
static void fsi_fifo_init(struct fsi_priv *fsi,
int is_play,
struct snd_soc_dai *dai)
Expand Down Expand Up @@ -622,18 +648,6 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
}
}

static void fsi_soft_all_reset(struct fsi_master *master)
{
/* port AB reset */
fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
mdelay(10);

/* soft reset */
fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
mdelay(10);
}

static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
{
struct snd_pcm_runtime *runtime;
Expand Down Expand Up @@ -818,10 +832,8 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,

fsi_irq_disable(fsi, is_play);

if (fsi_is_clk_master(fsi)) {
fsi_clk_ctrl(fsi, 0);
if (fsi_is_clk_master(fsi))
set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
}

fsi->rate = 0;

Expand All @@ -843,8 +855,10 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
frames_to_bytes(runtime, runtime->period_size));
ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
fsi_irq_enable(fsi, is_play);
fsi_port_start(fsi);
break;
case SNDRV_PCM_TRIGGER_STOP:
fsi_port_stop(fsi);
fsi_irq_disable(fsi, is_play);
fsi_stream_pop(fsi, is_play);
break;
Expand Down Expand Up @@ -1018,7 +1032,6 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,

fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
udelay(10);
fsi_clk_ctrl(fsi, 1);
ret = 0;
}

Expand Down Expand Up @@ -1233,9 +1246,7 @@ static int fsi_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
dev_set_drvdata(&pdev->dev, master);

pm_runtime_get_sync(&pdev->dev);
fsi_soft_all_reset(master);
pm_runtime_put_sync(&pdev->dev);
fsi_module_init(master, &pdev->dev);

ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
id_entry->name, master);
Expand Down Expand Up @@ -1279,6 +1290,8 @@ static int fsi_remove(struct platform_device *pdev)

master = dev_get_drvdata(&pdev->dev);

fsi_module_kill(master, &pdev->dev);

free_irq(master->irq, master);
pm_runtime_disable(&pdev->dev);

Expand Down Expand Up @@ -1334,6 +1347,9 @@ static int fsi_suspend(struct device *dev)
master->saved_iemsk = fsi_core_read(master, iemsk);
master->saved_imsk = fsi_core_read(master, imsk);
master->saved_clk_rst = fsi_master_read(master, CLK_RST);
master->saved_soft_rst = fsi_master_read(master, SOFT_RST);

fsi_module_kill(master, dev);

pm_runtime_put_sync(dev);

Expand All @@ -1347,14 +1363,17 @@ static int fsi_resume(struct device *dev)

pm_runtime_get_sync(dev);

__fsi_resume(&master->fsia, dev, set_rate);
__fsi_resume(&master->fsib, dev, set_rate);
fsi_module_init(master, dev);

fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst);
fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);
fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk);
fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk);
fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);

__fsi_resume(&master->fsia, dev, set_rate);
__fsi_resume(&master->fsib, dev, set_rate);

pm_runtime_put_sync(dev);

Expand Down

0 comments on commit 1f5e2a3

Please sign in to comment.