aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2014-07-22 13:58:30 -0400
committerFelipe Balbi <balbi@ti.com>2014-08-20 15:04:16 -0400
commitf8f93d244afad804e09595fcb14320fe2896fef5 (patch)
treebb6e0e0aca769fa559481cc10f84c24a98cfebc7
parent5d73abf2a77a090ca4c920ac99c8ec0e272398a9 (diff)
usb: gadget: f_uac2: convert to new function interface with backward compatibility
Converting uac2 to the new function interface requires converting the USB uac2's function code and its users. This patch converts the f_uac2.c to the new function interface. The file is now compiled into a separate usb_f_uac2.ko module. The old function interface is provided by means of a preprocessor conditional directives. After all users are converted, the old interface can be removed. Tested-by: Sebastian Reimers <sebastian.reimers@googlemail.com> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/Kconfig3
-rw-r--r--drivers/usb/gadget/function/Makefile2
-rw-r--r--drivers/usb/gadget/function/f_uac2.c244
-rw-r--r--drivers/usb/gadget/function/u_uac2.h32
-rw-r--r--drivers/usb/gadget/legacy/audio.c1
5 files changed, 242 insertions, 40 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 5c822afb6d70..ea8ebce60d8f 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -181,6 +181,9 @@ config USB_F_MASS_STORAGE
181config USB_F_FS 181config USB_F_FS
182 tristate 182 tristate
183 183
184config USB_F_UAC2
185 tristate
186
184choice 187choice
185 tristate "USB Gadget Drivers" 188 tristate "USB Gadget Drivers"
186 default USB_ETH 189 default USB_ETH
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile
index 6d91f21b52a6..20775a87e51a 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -32,3 +32,5 @@ usb_f_mass_storage-y := f_mass_storage.o storage_common.o
32obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o 32obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
33usb_f_fs-y := f_fs.o 33usb_f_fs-y := f_fs.o
34obj-$(CONFIG_USB_F_FS) += usb_f_fs.o 34obj-$(CONFIG_USB_F_FS) += usb_f_fs.o
35usb_f_uac2-y := f_uac2.o
36obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 91615619c204..29b477fa2050 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -20,6 +20,10 @@
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22 22
23#include "u_uac2.h"
24
25#ifdef USB_FUAC2_INCLUDED
26
23/* Playback(USB-IN) Default Stereo - Fl/Fr */ 27/* Playback(USB-IN) Default Stereo - Fl/Fr */
24static int p_chmask = 0x3; 28static int p_chmask = 0x3;
25module_param(p_chmask, uint, S_IRUGO); 29module_param(p_chmask, uint, S_IRUGO);
@@ -50,6 +54,8 @@ static int c_ssize = 2;
50module_param(c_ssize, uint, S_IRUGO); 54module_param(c_ssize, uint, S_IRUGO);
51MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); 55MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
52 56
57#endif
58
53/* Keep everyone on toes */ 59/* Keep everyone on toes */
54#define USB_XFERS 2 60#define USB_XFERS 2
55 61
@@ -340,6 +346,22 @@ static int uac2_pcm_open(struct snd_pcm_substream *substream)
340{ 346{
341 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); 347 struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
342 struct snd_pcm_runtime *runtime = substream->runtime; 348 struct snd_pcm_runtime *runtime = substream->runtime;
349#ifndef USB_FUAC2_INCLUDED
350 struct audio_dev *audio_dev;
351 struct f_uac2_opts *opts;
352 int p_ssize, c_ssize;
353 int p_srate, c_srate;
354 int p_chmask, c_chmask;
355
356 audio_dev = uac2_to_agdev(uac2);
357 opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
358 p_ssize = opts->p_ssize;
359 c_ssize = opts->c_ssize;
360 p_srate = opts->p_srate;
361 c_srate = opts->c_srate;
362 p_chmask = opts->p_chmask;
363 c_chmask = opts->c_chmask;
364#endif
343 365
344 runtime->hw = uac2_pcm_hardware; 366 runtime->hw = uac2_pcm_hardware;
345 367
@@ -409,7 +431,19 @@ static int snd_uac2_probe(struct platform_device *pdev)
409 struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); 431 struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev);
410 struct snd_card *card; 432 struct snd_card *card;
411 struct snd_pcm *pcm; 433 struct snd_pcm *pcm;
434#ifndef USB_FUAC2_INCLUDED
435 struct audio_dev *audio_dev;
436 struct f_uac2_opts *opts;
437#endif
412 int err; 438 int err;
439#ifndef USB_FUAC2_INCLUDED
440 int p_chmask, c_chmask;
441
442 audio_dev = uac2_to_agdev(uac2);
443 opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst);
444 p_chmask = opts->p_chmask;
445 c_chmask = opts->c_chmask;
446#endif
413 447
414 /* Choose any slot, with no id */ 448 /* Choose any slot, with no id */
415 err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); 449 err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card);
@@ -917,7 +951,7 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
917 "%s:%d Error!\n", __func__, __LINE__); 951 "%s:%d Error!\n", __func__, __LINE__);
918} 952}
919 953
920static int __init 954static int
921afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) 955afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
922{ 956{
923 struct audio_dev *agdev = func_to_agdev(fn); 957 struct audio_dev *agdev = func_to_agdev(fn);
@@ -925,8 +959,50 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
925 struct usb_composite_dev *cdev = cfg->cdev; 959 struct usb_composite_dev *cdev = cfg->cdev;
926 struct usb_gadget *gadget = cdev->gadget; 960 struct usb_gadget *gadget = cdev->gadget;
927 struct uac2_rtd_params *prm; 961 struct uac2_rtd_params *prm;
962#ifndef USB_FUAC2_INCLUDED
963 struct f_uac2_opts *uac2_opts;
964#endif
928 int ret; 965 int ret;
929 966
967#ifndef USB_FUAC2_INCLUDED
968 uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
969#endif
970
971 ret = usb_string_ids_tab(cfg->cdev, strings_fn);
972 if (ret)
973 return ret;
974 iad_desc.iFunction = strings_fn[STR_ASSOC].id;
975 std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id;
976 in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id;
977 out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id;
978 usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id;
979 io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id;
980 usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id;
981 io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id;
982 std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id;
983 std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id;
984 std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id;
985 std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id;
986
987#ifndef USB_FUAC2_INCLUDED
988 /* Initialize the configurable parameters */
989 usb_out_it_desc.bNrChannels = num_channels(uac2_opts->c_chmask);
990 usb_out_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask);
991 io_in_it_desc.bNrChannels = num_channels(uac2_opts->p_chmask);
992 io_in_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->p_chmask);
993 as_out_hdr_desc.bNrChannels = num_channels(uac2_opts->c_chmask);
994 as_out_hdr_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask);
995 as_in_hdr_desc.bNrChannels = num_channels(uac2_opts->p_chmask);
996 as_in_hdr_desc.bmChannelConfig = cpu_to_le32(uac2_opts->p_chmask);
997 as_out_fmt1_desc.bSubslotSize = uac2_opts->c_ssize;
998 as_out_fmt1_desc.bBitResolution = uac2_opts->c_ssize * 8;
999 as_in_fmt1_desc.bSubslotSize = uac2_opts->p_ssize;
1000 as_in_fmt1_desc.bBitResolution = uac2_opts->p_ssize * 8;
1001
1002 snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate);
1003 snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate);
1004#endif
1005
930 ret = usb_interface_id(cfg, fn); 1006 ret = usb_interface_id(cfg, fn);
931 if (ret < 0) { 1007 if (ret < 0) {
932 dev_err(&uac2->pdev.dev, 1008 dev_err(&uac2->pdev.dev,
@@ -1018,28 +1094,6 @@ err:
1018 return -EINVAL; 1094 return -EINVAL;
1019} 1095}
1020 1096
1021static void
1022afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn)
1023{
1024 struct audio_dev *agdev = func_to_agdev(fn);
1025 struct uac2_rtd_params *prm;
1026
1027 alsa_uac2_exit(agdev);
1028
1029 prm = &agdev->uac2.p_prm;
1030 kfree(prm->rbuf);
1031
1032 prm = &agdev->uac2.c_prm;
1033 kfree(prm->rbuf);
1034 usb_free_all_descriptors(fn);
1035
1036 if (agdev->in_ep)
1037 agdev->in_ep->driver_data = NULL;
1038 if (agdev->out_ep)
1039 agdev->out_ep->driver_data = NULL;
1040 kfree(agdev);
1041}
1042
1043static int 1097static int
1044afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) 1098afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
1045{ 1099{
@@ -1163,12 +1217,22 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1163 struct usb_request *req = fn->config->cdev->req; 1217 struct usb_request *req = fn->config->cdev->req;
1164 struct audio_dev *agdev = func_to_agdev(fn); 1218 struct audio_dev *agdev = func_to_agdev(fn);
1165 struct snd_uac2_chip *uac2 = &agdev->uac2; 1219 struct snd_uac2_chip *uac2 = &agdev->uac2;
1220#ifndef USB_FUAC2_INCLUDED
1221 struct f_uac2_opts *opts;
1222#endif
1166 u16 w_length = le16_to_cpu(cr->wLength); 1223 u16 w_length = le16_to_cpu(cr->wLength);
1167 u16 w_index = le16_to_cpu(cr->wIndex); 1224 u16 w_index = le16_to_cpu(cr->wIndex);
1168 u16 w_value = le16_to_cpu(cr->wValue); 1225 u16 w_value = le16_to_cpu(cr->wValue);
1169 u8 entity_id = (w_index >> 8) & 0xff; 1226 u8 entity_id = (w_index >> 8) & 0xff;
1170 u8 control_selector = w_value >> 8; 1227 u8 control_selector = w_value >> 8;
1171 int value = -EOPNOTSUPP; 1228 int value = -EOPNOTSUPP;
1229#ifndef USB_FUAC2_INCLUDED
1230 int p_srate, c_srate;
1231
1232 opts = container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
1233 p_srate = opts->p_srate;
1234 c_srate = opts->c_srate;
1235#endif
1172 1236
1173 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { 1237 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) {
1174 struct cntrl_cur_lay3 c; 1238 struct cntrl_cur_lay3 c;
@@ -1198,6 +1262,9 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1198 struct usb_request *req = fn->config->cdev->req; 1262 struct usb_request *req = fn->config->cdev->req;
1199 struct audio_dev *agdev = func_to_agdev(fn); 1263 struct audio_dev *agdev = func_to_agdev(fn);
1200 struct snd_uac2_chip *uac2 = &agdev->uac2; 1264 struct snd_uac2_chip *uac2 = &agdev->uac2;
1265#ifndef USB_FUAC2_INCLUDED
1266 struct f_uac2_opts *opts;
1267#endif
1201 u16 w_length = le16_to_cpu(cr->wLength); 1268 u16 w_length = le16_to_cpu(cr->wLength);
1202 u16 w_index = le16_to_cpu(cr->wIndex); 1269 u16 w_index = le16_to_cpu(cr->wIndex);
1203 u16 w_value = le16_to_cpu(cr->wValue); 1270 u16 w_value = le16_to_cpu(cr->wValue);
@@ -1205,6 +1272,13 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1205 u8 control_selector = w_value >> 8; 1272 u8 control_selector = w_value >> 8;
1206 struct cntrl_range_lay3 r; 1273 struct cntrl_range_lay3 r;
1207 int value = -EOPNOTSUPP; 1274 int value = -EOPNOTSUPP;
1275#ifndef USB_FUAC2_INCLUDED
1276 int p_srate, c_srate;
1277
1278 opts = container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
1279 p_srate = opts->p_srate;
1280 c_srate = opts->c_srate;
1281#endif
1208 1282
1209 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { 1283 if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) {
1210 if (entity_id == USB_IN_CLK_ID) 1284 if (entity_id == USB_IN_CLK_ID)
@@ -1308,6 +1382,30 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr)
1308 return value; 1382 return value;
1309} 1383}
1310 1384
1385#ifdef USB_FUAC2_INCLUDED
1386
1387static void
1388old_afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn)
1389{
1390 struct audio_dev *agdev = func_to_agdev(fn);
1391 struct uac2_rtd_params *prm;
1392
1393 alsa_uac2_exit(agdev);
1394
1395 prm = &agdev->uac2.p_prm;
1396 kfree(prm->rbuf);
1397
1398 prm = &agdev->uac2.c_prm;
1399 kfree(prm->rbuf);
1400 usb_free_all_descriptors(fn);
1401
1402 if (agdev->in_ep)
1403 agdev->in_ep->driver_data = NULL;
1404 if (agdev->out_ep)
1405 agdev->out_ep->driver_data = NULL;
1406 kfree(agdev);
1407}
1408
1311static int audio_bind_config(struct usb_configuration *cfg) 1409static int audio_bind_config(struct usb_configuration *cfg)
1312{ 1410{
1313 struct audio_dev *agdev; 1411 struct audio_dev *agdev;
@@ -1317,26 +1415,10 @@ static int audio_bind_config(struct usb_configuration *cfg)
1317 if (agdev == NULL) 1415 if (agdev == NULL)
1318 return -ENOMEM; 1416 return -ENOMEM;
1319 1417
1320 res = usb_string_ids_tab(cfg->cdev, strings_fn);
1321 if (res)
1322 return res;
1323 iad_desc.iFunction = strings_fn[STR_ASSOC].id;
1324 std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id;
1325 in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id;
1326 out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id;
1327 usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id;
1328 io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id;
1329 usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id;
1330 io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id;
1331 std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id;
1332 std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id;
1333 std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id;
1334 std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id;
1335
1336 agdev->func.name = "uac2_func"; 1418 agdev->func.name = "uac2_func";
1337 agdev->func.strings = fn_strings; 1419 agdev->func.strings = fn_strings;
1338 agdev->func.bind = afunc_bind; 1420 agdev->func.bind = afunc_bind;
1339 agdev->func.unbind = afunc_unbind; 1421 agdev->func.unbind = old_afunc_unbind;
1340 agdev->func.set_alt = afunc_set_alt; 1422 agdev->func.set_alt = afunc_set_alt;
1341 agdev->func.get_alt = afunc_get_alt; 1423 agdev->func.get_alt = afunc_get_alt;
1342 agdev->func.disable = afunc_disable; 1424 agdev->func.disable = afunc_disable;
@@ -1365,3 +1447,85 @@ static int audio_bind_config(struct usb_configuration *cfg)
1365 1447
1366 return res; 1448 return res;
1367} 1449}
1450
1451#else
1452
1453static void afunc_free_inst(struct usb_function_instance *f)
1454{
1455 struct f_uac2_opts *opts;
1456
1457 opts = container_of(f, struct f_uac2_opts, func_inst);
1458 kfree(opts);
1459}
1460
1461static struct usb_function_instance *afunc_alloc_inst(void)
1462{
1463 struct f_uac2_opts *opts;
1464
1465 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
1466 if (!opts)
1467 return ERR_PTR(-ENOMEM);
1468
1469 opts->func_inst.free_func_inst = afunc_free_inst;
1470
1471 return &opts->func_inst;
1472}
1473
1474static void afunc_free(struct usb_function *f)
1475{
1476 struct audio_dev *agdev;
1477
1478 agdev = func_to_agdev(f);
1479 kfree(agdev);
1480}
1481
1482static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
1483{
1484 struct audio_dev *agdev = func_to_agdev(f);
1485 struct uac2_rtd_params *prm;
1486
1487 alsa_uac2_exit(agdev);
1488
1489 prm = &agdev->uac2.p_prm;
1490 kfree(prm->rbuf);
1491
1492 prm = &agdev->uac2.c_prm;
1493 kfree(prm->rbuf);
1494 usb_free_all_descriptors(f);
1495
1496 if (agdev->in_ep)
1497 agdev->in_ep->driver_data = NULL;
1498 if (agdev->out_ep)
1499 agdev->out_ep->driver_data = NULL;
1500}
1501
1502struct usb_function *afunc_alloc(struct usb_function_instance *fi)
1503{
1504 struct audio_dev *agdev;
1505 struct f_uac2_opts *opts;
1506
1507 agdev = kzalloc(sizeof(*agdev), GFP_KERNEL);
1508 if (agdev == NULL)
1509 return ERR_PTR(-ENOMEM);
1510
1511 opts = container_of(fi, struct f_uac2_opts, func_inst);
1512
1513 agdev->func.name = "uac2_func";
1514 agdev->func.strings = fn_strings;
1515 agdev->func.bind = afunc_bind;
1516 agdev->func.unbind = afunc_unbind;
1517 agdev->func.set_alt = afunc_set_alt;
1518 agdev->func.get_alt = afunc_get_alt;
1519 agdev->func.disable = afunc_disable;
1520 agdev->func.setup = afunc_setup;
1521 agdev->func.free_func = afunc_free;
1522
1523 return &agdev->func;
1524}
1525
1526DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc);
1527MODULE_LICENSE("GPL");
1528MODULE_AUTHOR("Yadwinder Singh");
1529MODULE_AUTHOR("Jaswinder Singh");
1530
1531#endif
diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h
new file mode 100644
index 000000000000..290b83af1b69
--- /dev/null
+++ b/drivers/usb/gadget/function/u_uac2.h
@@ -0,0 +1,32 @@
1/*
2 * u_uac2.h
3 *
4 * Utility definitions for UAC2 function
5 *
6 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 * http://www.samsung.com
8 *
9 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef U_UAC2_H
17#define U_UAC2_H
18
19#include <linux/usb/composite.h>
20
21struct f_uac2_opts {
22 struct usb_function_instance func_inst;
23 int p_chmask;
24 int p_srate;
25 int p_ssize;
26 int c_chmask;
27 int c_srate;
28 int c_ssize;
29 bool bound;
30};
31
32#endif
diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c
index 3c2328316c05..a41316bb436a 100644
--- a/drivers/usb/gadget/legacy/audio.c
+++ b/drivers/usb/gadget/legacy/audio.c
@@ -45,6 +45,7 @@ static struct usb_gadget_strings *audio_strings[] = {
45#include "u_uac1.c" 45#include "u_uac1.c"
46#include "f_uac1.c" 46#include "f_uac1.c"
47#else 47#else
48#define USB_FUAC2_INCLUDED
48#include "f_uac2.c" 49#include "f_uac2.c"
49#endif 50#endif
50 51