static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ssi->cr_etc = 0; rsnd_ssi_hw_stop(ssi, rdai); return 0; }
static int rsnd_ssi_stop(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); rsnd_src_ssi_irq_disable(mod); rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); rsnd_ssi_hw_stop(ssi); rsnd_src_ssiu_stop(mod); return 0; }
static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); dev_dbg(dev, "%s.%d stop\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ssi->cr_etc = 0; rsnd_ssi_hw_stop(ssi, rdai); return 0; }
static int rsnd_ssi_dma_stop(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); ssi->cr_etc = 0; rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); rsnd_ssi_hw_stop(ssi, rdai); rsnd_dma_stop(dma); return 0; }
static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) { struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct device *dev = rsnd_priv_to_dev(priv); u32 cr; if (0 == ssi->usrcnt) /* stop might be called without start */ return; ssi->usrcnt--; if (0 == ssi->usrcnt) { /* * disable all IRQ, * and, wait all data was sent */ cr = ssi->cr_own | ssi->cr_clk; rsnd_mod_write(&ssi->mod, SSICR, cr | EN); rsnd_ssi_status_check(&ssi->mod, DIRQ); /* * disable SSI, * and, wait idle state */ rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ rsnd_ssi_status_check(&ssi->mod, IIRQ); if (rsnd_rdai_is_clk_master(rdai)) { if (rsnd_ssi_clk_from_parent(ssi)) rsnd_ssi_hw_stop(ssi->parent); else rsnd_ssi_master_clk_stop(ssi); } rsnd_mod_hw_stop(&ssi->mod); } dev_dbg(dev, "%s[%d] hw stopped\n", rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); }