Skip to content

Commit 2714769

Browse files
TE-N-ShengjiuWangbroonie
authored andcommitted
ASoC: fsl_easrc: define functions for memory to memory usage
ASRC can be used on memory to memory case, define several functions for m2m usage and export them as function pointer. Signed-off-by: Shengjiu Wang <[email protected]> Acked-by: Jaroslav Kysela <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 8ea7d04 commit 2714769

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

sound/soc/fsl/fsl_easrc.c

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,224 @@ static int fsl_easrc_get_fifo_addr(u8 dir, enum asrc_pair_index index)
18611861
return REG_EASRC_FIFO(dir, index);
18621862
}
18631863

1864+
/* Get sample numbers in FIFO */
1865+
static unsigned int fsl_easrc_get_output_fifo_size(struct fsl_asrc_pair *pair)
1866+
{
1867+
struct fsl_asrc *asrc = pair->asrc;
1868+
enum asrc_pair_index index = pair->index;
1869+
u32 val;
1870+
1871+
regmap_read(asrc->regmap, REG_EASRC_SFS(index), &val);
1872+
val &= EASRC_SFS_NSGO_MASK;
1873+
1874+
return val >> EASRC_SFS_NSGO_SHIFT;
1875+
}
1876+
1877+
static int fsl_easrc_m2m_prepare(struct fsl_asrc_pair *pair)
1878+
{
1879+
struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
1880+
struct fsl_asrc *asrc = pair->asrc;
1881+
struct device *dev = &asrc->pdev->dev;
1882+
int ret;
1883+
1884+
ctx_priv->in_params.sample_rate = pair->rate[IN];
1885+
ctx_priv->in_params.sample_format = pair->sample_format[IN];
1886+
ctx_priv->out_params.sample_rate = pair->rate[OUT];
1887+
ctx_priv->out_params.sample_format = pair->sample_format[OUT];
1888+
1889+
ctx_priv->in_params.fifo_wtmk = FSL_EASRC_INPUTFIFO_WML;
1890+
ctx_priv->out_params.fifo_wtmk = FSL_EASRC_OUTPUTFIFO_WML;
1891+
/* Fill the right half of the re-sampler with zeros */
1892+
ctx_priv->rs_init_mode = 0x2;
1893+
/* Zero fill the right half of the prefilter */
1894+
ctx_priv->pf_init_mode = 0x2;
1895+
1896+
ret = fsl_easrc_set_ctx_format(pair,
1897+
&ctx_priv->in_params.sample_format,
1898+
&ctx_priv->out_params.sample_format);
1899+
if (ret) {
1900+
dev_err(dev, "failed to set context format: %d\n", ret);
1901+
return ret;
1902+
}
1903+
1904+
ret = fsl_easrc_config_context(asrc, pair->index);
1905+
if (ret) {
1906+
dev_err(dev, "failed to config context %d\n", ret);
1907+
return ret;
1908+
}
1909+
1910+
ctx_priv->in_params.iterations = 1;
1911+
ctx_priv->in_params.group_len = pair->channels;
1912+
ctx_priv->in_params.access_len = pair->channels;
1913+
ctx_priv->out_params.iterations = 1;
1914+
ctx_priv->out_params.group_len = pair->channels;
1915+
ctx_priv->out_params.access_len = pair->channels;
1916+
1917+
ret = fsl_easrc_set_ctx_organziation(pair);
1918+
if (ret) {
1919+
dev_err(dev, "failed to set fifo organization\n");
1920+
return ret;
1921+
}
1922+
1923+
/* The context start flag */
1924+
pair->first_convert = 1;
1925+
return 0;
1926+
}
1927+
1928+
static int fsl_easrc_m2m_start(struct fsl_asrc_pair *pair)
1929+
{
1930+
/* start context once */
1931+
if (pair->first_convert) {
1932+
fsl_easrc_start_context(pair);
1933+
pair->first_convert = 0;
1934+
}
1935+
1936+
return 0;
1937+
}
1938+
1939+
static int fsl_easrc_m2m_stop(struct fsl_asrc_pair *pair)
1940+
{
1941+
/* Stop pair/context */
1942+
if (!pair->first_convert) {
1943+
fsl_easrc_stop_context(pair);
1944+
pair->first_convert = 1;
1945+
}
1946+
1947+
return 0;
1948+
}
1949+
1950+
/* calculate capture data length according to output data length and sample rate */
1951+
static int fsl_easrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int input_buffer_length)
1952+
{
1953+
struct fsl_asrc *easrc = pair->asrc;
1954+
struct fsl_easrc_priv *easrc_priv = easrc->private;
1955+
struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
1956+
unsigned int in_rate = ctx_priv->in_params.norm_rate;
1957+
unsigned int out_rate = ctx_priv->out_params.norm_rate;
1958+
unsigned int channels = pair->channels;
1959+
unsigned int in_samples, out_samples;
1960+
unsigned int in_width, out_width;
1961+
unsigned int out_length;
1962+
unsigned int frac_bits;
1963+
u64 val1, val2;
1964+
1965+
switch (easrc_priv->rs_num_taps) {
1966+
case EASRC_RS_32_TAPS:
1967+
/* integer bits = 5; */
1968+
frac_bits = 39;
1969+
break;
1970+
case EASRC_RS_64_TAPS:
1971+
/* integer bits = 6; */
1972+
frac_bits = 38;
1973+
break;
1974+
case EASRC_RS_128_TAPS:
1975+
/* integer bits = 7; */
1976+
frac_bits = 37;
1977+
break;
1978+
default:
1979+
return -EINVAL;
1980+
}
1981+
1982+
val1 = (u64)in_rate << frac_bits;
1983+
do_div(val1, out_rate);
1984+
val1 += (s64)ctx_priv->ratio_mod << (frac_bits - 31);
1985+
1986+
in_width = snd_pcm_format_physical_width(ctx_priv->in_params.sample_format) / 8;
1987+
out_width = snd_pcm_format_physical_width(ctx_priv->out_params.sample_format) / 8;
1988+
1989+
ctx_priv->in_filled_len += input_buffer_length;
1990+
if (ctx_priv->in_filled_len <= ctx_priv->in_filled_sample * in_width * channels) {
1991+
out_length = 0;
1992+
} else {
1993+
in_samples = ctx_priv->in_filled_len / (in_width * channels) -
1994+
ctx_priv->in_filled_sample;
1995+
1996+
/* right shift 12 bit to make ratio in 32bit space */
1997+
val2 = (u64)in_samples << (frac_bits - 12);
1998+
val1 = val1 >> 12;
1999+
do_div(val2, val1);
2000+
out_samples = val2;
2001+
2002+
out_length = out_samples * out_width * channels;
2003+
ctx_priv->in_filled_len = ctx_priv->in_filled_sample * in_width * channels;
2004+
}
2005+
2006+
return out_length;
2007+
}
2008+
2009+
static int fsl_easrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair)
2010+
{
2011+
struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
2012+
2013+
if (dir == IN)
2014+
return ctx_priv->in_params.fifo_wtmk * pair->channels;
2015+
else
2016+
return ctx_priv->out_params.fifo_wtmk * pair->channels;
2017+
}
2018+
2019+
static int fsl_easrc_m2m_pair_suspend(struct fsl_asrc_pair *pair)
2020+
{
2021+
fsl_easrc_stop_context(pair);
2022+
2023+
return 0;
2024+
}
2025+
2026+
static int fsl_easrc_m2m_pair_resume(struct fsl_asrc_pair *pair)
2027+
{
2028+
struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
2029+
2030+
pair->first_convert = 1;
2031+
ctx_priv->in_filled_len = 0;
2032+
2033+
return 0;
2034+
}
2035+
2036+
/* val is Q31 */
2037+
static int fsl_easrc_m2m_set_ratio_mod(struct fsl_asrc_pair *pair, int val)
2038+
{
2039+
struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
2040+
struct fsl_asrc *easrc = pair->asrc;
2041+
struct fsl_easrc_priv *easrc_priv = easrc->private;
2042+
unsigned int frac_bits;
2043+
2044+
ctx_priv->ratio_mod += val;
2045+
2046+
switch (easrc_priv->rs_num_taps) {
2047+
case EASRC_RS_32_TAPS:
2048+
/* integer bits = 5; */
2049+
frac_bits = 39;
2050+
break;
2051+
case EASRC_RS_64_TAPS:
2052+
/* integer bits = 6; */
2053+
frac_bits = 38;
2054+
break;
2055+
case EASRC_RS_128_TAPS:
2056+
/* integer bits = 7; */
2057+
frac_bits = 37;
2058+
break;
2059+
default:
2060+
return -EINVAL;
2061+
}
2062+
2063+
val <<= (frac_bits - 31);
2064+
regmap_write(easrc->regmap, REG_EASRC_RUC(pair->index), EASRC_RSUC_RS_RM(val));
2065+
2066+
return 0;
2067+
}
2068+
2069+
static int fsl_easrc_m2m_get_cap(struct fsl_asrc_m2m_cap *cap)
2070+
{
2071+
cap->fmt_in = FSL_EASRC_FORMATS;
2072+
cap->fmt_out = FSL_EASRC_FORMATS | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
2073+
cap->rate_in = easrc_rates;
2074+
cap->rate_in_count = ARRAY_SIZE(easrc_rates);
2075+
cap->rate_out = easrc_rates;
2076+
cap->rate_out_count = ARRAY_SIZE(easrc_rates);
2077+
cap->chan_min = 1;
2078+
cap->chan_max = 32;
2079+
return 0;
2080+
}
2081+
18642082
static const struct of_device_id fsl_easrc_dt_ids[] = {
18652083
{ .compatible = "fsl,imx8mn-easrc",},
18662084
{}
@@ -1926,6 +2144,16 @@ static int fsl_easrc_probe(struct platform_device *pdev)
19262144
easrc->release_pair = fsl_easrc_release_context;
19272145
easrc->get_fifo_addr = fsl_easrc_get_fifo_addr;
19282146
easrc->pair_priv_size = sizeof(struct fsl_easrc_ctx_priv);
2147+
easrc->m2m_prepare = fsl_easrc_m2m_prepare;
2148+
easrc->m2m_start = fsl_easrc_m2m_start;
2149+
easrc->m2m_stop = fsl_easrc_m2m_stop;
2150+
easrc->get_output_fifo_size = fsl_easrc_get_output_fifo_size;
2151+
easrc->m2m_calc_out_len = fsl_easrc_m2m_calc_out_len;
2152+
easrc->m2m_get_maxburst = fsl_easrc_m2m_get_maxburst;
2153+
easrc->m2m_pair_suspend = fsl_easrc_m2m_pair_suspend;
2154+
easrc->m2m_pair_resume = fsl_easrc_m2m_pair_resume;
2155+
easrc->m2m_set_ratio_mod = fsl_easrc_m2m_set_ratio_mod;
2156+
easrc->m2m_get_cap = fsl_easrc_m2m_get_cap;
19292157

19302158
easrc_priv->rs_num_taps = EASRC_RS_32_TAPS;
19312159
easrc_priv->const_coeff = 0x3FF0000000000000;

sound/soc/fsl/fsl_easrc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ struct fsl_easrc_slot {
601601
* @out_missed_sample: sample missed in output
602602
* @st1_addexp: exponent added for stage1
603603
* @st2_addexp: exponent added for stage2
604+
* @ratio_mod: update ratio
605+
* @in_filled_len: input filled length
604606
*/
605607
struct fsl_easrc_ctx_priv {
606608
struct fsl_easrc_io_params in_params;
@@ -618,6 +620,8 @@ struct fsl_easrc_ctx_priv {
618620
int out_missed_sample;
619621
int st1_addexp;
620622
int st2_addexp;
623+
int ratio_mod;
624+
unsigned int in_filled_len;
621625
};
622626

623627
/**

0 commit comments

Comments
 (0)