ASoC: fsi: reduce runtime calculation by using pre-setting
[deliverable/linux.git] / sound / soc / sh / fsi.c
index 3d7016e128f9374d2febb9564f404ed02db6b4db..0d78740d0a6b3209f3696f448c0e1b3690d544ec 100644 (file)
@@ -32,7 +32,9 @@
 #define REG_DIDT       0x0020
 #define REG_DODT       0x0024
 #define REG_MUTE_ST    0x0028
+#define REG_OUT_DMAC   0x002C
 #define REG_OUT_SEL    0x0030
+#define REG_IN_DMAC    0x0038
 
 /* master register */
 #define MST_CLK_RST    0x0210
@@ -165,6 +167,7 @@ struct fsi_stream {
        int buff_sample_pos;    /* sample position of ALSA buffer */
        int period_samples;     /* sample number / 1 period */
        int period_pos;         /* current period position */
+       int sample_width;       /* sample width */
 
        int uerr_num;
        int oerr_num;
@@ -235,13 +238,13 @@ static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
 }
 
 #define fsi_reg_write(p, r, d)\
-       __fsi_reg_write((u32)(p->base + REG_##r), d)
+       __fsi_reg_write((p->base + REG_##r), d)
 
 #define fsi_reg_read(p, r)\
-       __fsi_reg_read((u32)(p->base + REG_##r))
+       __fsi_reg_read((p->base + REG_##r))
 
 #define fsi_reg_mask_set(p, r, m, d)\
-       __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
+       __fsi_reg_mask_set((p->base + REG_##r), m, d)
 
 #define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
 #define fsi_core_read(p, r)   _fsi_master_read(p, p->core->r)
@@ -404,6 +407,7 @@ static void fsi_stream_push(struct fsi_priv *fsi,
        io->buff_sample_pos     = 0;
        io->period_samples      = fsi_frame2sample(fsi, runtime->period_size);
        io->period_pos          = 0;
+       io->sample_width        = samples_to_bytes(runtime, 1);
        io->oerr_num    = -1; /* ignore 1st err */
        io->uerr_num    = -1; /* ignore 1st err */
        spin_unlock_irqrestore(&master->lock, flags);
@@ -429,6 +433,7 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
        io->buff_sample_pos     = 0;
        io->period_samples      = 0;
        io->period_pos          = 0;
+       io->sample_width        = 0;
        io->oerr_num    = 0;
        io->uerr_num    = 0;
        spin_unlock_irqrestore(&master->lock, flags);
@@ -750,7 +755,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
        int is_play = fsi_stream_is_play(stream);
        struct fsi_stream *io = fsi_get_stream(fsi, is_play);
        int sample_residues;
-       int sample_width;
        int samples;
        int samples_max;
        int over_period;
@@ -778,9 +782,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
                        io->buff_sample_pos = 0;
        }
 
-       /* get 1 sample data width */
-       sample_width = samples_to_bytes(runtime, 1);
-
        /* get number of residue samples */
        sample_residues = io->buff_sample_capa - io->buff_sample_pos;
 
@@ -796,7 +797,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
 
                samples = sample_residues;
 
-               switch (sample_width) {
+               switch (io->sample_width) {
                case 2:
                        fn = fsi_dma_soft_push16;
                        break;
@@ -816,7 +817,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
                samples_max = sample_residues;
                samples     = fsi_get_current_fifo_samples(fsi, is_play);
 
-               switch (sample_width) {
+               switch (io->sample_width) {
                case 2:
                        fn = fsi_dma_soft_pop16;
                        break;
@@ -886,11 +887,11 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
                          int is_play,
                          struct device *dev)
 {
+       struct fsi_master *master = fsi_get_master(fsi);
+       int fsi_ver = master->core->ver;
        u32 flags = fsi_get_info_flags(fsi);
        u32 data = 0;
 
-       pm_runtime_get_sync(dev);
-
        /* clock setting */
        if (fsi_is_clk_master(fsi))
                data = DIMD | DOMD;
@@ -920,6 +921,17 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
                fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
        }
 
+       /*
+        * FIXME
+        *
+        * FSI driver assumed that data package is in-back.
+        * FSI2 chip can select it.
+        */
+       if (fsi_ver >= 2) {
+               fsi_reg_write(fsi, OUT_DMAC,    (1 << 4));
+               fsi_reg_write(fsi, IN_DMAC,     (1 << 4));
+       }
+
        /* irq clear */
        fsi_irq_disable(fsi, is_play);
        fsi_irq_clear_status(fsi);
@@ -936,8 +948,6 @@ static void fsi_hw_shutdown(struct fsi_priv *fsi,
 {
        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,
@@ -1081,7 +1091,7 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
        return ret;
 }
 
-static struct snd_soc_dai_ops fsi_dai_ops = {
+static const struct snd_soc_dai_ops fsi_dai_ops = {
        .startup        = fsi_dai_startup,
        .shutdown       = fsi_dai_shutdown,
        .trigger        = fsi_dai_trigger,
@@ -1397,23 +1407,9 @@ static int fsi_resume(struct device *dev)
        return 0;
 }
 
-static int fsi_runtime_nop(struct device *dev)
-{
-       /* Runtime PM callback shared between ->runtime_suspend()
-        * and ->runtime_resume(). Simply returns success.
-        *
-        * This driver re-initializes all registers after
-        * pm_runtime_get_sync() anyway so there is no need
-        * to save and restore registers here.
-        */
-       return 0;
-}
-
 static struct dev_pm_ops fsi_pm_ops = {
        .suspend                = fsi_suspend,
        .resume                 = fsi_resume,
-       .runtime_suspend        = fsi_runtime_nop,
-       .runtime_resume         = fsi_runtime_nop,
 };
 
 static struct fsi_core fsi1_core = {
@@ -1453,18 +1449,7 @@ static struct platform_driver fsi_driver = {
        .id_table       = fsi_id_table,
 };
 
-static int __init fsi_mobile_init(void)
-{
-       return platform_driver_register(&fsi_driver);
-}
-
-static void __exit fsi_mobile_exit(void)
-{
-       platform_driver_unregister(&fsi_driver);
-}
-
-module_init(fsi_mobile_init);
-module_exit(fsi_mobile_exit);
+module_platform_driver(fsi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
This page took 0.033659 seconds and 5 git commands to generate.