@@ -1342,10 +1342,27 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
13421342
13431343 if (param_to_update & BIT (SNDRV_PCM_HW_PARAM_FORMAT )) {
13441344 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1345+ int type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
13451346 snd_pcm_format_t snd_fmt ;
13461347 struct snd_mask * m ;
13471348
13481349 switch (valid_bits ) {
1350+ case 8 :
1351+ switch (type ) {
1352+ case SOF_IPC4_TYPE_A_LAW :
1353+ snd_fmt = SNDRV_PCM_FORMAT_A_LAW ;
1354+ break ;
1355+ case SOF_IPC4_TYPE_MU_LAW :
1356+ snd_fmt = SNDRV_PCM_FORMAT_MU_LAW ;
1357+ break ;
1358+ case SOF_IPC4_TYPE_UNSIGNED_INTEGER :
1359+ snd_fmt = SNDRV_PCM_FORMAT_U8 ;
1360+ break ;
1361+ default :
1362+ dev_err (sdev -> dev , "Unsupported PCM 8-bit IPC4 type %d\n" , type );
1363+ return - EINVAL ;
1364+ }
1365+ break ;
13491366 case 16 :
13501367 snd_fmt = SNDRV_PCM_FORMAT_S16_LE ;
13511368 break ;
@@ -1417,7 +1434,7 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
14171434 struct sof_ipc4_base_module_cfg * base_config ,
14181435 struct sof_ipc4_available_audio_format * available_fmt ,
14191436 u32 out_ref_rate , u32 out_ref_channels ,
1420- u32 out_ref_valid_bits )
1437+ u32 out_ref_valid_bits , u32 out_ref_type )
14211438{
14221439 struct sof_ipc4_pin_format * pin_fmts = available_fmt -> output_pin_fmts ;
14231440 u32 pin_fmts_size = available_fmt -> num_output_formats ;
@@ -1443,14 +1460,15 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
14431460 for (i = 0 ; i < pin_fmts_size ; i ++ ) {
14441461 struct sof_ipc4_audio_format * fmt = & pin_fmts [i ].audio_fmt ;
14451462
1446- u32 _out_rate , _out_channels , _out_valid_bits ;
1463+ u32 _out_rate , _out_channels , _out_valid_bits , _out_type ;
14471464
14481465 _out_rate = fmt -> sampling_frequency ;
14491466 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (fmt -> fmt_cfg );
14501467 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1468+ _out_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
14511469
14521470 if (_out_rate == out_ref_rate && _out_channels == out_ref_channels &&
1453- _out_valid_bits == out_ref_valid_bits )
1471+ _out_valid_bits == out_ref_valid_bits && _out_type == out_ref_type )
14541472 goto out_fmt ;
14551473 }
14561474
@@ -1468,6 +1486,10 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
14681486static int sof_ipc4_get_valid_bits (struct snd_sof_dev * sdev , struct snd_pcm_hw_params * params )
14691487{
14701488 switch (params_format (params )) {
1489+ case SNDRV_PCM_FORMAT_U8 :
1490+ case SNDRV_PCM_FORMAT_MU_LAW :
1491+ case SNDRV_PCM_FORMAT_A_LAW :
1492+ return 8 ;
14711493 case SNDRV_PCM_FORMAT_S16_LE :
14721494 return 16 ;
14731495 case SNDRV_PCM_FORMAT_S24_LE :
@@ -1480,6 +1502,26 @@ static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_p
14801502 }
14811503}
14821504
1505+ static int sof_ipc4_get_sample_type (struct snd_sof_dev * sdev , struct snd_pcm_hw_params * params )
1506+ {
1507+ switch (params_format (params )) {
1508+ case SNDRV_PCM_FORMAT_A_LAW :
1509+ return SOF_IPC4_TYPE_A_LAW ;
1510+ case SNDRV_PCM_FORMAT_MU_LAW :
1511+ return SOF_IPC4_TYPE_MU_LAW ;
1512+ case SNDRV_PCM_FORMAT_U8 :
1513+ return SOF_IPC4_TYPE_UNSIGNED_INTEGER ;
1514+ case SNDRV_PCM_FORMAT_S16_LE :
1515+ case SNDRV_PCM_FORMAT_S24_LE :
1516+ case SNDRV_PCM_FORMAT_S32_LE :
1517+ case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE :
1518+ return SOF_IPC4_TYPE_LSB_INTEGER ;
1519+ default :
1520+ dev_err (sdev -> dev , "invalid pcm sample type %d\n" , params_format (params ));
1521+ return - EINVAL ;
1522+ }
1523+ }
1524+
14831525static int sof_ipc4_init_input_audio_fmt (struct snd_sof_dev * sdev ,
14841526 struct snd_sof_widget * swidget ,
14851527 struct sof_ipc4_base_module_cfg * base_config ,
@@ -1491,8 +1533,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
14911533 u32 valid_bits ;
14921534 u32 channels ;
14931535 u32 rate ;
1536+ u32 type ;
14941537 bool single_format ;
14951538 int sample_valid_bits ;
1539+ int sample_type ;
14961540 int i = 0 ;
14971541
14981542 if (!pin_fmts_size ) {
@@ -1508,6 +1552,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
15081552 if (sample_valid_bits < 0 )
15091553 return sample_valid_bits ;
15101554
1555+ sample_type = sof_ipc4_get_sample_type (sdev , params );
1556+ if (sample_type < 0 )
1557+ return sample_type ;
1558+
15111559 /*
15121560 * Search supported input audio formats with pin index 0 to match rate, channels and
15131561 * sample_valid_bits from reference params
@@ -1521,8 +1569,9 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
15211569 rate = fmt -> sampling_frequency ;
15221570 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (fmt -> fmt_cfg );
15231571 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1572+ type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
15241573 if (params_rate (params ) == rate && params_channels (params ) == channels &&
1525- sample_valid_bits == valid_bits )
1574+ sample_valid_bits == valid_bits && sample_type == type )
15261575 break ;
15271576 }
15281577
@@ -1943,7 +1992,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
19431992 int * ipc_config_size ;
19441993 u32 * * data ;
19451994 int ipc_size , ret , out_ref_valid_bits ;
1946- u32 out_ref_rate , out_ref_channels ;
1995+ u32 out_ref_rate , out_ref_channels , out_ref_type ;
19471996 u32 deep_buffer_dma_ms = 0 ;
19481997 bool single_output_bitdepth ;
19491998 int i ;
@@ -1984,10 +2033,13 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
19842033 host_dma_id = platform_params -> stream_tag - 1 ;
19852034 pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID (host_dma_id );
19862035
1987- /* Set SCS bit for S16_LE format only */
19882036 if (params_format (fe_params ) == SNDRV_PCM_FORMAT_S16_LE )
19892037 pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK ;
19902038
2039+ /* Set SCS bit for 8 and 16 bit formats */
2040+ if (params_physical_width (fe_params ) <= 16 )
2041+ pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK ;
2042+
19912043 /*
19922044 * Despite its name the bitfield 'fifo_size' is used to define DMA buffer
19932045 * size. The expression calculates 2ms buffer size.
@@ -2112,6 +2164,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21122164 in_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
21132165 out_ref_rate = in_fmt -> sampling_frequency ;
21142166 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
2167+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
21152168
21162169 if (!single_output_bitdepth )
21172170 out_ref_valid_bits =
@@ -2122,6 +2175,10 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21222175 case snd_soc_dapm_dai_in :
21232176 out_ref_rate = params_rate (fe_params );
21242177 out_ref_channels = params_channels (fe_params );
2178+ out_ref_type = sof_ipc4_get_sample_type (sdev , fe_params );
2179+ if (out_ref_type < 0 )
2180+ return out_ref_type ;
2181+
21252182 if (!single_output_bitdepth ) {
21262183 out_ref_valid_bits = sof_ipc4_get_valid_bits (sdev , fe_params );
21272184 if (out_ref_valid_bits < 0 )
@@ -2146,12 +2203,14 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21462203 out_fmt = & available_fmt -> output_pin_fmts [0 ].audio_fmt ;
21472204 out_ref_valid_bits =
21482205 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (out_fmt -> fmt_cfg );
2206+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (out_fmt -> fmt_cfg );
21492207 }
21502208
21512209 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
21522210 & copier_data -> base_config ,
21532211 available_fmt , out_ref_rate ,
2154- out_ref_channels , out_ref_valid_bits );
2212+ out_ref_channels , out_ref_valid_bits ,
2213+ out_ref_type );
21552214 if (output_fmt_index < 0 )
21562215 return output_fmt_index ;
21572216
@@ -2380,7 +2439,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
23802439 struct sof_ipc4_gain * gain = swidget -> private ;
23812440 struct sof_ipc4_available_audio_format * available_fmt = & gain -> available_fmt ;
23822441 struct sof_ipc4_audio_format * in_fmt ;
2383- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2442+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
23842443 int input_fmt_index , output_fmt_index ;
23852444
23862445 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2394,13 +2453,15 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
23942453 out_ref_rate = in_fmt -> sampling_frequency ;
23952454 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
23962455 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2456+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
23972457
23982458 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
23992459 & gain -> data .base_config ,
24002460 available_fmt ,
24012461 out_ref_rate ,
24022462 out_ref_channels ,
2403- out_ref_valid_bits );
2463+ out_ref_valid_bits ,
2464+ out_ref_type );
24042465 if (output_fmt_index < 0 )
24052466 return output_fmt_index ;
24062467
@@ -2423,7 +2484,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
24232484 struct sof_ipc4_mixer * mixer = swidget -> private ;
24242485 struct sof_ipc4_available_audio_format * available_fmt = & mixer -> available_fmt ;
24252486 struct sof_ipc4_audio_format * in_fmt ;
2426- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2487+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
24272488 int input_fmt_index , output_fmt_index ;
24282489
24292490 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2437,13 +2498,15 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
24372498 out_ref_rate = in_fmt -> sampling_frequency ;
24382499 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
24392500 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2501+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
24402502
24412503 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
24422504 & mixer -> base_config ,
24432505 available_fmt ,
24442506 out_ref_rate ,
24452507 out_ref_channels ,
2446- out_ref_valid_bits );
2508+ out_ref_valid_bits ,
2509+ out_ref_type );
24472510 if (output_fmt_index < 0 )
24482511 return output_fmt_index ;
24492512
@@ -2467,7 +2530,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24672530 struct sof_ipc4_available_audio_format * available_fmt = & src -> available_fmt ;
24682531 struct sof_ipc4_audio_format * out_audio_fmt ;
24692532 struct sof_ipc4_audio_format * in_audio_fmt ;
2470- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2533+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
24712534 int output_fmt_index , input_fmt_index ;
24722535
24732536 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2494,6 +2557,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24942557 in_audio_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
24952558 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_audio_fmt -> fmt_cfg );
24962559 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_audio_fmt -> fmt_cfg );
2560+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_audio_fmt -> fmt_cfg );
24972561
24982562 /*
24992563 * For capture, the SRC module should convert the rate to match the rate requested by the
@@ -2507,7 +2571,8 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
25072571 available_fmt ,
25082572 out_ref_rate ,
25092573 out_ref_channels ,
2510- out_ref_valid_bits );
2574+ out_ref_valid_bits ,
2575+ out_ref_type );
25112576 if (output_fmt_index < 0 )
25122577 return output_fmt_index ;
25132578
@@ -2631,20 +2696,22 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
26312696 struct sof_ipc4_audio_format * in_fmt ;
26322697 struct sof_ipc4_pin_format * pin_fmt ;
26332698 u32 out_ref_rate , out_ref_channels ;
2634- int out_ref_valid_bits ;
2699+ int out_ref_valid_bits , out_ref_type ;
26352700
26362701 in_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
26372702
26382703 out_ref_rate = in_fmt -> sampling_frequency ;
26392704 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
26402705 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2706+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
26412707
26422708 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
26432709 & process -> base_config ,
26442710 available_fmt ,
26452711 out_ref_rate ,
26462712 out_ref_channels ,
2647- out_ref_valid_bits );
2713+ out_ref_valid_bits ,
2714+ out_ref_type );
26482715 if (output_fmt_index < 0 )
26492716 return output_fmt_index ;
26502717
0 commit comments