static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) { struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct rsnd_src *src = rsnd_mod_to_src(mod); u32 convert_rate = rsnd_src_convert_rate(src); u32 fsrate = 0; if (convert_rate) fsrate = 0x0400000 / convert_rate * runtime->rate; /* set/clear soft reset */ rsnd_mod_write(mod, SRC_SWRSR, 0); rsnd_mod_write(mod, SRC_SWRSR, 1); /* Set channel number and output bit length */ rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); /* Enable the initial value of IFS */ if (fsrate) { rsnd_mod_write(mod, SRC_IFSCR, 1); /* Set initial value of IFS */ rsnd_mod_write(mod, SRC_IFSVR, fsrate); } /* use DMA transfer */ rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); return 0; }
/* * Gen2 functions */ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, struct rsnd_dai *rdai) { int ret; ret = rsnd_src_set_convert_rate(mod, rdai); if (ret < 0) return ret; rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod)); rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); rsnd_mod_write(mod, SRC_BSDSR, 0x01800000); rsnd_mod_write(mod, SRC_BSISR, 0x00100060); return 0; }
/* * Gen1/Gen2 common functions */ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, int use_busif) { struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); int ssi_id = rsnd_mod_id(ssi_mod); /* * SSI_MODE0 */ rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), !use_busif << ssi_id); /* * SSI_MODE1 */ if (rsnd_ssi_is_pin_sharing(ssi_mod)) { int shift = -1; switch (ssi_id) { case 1: shift = 0; break; case 2: shift = 2; break; case 4: shift = 16; break; } if (shift >= 0) rsnd_mod_bset(ssi_mod, SSI_MODE1, 0x3 << shift, rsnd_rdai_is_clk_master(rdai) ? 0x2 << shift : 0x1 << shift); } /* * DMA settings for SSIU */ if (use_busif) { u32 val = 0x76543210; u32 mask = ~0; rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, rsnd_get_adinr(ssi_mod)); rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); mask <<= runtime->channels * 4; val = val & mask; switch (runtime->sample_bits) { case 16: val |= 0x67452301 & ~mask; break; case 32: val |= 0x76543210 & ~mask; break; } rsnd_mod_write(ssi_mod, BUSIF_DALIGN, val); } return 0; }