diff options
author | Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 2014-07-22 13:58:30 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2014-08-20 15:04:16 -0400 |
commit | f8f93d244afad804e09595fcb14320fe2896fef5 (patch) | |
tree | bb6e0e0aca769fa559481cc10f84c24a98cfebc7 | |
parent | 5d73abf2a77a090ca4c920ac99c8ec0e272398a9 (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/Kconfig | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/function/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_uac2.c | 244 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_uac2.h | 32 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/audio.c | 1 |
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 | |||
181 | config USB_F_FS | 181 | config USB_F_FS |
182 | tristate | 182 | tristate |
183 | 183 | ||
184 | config USB_F_UAC2 | ||
185 | tristate | ||
186 | |||
184 | choice | 187 | choice |
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 | |||
32 | obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o | 32 | obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o |
33 | usb_f_fs-y := f_fs.o | 33 | usb_f_fs-y := f_fs.o |
34 | obj-$(CONFIG_USB_F_FS) += usb_f_fs.o | 34 | obj-$(CONFIG_USB_F_FS) += usb_f_fs.o |
35 | usb_f_uac2-y := f_uac2.o | ||
36 | obj-$(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 */ |
24 | static int p_chmask = 0x3; | 28 | static int p_chmask = 0x3; |
25 | module_param(p_chmask, uint, S_IRUGO); | 29 | module_param(p_chmask, uint, S_IRUGO); |
@@ -50,6 +54,8 @@ static int c_ssize = 2; | |||
50 | module_param(c_ssize, uint, S_IRUGO); | 54 | module_param(c_ssize, uint, S_IRUGO); |
51 | MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); | 55 | MODULE_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 | ||
920 | static int __init | 954 | static int |
921 | afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) | 955 | afunc_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 | ||
1021 | static void | ||
1022 | afunc_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 | |||
1043 | static int | 1097 | static int |
1044 | afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) | 1098 | afunc_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 | |||
1387 | static void | ||
1388 | old_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 | |||
1311 | static int audio_bind_config(struct usb_configuration *cfg) | 1409 | static 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 | |||
1453 | static 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 | |||
1461 | static 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 | |||
1474 | static 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 | |||
1482 | static 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 | |||
1502 | struct 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 | |||
1526 | DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc); | ||
1527 | MODULE_LICENSE("GPL"); | ||
1528 | MODULE_AUTHOR("Yadwinder Singh"); | ||
1529 | MODULE_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 | |||
21 | struct 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 | ||