@@ -1300,10 +1300,27 @@ static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw
13001300
13011301 if (param_to_update & BIT (SNDRV_PCM_HW_PARAM_FORMAT )) {
13021302 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1303+ int type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
13031304 snd_pcm_format_t snd_fmt ;
13041305 struct snd_mask * m ;
13051306
13061307 switch (valid_bits ) {
1308+ case 8 :
1309+ switch (type ) {
1310+ case SOF_IPC4_TYPE_A_LAW :
1311+ snd_fmt = SNDRV_PCM_FORMAT_A_LAW ;
1312+ break ;
1313+ case SOF_IPC4_TYPE_MU_LAW :
1314+ snd_fmt = SNDRV_PCM_FORMAT_MU_LAW ;
1315+ break ;
1316+ case SOF_IPC4_TYPE_UNSIGNED_INTEGER :
1317+ snd_fmt = SNDRV_PCM_FORMAT_U8 ;
1318+ break ;
1319+ default :
1320+ dev_err (sdev -> dev , "Unsupported PCM 8-bit IPC4 type %d\n" , type );
1321+ return - EINVAL ;
1322+ }
1323+ break ;
13071324 case 16 :
13081325 snd_fmt = SNDRV_PCM_FORMAT_S16_LE ;
13091326 break ;
@@ -1375,7 +1392,7 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
13751392 struct sof_ipc4_base_module_cfg * base_config ,
13761393 struct sof_ipc4_available_audio_format * available_fmt ,
13771394 u32 out_ref_rate , u32 out_ref_channels ,
1378- u32 out_ref_valid_bits )
1395+ u32 out_ref_valid_bits , u32 out_ref_type )
13791396{
13801397 struct sof_ipc4_pin_format * pin_fmts = available_fmt -> output_pin_fmts ;
13811398 u32 pin_fmts_size = available_fmt -> num_output_formats ;
@@ -1401,14 +1418,15 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
14011418 for (i = 0 ; i < pin_fmts_size ; i ++ ) {
14021419 struct sof_ipc4_audio_format * fmt = & pin_fmts [i ].audio_fmt ;
14031420
1404- u32 _out_rate , _out_channels , _out_valid_bits ;
1421+ u32 _out_rate , _out_channels , _out_valid_bits , _out_type ;
14051422
14061423 _out_rate = fmt -> sampling_frequency ;
14071424 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (fmt -> fmt_cfg );
14081425 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1426+ _out_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
14091427
14101428 if (_out_rate == out_ref_rate && _out_channels == out_ref_channels &&
1411- _out_valid_bits == out_ref_valid_bits )
1429+ _out_valid_bits == out_ref_valid_bits && _out_type == out_ref_type )
14121430 goto out_fmt ;
14131431 }
14141432
@@ -1426,6 +1444,10 @@ static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev,
14261444static int sof_ipc4_get_valid_bits (struct snd_sof_dev * sdev , struct snd_pcm_hw_params * params )
14271445{
14281446 switch (params_format (params )) {
1447+ case SNDRV_PCM_FORMAT_U8 :
1448+ case SNDRV_PCM_FORMAT_MU_LAW :
1449+ case SNDRV_PCM_FORMAT_A_LAW :
1450+ return 8 ;
14291451 case SNDRV_PCM_FORMAT_S16_LE :
14301452 return 16 ;
14311453 case SNDRV_PCM_FORMAT_S24_LE :
@@ -1438,6 +1460,25 @@ static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_p
14381460 }
14391461}
14401462
1463+ static int sof_ipc4_get_sample_type (struct snd_sof_dev * sdev , struct snd_pcm_hw_params * params )
1464+ {
1465+ switch (params_format (params )) {
1466+ case SNDRV_PCM_FORMAT_A_LAW :
1467+ return SOF_IPC4_TYPE_A_LAW ;
1468+ case SNDRV_PCM_FORMAT_MU_LAW :
1469+ return SOF_IPC4_TYPE_MU_LAW ;
1470+ case SNDRV_PCM_FORMAT_U8 :
1471+ return SOF_IPC4_TYPE_UNSIGNED_INTEGER ;
1472+ case SNDRV_PCM_FORMAT_S16_LE :
1473+ case SNDRV_PCM_FORMAT_S24_LE :
1474+ case SNDRV_PCM_FORMAT_S32_LE :
1475+ return SOF_IPC4_TYPE_LSB_INTEGER ;
1476+ default :
1477+ dev_err (sdev -> dev , "invalid pcm sample type %d\n" , params_format (params ));
1478+ return - EINVAL ;
1479+ }
1480+ }
1481+
14411482static int sof_ipc4_init_input_audio_fmt (struct snd_sof_dev * sdev ,
14421483 struct snd_sof_widget * swidget ,
14431484 struct sof_ipc4_base_module_cfg * base_config ,
@@ -1449,8 +1490,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
14491490 u32 valid_bits ;
14501491 u32 channels ;
14511492 u32 rate ;
1493+ u32 type ;
14521494 bool single_format ;
14531495 int sample_valid_bits ;
1496+ int sample_type ;
14541497 int i = 0 ;
14551498
14561499 if (!pin_fmts_size ) {
@@ -1466,6 +1509,10 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
14661509 if (sample_valid_bits < 0 )
14671510 return sample_valid_bits ;
14681511
1512+ sample_type = sof_ipc4_get_sample_type (sdev , params );
1513+ if (sample_type < 0 )
1514+ return sample_type ;
1515+
14691516 /*
14701517 * Search supported input audio formats with pin index 0 to match rate, channels and
14711518 * sample_valid_bits from reference params
@@ -1479,8 +1526,9 @@ static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev,
14791526 rate = fmt -> sampling_frequency ;
14801527 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (fmt -> fmt_cfg );
14811528 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
1529+ type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (fmt -> fmt_cfg );
14821530 if (params_rate (params ) == rate && params_channels (params ) == channels &&
1483- sample_valid_bits == valid_bits )
1531+ sample_valid_bits == valid_bits && sample_type == type )
14841532 break ;
14851533 }
14861534
@@ -1901,7 +1949,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
19011949 int * ipc_config_size ;
19021950 u32 * * data ;
19031951 int ipc_size , ret , out_ref_valid_bits ;
1904- u32 out_ref_rate , out_ref_channels ;
1952+ u32 out_ref_rate , out_ref_channels , out_ref_type ;
19051953 u32 deep_buffer_dma_ms = 0 ;
19061954 bool single_output_bitdepth ;
19071955 int i ;
@@ -1942,10 +1990,20 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
19421990 host_dma_id = platform_params -> stream_tag - 1 ;
19431991 pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID (host_dma_id );
19441992
1945- /* Set SCS bit for S16_LE format only */
19461993 if (params_format (fe_params ) == SNDRV_PCM_FORMAT_S16_LE )
19471994 pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK ;
19481995
1996+ /* Set SCS bit for 8 and 16 bit formats */
1997+ switch (params_format (fe_params )) {
1998+ case SNDRV_PCM_FORMAT_S16_LE :
1999+ case SNDRV_PCM_FORMAT_U8 :
2000+ case SNDRV_PCM_FORMAT_A_LAW :
2001+ case SNDRV_PCM_FORMAT_MU_LAW :
2002+ pipeline -> msg .primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK ;
2003+ default :
2004+ break ;
2005+ }
2006+
19492007 /*
19502008 * Despite its name the bitfield 'fifo_size' is used to define DMA buffer
19512009 * size. The expression calculates 2ms buffer size.
@@ -2070,6 +2128,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
20702128 in_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
20712129 out_ref_rate = in_fmt -> sampling_frequency ;
20722130 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
2131+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
20732132
20742133 if (!single_output_bitdepth )
20752134 out_ref_valid_bits =
@@ -2080,6 +2139,10 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
20802139 case snd_soc_dapm_dai_in :
20812140 out_ref_rate = params_rate (fe_params );
20822141 out_ref_channels = params_channels (fe_params );
2142+ out_ref_type = sof_ipc4_get_sample_type (sdev , fe_params );
2143+ if (out_ref_type < 0 )
2144+ return out_ref_type ;
2145+
20832146 if (!single_output_bitdepth ) {
20842147 out_ref_valid_bits = sof_ipc4_get_valid_bits (sdev , fe_params );
20852148 if (out_ref_valid_bits < 0 )
@@ -2104,12 +2167,14 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
21042167 out_fmt = & available_fmt -> output_pin_fmts [0 ].audio_fmt ;
21052168 out_ref_valid_bits =
21062169 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (out_fmt -> fmt_cfg );
2170+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (out_fmt -> fmt_cfg );
21072171 }
21082172
21092173 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
21102174 & copier_data -> base_config ,
21112175 available_fmt , out_ref_rate ,
2112- out_ref_channels , out_ref_valid_bits );
2176+ out_ref_channels , out_ref_valid_bits ,
2177+ out_ref_type );
21132178 if (output_fmt_index < 0 )
21142179 return output_fmt_index ;
21152180
@@ -2338,7 +2403,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
23382403 struct sof_ipc4_gain * gain = swidget -> private ;
23392404 struct sof_ipc4_available_audio_format * available_fmt = & gain -> available_fmt ;
23402405 struct sof_ipc4_audio_format * in_fmt ;
2341- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2406+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
23422407 int input_fmt_index , output_fmt_index ;
23432408
23442409 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2352,13 +2417,15 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
23522417 out_ref_rate = in_fmt -> sampling_frequency ;
23532418 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
23542419 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2420+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
23552421
23562422 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
23572423 & gain -> data .base_config ,
23582424 available_fmt ,
23592425 out_ref_rate ,
23602426 out_ref_channels ,
2361- out_ref_valid_bits );
2427+ out_ref_valid_bits ,
2428+ out_ref_type );
23622429 if (output_fmt_index < 0 )
23632430 return output_fmt_index ;
23642431
@@ -2381,7 +2448,7 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
23812448 struct sof_ipc4_mixer * mixer = swidget -> private ;
23822449 struct sof_ipc4_available_audio_format * available_fmt = & mixer -> available_fmt ;
23832450 struct sof_ipc4_audio_format * in_fmt ;
2384- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2451+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
23852452 int input_fmt_index , output_fmt_index ;
23862453
23872454 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2395,13 +2462,15 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
23952462 out_ref_rate = in_fmt -> sampling_frequency ;
23962463 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
23972464 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2465+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
23982466
23992467 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
24002468 & mixer -> base_config ,
24012469 available_fmt ,
24022470 out_ref_rate ,
24032471 out_ref_channels ,
2404- out_ref_valid_bits );
2472+ out_ref_valid_bits ,
2473+ out_ref_type );
24052474 if (output_fmt_index < 0 )
24062475 return output_fmt_index ;
24072476
@@ -2425,7 +2494,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24252494 struct sof_ipc4_available_audio_format * available_fmt = & src -> available_fmt ;
24262495 struct sof_ipc4_audio_format * out_audio_fmt ;
24272496 struct sof_ipc4_audio_format * in_audio_fmt ;
2428- u32 out_ref_rate , out_ref_channels , out_ref_valid_bits ;
2497+ u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
24292498 int output_fmt_index , input_fmt_index ;
24302499
24312500 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
@@ -2452,6 +2521,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24522521 in_audio_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
24532522 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_audio_fmt -> fmt_cfg );
24542523 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_audio_fmt -> fmt_cfg );
2524+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_audio_fmt -> fmt_cfg );
24552525
24562526 /*
24572527 * For capture, the SRC module should convert the rate to match the rate requested by the
@@ -2465,7 +2535,8 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
24652535 available_fmt ,
24662536 out_ref_rate ,
24672537 out_ref_channels ,
2468- out_ref_valid_bits );
2538+ out_ref_valid_bits ,
2539+ out_ref_type );
24692540 if (output_fmt_index < 0 )
24702541 return output_fmt_index ;
24712542
@@ -2589,20 +2660,22 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
25892660 struct sof_ipc4_audio_format * in_fmt ;
25902661 struct sof_ipc4_pin_format * pin_fmt ;
25912662 u32 out_ref_rate , out_ref_channels ;
2592- int out_ref_valid_bits ;
2663+ int out_ref_valid_bits , out_ref_type ;
25932664
25942665 in_fmt = & available_fmt -> input_pin_fmts [input_fmt_index ].audio_fmt ;
25952666
25962667 out_ref_rate = in_fmt -> sampling_frequency ;
25972668 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (in_fmt -> fmt_cfg );
25982669 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (in_fmt -> fmt_cfg );
2670+ out_ref_type = SOF_IPC4_AUDIO_FORMAT_CFG_SAMPLE_TYPE (in_fmt -> fmt_cfg );
25992671
26002672 output_fmt_index = sof_ipc4_init_output_audio_fmt (sdev , swidget ,
26012673 & process -> base_config ,
26022674 available_fmt ,
26032675 out_ref_rate ,
26042676 out_ref_channels ,
2605- out_ref_valid_bits );
2677+ out_ref_valid_bits ,
2678+ out_ref_type );
26062679 if (output_fmt_index < 0 )
26072680 return output_fmt_index ;
26082681
0 commit comments