@@ -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+
18642082static 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 ;
0 commit comments