* [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI
@ 2011-05-23 11:45 Kuninori Morimoto
2011-05-23 11:45 ` [PATCH 1/9] ASoC: sh: fsi: tidyup parameter of fsi_stream_push Kuninori Morimoto
` (10 more replies)
0 siblings, 11 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:45 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
Dear Mark, Liam
Cc Simon, yoshii-san, Magnus
These are tidyup and cleanup patches for FSI
Kuninori Morimoto (9):
ASoC: sh: fsi: tidyup parameter of fsi_stream_push
ASoC: sh: fsi: tidyup unclear variable naming
ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt.
ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock
ASoC: sh: fsi: Add fsi_set_master_clk
ASoC: sh: fsi: irq control moves to fsi_port_start/stop
ASoC: sh: fsi: Add fsi_hw_startup/shutdown
ASoC: sh: fsi: remove fsi_module_init/kill
ASoC: sh: fsi: cleanup suspend/resume
#1 and #2 are tidyup for fsi_fifo_data_ctrl.
The variables and sub-functions were unclear nameing.
So, it was difficult to understand the detail of calculation.
Thank you for pointing it yoshii-san.
#3 - #9 are clean up for RuntimePM.
Current FSI driver was wrong for RuntimePM.
these patches fixup for RuntimePM and
clean up for suspend/resume.
last patch remove noisy saved_xxx variable.
Best regards
--
Kuninori Morimoto
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/9] ASoC: sh: fsi: tidyup parameter of fsi_stream_push
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
@ 2011-05-23 11:45 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 2/9] ASoC: sh: fsi: tidyup unclear variable naming Kuninori Morimoto
` (9 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:45 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
It is possible to create buff_len and period_len
from substream->runtime.
This patch is preparation of tidyup unclear variable naming patch.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 4a9da6b..7025885 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -344,16 +344,15 @@ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
static void fsi_stream_push(struct fsi_priv *fsi,
int is_play,
- struct snd_pcm_substream *substream,
- u32 buffer_len,
- u32 period_len)
+ struct snd_pcm_substream *substream)
{
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_pcm_runtime *runtime = substream->runtime;
io->substream = substream;
- io->buff_len = buffer_len;
+ io->buff_len = frames_to_bytes(runtime, runtime->buffer_size);
io->buff_offset = 0;
- io->period_len = period_len;
+ io->period_len = frames_to_bytes(runtime, runtime->period_size);
io->period_num = 0;
io->oerr_num = -1; /* ignore 1st err */
io->uerr_num = -1; /* ignore 1st err */
@@ -844,15 +843,12 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct fsi_priv *fsi = fsi_get_priv(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
int is_play = fsi_is_play(substream);
int ret = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- fsi_stream_push(fsi, is_play, substream,
- frames_to_bytes(runtime, runtime->buffer_size),
- frames_to_bytes(runtime, runtime->period_size));
+ fsi_stream_push(fsi, is_play, substream);
ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
fsi_irq_enable(fsi, is_play);
fsi_port_start(fsi);
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/9] ASoC: sh: fsi: tidyup unclear variable naming
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
2011-05-23 11:45 ` [PATCH 1/9] ASoC: sh: fsi: tidyup parameter of fsi_stream_push Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 3/9] ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt Kuninori Morimoto
` (8 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
Some variables on this driver were a unclear naming,
and were different unit (byte, frame, sample).
And some functions had wrong name
(ex. it returned "sample width" but name was "fsi_get_frame_width").
This patch tidy-up this issue, and the minimum unit become "sample".
Special thanks to Takashi YOSHII.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 182 ++++++++++++++++++++++++++++-----------------------
1 files changed, 100 insertions(+), 82 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 7025885..14fed47 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -118,10 +118,38 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
/*
* FSI driver use below type name for variable
*
- * xxx_len : data length
- * xxx_width : data width
- * xxx_offset : data offset
* xxx_num : number of data
+ * xxx_pos : position of data
+ * xxx_capa : capacity of data
+ */
+
+/*
+ * period/frame/sample image
+ *
+ * ex) PCM (2ch)
+ *
+ * period pos period pos
+ * [n] [n + 1]
+ * |<-------------------- period--------------------->|
+ * ==|============================================ ... =|==
+ * | |
+ * ||<----- frame ----->|<------ frame ----->| ... |
+ * |+--------------------+--------------------+- ... |
+ * ||[ sample ][ sample ]|[ sample ][ sample ]| ... |
+ * |+--------------------+--------------------+- ... |
+ * ==|============================================ ... =|==
+ */
+
+/*
+ * FSI FIFO image
+ *
+ * | |
+ * | |
+ * | [ sample ] |
+ * | [ sample ] |
+ * | [ sample ] |
+ * | [ sample ] |
+ * --> go to codecs
*/
/*
@@ -131,12 +159,11 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
struct fsi_stream {
struct snd_pcm_substream *substream;
- int fifo_max_num;
-
- int buff_offset;
- int buff_len;
- int period_len;
- int period_num;
+ int fifo_sample_capa; /* sample capacity of FSI FIFO */
+ int buff_sample_capa; /* sample capacity of ALSA buffer */
+ int buff_sample_pos; /* sample position of ALSA buffer */
+ int period_samples; /* sample number / 1 period */
+ int period_pos; /* current period position */
int uerr_num;
int oerr_num;
@@ -342,6 +369,16 @@ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
return shift;
}
+static int fsi_frame2sample(struct fsi_priv *fsi, int frames)
+{
+ return frames * fsi->chan_num;
+}
+
+static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
+{
+ return samples / fsi->chan_num;
+}
+
static void fsi_stream_push(struct fsi_priv *fsi,
int is_play,
struct snd_pcm_substream *substream)
@@ -350,10 +387,10 @@ static void fsi_stream_push(struct fsi_priv *fsi,
struct snd_pcm_runtime *runtime = substream->runtime;
io->substream = substream;
- io->buff_len = frames_to_bytes(runtime, runtime->buffer_size);
- io->buff_offset = 0;
- io->period_len = frames_to_bytes(runtime, runtime->period_size);
- io->period_num = 0;
+ io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size);
+ io->buff_sample_pos = 0;
+ io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
+ io->period_pos = 0;
io->oerr_num = -1; /* ignore 1st err */
io->uerr_num = -1; /* ignore 1st err */
}
@@ -371,47 +408,26 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
io->substream = NULL;
- io->buff_len = 0;
- io->buff_offset = 0;
- io->period_len = 0;
- io->period_num = 0;
+ io->buff_sample_capa = 0;
+ io->buff_sample_pos = 0;
+ io->period_samples = 0;
+ io->period_pos = 0;
io->oerr_num = 0;
io->uerr_num = 0;
}
-static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
+static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
{
u32 status;
- int data_num;
+ int frames;
status = is_play ?
fsi_reg_read(fsi, DOFF_ST) :
fsi_reg_read(fsi, DIFF_ST);
- data_num = 0x1ff & (status >> 8);
- data_num *= fsi->chan_num;
-
- return data_num;
-}
-
-static int fsi_len2num(int len, int width)
-{
- return len / width;
-}
+ frames = 0x1ff & (status >> 8);
-#define fsi_num2offset(a, b) fsi_num2len(a, b)
-static int fsi_num2len(int num, int width)
-{
- return num * width;
-}
-
-static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
-{
- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- struct snd_pcm_substream *substream = io->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- return frames_to_bytes(runtime, 1) / fsi->chan_num;
+ return fsi_frame2sample(fsi, frames);
}
static void fsi_count_fifo_err(struct fsi_priv *fsi)
@@ -443,8 +459,10 @@ static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
{
int is_play = fsi_stream_is_play(stream);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_pcm_runtime *runtime = io->substream->runtime;
- return io->substream->runtime->dma_area + io->buff_offset;
+ return runtime->dma_area +
+ samples_to_bytes(runtime, io->buff_sample_pos);
}
static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
@@ -602,13 +620,14 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
struct fsi_master *master = fsi_get_master(fsi);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
u32 shift, i;
+ int frame_capa;
/* get on-chip RAM capacity */
shift = fsi_master_read(master, FIFO_SZ);
shift >>= fsi_get_port_shift(fsi, is_play);
shift &= FIFO_SZ_MASK;
- io->fifo_max_num = 256 << shift;
- dev_dbg(dai->dev, "fifo = %d words\n", io->fifo_max_num);
+ frame_capa = 256 << shift;
+ dev_dbg(dai->dev, "fifo = %d words\n", frame_capa);
/*
* The maximum number of sample data varies depending
@@ -630,9 +649,11 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
* 8 channels: 32 ( 32 x 8 = 256)
*/
for (i = 1; i < fsi->chan_num; i <<= 1)
- io->fifo_max_num >>= 1;
+ frame_capa >>= 1;
dev_dbg(dai->dev, "%d channel %d store\n",
- fsi->chan_num, io->fifo_max_num);
+ fsi->chan_num, frame_capa);
+
+ io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
/*
* set interrupt generation factor
@@ -653,10 +674,10 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
struct snd_pcm_substream *substream = NULL;
int is_play = fsi_stream_is_play(stream);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
- int data_residue_num;
- int data_num;
- int data_num_max;
- int ch_width;
+ int sample_residues;
+ int sample_width;
+ int samples;
+ int samples_max;
int over_period;
void (*fn)(struct fsi_priv *fsi, int size);
@@ -672,36 +693,35 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
/* FSI FIFO has limit.
* So, this driver can not send periods data at a time
*/
- if (io->buff_offset >=
- fsi_num2offset(io->period_num + 1, io->period_len)) {
+ if (io->buff_sample_pos >=
+ io->period_samples * (io->period_pos + 1)) {
over_period = 1;
- io->period_num = (io->period_num + 1) % runtime->periods;
+ io->period_pos = (io->period_pos + 1) % runtime->periods;
- if (0 == io->period_num)
- io->buff_offset = 0;
+ if (0 == io->period_pos)
+ io->buff_sample_pos = 0;
}
- /* get 1 channel data width */
- ch_width = fsi_get_frame_width(fsi, is_play);
+ /* get 1 sample data width */
+ sample_width = samples_to_bytes(runtime, 1);
- /* get residue data number of alsa */
- data_residue_num = fsi_len2num(io->buff_len - io->buff_offset,
- ch_width);
+ /* get number of residue samples */
+ sample_residues = io->buff_sample_capa - io->buff_sample_pos;
if (is_play) {
/*
* for play-back
*
- * data_num_max : number of FSI fifo free space
- * data_num : number of ALSA residue data
+ * samples_max : number of FSI fifo free samples space
+ * samples : number of ALSA residue samples
*/
- data_num_max = io->fifo_max_num * fsi->chan_num;
- data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
+ samples_max = io->fifo_sample_capa;
+ samples_max -= fsi_get_current_fifo_samples(fsi, is_play);
- data_num = data_residue_num;
+ samples = sample_residues;
- switch (ch_width) {
+ switch (sample_width) {
case 2:
fn = fsi_dma_soft_push16;
break;
@@ -715,13 +735,13 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
/*
* for capture
*
- * data_num_max : number of ALSA free space
- * data_num : number of data in FSI fifo
+ * samples_max : number of ALSA free samples space
+ * samples : number of samples in FSI fifo
*/
- data_num_max = data_residue_num;
- data_num = fsi_get_fifo_data_num(fsi, is_play);
+ samples_max = sample_residues;
+ samples = fsi_get_current_fifo_samples(fsi, is_play);
- switch (ch_width) {
+ switch (sample_width) {
case 2:
fn = fsi_dma_soft_pop16;
break;
@@ -733,12 +753,12 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
}
}
- data_num = min(data_num, data_num_max);
+ samples = min(samples, samples_max);
- fn(fsi, data_num);
+ fn(fsi, samples);
- /* update buff_offset */
- io->buff_offset += fsi_num2offset(data_num, ch_width);
+ /* update buff_sample_pos */
+ io->buff_sample_pos += samples;
if (over_period)
snd_pcm_period_elapsed(substream);
@@ -1093,16 +1113,14 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
{
- struct snd_pcm_runtime *runtime = substream->runtime;
struct fsi_priv *fsi = fsi_get_priv(substream);
struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
- long location;
+ int samples_pos = io->buff_sample_pos - 1;
- location = (io->buff_offset - 1);
- if (location < 0)
- location = 0;
+ if (samples_pos < 0)
+ samples_pos = 0;
- return bytes_to_frames(runtime, location);
+ return fsi_sample2frame(fsi, samples_pos);
}
static struct snd_pcm_ops fsi_pcm_ops = {
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/9] ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt.
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
2011-05-23 11:45 ` [PATCH 1/9] ASoC: sh: fsi: tidyup parameter of fsi_stream_push Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 2/9] ASoC: sh: fsi: tidyup unclear variable naming Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock Kuninori Morimoto
` (7 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
pm_runtime_get/put_sync were used to access FSI register in fsi_dai_set_fmt
which is called when ALSA probe.
But this register value will disappear after pm_runtime_put_sync
if platform is supporting RuntimePM.
To solve this issue, this patch adds new variable for format,
and remove pm_runtime_get/put_sync from fsi_dai_set_fmt.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 52 ++++++++++++++++++++++++++++++++--------------------
1 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 14fed47..bdf2d65 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -176,8 +176,12 @@ struct fsi_priv {
struct fsi_stream playback;
struct fsi_stream capture;
+ u32 do_fmt;
+ u32 di_fmt;
+
int chan_num:16;
int clk_master:1;
+ int spdif:1;
long rate;
@@ -298,6 +302,11 @@ static int fsi_is_port_a(struct fsi_priv *fsi)
return fsi->master->base == fsi->base;
}
+static int fsi_is_spdif(struct fsi_priv *fsi)
+{
+ return fsi->spdif;
+}
+
static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -812,11 +821,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
u32 flags = fsi_get_info_flags(fsi);
- u32 data;
+ u32 data = 0;
int is_play = fsi_is_play(substream);
pm_runtime_get_sync(dai->dev);
+ /* clock setting */
+ if (fsi_is_clk_master(fsi))
+ data = DIMD | DOMD;
+
+ fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
/* clock inversion (CKG2) */
data = 0;
@@ -831,6 +845,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
fsi_reg_write(fsi, CKG2, data);
+ /* set format */
+ fsi_reg_write(fsi, DO_FMT, fsi->do_fmt);
+ fsi_reg_write(fsi, DI_FMT, fsi->di_fmt);
+
+ /* spdif ? */
+ if (fsi_is_spdif(fsi)) {
+ fsi_spdif_clk_ctrl(fsi, 1);
+ fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
+ }
+
/* irq clear */
fsi_irq_disable(fsi, is_play);
fsi_irq_clear_status(fsi);
@@ -900,8 +924,8 @@ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
return -EINVAL;
}
- fsi_reg_write(fsi, DO_FMT, data);
- fsi_reg_write(fsi, DI_FMT, data);
+ fsi->do_fmt = data;
+ fsi->di_fmt = data;
return 0;
}
@@ -916,11 +940,10 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
fsi->chan_num = 2;
- fsi_spdif_clk_ctrl(fsi, 1);
- fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
+ fsi->spdif = 1;
- fsi_reg_write(fsi, DO_FMT, data);
- fsi_reg_write(fsi, DI_FMT, data);
+ fsi->do_fmt = data;
+ fsi->di_fmt = data;
return 0;
}
@@ -931,32 +954,24 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
struct fsi_master *master = fsi_get_master(fsi);
set_rate_func set_rate = fsi_get_info_set_rate(master);
u32 flags = fsi_get_info_flags(fsi);
- u32 data = 0;
int ret;
- pm_runtime_get_sync(dai->dev);
-
/* set master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
- data = DIMD | DOMD;
fsi->clk_master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFS:
break;
default:
- ret = -EINVAL;
- goto set_fmt_exit;
+ return -EINVAL;
}
if (fsi_is_clk_master(fsi) && !set_rate) {
dev_err(dai->dev, "platform doesn't have set_rate\n");
- ret = -EINVAL;
- goto set_fmt_exit;
+ return -EINVAL;
}
- fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
-
/* set format */
switch (flags & SH_FSI_FMT_MASK) {
case SH_FSI_FMT_DAI:
@@ -969,9 +984,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
ret = -EINVAL;
}
-set_fmt_exit:
- pm_runtime_put_sync(dai->dev);
-
return ret;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (2 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 3/9] ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-24 10:39 ` Mark Brown
2011-05-23 11:46 ` [PATCH 5/9] ASoC: sh: fsi: add fsi_set_master_clk Kuninori Morimoto
` (6 subsequent siblings)
10 siblings, 1 reply; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
fsi_stream_push/pop might be called in same time.
This patch protect it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index bdf2d65..33a6bd0 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -394,7 +394,10 @@ static void fsi_stream_push(struct fsi_priv *fsi,
{
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
struct snd_pcm_runtime *runtime = substream->runtime;
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+ spin_lock_irqsave(&master->lock, flags);
io->substream = substream;
io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size);
io->buff_sample_pos = 0;
@@ -402,13 +405,17 @@ static void fsi_stream_push(struct fsi_priv *fsi,
io->period_pos = 0;
io->oerr_num = -1; /* ignore 1st err */
io->uerr_num = -1; /* ignore 1st err */
+ spin_unlock_irqrestore(&master->lock, flags);
}
static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
{
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+ spin_lock_irqsave(&master->lock, flags);
if (io->oerr_num > 0)
dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
@@ -423,6 +430,7 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
io->period_pos = 0;
io->oerr_num = 0;
io->uerr_num = 0;
+ spin_unlock_irqrestore(&master->lock, flags);
}
static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/9] ASoC: sh: fsi: add fsi_set_master_clk
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (3 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 6/9] ASoC: sh: fsi: irq control moves to fsi_port_start/stop Kuninori Morimoto
` (5 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
Current FSI driver is using set_rate call back function which is for
master mode.
By this patch, it is used from fsi_set_master_clk.
This patch is preparation of cleanup suspend/resume patch.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 164 +++++++++++++++++++++++++++------------------------
1 files changed, 87 insertions(+), 77 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 33a6bd0..ae05d8f 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -593,6 +593,82 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
/*
* clock function
*/
+static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
+ long rate, int enable)
+{
+ struct fsi_master *master = fsi_get_master(fsi);
+ set_rate_func set_rate = fsi_get_info_set_rate(master);
+ int fsi_ver = master->core->ver;
+ int ret;
+
+ ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable);
+ if (ret < 0) /* error */
+ return ret;
+
+ if (!enable)
+ return 0;
+
+ 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(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(dev, "unsupported ACKMD\n");
+ else
+ data |= (0x7 << 8);
+ break;
+ }
+
+ fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
+ udelay(10);
+ ret = 0;
+ }
+
+ return ret;
+
+}
+
#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,
@@ -878,13 +954,11 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
{
struct fsi_priv *fsi = fsi_get_priv(substream);
int is_play = fsi_is_play(substream);
- struct fsi_master *master = fsi_get_master(fsi);
- set_rate_func set_rate = fsi_get_info_set_rate(master);
fsi_irq_disable(fsi, is_play);
if (fsi_is_clk_master(fsi))
- set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
+ fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);
fsi->rate = 0;
@@ -1000,79 +1074,19 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsi_priv *fsi = fsi_get_priv(substream);
- struct fsi_master *master = fsi_get_master(fsi);
- set_rate_func set_rate = fsi_get_info_set_rate(master);
- int fsi_ver = master->core->ver;
long rate = params_rate(params);
int ret;
if (!fsi_is_clk_master(fsi))
return 0;
- ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
- if (ret < 0) /* error */
+ ret = fsi_set_master_clk(dai->dev, fsi, rate, 1);
+ if (ret < 0)
return ret;
fsi->rate = rate;
- 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);
- ret = 0;
- }
return ret;
-
}
static struct snd_soc_dai_ops fsi_dai_ops = {
@@ -1339,8 +1353,7 @@ static int fsi_remove(struct platform_device *pdev)
}
static void __fsi_suspend(struct fsi_priv *fsi,
- struct device *dev,
- set_rate_func set_rate)
+ struct device *dev)
{
fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
@@ -1349,12 +1362,11 @@ static void __fsi_suspend(struct fsi_priv *fsi,
fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
if (fsi_is_clk_master(fsi))
- set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0);
+ fsi_set_master_clk(dev, fsi, fsi->rate, 0);
}
static void __fsi_resume(struct fsi_priv *fsi,
- struct device *dev,
- set_rate_func set_rate)
+ struct device *dev)
{
fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
@@ -1363,18 +1375,17 @@ static void __fsi_resume(struct fsi_priv *fsi,
fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
if (fsi_is_clk_master(fsi))
- set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1);
+ fsi_set_master_clk(dev, fsi, fsi->rate, 1);
}
static int fsi_suspend(struct device *dev)
{
struct fsi_master *master = dev_get_drvdata(dev);
- set_rate_func set_rate = fsi_get_info_set_rate(master);
pm_runtime_get_sync(dev);
- __fsi_suspend(&master->fsia, dev, set_rate);
- __fsi_suspend(&master->fsib, dev, set_rate);
+ __fsi_suspend(&master->fsia, dev);
+ __fsi_suspend(&master->fsib, dev);
master->saved_a_mclk = fsi_core_read(master, a_mclk);
master->saved_b_mclk = fsi_core_read(master, b_mclk);
@@ -1393,7 +1404,6 @@ static int fsi_suspend(struct device *dev)
static int fsi_resume(struct device *dev)
{
struct fsi_master *master = dev_get_drvdata(dev);
- set_rate_func set_rate = fsi_get_info_set_rate(master);
pm_runtime_get_sync(dev);
@@ -1406,8 +1416,8 @@ static int fsi_resume(struct device *dev)
fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
- __fsi_resume(&master->fsia, dev, set_rate);
- __fsi_resume(&master->fsib, dev, set_rate);
+ __fsi_resume(&master->fsia, dev);
+ __fsi_resume(&master->fsib, dev);
pm_runtime_put_sync(dev);
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/9] ASoC: sh: fsi: irq control moves to fsi_port_start/stop
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (4 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 5/9] ASoC: sh: fsi: add fsi_set_master_clk Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 7/9] ASoC: sh: fsi: add fsi_hw_startup/shutdown Kuninori Morimoto
` (4 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
Using fsi_irq_enable/disable in fsi_port_start/stop is very natural.
This patch is preparation of cleanup suspend/resume patch.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index ae05d8f..a00fe37 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -689,15 +689,20 @@ static void __fsi_module_clk_ctrl(struct fsi_master *master,
pm_runtime_put_sync(dev);
}
-#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)
+#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
+#define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0)
+static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
{
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_irq_enable(fsi, is_play);
+ else
+ fsi_irq_disable(fsi, is_play);
+
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);
@@ -953,9 +958,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsi_priv *fsi = fsi_get_priv(substream);
- int is_play = fsi_is_play(substream);
-
- fsi_irq_disable(fsi, is_play);
if (fsi_is_clk_master(fsi))
fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);
@@ -976,12 +978,10 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
fsi_stream_push(fsi, is_play, substream);
ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
- fsi_irq_enable(fsi, is_play);
- fsi_port_start(fsi);
+ fsi_port_start(fsi, is_play);
break;
case SNDRV_PCM_TRIGGER_STOP:
- fsi_port_stop(fsi);
- fsi_irq_disable(fsi, is_play);
+ fsi_port_stop(fsi, is_play);
fsi_stream_pop(fsi, is_play);
break;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/9] ASoC: sh: fsi: add fsi_hw_startup/shutdown
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (5 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 6/9] ASoC: sh: fsi: irq control moves to fsi_port_start/stop Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 8/9] ASoC: sh: fsi: remove fsi_module_init/kill Kuninori Morimoto
` (3 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
This patch is preparation of cleanup suspend/resume patch.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 43 +++++++++++++++++++++++++++++--------------
1 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index a00fe37..c755d21 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -713,7 +713,7 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
*/
static void fsi_fifo_init(struct fsi_priv *fsi,
int is_play,
- struct snd_soc_dai *dai)
+ struct device *dev)
{
struct fsi_master *master = fsi_get_master(fsi);
struct fsi_stream *io = fsi_get_stream(fsi, is_play);
@@ -725,7 +725,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
shift >>= fsi_get_port_shift(fsi, is_play);
shift &= FIFO_SZ_MASK;
frame_capa = 256 << shift;
- dev_dbg(dai->dev, "fifo = %d words\n", frame_capa);
+ dev_dbg(dev, "fifo = %d words\n", frame_capa);
/*
* The maximum number of sample data varies depending
@@ -748,7 +748,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
*/
for (i = 1; i < fsi->chan_num; i <<= 1)
frame_capa >>= 1;
- dev_dbg(dai->dev, "%d channel %d store\n",
+ dev_dbg(dev, "%d channel %d store\n",
fsi->chan_num, frame_capa);
io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
@@ -905,15 +905,14 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
* dai ops
*/
-static int fsi_dai_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
+static int fsi_hw_startup(struct fsi_priv *fsi,
+ int is_play,
+ struct device *dev)
{
- struct fsi_priv *fsi = fsi_get_priv(substream);
u32 flags = fsi_get_info_flags(fsi);
u32 data = 0;
- int is_play = fsi_is_play(substream);
- pm_runtime_get_sync(dai->dev);
+ pm_runtime_get_sync(dev);
/* clock setting */
if (fsi_is_clk_master(fsi))
@@ -949,22 +948,38 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
fsi_irq_clear_status(fsi);
/* fifo init */
- fsi_fifo_init(fsi, is_play, dai);
+ fsi_fifo_init(fsi, is_play, dev);
return 0;
}
+static void fsi_hw_shutdown(struct fsi_priv *fsi,
+ int is_play,
+ struct device *dev)
+{
+ if (fsi_is_clk_master(fsi))
+ fsi_set_master_clk(dev, fsi, fsi->rate, 0);
+
+ pm_runtime_put_sync(dev);
+}
+
+static int fsi_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+ int is_play = fsi_is_play(substream);
+
+ return fsi_hw_startup(fsi, is_play, dai->dev);
+}
+
static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsi_priv *fsi = fsi_get_priv(substream);
+ int is_play = fsi_is_play(substream);
- if (fsi_is_clk_master(fsi))
- fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);
-
+ fsi_hw_shutdown(fsi, is_play, dai->dev);
fsi->rate = 0;
-
- pm_runtime_put_sync(dai->dev);
}
static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 8/9] ASoC: sh: fsi: remove fsi_module_init/kill
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (6 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 7/9] ASoC: sh: fsi: add fsi_hw_startup/shutdown Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 9/9] ASoC: sh: fsi: cleanup suspend/resume Kuninori Morimoto
` (2 subsequent siblings)
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
FSIA/B ports is enabled by default when power-on,
and current FSI is supporting RuntimePM.
In addition, current fsi_module_init/kill doesn't care
simultaneous playback/recorde.
This mean FSI port control is not needed.
This patch remove fsi_module_init/kill
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 30 ------------------------------
1 files changed, 0 insertions(+), 30 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index c755d21..a457e5b 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -669,32 +669,11 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
}
-#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);
-}
-
#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
#define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0)
static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
{
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);
@@ -703,7 +682,6 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
else
fsi_irq_disable(fsi, is_play);
- 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);
}
@@ -1309,8 +1287,6 @@ static int fsi_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
dev_set_drvdata(&pdev->dev, master);
- fsi_module_init(master, &pdev->dev);
-
ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
id_entry->name, master);
if (ret) {
@@ -1353,8 +1329,6 @@ 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);
@@ -1409,8 +1383,6 @@ static int fsi_suspend(struct device *dev)
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);
return 0;
@@ -1422,8 +1394,6 @@ static int fsi_resume(struct device *dev)
pm_runtime_get_sync(dev);
- 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);
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 9/9] ASoC: sh: fsi: cleanup suspend/resume
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (7 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 8/9] ASoC: sh: fsi: remove fsi_module_init/kill Kuninori Morimoto
@ 2011-05-23 11:46 ` Kuninori Morimoto
2011-05-23 14:43 ` [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Liam Girdwood
2011-05-24 10:43 ` Mark Brown
10 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-23 11:46 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
Current FSI driver was using saved_xxx variable for suspend/resume.
OTOH, the start and stop of power/clock are controlled by
fsi_hw_startup/fsi_hw_shutdown in current FSI driver.
The all necessary registers value are set by fsi_hw_startup.
So, if fsi_hw_shutdown is called when "suspend" is generated,
and fsi_hw_startup is called at "resume",
the saved_xxx are not needed.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
sound/soc/sh/fsi.c | 97 ++++++++++++++++++++++-----------------------------
1 files changed, 42 insertions(+), 55 deletions(-)
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index a457e5b..d2f17ce 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -184,13 +184,6 @@ struct fsi_priv {
int spdif:1;
long rate;
-
- /* for suspend/resume */
- u32 saved_do_fmt;
- u32 saved_di_fmt;
- u32 saved_ckg1;
- u32 saved_ckg2;
- u32 saved_out_sel;
};
struct fsi_core {
@@ -211,14 +204,6 @@ struct fsi_master {
struct fsi_core *core;
struct sh_fsi_platform_info *info;
spinlock_t lock;
-
- /* for suspend/resume */
- u32 saved_a_mclk;
- u32 saved_b_mclk;
- u32 saved_iemsk;
- u32 saved_imsk;
- u32 saved_clk_rst;
- u32 saved_soft_rst;
};
/*
@@ -388,6 +373,21 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
return samples / fsi->chan_num;
}
+static int fsi_stream_is_working(struct fsi_priv *fsi,
+ int is_play)
+{
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&master->lock, flags);
+ ret = !!io->substream;
+ spin_unlock_irqrestore(&master->lock, flags);
+
+ return ret;
+}
+
static void fsi_stream_push(struct fsi_priv *fsi,
int is_play,
struct snd_pcm_substream *substream)
@@ -666,7 +666,6 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
}
return ret;
-
}
#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
@@ -675,14 +674,13 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
{
struct fsi_master *master = fsi_get_master(fsi);
u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
- int is_master = fsi_is_clk_master(fsi);
if (enable)
fsi_irq_enable(fsi, is_play);
else
fsi_irq_disable(fsi, is_play);
- if (is_master)
+ if (fsi_is_clk_master(fsi))
fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
}
@@ -1342,48 +1340,43 @@ static int fsi_remove(struct platform_device *pdev)
}
static void __fsi_suspend(struct fsi_priv *fsi,
+ int is_play,
struct device *dev)
{
- fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
- fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
- fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1);
- fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2);
- fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
+ if (!fsi_stream_is_working(fsi, is_play))
+ return;
- if (fsi_is_clk_master(fsi))
- fsi_set_master_clk(dev, fsi, fsi->rate, 0);
+ fsi_port_stop(fsi, is_play);
+ fsi_hw_shutdown(fsi, is_play, dev);
}
static void __fsi_resume(struct fsi_priv *fsi,
+ int is_play,
struct device *dev)
{
- fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
- fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
- fsi_reg_write(fsi, CKG1, fsi->saved_ckg1);
- fsi_reg_write(fsi, CKG2, fsi->saved_ckg2);
- fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
+ if (!fsi_stream_is_working(fsi, is_play))
+ return;
- if (fsi_is_clk_master(fsi))
+ fsi_hw_startup(fsi, is_play, dev);
+
+ if (fsi_is_clk_master(fsi) && fsi->rate)
fsi_set_master_clk(dev, fsi, fsi->rate, 1);
+
+ fsi_port_start(fsi, is_play);
+
}
static int fsi_suspend(struct device *dev)
{
struct fsi_master *master = dev_get_drvdata(dev);
+ struct fsi_priv *fsia = &master->fsia;
+ struct fsi_priv *fsib = &master->fsib;
- pm_runtime_get_sync(dev);
-
- __fsi_suspend(&master->fsia, dev);
- __fsi_suspend(&master->fsib, dev);
+ __fsi_suspend(fsia, 1, dev);
+ __fsi_suspend(fsia, 0, dev);
- master->saved_a_mclk = fsi_core_read(master, a_mclk);
- master->saved_b_mclk = fsi_core_read(master, b_mclk);
- 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);
-
- pm_runtime_put_sync(dev);
+ __fsi_suspend(fsib, 1, dev);
+ __fsi_suspend(fsib, 0, dev);
return 0;
}
@@ -1391,20 +1384,14 @@ static int fsi_suspend(struct device *dev)
static int fsi_resume(struct device *dev)
{
struct fsi_master *master = dev_get_drvdata(dev);
+ struct fsi_priv *fsia = &master->fsia;
+ struct fsi_priv *fsib = &master->fsib;
- pm_runtime_get_sync(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_resume(fsia, 1, dev);
+ __fsi_resume(fsia, 0, dev);
- __fsi_resume(&master->fsia, dev);
- __fsi_resume(&master->fsib, dev);
-
- pm_runtime_put_sync(dev);
+ __fsi_resume(fsib, 1, dev);
+ __fsi_resume(fsib, 0, dev);
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (8 preceding siblings ...)
2011-05-23 11:46 ` [PATCH 9/9] ASoC: sh: fsi: cleanup suspend/resume Kuninori Morimoto
@ 2011-05-23 14:43 ` Liam Girdwood
2011-05-24 10:43 ` Mark Brown
10 siblings, 0 replies; 14+ messages in thread
From: Liam Girdwood @ 2011-05-23 14:43 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: Linux-ALSA, yoshii, Mark Brown, Magnus, Simon, Liam Girdwood
On 23/05/11 12:45, Kuninori Morimoto wrote:
>
> Dear Mark, Liam
>
> Cc Simon, yoshii-san, Magnus
>
> These are tidyup and cleanup patches for FSI
>
> Kuninori Morimoto (9):
> ASoC: sh: fsi: tidyup parameter of fsi_stream_push
> ASoC: sh: fsi: tidyup unclear variable naming
> ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt.
> ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock
> ASoC: sh: fsi: Add fsi_set_master_clk
> ASoC: sh: fsi: irq control moves to fsi_port_start/stop
> ASoC: sh: fsi: Add fsi_hw_startup/shutdown
> ASoC: sh: fsi: remove fsi_module_init/kill
> ASoC: sh: fsi: cleanup suspend/resume
>
> #1 and #2 are tidyup for fsi_fifo_data_ctrl.
> The variables and sub-functions were unclear nameing.
> So, it was difficult to understand the detail of calculation.
> Thank you for pointing it yoshii-san.
>
> #3 - #9 are clean up for RuntimePM.
> Current FSI driver was wrong for RuntimePM.
> these patches fixup for RuntimePM and
> clean up for suspend/resume.
> last patch remove noisy saved_xxx variable.
>
All
Acked-by: Liam Girdwood <lrg@ti.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock
2011-05-23 11:46 ` [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock Kuninori Morimoto
@ 2011-05-24 10:39 ` Mark Brown
2011-05-25 0:32 ` Kuninori Morimoto
0 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2011-05-24 10:39 UTC (permalink / raw)
To: Kuninori Morimoto; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
On Mon, May 23, 2011 at 08:46:13PM +0900, Kuninori Morimoto wrote:
> fsi_stream_push/pop might be called in same time.
> This patch protect it.
>
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
This one looks like a bug fix which should be done in 2.6.40 also? If
that is the case could you please also provide a version of this patch
against 2.6.40.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
` (9 preceding siblings ...)
2011-05-23 14:43 ` [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Liam Girdwood
@ 2011-05-24 10:43 ` Mark Brown
10 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2011-05-24 10:43 UTC (permalink / raw)
To: Kuninori Morimoto; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
On Mon, May 23, 2011 at 08:45:26PM +0900, Kuninori Morimoto wrote:
>
> Dear Mark, Liam
>
> Cc Simon, yoshii-san, Magnus
>
> These are tidyup and cleanup patches for FSI
>
> Kuninori Morimoto (9):
Applied all, thanks.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock
2011-05-24 10:39 ` Mark Brown
@ 2011-05-25 0:32 ` Kuninori Morimoto
0 siblings, 0 replies; 14+ messages in thread
From: Kuninori Morimoto @ 2011-05-25 0:32 UTC (permalink / raw)
To: Mark Brown; +Cc: yoshii, Linux-ALSA, Simon, Magnus, Liam Girdwood
Dear Mark
> > fsi_stream_push/pop might be called in same time.
> > This patch protect it.
> >
> > Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
>
> This one looks like a bug fix which should be done in 2.6.40 also? If
> that is the case could you please also provide a version of this patch
> against 2.6.40.
Thank you for pointing it.
Sorry. the order of patch series (and explain) was a little bit wrong.
My point was "snd_soc_dai_ops :: trigger" (which call fsi_stream_push/pop)
and "suspend/resume" (which call fsi_stream_is_working)
might be called in same time.
This patch was preparation of cleanup suspend/resume patch.
Best regards
--
Kuninori Morimoto
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-05-25 0:32 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-23 11:45 [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Kuninori Morimoto
2011-05-23 11:45 ` [PATCH 1/9] ASoC: sh: fsi: tidyup parameter of fsi_stream_push Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 2/9] ASoC: sh: fsi: tidyup unclear variable naming Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 3/9] ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 4/9] ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock Kuninori Morimoto
2011-05-24 10:39 ` Mark Brown
2011-05-25 0:32 ` Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 5/9] ASoC: sh: fsi: add fsi_set_master_clk Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 6/9] ASoC: sh: fsi: irq control moves to fsi_port_start/stop Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 7/9] ASoC: sh: fsi: add fsi_hw_startup/shutdown Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 8/9] ASoC: sh: fsi: remove fsi_module_init/kill Kuninori Morimoto
2011-05-23 11:46 ` [PATCH 9/9] ASoC: sh: fsi: cleanup suspend/resume Kuninori Morimoto
2011-05-23 14:43 ` [PATCH 0/9] ASoC: sh: fsi: tidyup and cleanup FSI Liam Girdwood
2011-05-24 10:43 ` Mark Brown
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.