@@ -1246,3 +1246,115 @@ u64 hda_dsp_get_stream_ldp(struct snd_sof_dev *sdev,
12461246 return ((u64 )ldp_u << 32 ) | ldp_l ;
12471247}
12481248EXPORT_SYMBOL_NS (hda_dsp_get_stream_ldp , "SND_SOC_SOF_INTEL_HDA_COMMON" );
1249+
1250+ struct hdac_ext_stream *
1251+ hda_dma_prepare (struct device * dev , unsigned int format , unsigned int size ,
1252+ struct snd_dma_buffer * dmab , bool persistent_buffer , int direction ,
1253+ bool is_iccmax , bool pair )
1254+ {
1255+ struct snd_sof_dev * sdev = dev_get_drvdata (dev );
1256+ struct hdac_ext_stream * hext_stream ;
1257+ struct hdac_stream * hstream ;
1258+ int ret ;
1259+
1260+ if (pair )
1261+ hext_stream = hda_dsp_stream_pair_get (sdev , direction , 0 );
1262+ else
1263+ hext_stream = hda_dsp_stream_get (sdev , direction , 0 );
1264+
1265+ if (!hext_stream ) {
1266+ dev_err (sdev -> dev , "error: no stream available\n" );
1267+ return ERR_PTR (- ENODEV );
1268+ }
1269+ hstream = & hext_stream -> hstream ;
1270+ hstream -> substream = NULL ;
1271+
1272+ /*
1273+ * Allocate DMA buffer if it is temporary or if the buffer is intended
1274+ * to be persistent but not yet allocated.
1275+ * We cannot rely solely on !dmab->area as caller might use a struct on
1276+ * stack (when it is temporary) without clearing it to 0.
1277+ */
1278+ if (!persistent_buffer || !dmab -> area ) {
1279+ ret = snd_dma_alloc_pages (SNDRV_DMA_TYPE_DEV_SG , dev , size , dmab );
1280+ if (ret < 0 ) {
1281+ dev_err (sdev -> dev , "%s: memory alloc failed: %d\n" ,
1282+ __func__ , ret );
1283+ goto out_put ;
1284+ }
1285+ }
1286+
1287+ hstream -> period_bytes = 0 ;/* initialize period_bytes */
1288+ hstream -> format_val = format ;
1289+ hstream -> bufsize = size ;
1290+
1291+ if (is_iccmax ) {
1292+ ret = hda_dsp_iccmax_stream_hw_params (sdev , hext_stream , dmab , NULL );
1293+ if (ret < 0 ) {
1294+ dev_err (sdev -> dev , "error: iccmax stream prepare failed: %d\n" , ret );
1295+ goto out_free ;
1296+ }
1297+ } else {
1298+ ret = hda_dsp_stream_hw_params (sdev , hext_stream , dmab , NULL );
1299+ if (ret < 0 ) {
1300+ dev_err (sdev -> dev , "error: hdac prepare failed: %d\n" , ret );
1301+ goto out_free ;
1302+ }
1303+ hda_dsp_stream_spib_config (sdev , hext_stream , HDA_DSP_SPIB_ENABLE , size );
1304+ }
1305+
1306+ return hext_stream ;
1307+
1308+ out_free :
1309+ snd_dma_free_pages (dmab );
1310+ dmab -> area = NULL ;
1311+ dmab -> bytes = 0 ;
1312+ hstream -> bufsize = 0 ;
1313+ hstream -> format_val = 0 ;
1314+ out_put :
1315+ hda_dsp_stream_put (sdev , direction , hstream -> stream_tag );
1316+ return ERR_PTR (ret );
1317+ }
1318+ EXPORT_SYMBOL_NS (hda_dma_prepare , "SND_SOC_SOF_INTEL_HDA_COMMON" );
1319+
1320+ int hda_dma_cleanup (struct device * dev , struct snd_dma_buffer * dmab ,
1321+ bool persistent_buffer , struct hdac_ext_stream * hext_stream , bool pair )
1322+ {
1323+ struct snd_sof_dev * sdev = dev_get_drvdata (dev );
1324+ struct hdac_stream * hstream = hdac_stream (hext_stream );
1325+ int sd_offset = SOF_STREAM_SD_OFFSET (hstream );
1326+ int ret = 0 ;
1327+
1328+ if (hstream -> direction == SNDRV_PCM_STREAM_PLAYBACK )
1329+ ret = hda_dsp_stream_spib_config (sdev , hext_stream , HDA_DSP_SPIB_DISABLE , 0 );
1330+ else
1331+ snd_sof_dsp_update_bits (sdev , HDA_DSP_HDA_BAR , sd_offset ,
1332+ SOF_HDA_SD_CTL_DMA_START , 0 );
1333+
1334+ if (pair )
1335+ hda_dsp_stream_pair_put (sdev , hstream -> direction , hstream -> stream_tag );
1336+ else
1337+ hda_dsp_stream_put (sdev , hstream -> direction , hstream -> stream_tag );
1338+
1339+ hstream -> running = 0 ;
1340+ hstream -> substream = NULL ;
1341+
1342+ /* reset BDL address */
1343+ snd_sof_dsp_write (sdev , HDA_DSP_HDA_BAR ,
1344+ sd_offset + SOF_HDA_ADSP_REG_SD_BDLPL , 0 );
1345+ snd_sof_dsp_write (sdev , HDA_DSP_HDA_BAR ,
1346+ sd_offset + SOF_HDA_ADSP_REG_SD_BDLPU , 0 );
1347+
1348+ snd_sof_dsp_write (sdev , HDA_DSP_HDA_BAR , sd_offset , 0 );
1349+
1350+ if (!persistent_buffer ) {
1351+ snd_dma_free_pages (dmab );
1352+ dmab -> area = NULL ;
1353+ dmab -> bytes = 0 ;
1354+ hstream -> bufsize = 0 ;
1355+ hstream -> format_val = 0 ;
1356+ }
1357+
1358+ return ret ;
1359+ }
1360+ EXPORT_SYMBOL_NS (hda_dma_cleanup , "SND_SOC_SOF_INTEL_HDA_COMMON" );
0 commit comments