@@ -145,10 +145,9 @@ static int plug_ctl_get_attribute(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
145145 // TODO: ??
146146 break ;
147147 case SND_SOC_TPLG_CTL_BYTES :
148- printf ("%s %d\n" , __func__ , __LINE__ );
149148 bytes_ctl = (struct snd_soc_tplg_bytes_control * )hdr ;
150149 * type = SND_CTL_ELEM_TYPE_BYTES ;
151- * count = bytes_ctl -> size ; // Not sure if size is correct
150+ * count = bytes_ctl -> max ;
152151 break ;
153152 }
154153
@@ -536,36 +535,147 @@ static int plug_ctl_write_enumerated(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
536535/*
537536 * Bytes ops
538537 */
538+ static int plug_ctl_get_bytes_data (snd_sof_ctl_t * ctl , snd_ctl_ext_key_t key ,
539+ struct sof_abi_hdr * abi , unsigned int max_bytes )
540+ {
541+ struct snd_soc_tplg_bytes_control * bytes_ctl = CTL_GET_TPLG_BYTES (ctl , key );
542+ struct ipc4_module_large_config config = {{ 0 }};
543+ struct ipc4_module_large_config_reply * reply ;
544+ char * reply_data , * data ;
545+ void * msg ;
546+ uint32_t data_size ;
547+ int size , reply_data_size ;
548+ int err ;
549+
550+ /* configure the IPC message */
551+ plug_ctl_ipc_message (& config , abi -> type , 0 ,
552+ ctl -> glb -> ctl [key ].module_id , ctl -> glb -> ctl [key ].instance_id ,
553+ SOF_IPC4_MOD_LARGE_CONFIG_GET );
554+
555+ config .extension .r .final_block = 1 ;
556+ config .extension .r .init_block = 1 ;
557+
558+ size = sizeof (config );
559+ msg = calloc (size , 1 );
560+ if (!msg )
561+ return - ENOMEM ;
562+
563+ /*
564+ * reply contains both the requested data and the reply status. Allocate enough memory
565+ * for max data
566+ */
567+ reply_data_size = sizeof (* reply ) + sizeof (* data ) + bytes_ctl -> max ;
568+ reply_data = calloc (reply_data_size , 1 );
569+ if (!reply_data_size ) {
570+ free (msg );
571+ return - ENOMEM ;
572+ }
573+
574+ /* send the IPC message */
575+ memcpy (msg , & config , sizeof (config ));
576+ err = plug_mq_cmd_tx_rx (& ctl -> ipc_tx , & ctl -> ipc_rx ,
577+ msg , size , reply_data , reply_data_size );
578+ free (msg );
579+ if (err < 0 ) {
580+ SNDERR ("failed to get bytes data for control %s\n" , bytes_ctl -> hdr .name );
581+ goto out ;
582+ }
583+
584+ reply = (struct ipc4_module_large_config_reply * )reply_data ;
585+ if (reply -> primary .r .status != IPC4_SUCCESS ) {
586+ SNDERR ("bytes control %s get failed with status %d\n" ,
587+ bytes_ctl -> hdr .name , reply -> primary .r .status );
588+ err = - EINVAL ;
589+ goto out ;
590+ }
591+
592+ /* check data sanity */
593+ data = (char * )(reply_data + sizeof (* reply ));
594+ data_size = reply -> extension .r .data_off_size ;
595+ if (data_size > bytes_ctl -> max ) {
596+ SNDERR ("received data size %d is larger than max %d for bytes control %s\n" ,
597+ data_size , bytes_ctl -> max , bytes_ctl -> hdr .name );
598+ err = - EINVAL ;
599+ goto out ;
600+ }
601+
602+ abi -> size = data_size ;
603+
604+ if (data_size )
605+ memcpy (abi -> data , data , MIN (data_size , max_bytes ));
606+
607+ err = data_size ;
608+ out :
609+ free (reply_data );
610+ return err ;
611+ }
612+
539613static int plug_ctl_read_bytes (snd_ctl_ext_t * ext , snd_ctl_ext_key_t key ,
540614 unsigned char * data , size_t max_bytes )
541615{
616+ snd_sof_ctl_t * ctl = ext -> private_data ;
617+ struct sof_abi_hdr * abi = (struct sof_abi_hdr * )data ;
618+ int data_size ;
619+
620+ data_size = plug_ctl_get_bytes_data (ctl , key , abi , max_bytes );
621+ if (data_size < 0 )
622+ return data_size ;
623+
542624 return 0 ;
543625}
544626
545627static int plug_ctl_write_bytes (snd_ctl_ext_t * ext , snd_ctl_ext_key_t key ,
546628 unsigned char * data , size_t max_bytes )
547629{
630+ snd_sof_ctl_t * ctl = ext -> private_data ;
631+ struct snd_soc_tplg_bytes_control * bytes_ctl = CTL_GET_TPLG_BYTES (ctl , key );
632+ struct sof_abi_hdr * abi = (struct sof_abi_hdr * )data ;
633+ int err ;
634+
635+ /* send IPC with kcontrol data */
636+ err = plug_send_bytes_data (& ctl -> ipc_tx , & ctl -> ipc_rx ,
637+ ctl -> glb -> ctl [key ].module_id , ctl -> glb -> ctl [key ].instance_id ,
638+ abi );
639+ if (err < 0 ) {
640+ SNDERR ("failed to set bytes data for control %s\n" , bytes_ctl -> hdr .name );
641+ return err ;
642+ }
643+
548644 return 0 ;
549645}
550646
551- /*
552- * TLV ops
553- *
554- * The format of an array of \a tlv argument is:
555- * tlv[0]: Type. One of SND_CTL_TLVT_XXX.
556- * tlv[1]: Length. The length of value in units of byte.
557- * tlv[2..]: Value. Depending on the type.
558- */
647+ /* TLV ops used for TLV bytes control callback */
559648static int plug_tlv_rw (snd_ctl_ext_t * ext , snd_ctl_ext_key_t key , int op_flag ,
560649 unsigned int numid , unsigned int * tlv , unsigned int tlv_size )
561650{
562651 snd_sof_ctl_t * ctl = ext -> private_data ;
563- struct snd_soc_tplg_ctl_hdr * hdr = CTL_GET_TPLG_HDR (ctl , key );
652+ struct snd_soc_tplg_bytes_control * bytes_ctl = CTL_GET_TPLG_BYTES (ctl , key );
653+ struct sof_abi_hdr * abi = (struct sof_abi_hdr * )(tlv + 2 ); /* skip TLV header */
654+ int data_size ;
655+
656+ /* send IPC with kcontrol data if op_flag is > 0 else send IPC to get kcontrol data */
657+ if (op_flag ) {
658+ int err ;
659+
660+ err = plug_send_bytes_data (& ctl -> ipc_tx , & ctl -> ipc_rx ,
661+ ctl -> glb -> ctl [key ].module_id ,
662+ ctl -> glb -> ctl [key ].instance_id , abi );
663+ if (err < 0 ) {
664+ SNDERR ("failed to set bytes data for control %s\n" , bytes_ctl -> hdr .name );
665+ return err ;
666+ }
667+
668+ return 0 ;
669+ }
670+
671+ /* read kcontrol data */
672+ data_size = plug_ctl_get_bytes_data (ctl , key , abi , tlv_size );
673+ if (data_size < 0 )
674+ return data_size ;
564675
565- //TODO: alsamixer showing wrong dB scales
566- tlv [0 ] = hdr -> tlv .type ;
567- tlv [1 ] = hdr -> tlv .size - sizeof (uint32_t ) * 2 ;
568- memcpy (& tlv [2 ], hdr -> tlv .data , hdr -> tlv .size - sizeof (uint32_t ) * 2 );
676+ /* set data size and numid */
677+ tlv [0 ] = numid ;
678+ tlv [1 ] = data_size + sizeof (* abi );
569679
570680 return 0 ;
571681}
0 commit comments