static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); struct device *dev = rsnd_priv_to_dev(priv); u32 cr; if (0 == ssi->usrcnt) { clk_enable(ssi->clk); if (rsnd_rdai_is_clk_master(rdai)) { if (rsnd_ssi_clk_from_parent(ssi)) rsnd_ssi_hw_start(ssi->parent, rdai, io); else rsnd_ssi_master_clk_start(ssi, io); } } cr = ssi->cr_own | ssi->cr_clk | ssi->cr_etc | EN; rsnd_mod_write(&ssi->mod, SSICR, cr); ssi->usrcnt++; dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod)); }
static int rsnd_ssi_start(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod)); rsnd_ssi_hw_start(ssi, io); rsnd_src_ssi_irq_enable(mod); return 0; }
static int rsnd_ssi_pio_start(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); /* enable PIO IRQ */ ssi->cr_etc = UIEN | OIEN | DIEN; rsnd_src_enable_ssi_irq(mod, rdai, io); rsnd_ssi_hw_start(ssi, rdai, io); return 0; }
static int rsnd_ssi_pio_start(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct device *dev = rsnd_priv_to_dev(priv); /* enable PIO IRQ */ ssi->cr_etc = UIEN | OIEN | DIEN; rsnd_ssi_hw_start(ssi, rdai, io); dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); return 0; }
static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_io_to_priv(io); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct device *dev = rsnd_priv_to_dev(priv); u32 cr_mode; u32 cr; if (0 == ssi->usrcnt) { rsnd_mod_hw_start(&ssi->mod); if (rsnd_rdai_is_clk_master(rdai)) { if (rsnd_ssi_clk_from_parent(ssi)) rsnd_ssi_hw_start(ssi->parent, io); else rsnd_ssi_master_clk_start(ssi, io); } } cr_mode = rsnd_ssi_is_dma_mode(&ssi->mod) ? DMEN : /* DMA : enable DMA */ DIEN; /* PIO : enable Data interrupt */ cr = ssi->cr_own | ssi->cr_clk | cr_mode | UIEN | OIEN | EN; rsnd_mod_write(&ssi->mod, SSICR, cr); /* enable WS continue */ if (rsnd_rdai_is_clk_master(rdai)) rsnd_mod_write(&ssi->mod, SSIWSR, CONT); /* clear error status */ rsnd_mod_write(&ssi->mod, SSISR, 0); ssi->usrcnt++; dev_dbg(dev, "%s[%d] hw started\n", rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); }
static int rsnd_ssi_dma_start(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); /* enable DMA transfer */ ssi->cr_etc = DMEN; rsnd_dma_start(dma); rsnd_ssi_hw_start(ssi, ssi->rdai, io); /* enable WS continue */ if (rsnd_dai_is_clk_master(rdai)) rsnd_mod_write(&ssi->mod, SSIWSR, CONT); return 0; }
static int rsnd_ssi_pio_start(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct device *dev = rsnd_priv_to_dev(priv); /* enable PIO IRQ */ ssi->cr_etc = UIEN | OIEN | DIEN; /* enable PIO interrupt if gen2 */ if (rsnd_is_gen2(priv)) rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000); rsnd_ssi_hw_start(ssi, rdai, io); dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); return 0; }