aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_uac2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_uac2.c')
-rw-r--r--drivers/usb/gadget/f_uac2.c222
1 files changed, 75 insertions, 147 deletions
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c
index d3c6cffccb72..d7da258fa3f6 100644
--- a/drivers/usb/gadget/f_uac2.c
+++ b/drivers/usb/gadget/f_uac2.c
@@ -50,13 +50,6 @@ static int c_ssize = 2;
50module_param(c_ssize, uint, S_IRUGO); 50module_param(c_ssize, uint, S_IRUGO);
51MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); 51MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
52 52
53#define DMA_ADDR_INVALID (~(dma_addr_t)0)
54
55#define ALT_SET(x, a) do {(x) &= ~0xff; (x) |= (a); } while (0)
56#define ALT_GET(x) ((x) & 0xff)
57#define INTF_SET(x, i) do {(x) &= 0xff; (x) |= ((i) << 8); } while (0)
58#define INTF_GET(x) ((x >> 8) & 0xff)
59
60/* Keep everyone on toes */ 53/* Keep everyone on toes */
61#define USB_XFERS 2 54#define USB_XFERS 2
62 55
@@ -144,8 +137,9 @@ static struct snd_pcm_hardware uac2_pcm_hardware = {
144}; 137};
145 138
146struct audio_dev { 139struct audio_dev {
147 /* Currently active {Interface[15:8] | AltSettings[7:0]} */ 140 u8 ac_intf, ac_alt;
148 __u16 ac_alt, as_out_alt, as_in_alt; 141 u8 as_out_intf, as_out_alt;
142 u8 as_in_intf, as_in_alt;
149 143
150 struct usb_ep *in_ep, *out_ep; 144 struct usb_ep *in_ep, *out_ep;
151 struct usb_function func; 145 struct usb_function func;
@@ -408,7 +402,7 @@ static struct snd_pcm_ops uac2_pcm_ops = {
408 .prepare = uac2_pcm_null, 402 .prepare = uac2_pcm_null,
409}; 403};
410 404
411static int __devinit snd_uac2_probe(struct platform_device *pdev) 405static int snd_uac2_probe(struct platform_device *pdev)
412{ 406{
413 struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); 407 struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
414 struct snd_card *card; 408 struct snd_card *card;
@@ -526,32 +520,22 @@ enum {
526 STR_AS_IN_ALT1, 520 STR_AS_IN_ALT1,
527}; 521};
528 522
529static const char ifassoc[] = "Source/Sink";
530static const char ifctrl[] = "Topology Control";
531static char clksrc_in[8]; 523static char clksrc_in[8];
532static char clksrc_out[8]; 524static char clksrc_out[8];
533static const char usb_it[] = "USBH Out";
534static const char io_it[] = "USBD Out";
535static const char usb_ot[] = "USBH In";
536static const char io_ot[] = "USBD In";
537static const char out_alt0[] = "Playback Inactive";
538static const char out_alt1[] = "Playback Active";
539static const char in_alt0[] = "Capture Inactive";
540static const char in_alt1[] = "Capture Active";
541 525
542static struct usb_string strings_fn[] = { 526static struct usb_string strings_fn[] = {
543 [STR_ASSOC].s = ifassoc, 527 [STR_ASSOC].s = "Source/Sink",
544 [STR_IF_CTRL].s = ifctrl, 528 [STR_IF_CTRL].s = "Topology Control",
545 [STR_CLKSRC_IN].s = clksrc_in, 529 [STR_CLKSRC_IN].s = clksrc_in,
546 [STR_CLKSRC_OUT].s = clksrc_out, 530 [STR_CLKSRC_OUT].s = clksrc_out,
547 [STR_USB_IT].s = usb_it, 531 [STR_USB_IT].s = "USBH Out",
548 [STR_IO_IT].s = io_it, 532 [STR_IO_IT].s = "USBD Out",
549 [STR_USB_OT].s = usb_ot, 533 [STR_USB_OT].s = "USBH In",
550 [STR_IO_OT].s = io_ot, 534 [STR_IO_OT].s = "USBD In",
551 [STR_AS_OUT_ALT0].s = out_alt0, 535 [STR_AS_OUT_ALT0].s = "Playback Inactive",
552 [STR_AS_OUT_ALT1].s = out_alt1, 536 [STR_AS_OUT_ALT1].s = "Playback Active",
553 [STR_AS_IN_ALT0].s = in_alt0, 537 [STR_AS_IN_ALT0].s = "Capture Inactive",
554 [STR_AS_IN_ALT1].s = in_alt1, 538 [STR_AS_IN_ALT1].s = "Capture Active",
555 { }, 539 { },
556}; 540};
557 541
@@ -952,8 +936,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
952 return ret; 936 return ret;
953 } 937 }
954 std_ac_if_desc.bInterfaceNumber = ret; 938 std_ac_if_desc.bInterfaceNumber = ret;
955 ALT_SET(agdev->ac_alt, 0); 939 agdev->ac_intf = ret;
956 INTF_SET(agdev->ac_alt, ret); 940 agdev->ac_alt = 0;
957 941
958 ret = usb_interface_id(cfg, fn); 942 ret = usb_interface_id(cfg, fn);
959 if (ret < 0) { 943 if (ret < 0) {
@@ -963,8 +947,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
963 } 947 }
964 std_as_out_if0_desc.bInterfaceNumber = ret; 948 std_as_out_if0_desc.bInterfaceNumber = ret;
965 std_as_out_if1_desc.bInterfaceNumber = ret; 949 std_as_out_if1_desc.bInterfaceNumber = ret;
966 ALT_SET(agdev->as_out_alt, 0); 950 agdev->as_out_intf = ret;
967 INTF_SET(agdev->as_out_alt, ret); 951 agdev->as_out_alt = 0;
968 952
969 ret = usb_interface_id(cfg, fn); 953 ret = usb_interface_id(cfg, fn);
970 if (ret < 0) { 954 if (ret < 0) {
@@ -974,19 +958,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
974 } 958 }
975 std_as_in_if0_desc.bInterfaceNumber = ret; 959 std_as_in_if0_desc.bInterfaceNumber = ret;
976 std_as_in_if1_desc.bInterfaceNumber = ret; 960 std_as_in_if1_desc.bInterfaceNumber = ret;
977 ALT_SET(agdev->as_in_alt, 0); 961 agdev->as_in_intf = ret;
978 INTF_SET(agdev->as_in_alt, ret); 962 agdev->as_in_alt = 0;
979 963
980 agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); 964 agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
981 if (!agdev->out_ep) 965 if (!agdev->out_ep) {
982 dev_err(&uac2->pdev.dev, 966 dev_err(&uac2->pdev.dev,
983 "%s:%d Error!\n", __func__, __LINE__); 967 "%s:%d Error!\n", __func__, __LINE__);
968 goto err;
969 }
984 agdev->out_ep->driver_data = agdev; 970 agdev->out_ep->driver_data = agdev;
985 971
986 agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); 972 agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
987 if (!agdev->in_ep) 973 if (!agdev->in_ep) {
988 dev_err(&uac2->pdev.dev, 974 dev_err(&uac2->pdev.dev,
989 "%s:%d Error!\n", __func__, __LINE__); 975 "%s:%d Error!\n", __func__, __LINE__);
976 goto err;
977 }
990 agdev->in_ep->driver_data = agdev; 978 agdev->in_ep->driver_data = agdev;
991 979
992 hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; 980 hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
@@ -994,9 +982,9 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
994 hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; 982 hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
995 hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize; 983 hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
996 984
997 fn->descriptors = usb_copy_descriptors(fs_audio_desc); 985 ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
998 if (gadget_is_dualspeed(gadget)) 986 if (ret)
999 fn->hs_descriptors = usb_copy_descriptors(hs_audio_desc); 987 goto err;
1000 988
1001 prm = &agdev->uac2.c_prm; 989 prm = &agdev->uac2.c_prm;
1002 prm->max_psize = hs_epout_desc.wMaxPacketSize; 990 prm->max_psize = hs_epout_desc.wMaxPacketSize;
@@ -1005,6 +993,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
1005 prm->max_psize = 0; 993 prm->max_psize = 0;
1006 dev_err(&uac2->pdev.dev, 994 dev_err(&uac2->pdev.dev,
1007 "%s:%d Error!\n", __func__, __LINE__); 995 "%s:%d Error!\n", __func__, __LINE__);
996 goto err;
1008 } 997 }
1009 998
1010 prm = &agdev->uac2.p_prm; 999 prm = &agdev->uac2.p_prm;
@@ -1014,17 +1003,28 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
1014 prm->max_psize = 0; 1003 prm->max_psize = 0;
1015 dev_err(&uac2->pdev.dev, 1004 dev_err(&uac2->pdev.dev,
1016 "%s:%d Error!\n", __func__, __LINE__); 1005 "%s:%d Error!\n", __func__, __LINE__);
1006 goto err;
1017 } 1007 }
1018 1008
1019 return alsa_uac2_init(agdev); 1009 ret = alsa_uac2_init(agdev);
1010 if (ret)
1011 goto err;
1012 return 0;
1013err:
1014 kfree(agdev->uac2.p_prm.rbuf);
1015 kfree(agdev->uac2.c_prm.rbuf);
1016 usb_free_all_descriptors(fn);
1017 if (agdev->in_ep)
1018 agdev->in_ep->driver_data = NULL;
1019 if (agdev->out_ep)
1020 agdev->out_ep->driver_data = NULL;
1021 return -EINVAL;
1020} 1022}
1021 1023
1022static void 1024static void
1023afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) 1025afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn)
1024{ 1026{
1025 struct audio_dev *agdev = func_to_agdev(fn); 1027 struct audio_dev *agdev = func_to_agdev(fn);
1026 struct usb_composite_dev *cdev = cfg->cdev;
1027 struct usb_gadget *gadget = cdev->gadget;
1028 struct uac2_rtd_params *prm; 1028 struct uac2_rtd_params *prm;
1029 1029
1030 alsa_uac2_exit(agdev); 1030 alsa_uac2_exit(agdev);
@@ -1034,10 +1034,7 @@ afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn)
1034 1034
1035 prm = &agdev->uac2.c_prm; 1035 prm = &agdev->uac2.c_prm;
1036 kfree(prm->rbuf); 1036 kfree(prm->rbuf);
1037 1037 usb_free_all_descriptors(fn);
1038 if (gadget_is_dualspeed(gadget))
1039 usb_free_descriptors(fn->hs_descriptors);
1040 usb_free_descriptors(fn->descriptors);
1041 1038
1042 if (agdev->in_ep) 1039 if (agdev->in_ep)
1043 agdev->in_ep->driver_data = NULL; 1040 agdev->in_ep->driver_data = NULL;
@@ -1064,7 +1061,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
1064 return -EINVAL; 1061 return -EINVAL;
1065 } 1062 }
1066 1063
1067 if (intf == INTF_GET(agdev->ac_alt)) { 1064 if (intf == agdev->ac_intf) {
1068 /* Control I/f has only 1 AltSetting - 0 */ 1065 /* Control I/f has only 1 AltSetting - 0 */
1069 if (alt) { 1066 if (alt) {
1070 dev_err(&uac2->pdev.dev, 1067 dev_err(&uac2->pdev.dev,
@@ -1074,16 +1071,16 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
1074 return 0; 1071 return 0;
1075 } 1072 }
1076 1073
1077 if (intf == INTF_GET(agdev->as_out_alt)) { 1074 if (intf == agdev->as_out_intf) {
1078 ep = agdev->out_ep; 1075 ep = agdev->out_ep;
1079 prm = &uac2->c_prm; 1076 prm = &uac2->c_prm;
1080 config_ep_by_speed(gadget, fn, ep); 1077 config_ep_by_speed(gadget, fn, ep);
1081 ALT_SET(agdev->as_out_alt, alt); 1078 agdev->as_out_alt = alt;
1082 } else if (intf == INTF_GET(agdev->as_in_alt)) { 1079 } else if (intf == agdev->as_in_intf) {
1083 ep = agdev->in_ep; 1080 ep = agdev->in_ep;
1084 prm = &uac2->p_prm; 1081 prm = &uac2->p_prm;
1085 config_ep_by_speed(gadget, fn, ep); 1082 config_ep_by_speed(gadget, fn, ep);
1086 ALT_SET(agdev->as_in_alt, alt); 1083 agdev->as_in_alt = alt;
1087 } else { 1084 } else {
1088 dev_err(&uac2->pdev.dev, 1085 dev_err(&uac2->pdev.dev,
1089 "%s:%d Error!\n", __func__, __LINE__); 1086 "%s:%d Error!\n", __func__, __LINE__);
@@ -1117,7 +1114,6 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
1117 prm->ureq[i].pp = prm; 1114 prm->ureq[i].pp = prm;
1118 1115
1119 req->zero = 0; 1116 req->zero = 0;
1120 req->dma = DMA_ADDR_INVALID;
1121 req->context = &prm->ureq[i]; 1117 req->context = &prm->ureq[i];
1122 req->length = prm->max_psize; 1118 req->length = prm->max_psize;
1123 req->complete = agdev_iso_complete; 1119 req->complete = agdev_iso_complete;
@@ -1136,12 +1132,12 @@ afunc_get_alt(struct usb_function *fn, unsigned intf)
1136 struct audio_dev *agdev = func_to_agdev(fn); 1132 struct audio_dev *agdev = func_to_agdev(fn);
1137 struct snd_uac2_chip *uac2 = &agdev->uac2; 1133 struct snd_uac2_chip *uac2 = &agdev->uac2;
1138 1134
1139 if (intf == INTF_GET(agdev->ac_alt)) 1135 if (intf == agdev->ac_intf)
1140 return ALT_GET(agdev->ac_alt); 1136 return agdev->ac_alt;
1141 else if (intf == INTF_GET(agdev->as_out_alt)) 1137 else if (intf == agdev->as_out_intf)
1142 return ALT_GET(agdev->as_out_alt); 1138 return agdev->as_out_alt;
1143 else if (intf == INTF_GET(agdev->as_in_alt)) 1139 else if (intf == agdev->as_in_intf)
1144 return ALT_GET(agdev->as_in_alt); 1140 return agdev->as_in_alt;
1145 else 1141 else
1146 dev_err(&uac2->pdev.dev, 1142 dev_err(&uac2->pdev.dev,
1147 "%s:%d Invalid Interface %d!\n", 1143 "%s:%d Invalid Interface %d!\n",
@@ -1157,10 +1153,10 @@ afunc_disable(struct usb_function *fn)
1157 struct snd_uac2_chip *uac2 = &agdev->uac2; 1153 struct snd_uac2_chip *uac2 = &agdev->uac2;
1158 1154
1159 free_ep(&uac2->p_prm, agdev->in_ep); 1155 free_ep(&uac2->p_prm, agdev->in_ep);
1160 ALT_SET(agdev->as_in_alt, 0); 1156 agdev->as_in_alt = 0;
1161 1157
1162 free_ep(&uac2->c_prm, agdev->out_ep); 1158 free_ep(&uac2->c_prm, agdev->out_ep);
1163 ALT_SET(agdev->as_out_alt, 0); 1159 agdev->as_out_alt = 0;
1164} 1160}
1165 1161
1166static int 1162static int
@@ -1267,7 +1263,7 @@ setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1267 u16 w_index = le16_to_cpu(cr->wIndex); 1263 u16 w_index = le16_to_cpu(cr->wIndex);
1268 u8 intf = w_index & 0xff; 1264 u8 intf = w_index & 0xff;
1269 1265
1270 if (intf != INTF_GET(agdev->ac_alt)) { 1266 if (intf != agdev->ac_intf) {
1271 dev_err(&uac2->pdev.dev, 1267 dev_err(&uac2->pdev.dev,
1272 "%s:%d Error!\n", __func__, __LINE__); 1268 "%s:%d Error!\n", __func__, __LINE__);
1273 return -EOPNOTSUPP; 1269 return -EOPNOTSUPP;
@@ -1316,7 +1312,7 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1316 1312
1317static int audio_bind_config(struct usb_configuration *cfg) 1313static int audio_bind_config(struct usb_configuration *cfg)
1318{ 1314{
1319 int id, res; 1315 int res;
1320 1316
1321 agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); 1317 agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL);
1322 if (agdev_g == NULL) { 1318 if (agdev_g == NULL) {
@@ -1324,89 +1320,21 @@ static int audio_bind_config(struct usb_configuration *cfg)
1324 return -ENOMEM; 1320 return -ENOMEM;
1325 } 1321 }
1326 1322
1327 id = usb_string_id(cfg->cdev); 1323 res = usb_string_ids_tab(cfg->cdev, strings_fn);
1328 if (id < 0) 1324 if (res)
1329 return id; 1325 return res;
1330 1326 iad_desc.iFunction = strings_fn[STR_ASSOC].id;
1331 strings_fn[STR_ASSOC].id = id; 1327 std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id;
1332 iad_desc.iFunction = id, 1328 in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id;
1333 1329 out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id;
1334 id = usb_string_id(cfg->cdev); 1330 usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id;
1335 if (id < 0) 1331 io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id;
1336 return id; 1332 usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id;
1337 1333 io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id;
1338 strings_fn[STR_IF_CTRL].id = id; 1334 std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id;
1339 std_ac_if_desc.iInterface = id, 1335 std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id;
1340 1336 std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id;
1341 id = usb_string_id(cfg->cdev); 1337 std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id;
1342 if (id < 0)
1343 return id;
1344
1345 strings_fn[STR_CLKSRC_IN].id = id;
1346 in_clk_src_desc.iClockSource = id,
1347
1348 id = usb_string_id(cfg->cdev);
1349 if (id < 0)
1350 return id;
1351
1352 strings_fn[STR_CLKSRC_OUT].id = id;
1353 out_clk_src_desc.iClockSource = id,
1354
1355 id = usb_string_id(cfg->cdev);
1356 if (id < 0)
1357 return id;
1358
1359 strings_fn[STR_USB_IT].id = id;
1360 usb_out_it_desc.iTerminal = id,
1361
1362 id = usb_string_id(cfg->cdev);
1363 if (id < 0)
1364 return id;
1365
1366 strings_fn[STR_IO_IT].id = id;
1367 io_in_it_desc.iTerminal = id;
1368
1369 id = usb_string_id(cfg->cdev);
1370 if (id < 0)
1371 return id;
1372
1373 strings_fn[STR_USB_OT].id = id;
1374 usb_in_ot_desc.iTerminal = id;
1375
1376 id = usb_string_id(cfg->cdev);
1377 if (id < 0)
1378 return id;
1379
1380 strings_fn[STR_IO_OT].id = id;
1381 io_out_ot_desc.iTerminal = id;
1382
1383 id = usb_string_id(cfg->cdev);
1384 if (id < 0)
1385 return id;
1386
1387 strings_fn[STR_AS_OUT_ALT0].id = id;
1388 std_as_out_if0_desc.iInterface = id;
1389
1390 id = usb_string_id(cfg->cdev);
1391 if (id < 0)
1392 return id;
1393
1394 strings_fn[STR_AS_OUT_ALT1].id = id;
1395 std_as_out_if1_desc.iInterface = id;
1396
1397 id = usb_string_id(cfg->cdev);
1398 if (id < 0)
1399 return id;
1400
1401 strings_fn[STR_AS_IN_ALT0].id = id;
1402 std_as_in_if0_desc.iInterface = id;
1403
1404 id = usb_string_id(cfg->cdev);
1405 if (id < 0)
1406 return id;
1407
1408 strings_fn[STR_AS_IN_ALT1].id = id;
1409 std_as_in_if1_desc.iInterface = id;
1410 1338
1411 agdev_g->func.name = "uac2_func"; 1339 agdev_g->func.name = "uac2_func";
1412 agdev_g->func.strings = fn_strings; 1340 agdev_g->func.strings = fn_strings;