@@ -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,25 @@ 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+ return SOF_IPC4_TYPE_LSB_INTEGER ;
1518+ default :
1519+ dev_err (sdev -> dev , "invalid pcm sample type %d\n" , params_format (params ));
1520+ return - EINVAL ;
1521+ }
1522+ }
1523+
14831524static int sof_ipc4_init_input_audio_fmt (struct snd_sof_dev * sdev ,
14841525 struct snd_sof_widget * swidget ,
14851526 struct sof_ipc4_base_module_cfg * base_config ,
@@ -1491,8 +1532,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
14911532 u32 valid_bits ;
14921533 u32 channels ;
14931534 u32 rate ;
1535+ u32 type ;
14941536 bool single_format ;
14951537 int sample_valid_bits ;
1538+ int sample_type ;
14961539 int i = 0 ;
14971540
14981541 if (!pin_fmts_size ) {
@@ -1508,6 +1551,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
15081551 if (sample_valid_bits < 0 )
15091552 return sample_valid_bits ;
15101553
1554+ sample_type = sof_ipc4_get_sample_type (sdev , params );
1555+ if (sample_type < 0 )
1556+ return sample_type ;
1557+
15111558 /*
15121559 * Search supported input audio formats with pin index 0 to match rate, channels and
15131560 * sample_valid_bits from reference params
@@ -1521,8 +1568,9 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
15211568 rate = fmt -> sampling_frequency ;
15221569 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (fmt -> fmt_cfg );
15231570 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1571+ type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
15241572 if (params_rate (params ) == rate && params_channels (params ) == channels &&
1525- sample_valid_bits == valid_bits )
1573+ sample_valid_bits == valid_bits && sample_type == type )
15261574 break ;
15271575 }
15281576
@@ -1943,7 +1991,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
19431991 int * ipc_config_size ;
19441992 u32 * * data ;
19451993 int ipc_size , ret , out_ref_valid_bits ;
1946- u32 out_ref_rate , out_ref_channels ;
1994+ u32 out_ref_rate , out_ref_channels , out_ref_type ;
19471995 u32 deep_buffer_dma_ms = 0 ;
19481996 bool single_output_bitdepth ;
19491997 int i ;
@@ -1984,10 +2032,20 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
19842032 host_dma_id = platform_params -> stream_tag - 1 ;
19852033 pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID (host_dma_id );
19862034
1987- /* Set SCS bit for S16_LE format only */
19882035 if (params_format (fe_params ) == SNDRV_PCM_FORMAT_S16_LE )
19892036 pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK ;
19902037
2038+ /* Set SCS bit for 8 and 16 bit formats */
2039+ switch (params_format (fe_params )) {
2040+ case SNDRV_PCM_FORMAT_S16_LE :
2041+ case SNDRV_PCM_FORMAT_U8 :
2042+ case SNDRV_PCM_FORMAT_A_LAW :
2043+ case SNDRV_PCM_FORMAT_MU_LAW :
2044+ pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK ;
2045+ default :
2046+ break ;
2047+ }
2048+
19912049 /*
19922050 * Despite its name the bitfield 'fifo_size' is used to define DMA buffer
19932051 * size. The expression calculates 2ms buffer size.
@@ -2112,6 +2170,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21122170 in_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
21132171 out_ref_rate = in_fmt -> sampling_frequency ;
21142172 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
2173+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
21152174
21162175 if (!single_output_bitdepth )
21172176 out_ref_valid_bits =
@@ -2122,6 +2181,10 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21222181 case snd_soc_dapm_dai_in :
21232182 out_ref_rate = params_rate (fe_params );
21242183 out_ref_channels = params_channels (fe_params );
2184+ out_ref_type = sof_ipc4_get_sample_type (sdev , fe_params );
2185+ if (out_ref_type < 0 )
2186+ return out_ref_type ;
2187+
21252188 if (!single_output_bitdepth ) {
21262189 out_ref_valid_bits = sof_ipc4_get_valid_bits (sdev , fe_params );
21272190 if (out_ref_valid_bits < 0 )
@@ -2146,12 +2209,14 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21462209 out_fmt = & available_fmt -> output_pin_fmts [0 ].audio_fmt ;
21472210 out_ref_valid_bits =
21482211 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (out_fmt -> fmt_cfg );
2212+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (out_fmt -> fmt_cfg );
21492213 }
21502214
21512215 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
21522216 & copier_data -> base_config ,
21532217 available_fmt , out_ref_rate ,
2154- out_ref_channels , out_ref_valid_bits );
2218+ out_ref_channels , out_ref_valid_bits ,
2219+ out_ref_type );
21552220 if (output_fmt_index < 0 )
21562221 return output_fmt_index ;
21572222
@@ -2380,7 +2445,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
23802445 struct sof_ipc4_gain * gain = swidget -> private ;
23812446 struct sof_ipc4_available_audio_format * available_fmt = & gain -> available_fmt ;
23822447 struct sof_ipc4_audio_format * in_fmt ;
2383- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2448+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
23842449 int input_fmt_index , output_fmt_index ;
23852450
23862451 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2394,13 +2459,15 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
23942459 out_ref_rate = in_fmt -> sampling_frequency ;
23952460 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
23962461 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2462+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
23972463
23982464 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
23992465 & gain -> data .base_config ,
24002466 available_fmt ,
24012467 out_ref_rate ,
24022468 out_ref_channels ,
2403- out_ref_valid_bits );
2469+ out_ref_valid_bits ,
2470+ out_ref_type );
24042471 if (output_fmt_index < 0 )
24052472 return output_fmt_index ;
24062473
@@ -2423,7 +2490,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
24232490 struct sof_ipc4_mixer * mixer = swidget -> private ;
24242491 struct sof_ipc4_available_audio_format * available_fmt = & mixer -> available_fmt ;
24252492 struct sof_ipc4_audio_format * in_fmt ;
2426- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2493+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
24272494 int input_fmt_index , output_fmt_index ;
24282495
24292496 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2437,13 +2504,15 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
24372504 out_ref_rate = in_fmt -> sampling_frequency ;
24382505 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
24392506 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2507+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
24402508
24412509 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
24422510 & mixer -> base_config ,
24432511 available_fmt ,
24442512 out_ref_rate ,
24452513 out_ref_channels ,
2446- out_ref_valid_bits );
2514+ out_ref_valid_bits ,
2515+ out_ref_type );
24472516 if (output_fmt_index < 0 )
24482517 return output_fmt_index ;
24492518
@@ -2467,7 +2536,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24672536 struct sof_ipc4_available_audio_format * available_fmt = & src -> available_fmt ;
24682537 struct sof_ipc4_audio_format * out_audio_fmt ;
24692538 struct sof_ipc4_audio_format * in_audio_fmt ;
2470- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2539+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
24712540 int output_fmt_index , input_fmt_index ;
24722541
24732542 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2494,6 +2563,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24942563 in_audio_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
24952564 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_audio_fmt -> fmt_cfg );
24962565 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_audio_fmt -> fmt_cfg );
2566+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_audio_fmt -> fmt_cfg );
24972567
24982568 /*
24992569 * For capture, the SRC module should convert the rate to match the rate requested by the
@@ -2507,7 +2577,8 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
25072577 available_fmt ,
25082578 out_ref_rate ,
25092579 out_ref_channels ,
2510- out_ref_valid_bits );
2580+ out_ref_valid_bits ,
2581+ out_ref_type );
25112582 if (output_fmt_index < 0 )
25122583 return output_fmt_index ;
25132584
@@ -2631,20 +2702,22 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
26312702 struct sof_ipc4_audio_format * in_fmt ;
26322703 struct sof_ipc4_pin_format * pin_fmt ;
26332704 u32 out_ref_rate , out_ref_channels ;
2634- int out_ref_valid_bits ;
2705+ int out_ref_valid_bits , out_ref_type ;
26352706
26362707 in_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
26372708
26382709 out_ref_rate = in_fmt -> sampling_frequency ;
26392710 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
26402711 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2712+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
26412713
26422714 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
26432715 & process -> base_config ,
26442716 available_fmt ,
26452717 out_ref_rate ,
26462718 out_ref_channels ,
2647- out_ref_valid_bits );
2719+ out_ref_valid_bits ,
2720+ out_ref_type );
26482721 if (output_fmt_index < 0 )
26492722 return output_fmt_index ;
26502723
0 commit comments