@@ -737,6 +737,85 @@ static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
737737 return ret ;
738738}
739739
740+ static int q6apm_dai_compr_mmap (struct snd_soc_component * component ,
741+ struct snd_compr_stream * stream ,
742+ struct vm_area_struct * vma )
743+ {
744+ struct snd_compr_runtime * runtime = stream -> runtime ;
745+ struct q6apm_dai_rtd * prtd = runtime -> private_data ;
746+ struct device * dev = component -> dev ;
747+
748+ return dma_mmap_coherent (dev , vma , prtd -> dma_buffer .area , prtd -> dma_buffer .addr ,
749+ prtd -> dma_buffer .bytes );
750+ }
751+
752+ static int q6apm_compr_copy (struct snd_soc_component * component ,
753+ struct snd_compr_stream * stream , char __user * buf ,
754+ size_t count )
755+ {
756+ struct snd_compr_runtime * runtime = stream -> runtime ;
757+ struct q6apm_dai_rtd * prtd = runtime -> private_data ;
758+ void * dstn ;
759+ unsigned long flags ;
760+ size_t copy ;
761+ u32 wflags = 0 ;
762+ u32 app_pointer ;
763+ u32 bytes_received ;
764+ uint32_t bytes_to_write ;
765+ int avail , bytes_in_flight = 0 ;
766+
767+ bytes_received = prtd -> bytes_received ;
768+
769+ /**
770+ * Make sure that next track data pointer is aligned at 32 bit boundary
771+ * This is a Mandatory requirement from DSP data buffers alignment
772+ */
773+ if (prtd -> next_track )
774+ bytes_received = ALIGN (prtd -> bytes_received , prtd -> pcm_count );
775+
776+ app_pointer = bytes_received /prtd -> pcm_size ;
777+ app_pointer = bytes_received - (app_pointer * prtd -> pcm_size );
778+ dstn = prtd -> dma_buffer .area + app_pointer ;
779+
780+ if (count < prtd -> pcm_size - app_pointer ) {
781+ if (copy_from_user (dstn , buf , count ))
782+ return - EFAULT ;
783+ } else {
784+ copy = prtd -> pcm_size - app_pointer ;
785+ if (copy_from_user (dstn , buf , copy ))
786+ return - EFAULT ;
787+ if (copy_from_user (prtd -> dma_buffer .area , buf + copy , count - copy ))
788+ return - EFAULT ;
789+ }
790+
791+ spin_lock_irqsave (& prtd -> lock , flags );
792+ bytes_in_flight = prtd -> bytes_received - prtd -> copied_total ;
793+
794+ if (prtd -> next_track ) {
795+ prtd -> next_track = false;
796+ prtd -> copied_total = ALIGN (prtd -> copied_total , prtd -> pcm_count );
797+ prtd -> bytes_sent = ALIGN (prtd -> bytes_sent , prtd -> pcm_count );
798+ }
799+
800+ prtd -> bytes_received = bytes_received + count ;
801+
802+ /* Kick off the data to dsp if its starving!! */
803+ if (prtd -> state == Q6APM_STREAM_RUNNING && (bytes_in_flight == 0 )) {
804+ bytes_to_write = prtd -> pcm_count ;
805+ avail = prtd -> bytes_received - prtd -> bytes_sent ;
806+
807+ if (avail < prtd -> pcm_count )
808+ bytes_to_write = avail ;
809+
810+ q6apm_write_async (prtd -> graph , bytes_to_write , 0 , 0 , wflags );
811+ prtd -> bytes_sent += bytes_to_write ;
812+ }
813+
814+ spin_unlock_irqrestore (& prtd -> lock , flags );
815+
816+ return count ;
817+ }
818+
740819static const struct snd_compress_ops q6apm_dai_compress_ops = {
741820 .open = q6apm_dai_compr_open ,
742821 .free = q6apm_dai_compr_free ,
@@ -747,6 +826,8 @@ static const struct snd_compress_ops q6apm_dai_compress_ops = {
747826 .ack = q6apm_dai_compr_ack ,
748827 .set_params = q6apm_dai_compr_set_params ,
749828 .set_metadata = q6apm_dai_compr_set_metadata ,
829+ .mmap = q6apm_dai_compr_mmap ,
830+ .copy = q6apm_compr_copy ,
750831};
751832
752833static const struct snd_soc_component_driver q6apm_fe_dai_component = {
0 commit comments