@@ -516,21 +516,38 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction,
516516EXPORT_SYMBOL (snd_pcm_set_ops );
517517
518518/**
519- * snd_pcm_set_sync - set the PCM sync id
519+ * snd_pcm_set_sync_per_card - set the PCM sync id with card number
520520 * @substream: the pcm substream
521+ * @params: modified hardware parameters
522+ * @id: identifier (max 12 bytes)
523+ * @len: identifier length (max 12 bytes)
521524 *
522- * Sets the PCM sync identifier for the card.
525+ * Sets the PCM sync identifier for the card with zero padding.
526+ *
527+ * User space or any user should use this 16-byte identifier for a comparison only
528+ * to check if two IDs are similar or different. Special case is the identifier
529+ * containing only zeros. Interpretation for this combination is - empty (not set).
530+ * The contents of the identifier should not be interpreted in any other way.
531+ *
532+ * The synchronization ID must be unique per clock source (usually one sound card,
533+ * but multiple soundcard may use one PCM word clock source which means that they
534+ * are fully synchronized).
535+ *
536+ * This routine composes this ID using card number in first four bytes and
537+ * 12-byte additional ID. When other ID composition is used (e.g. for multiple
538+ * sound cards), make sure that the composition does not clash with this
539+ * composition scheme.
523540 */
524- void snd_pcm_set_sync (struct snd_pcm_substream * substream )
541+ void snd_pcm_set_sync_per_card (struct snd_pcm_substream * substream ,
542+ struct snd_pcm_hw_params * params ,
543+ const unsigned char * id , unsigned int len )
525544{
526- struct snd_pcm_runtime * runtime = substream -> runtime ;
527-
528- runtime -> sync .id32 [0 ] = substream -> pcm -> card -> number ;
529- runtime -> sync .id32 [1 ] = -1 ;
530- runtime -> sync .id32 [2 ] = -1 ;
531- runtime -> sync .id32 [3 ] = -1 ;
545+ * (__u32 * )params -> sync = cpu_to_le32 (substream -> pcm -> card -> number );
546+ len = min (12 , len );
547+ memcpy (params -> sync + 4 , id , len );
548+ memset (params -> sync + 4 + len , 0 , 12 - len );
532549}
533- EXPORT_SYMBOL ( snd_pcm_set_sync );
550+ EXPORT_SYMBOL_GPL ( snd_pcm_set_sync_per_card );
534551
535552/*
536553 * Standard ioctl routine
@@ -1810,6 +1827,18 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
18101827 return 0 ;
18111828}
18121829
1830+ static int snd_pcm_lib_ioctl_sync_id (struct snd_pcm_substream * substream ,
1831+ void * arg )
1832+ {
1833+ static const unsigned char id [12 ] = { 0xff , 0xff , 0xff , 0xff ,
1834+ 0xff , 0xff , 0xff , 0xff ,
1835+ 0xff , 0xff , 0xff , 0xff };
1836+
1837+ if (substream -> runtime -> std_sync_id )
1838+ snd_pcm_set_sync_per_card (substream , arg , id , sizeof (id ));
1839+ return 0 ;
1840+ }
1841+
18131842/**
18141843 * snd_pcm_lib_ioctl - a generic PCM ioctl callback
18151844 * @substream: the pcm substream instance
@@ -1831,6 +1860,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
18311860 return snd_pcm_lib_ioctl_channel_info (substream , arg );
18321861 case SNDRV_PCM_IOCTL1_FIFO_SIZE :
18331862 return snd_pcm_lib_ioctl_fifo_size (substream , arg );
1863+ case SNDRV_PCM_IOCTL1_SYNC_ID :
1864+ return snd_pcm_lib_ioctl_sync_id (substream , arg );
18341865 }
18351866 return - ENXIO ;
18361867}
@@ -2556,6 +2587,7 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
25562587 struct snd_kcontrol_new knew = {
25572588 .iface = SNDRV_CTL_ELEM_IFACE_PCM ,
25582589 .access = SNDRV_CTL_ELEM_ACCESS_READ |
2590+ SNDRV_CTL_ELEM_ACCESS_VOLATILE |
25592591 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
25602592 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK ,
25612593 .info = pcm_chmap_ctl_info ,
0 commit comments