37
37
#include "format.h"
38
38
#include "clock.h"
39
39
#include "stream.h"
40
+ #include "power.h"
40
41
41
42
/*
42
43
* free a substream
@@ -53,6 +54,7 @@ static void free_substream(struct snd_usb_substream *subs)
53
54
kfree (fp );
54
55
}
55
56
kfree (subs -> rate_list .list );
57
+ kfree (subs -> str_pd );
56
58
}
57
59
58
60
@@ -82,7 +84,8 @@ static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
82
84
83
85
static void snd_usb_init_substream (struct snd_usb_stream * as ,
84
86
int stream ,
85
- struct audioformat * fp )
87
+ struct audioformat * fp ,
88
+ struct snd_usb_power_domain * pd )
86
89
{
87
90
struct snd_usb_substream * subs = & as -> substream [stream ];
88
91
@@ -107,6 +110,9 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
107
110
if (fp -> channels > subs -> channels_max )
108
111
subs -> channels_max = fp -> channels ;
109
112
113
+ if (pd )
114
+ subs -> str_pd = pd ;
115
+
110
116
snd_usb_preallocate_buffer (subs );
111
117
}
112
118
@@ -468,9 +474,11 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
468
474
* fmt_list and will be freed on the chip instance release. do not free
469
475
* fp or do remove it from the substream fmt_list to avoid double-free.
470
476
*/
471
- int snd_usb_add_audio_stream (struct snd_usb_audio * chip ,
472
- int stream ,
473
- struct audioformat * fp )
477
+ static int __snd_usb_add_audio_stream (struct snd_usb_audio * chip ,
478
+ int stream ,
479
+ struct audioformat * fp ,
480
+ struct snd_usb_power_domain * pd )
481
+
474
482
{
475
483
struct snd_usb_stream * as ;
476
484
struct snd_usb_substream * subs ;
@@ -498,7 +506,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
498
506
err = snd_pcm_new_stream (as -> pcm , stream , 1 );
499
507
if (err < 0 )
500
508
return err ;
501
- snd_usb_init_substream (as , stream , fp );
509
+ snd_usb_init_substream (as , stream , fp , pd );
502
510
return add_chmap (as -> pcm , stream , subs );
503
511
}
504
512
@@ -526,7 +534,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
526
534
else
527
535
strcpy (pcm -> name , "USB Audio" );
528
536
529
- snd_usb_init_substream (as , stream , fp );
537
+ snd_usb_init_substream (as , stream , fp , pd );
530
538
531
539
/*
532
540
* Keep using head insertion for M-Audio Audiophile USB (tm) which has a
@@ -544,6 +552,21 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
544
552
return add_chmap (pcm , stream , & as -> substream [stream ]);
545
553
}
546
554
555
+ int snd_usb_add_audio_stream (struct snd_usb_audio * chip ,
556
+ int stream ,
557
+ struct audioformat * fp )
558
+ {
559
+ return __snd_usb_add_audio_stream (chip , stream , fp , NULL );
560
+ }
561
+
562
+ static int snd_usb_add_audio_stream_v3 (struct snd_usb_audio * chip ,
563
+ int stream ,
564
+ struct audioformat * fp ,
565
+ struct snd_usb_power_domain * pd )
566
+ {
567
+ return __snd_usb_add_audio_stream (chip , stream , fp , pd );
568
+ }
569
+
547
570
static int parse_uac_endpoint_attributes (struct snd_usb_audio * chip ,
548
571
struct usb_host_interface * alts ,
549
572
int protocol , int iface_no )
@@ -819,6 +842,7 @@ snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip,
819
842
static struct audioformat *
820
843
snd_usb_get_audioformat_uac3 (struct snd_usb_audio * chip ,
821
844
struct usb_host_interface * alts ,
845
+ struct snd_usb_power_domain * * pd_out ,
822
846
int iface_no , int altset_idx ,
823
847
int altno , int stream )
824
848
{
@@ -829,6 +853,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
829
853
struct uac3_as_header_descriptor * as = NULL ;
830
854
struct uac3_hc_descriptor_header hc_header ;
831
855
struct snd_pcm_chmap_elem * chmap ;
856
+ struct snd_usb_power_domain * pd ;
832
857
unsigned char badd_profile ;
833
858
u64 badd_formats = 0 ;
834
859
unsigned int num_channels ;
@@ -1008,19 +1033,38 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
1008
1033
fp -> rate_max = UAC3_BADD_SAMPLING_RATE ;
1009
1034
fp -> rates = SNDRV_PCM_RATE_CONTINUOUS ;
1010
1035
1036
+ pd = kzalloc (sizeof (pd ), GFP_KERNEL );
1037
+ if (!pd ) {
1038
+ kfree (fp -> rate_table );
1039
+ kfree (fp );
1040
+ return NULL ;
1041
+ }
1042
+ pd -> pd_id = (stream == SNDRV_PCM_STREAM_PLAYBACK ) ?
1043
+ UAC3_BADD_PD_ID10 : UAC3_BADD_PD_ID11 ;
1044
+ pd -> pd_d1d0_rec = UAC3_BADD_PD_RECOVER_D1D0 ;
1045
+ pd -> pd_d2d0_rec = UAC3_BADD_PD_RECOVER_D2D0 ;
1046
+
1011
1047
} else {
1012
1048
fp -> attributes = parse_uac_endpoint_attributes (chip , alts ,
1013
1049
UAC_VERSION_3 ,
1014
1050
iface_no );
1051
+
1052
+ pd = snd_usb_find_power_domain (chip -> ctrl_intf ,
1053
+ as -> bTerminalLink );
1054
+
1015
1055
/* ok, let's parse further... */
1016
1056
if (snd_usb_parse_audio_format_v3 (chip , fp , as , stream ) < 0 ) {
1057
+ kfree (pd );
1017
1058
kfree (fp -> chmap );
1018
1059
kfree (fp -> rate_table );
1019
1060
kfree (fp );
1020
1061
return NULL ;
1021
1062
}
1022
1063
}
1023
1064
1065
+ if (pd )
1066
+ * pd_out = pd ;
1067
+
1024
1068
return fp ;
1025
1069
}
1026
1070
@@ -1032,6 +1076,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
1032
1076
struct usb_interface_descriptor * altsd ;
1033
1077
int i , altno , err , stream ;
1034
1078
struct audioformat * fp = NULL ;
1079
+ struct snd_usb_power_domain * pd = NULL ;
1035
1080
int num , protocol ;
1036
1081
1037
1082
dev = chip -> dev ;
@@ -1114,7 +1159,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
1114
1159
break ;
1115
1160
}
1116
1161
case UAC_VERSION_3 :
1117
- fp = snd_usb_get_audioformat_uac3 (chip , alts ,
1162
+ fp = snd_usb_get_audioformat_uac3 (chip , alts , & pd ,
1118
1163
iface_no , i , altno , stream );
1119
1164
break ;
1120
1165
}
@@ -1125,9 +1170,14 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
1125
1170
return PTR_ERR (fp );
1126
1171
1127
1172
dev_dbg (& dev -> dev , "%u:%d: add audio endpoint %#x\n" , iface_no , altno , fp -> endpoint );
1128
- err = snd_usb_add_audio_stream (chip , stream , fp );
1173
+ if (protocol == UAC_VERSION_3 )
1174
+ err = snd_usb_add_audio_stream_v3 (chip , stream , fp , pd );
1175
+ else
1176
+ err = snd_usb_add_audio_stream (chip , stream , fp );
1177
+
1129
1178
if (err < 0 ) {
1130
1179
list_del (& fp -> list ); /* unlink for avoiding double-free */
1180
+ kfree (pd );
1131
1181
kfree (fp -> rate_table );
1132
1182
kfree (fp -> chmap );
1133
1183
kfree (fp );
0 commit comments