@@ -244,7 +244,10 @@ struct audio_source_config {
244244 int device ;
245245};
246246
247+ static struct class * audio_source_class ;
248+
247249struct audio_dev {
250+ struct device * dev ;
248251 struct usb_function func ;
249252 struct snd_card * card ;
250253 struct snd_pcm * pcm ;
@@ -253,13 +256,17 @@ struct audio_dev {
253256 struct list_head idle_reqs ;
254257 struct usb_ep * in_ep ;
255258
259+ struct work_struct work ;
260+
256261 spinlock_t lock ;
257262
258263 /* beginning, end and current position in our buffer */
259264 void * buffer_start ;
260265 void * buffer_end ;
261266 void * buffer_pos ;
262267
268+ unsigned int alt ;
269+
263270 /* byte size of a "period" */
264271 unsigned int period ;
265272 /* bytes sent since last call to snd_pcm_period_elapsed */
@@ -278,6 +285,84 @@ static inline struct audio_dev *func_to_audio(struct usb_function *f)
278285 return container_of (f , struct audio_dev , func );
279286}
280287
288+ static void audio_source_work (struct work_struct * data )
289+ {
290+ struct audio_dev * audio = container_of (data , struct audio_dev , work );
291+ char * set_interface [3 ] = { "USB_STATE=SET_INTERFACE" , NULL , NULL };
292+ char * * uevent_envp = NULL ;
293+
294+ if (audio -> alt )
295+ set_interface [1 ] = "1" ;
296+ else
297+ set_interface [1 ] = "0" ;
298+ uevent_envp = set_interface ;
299+
300+ if (uevent_envp ) {
301+ kobject_uevent_env (& audio -> dev -> kobj , KOBJ_CHANGE ,
302+ uevent_envp );
303+ pr_info ("%s: sent uevent %s\n" , __func__ ,
304+ uevent_envp [0 ]);
305+ } else {
306+ pr_info ("%s: did not send uevent set interface\n" ,
307+ __func__ );
308+ }
309+ }
310+
311+ static ssize_t
312+ alt_show (struct device * dev , struct device_attribute * attr ,
313+ char * buf )
314+ {
315+ struct audio_dev * audio = dev_get_drvdata (dev );
316+
317+ return sprintf (buf , "%d\n" , audio -> alt );
318+ }
319+
320+ static ssize_t
321+ alt_store (struct device * dev , struct device_attribute * attr ,
322+ const char * buf , size_t size )
323+ {
324+ unsigned int value ;
325+ struct audio_dev * audio = dev_get_drvdata (dev );
326+
327+ if (sscanf (buf , "%d\n" , & value ) != 1 )
328+ return -1 ;
329+
330+ if (audio -> alt != value ) {
331+ audio -> alt = value ;
332+ schedule_work (& audio -> work );
333+ }
334+ return size ;
335+ }
336+ static DEVICE_ATTR_RW (alt );
337+
338+ static struct device_attribute * audio_source_attributes [] = {
339+ & dev_attr_alt ,
340+ NULL
341+ };
342+
343+ static int audio_source_create_device (struct audio_dev * audio )
344+ {
345+ struct device_attribute * * attrs = audio_source_attributes ;
346+ struct device_attribute * attr ;
347+ int err ;
348+
349+ audio -> dev = device_create (audio_source_class , NULL ,
350+ MKDEV (0 , 0 ), NULL , "audio_source0" );
351+ if (IS_ERR (audio -> dev ))
352+ return PTR_ERR (audio -> dev );
353+
354+ dev_set_drvdata (audio -> dev , audio );
355+
356+ while ((attr = * attrs ++ )) {
357+ err = device_create_file (audio -> dev , attr );
358+ if (err ) {
359+ device_destroy (audio_source_class , audio -> dev -> devt );
360+ return err ;
361+ }
362+ }
363+ return 0 ;
364+ }
365+
281366/*-------------------------------------------------------------------------*/
282367
283368struct audio_source_instance {
@@ -574,6 +659,11 @@ static int audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
574659 if (ret )
575660 return ret ;
576661
662+ if (audio -> alt != alt ) {
663+ audio -> alt = alt ;
664+ schedule_work (& audio -> work );
665+ }
666+
577667 usb_ep_enable (audio -> in_ep );
578668 return 0 ;
579669}
@@ -636,6 +726,13 @@ audio_bind(struct usb_configuration *c, struct usb_function *f)
636726 err = snd_card_setup (c , config );
637727 if (err )
638728 return err ;
729+
730+ audio_source_class = class_create (THIS_MODULE , "audio_source" );
731+ if (IS_ERR (audio_source_class ))
732+ return PTR_ERR (audio_source_class );
733+
734+ INIT_WORK (& audio -> work , audio_source_work );
735+ audio_source_create_device (audio );
639736 }
640737
641738 audio_build_desc (audio );
@@ -697,11 +794,16 @@ audio_unbind(struct usb_configuration *c, struct usb_function *f)
697794 while ((req = audio_req_get (audio )))
698795 audio_request_free (req , audio -> in_ep );
699796
797+ cancel_work_sync (& audio -> work );
798+ device_destroy (audio_source_class , audio -> dev -> devt );
799+ class_destroy (audio_source_class );
800+
700801 snd_card_free_when_closed (audio -> card );
701802 audio -> card = NULL ;
702803 audio -> pcm = NULL ;
703804 audio -> substream = NULL ;
704805 audio -> in_ep = NULL ;
806+ audio -> dev = NULL ;
705807
706808 if (IS_ENABLED (CONFIG_USB_CONFIGFS )) {
707809 struct audio_source_instance * fi_audio =
@@ -879,6 +981,13 @@ int audio_source_bind_config(struct usb_configuration *c,
879981 if (err )
880982 goto add_fail ;
881983
984+ audio_source_class = class_create (THIS_MODULE , "audio_source" );
985+ if (IS_ERR (audio_source_class ))
986+ return PTR_ERR (audio_source_class );
987+
988+ INIT_WORK (& audio -> work , audio_source_work );
989+ audio_source_create_device (audio );
990+
882991 return 0 ;
883992
884993add_fail :
0 commit comments