aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/function/f_midi.c')
-rw-r--r--drivers/usb/gadget/function/f_midi.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index 8fff995b8dd5..566531bf6cab 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -1222,6 +1222,65 @@ static void f_midi_free_inst(struct usb_function_instance *f)
1222 } 1222 }
1223} 1223}
1224 1224
1225#ifdef CONFIG_USB_CONFIGFS_UEVENT
1226extern struct device *create_function_device(char *name);
1227static ssize_t alsa_show(struct device *dev,
1228 struct device_attribute *attr, char *buf)
1229{
1230 struct usb_function_instance *fi_midi = dev_get_drvdata(dev);
1231 struct f_midi *midi;
1232
1233 if (!fi_midi->f)
1234 dev_warn(dev, "f_midi: function not set\n");
1235
1236 if (fi_midi && fi_midi->f) {
1237 midi = func_to_midi(fi_midi->f);
1238 if (midi->rmidi && midi->card && midi->rmidi->card)
1239 return sprintf(buf, "%d %d\n",
1240 midi->rmidi->card->number, midi->rmidi->device);
1241 }
1242
1243 /* print PCM card and device numbers */
1244 return sprintf(buf, "%d %d\n", -1, -1);
1245}
1246
1247static DEVICE_ATTR(alsa, S_IRUGO, alsa_show, NULL);
1248
1249static struct device_attribute *alsa_function_attributes[] = {
1250 &dev_attr_alsa,
1251 NULL
1252};
1253
1254static int create_alsa_device(struct usb_function_instance *fi)
1255{
1256 struct device *dev;
1257 struct device_attribute **attrs;
1258 struct device_attribute *attr;
1259 int err = 0;
1260
1261 dev = create_function_device("f_midi");
1262 if (IS_ERR(dev))
1263 return PTR_ERR(dev);
1264
1265 attrs = alsa_function_attributes;
1266 if (attrs) {
1267 while ((attr = *attrs++) && !err)
1268 err = device_create_file(dev, attr);
1269 if (err) {
1270 device_destroy(dev->class, dev->devt);
1271 return -EINVAL;
1272 }
1273 }
1274 dev_set_drvdata(dev, fi);
1275 return 0;
1276}
1277#else
1278static int create_alsa_device(struct usb_function_instance *fi)
1279{
1280 return 0;
1281}
1282#endif
1283
1225static struct usb_function_instance *f_midi_alloc_inst(void) 1284static struct usb_function_instance *f_midi_alloc_inst(void)
1226{ 1285{
1227 struct f_midi_opts *opts; 1286 struct f_midi_opts *opts;
@@ -1240,6 +1299,11 @@ static struct usb_function_instance *f_midi_alloc_inst(void)
1240 opts->out_ports = 1; 1299 opts->out_ports = 1;
1241 opts->refcnt = 1; 1300 opts->refcnt = 1;
1242 1301
1302 if (create_alsa_device(&opts->func_inst)) {
1303 kfree(opts);
1304 return ERR_PTR(-ENODEV);
1305 }
1306
1243 config_group_init_type_name(&opts->func_inst.group, "", 1307 config_group_init_type_name(&opts->func_inst.group, "",
1244 &midi_func_type); 1308 &midi_func_type);
1245 1309
@@ -1260,6 +1324,7 @@ static void f_midi_free(struct usb_function *f)
1260 kfifo_free(&midi->in_req_fifo); 1324 kfifo_free(&midi->in_req_fifo);
1261 kfree(midi); 1325 kfree(midi);
1262 free = true; 1326 free = true;
1327 opts->func_inst.f = NULL;
1263 } 1328 }
1264 mutex_unlock(&opts->lock); 1329 mutex_unlock(&opts->lock);
1265 1330
@@ -1347,6 +1412,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
1347 midi->func.disable = f_midi_disable; 1412 midi->func.disable = f_midi_disable;
1348 midi->func.free_func = f_midi_free; 1413 midi->func.free_func = f_midi_free;
1349 1414
1415 fi->f = &midi->func;
1350 return &midi->func; 1416 return &midi->func;
1351 1417
1352midi_free: 1418midi_free: