uvc_configfs.c 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367
  1. /*
  2. * uvc_configfs.c
  3. *
  4. * Configfs support for the uvc 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. #include "u_uvc.h"
  16. #include "uvc_configfs.h"
  17. #define UVCG_STREAMING_CONTROL_SIZE 1
  18. #define UVC_ATTR(prefix, cname, aname) \
  19. static struct configfs_attribute prefix##attr_##cname = { \
  20. .ca_name = __stringify(aname), \
  21. .ca_mode = S_IRUGO | S_IWUGO, \
  22. .ca_owner = THIS_MODULE, \
  23. .show = prefix##cname##_show, \
  24. .store = prefix##cname##_store, \
  25. }
  26. #define UVC_ATTR_RO(prefix, cname, aname) \
  27. static struct configfs_attribute prefix##attr_##cname = { \
  28. .ca_name = __stringify(aname), \
  29. .ca_mode = S_IRUGO, \
  30. .ca_owner = THIS_MODULE, \
  31. .show = prefix##cname##_show, \
  32. }
  33. static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item);
  34. /* control/header/<NAME> */
  35. DECLARE_UVC_HEADER_DESCRIPTOR(1);
  36. struct uvcg_control_header {
  37. struct config_item item;
  38. struct UVC_HEADER_DESCRIPTOR(1) desc;
  39. unsigned linked;
  40. };
  41. static struct uvcg_control_header *to_uvcg_control_header(struct config_item *item)
  42. {
  43. return container_of(item, struct uvcg_control_header, item);
  44. }
  45. #define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \
  46. static ssize_t uvcg_control_header_##cname##_show( \
  47. struct config_item *item, char *page) \
  48. { \
  49. struct uvcg_control_header *ch = to_uvcg_control_header(item); \
  50. struct f_uvc_opts *opts; \
  51. struct config_item *opts_item; \
  52. struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
  53. int result; \
  54. \
  55. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  56. \
  57. opts_item = ch->item.ci_parent->ci_parent->ci_parent; \
  58. opts = to_f_uvc_opts(opts_item); \
  59. \
  60. mutex_lock(&opts->lock); \
  61. result = sprintf(page, "%d\n", conv(ch->desc.aname)); \
  62. mutex_unlock(&opts->lock); \
  63. \
  64. mutex_unlock(su_mutex); \
  65. return result; \
  66. } \
  67. \
  68. static ssize_t \
  69. uvcg_control_header_##cname##_store(struct config_item *item, \
  70. const char *page, size_t len) \
  71. { \
  72. struct uvcg_control_header *ch = to_uvcg_control_header(item); \
  73. struct f_uvc_opts *opts; \
  74. struct config_item *opts_item; \
  75. struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\
  76. int ret; \
  77. uxx num; \
  78. \
  79. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  80. \
  81. opts_item = ch->item.ci_parent->ci_parent->ci_parent; \
  82. opts = to_f_uvc_opts(opts_item); \
  83. \
  84. mutex_lock(&opts->lock); \
  85. if (ch->linked || opts->refcnt) { \
  86. ret = -EBUSY; \
  87. goto end; \
  88. } \
  89. \
  90. ret = str2u(page, 0, &num); \
  91. if (ret) \
  92. goto end; \
  93. \
  94. if (num > limit) { \
  95. ret = -EINVAL; \
  96. goto end; \
  97. } \
  98. ch->desc.aname = vnoc(num); \
  99. ret = len; \
  100. end: \
  101. mutex_unlock(&opts->lock); \
  102. mutex_unlock(su_mutex); \
  103. return ret; \
  104. } \
  105. \
  106. UVC_ATTR(uvcg_control_header_, cname, aname)
  107. UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16,
  108. 0xffff);
  109. UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32,
  110. u32, cpu_to_le32, 0x7fffffff);
  111. #undef UVCG_CTRL_HDR_ATTR
  112. static struct configfs_attribute *uvcg_control_header_attrs[] = {
  113. &uvcg_control_header_attr_bcd_uvc,
  114. &uvcg_control_header_attr_dw_clock_frequency,
  115. NULL,
  116. };
  117. static struct config_item_type uvcg_control_header_type = {
  118. .ct_attrs = uvcg_control_header_attrs,
  119. .ct_owner = THIS_MODULE,
  120. };
  121. static struct config_item *uvcg_control_header_make(struct config_group *group,
  122. const char *name)
  123. {
  124. struct uvcg_control_header *h;
  125. h = kzalloc(sizeof(*h), GFP_KERNEL);
  126. if (!h)
  127. return ERR_PTR(-ENOMEM);
  128. h->desc.bLength = UVC_DT_HEADER_SIZE(1);
  129. h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
  130. h->desc.bDescriptorSubType = UVC_VC_HEADER;
  131. h->desc.bcdUVC = cpu_to_le16(0x0100);
  132. h->desc.dwClockFrequency = cpu_to_le32(48000000);
  133. config_item_init_type_name(&h->item, name, &uvcg_control_header_type);
  134. return &h->item;
  135. }
  136. static void uvcg_control_header_drop(struct config_group *group,
  137. struct config_item *item)
  138. {
  139. struct uvcg_control_header *h = to_uvcg_control_header(item);
  140. kfree(h);
  141. }
  142. /* control/header */
  143. static struct uvcg_control_header_grp {
  144. struct config_group group;
  145. } uvcg_control_header_grp;
  146. static struct configfs_group_operations uvcg_control_header_grp_ops = {
  147. .make_item = uvcg_control_header_make,
  148. .drop_item = uvcg_control_header_drop,
  149. };
  150. static struct config_item_type uvcg_control_header_grp_type = {
  151. .ct_group_ops = &uvcg_control_header_grp_ops,
  152. .ct_owner = THIS_MODULE,
  153. };
  154. /* control/processing/default */
  155. static struct uvcg_default_processing {
  156. struct config_group group;
  157. } uvcg_default_processing;
  158. static inline struct uvcg_default_processing
  159. *to_uvcg_default_processing(struct config_item *item)
  160. {
  161. return container_of(to_config_group(item),
  162. struct uvcg_default_processing, group);
  163. }
  164. #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv) \
  165. static ssize_t uvcg_default_processing_##cname##_show( \
  166. struct config_item *item, char *page) \
  167. { \
  168. struct uvcg_default_processing *dp = to_uvcg_default_processing(item); \
  169. struct f_uvc_opts *opts; \
  170. struct config_item *opts_item; \
  171. struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; \
  172. struct uvc_processing_unit_descriptor *pd; \
  173. int result; \
  174. \
  175. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  176. \
  177. opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; \
  178. opts = to_f_uvc_opts(opts_item); \
  179. pd = &opts->uvc_processing; \
  180. \
  181. mutex_lock(&opts->lock); \
  182. result = sprintf(page, "%d\n", conv(pd->aname)); \
  183. mutex_unlock(&opts->lock); \
  184. \
  185. mutex_unlock(su_mutex); \
  186. return result; \
  187. } \
  188. \
  189. UVC_ATTR_RO(uvcg_default_processing_, cname, aname)
  190. #define identity_conv(x) (x)
  191. UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, identity_conv);
  192. UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, identity_conv);
  193. UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, le16_to_cpu);
  194. UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv);
  195. #undef identity_conv
  196. #undef UVCG_DEFAULT_PROCESSING_ATTR
  197. static ssize_t uvcg_default_processing_bm_controls_show(
  198. struct config_item *item, char *page)
  199. {
  200. struct uvcg_default_processing *dp = to_uvcg_default_processing(item);
  201. struct f_uvc_opts *opts;
  202. struct config_item *opts_item;
  203. struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;
  204. struct uvc_processing_unit_descriptor *pd;
  205. int result, i;
  206. char *pg = page;
  207. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  208. opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;
  209. opts = to_f_uvc_opts(opts_item);
  210. pd = &opts->uvc_processing;
  211. mutex_lock(&opts->lock);
  212. for (result = 0, i = 0; i < pd->bControlSize; ++i) {
  213. result += sprintf(pg, "%d\n", pd->bmControls[i]);
  214. pg = page + result;
  215. }
  216. mutex_unlock(&opts->lock);
  217. mutex_unlock(su_mutex);
  218. return result;
  219. }
  220. UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls);
  221. static struct configfs_attribute *uvcg_default_processing_attrs[] = {
  222. &uvcg_default_processing_attr_b_unit_id,
  223. &uvcg_default_processing_attr_b_source_id,
  224. &uvcg_default_processing_attr_w_max_multiplier,
  225. &uvcg_default_processing_attr_bm_controls,
  226. &uvcg_default_processing_attr_i_processing,
  227. NULL,
  228. };
  229. static struct config_item_type uvcg_default_processing_type = {
  230. .ct_attrs = uvcg_default_processing_attrs,
  231. .ct_owner = THIS_MODULE,
  232. };
  233. /* struct uvcg_processing {}; */
  234. static struct config_group *uvcg_processing_default_groups[] = {
  235. &uvcg_default_processing.group,
  236. NULL,
  237. };
  238. /* control/processing */
  239. static struct uvcg_processing_grp {
  240. struct config_group group;
  241. } uvcg_processing_grp;
  242. static struct config_item_type uvcg_processing_grp_type = {
  243. .ct_owner = THIS_MODULE,
  244. };
  245. /* control/terminal/camera/default */
  246. static struct uvcg_default_camera {
  247. struct config_group group;
  248. } uvcg_default_camera;
  249. static inline struct uvcg_default_camera
  250. *to_uvcg_default_camera(struct config_item *item)
  251. {
  252. return container_of(to_config_group(item),
  253. struct uvcg_default_camera, group);
  254. }
  255. #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv) \
  256. static ssize_t uvcg_default_camera_##cname##_show( \
  257. struct config_item *item, char *page) \
  258. { \
  259. struct uvcg_default_camera *dc = to_uvcg_default_camera(item); \
  260. struct f_uvc_opts *opts; \
  261. struct config_item *opts_item; \
  262. struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; \
  263. struct uvc_camera_terminal_descriptor *cd; \
  264. int result; \
  265. \
  266. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  267. \
  268. opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent-> \
  269. ci_parent; \
  270. opts = to_f_uvc_opts(opts_item); \
  271. cd = &opts->uvc_camera_terminal; \
  272. \
  273. mutex_lock(&opts->lock); \
  274. result = sprintf(page, "%d\n", conv(cd->aname)); \
  275. mutex_unlock(&opts->lock); \
  276. \
  277. mutex_unlock(su_mutex); \
  278. \
  279. return result; \
  280. } \
  281. \
  282. UVC_ATTR_RO(uvcg_default_camera_, cname, aname)
  283. #define identity_conv(x) (x)
  284. UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, identity_conv);
  285. UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
  286. UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
  287. UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, identity_conv);
  288. UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin,
  289. le16_to_cpu);
  290. UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax,
  291. le16_to_cpu);
  292. UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength,
  293. le16_to_cpu);
  294. #undef identity_conv
  295. #undef UVCG_DEFAULT_CAMERA_ATTR
  296. static ssize_t uvcg_default_camera_bm_controls_show(
  297. struct config_item *item, char *page)
  298. {
  299. struct uvcg_default_camera *dc = to_uvcg_default_camera(item);
  300. struct f_uvc_opts *opts;
  301. struct config_item *opts_item;
  302. struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex;
  303. struct uvc_camera_terminal_descriptor *cd;
  304. int result, i;
  305. char *pg = page;
  306. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  307. opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent->
  308. ci_parent;
  309. opts = to_f_uvc_opts(opts_item);
  310. cd = &opts->uvc_camera_terminal;
  311. mutex_lock(&opts->lock);
  312. for (result = 0, i = 0; i < cd->bControlSize; ++i) {
  313. result += sprintf(pg, "%d\n", cd->bmControls[i]);
  314. pg = page + result;
  315. }
  316. mutex_unlock(&opts->lock);
  317. mutex_unlock(su_mutex);
  318. return result;
  319. }
  320. UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls);
  321. static struct configfs_attribute *uvcg_default_camera_attrs[] = {
  322. &uvcg_default_camera_attr_b_terminal_id,
  323. &uvcg_default_camera_attr_w_terminal_type,
  324. &uvcg_default_camera_attr_b_assoc_terminal,
  325. &uvcg_default_camera_attr_i_terminal,
  326. &uvcg_default_camera_attr_w_objective_focal_length_min,
  327. &uvcg_default_camera_attr_w_objective_focal_length_max,
  328. &uvcg_default_camera_attr_w_ocular_focal_length,
  329. &uvcg_default_camera_attr_bm_controls,
  330. NULL,
  331. };
  332. static struct config_item_type uvcg_default_camera_type = {
  333. .ct_attrs = uvcg_default_camera_attrs,
  334. .ct_owner = THIS_MODULE,
  335. };
  336. /* struct uvcg_camera {}; */
  337. static struct config_group *uvcg_camera_default_groups[] = {
  338. &uvcg_default_camera.group,
  339. NULL,
  340. };
  341. /* control/terminal/camera */
  342. static struct uvcg_camera_grp {
  343. struct config_group group;
  344. } uvcg_camera_grp;
  345. static struct config_item_type uvcg_camera_grp_type = {
  346. .ct_owner = THIS_MODULE,
  347. };
  348. /* control/terminal/output/default */
  349. static struct uvcg_default_output {
  350. struct config_group group;
  351. } uvcg_default_output;
  352. static inline struct uvcg_default_output
  353. *to_uvcg_default_output(struct config_item *item)
  354. {
  355. return container_of(to_config_group(item),
  356. struct uvcg_default_output, group);
  357. }
  358. #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv) \
  359. static ssize_t uvcg_default_output_##cname##_show( \
  360. struct config_item *item, char *page) \
  361. { \
  362. struct uvcg_default_output *dout = to_uvcg_default_output(item); \
  363. struct f_uvc_opts *opts; \
  364. struct config_item *opts_item; \
  365. struct mutex *su_mutex = &dout->group.cg_subsys->su_mutex; \
  366. struct uvc_output_terminal_descriptor *cd; \
  367. int result; \
  368. \
  369. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  370. \
  371. opts_item = dout->group.cg_item.ci_parent->ci_parent-> \
  372. ci_parent->ci_parent; \
  373. opts = to_f_uvc_opts(opts_item); \
  374. cd = &opts->uvc_output_terminal; \
  375. \
  376. mutex_lock(&opts->lock); \
  377. result = sprintf(page, "%d\n", conv(cd->aname)); \
  378. mutex_unlock(&opts->lock); \
  379. \
  380. mutex_unlock(su_mutex); \
  381. \
  382. return result; \
  383. } \
  384. \
  385. UVC_ATTR_RO(uvcg_default_output_, cname, aname)
  386. #define identity_conv(x) (x)
  387. UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, identity_conv);
  388. UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, le16_to_cpu);
  389. UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv);
  390. UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, identity_conv);
  391. UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv);
  392. #undef identity_conv
  393. #undef UVCG_DEFAULT_OUTPUT_ATTR
  394. static struct configfs_attribute *uvcg_default_output_attrs[] = {
  395. &uvcg_default_output_attr_b_terminal_id,
  396. &uvcg_default_output_attr_w_terminal_type,
  397. &uvcg_default_output_attr_b_assoc_terminal,
  398. &uvcg_default_output_attr_b_source_id,
  399. &uvcg_default_output_attr_i_terminal,
  400. NULL,
  401. };
  402. static struct config_item_type uvcg_default_output_type = {
  403. .ct_attrs = uvcg_default_output_attrs,
  404. .ct_owner = THIS_MODULE,
  405. };
  406. /* struct uvcg_output {}; */
  407. static struct config_group *uvcg_output_default_groups[] = {
  408. &uvcg_default_output.group,
  409. NULL,
  410. };
  411. /* control/terminal/output */
  412. static struct uvcg_output_grp {
  413. struct config_group group;
  414. } uvcg_output_grp;
  415. static struct config_item_type uvcg_output_grp_type = {
  416. .ct_owner = THIS_MODULE,
  417. };
  418. static struct config_group *uvcg_terminal_default_groups[] = {
  419. &uvcg_camera_grp.group,
  420. &uvcg_output_grp.group,
  421. NULL,
  422. };
  423. /* control/terminal */
  424. static struct uvcg_terminal_grp {
  425. struct config_group group;
  426. } uvcg_terminal_grp;
  427. static struct config_item_type uvcg_terminal_grp_type = {
  428. .ct_owner = THIS_MODULE,
  429. };
  430. /* control/class/{fs} */
  431. static struct uvcg_control_class {
  432. struct config_group group;
  433. } uvcg_control_class_fs, uvcg_control_class_ss;
  434. static inline struct uvc_descriptor_header
  435. **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o)
  436. {
  437. struct uvcg_control_class *cl = container_of(to_config_group(i),
  438. struct uvcg_control_class, group);
  439. if (cl == &uvcg_control_class_fs)
  440. return o->uvc_fs_control_cls;
  441. if (cl == &uvcg_control_class_ss)
  442. return o->uvc_ss_control_cls;
  443. return NULL;
  444. }
  445. static int uvcg_control_class_allow_link(struct config_item *src,
  446. struct config_item *target)
  447. {
  448. struct config_item *control, *header;
  449. struct f_uvc_opts *opts;
  450. struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
  451. struct uvc_descriptor_header **class_array;
  452. struct uvcg_control_header *target_hdr;
  453. int ret = -EINVAL;
  454. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  455. control = src->ci_parent->ci_parent;
  456. header = config_group_find_item(to_config_group(control), "header");
  457. if (!header || target->ci_parent != header)
  458. goto out;
  459. opts = to_f_uvc_opts(control->ci_parent);
  460. mutex_lock(&opts->lock);
  461. class_array = uvcg_get_ctl_class_arr(src, opts);
  462. if (!class_array)
  463. goto unlock;
  464. if (opts->refcnt || class_array[0]) {
  465. ret = -EBUSY;
  466. goto unlock;
  467. }
  468. target_hdr = to_uvcg_control_header(target);
  469. ++target_hdr->linked;
  470. class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc;
  471. ret = 0;
  472. unlock:
  473. mutex_unlock(&opts->lock);
  474. out:
  475. mutex_unlock(su_mutex);
  476. return ret;
  477. }
  478. static int uvcg_control_class_drop_link(struct config_item *src,
  479. struct config_item *target)
  480. {
  481. struct config_item *control, *header;
  482. struct f_uvc_opts *opts;
  483. struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
  484. struct uvc_descriptor_header **class_array;
  485. struct uvcg_control_header *target_hdr;
  486. int ret = -EINVAL;
  487. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  488. control = src->ci_parent->ci_parent;
  489. header = config_group_find_item(to_config_group(control), "header");
  490. if (!header || target->ci_parent != header)
  491. goto out;
  492. opts = to_f_uvc_opts(control->ci_parent);
  493. mutex_lock(&opts->lock);
  494. class_array = uvcg_get_ctl_class_arr(src, opts);
  495. if (!class_array)
  496. goto unlock;
  497. if (opts->refcnt) {
  498. ret = -EBUSY;
  499. goto unlock;
  500. }
  501. target_hdr = to_uvcg_control_header(target);
  502. --target_hdr->linked;
  503. class_array[0] = NULL;
  504. ret = 0;
  505. unlock:
  506. mutex_unlock(&opts->lock);
  507. out:
  508. mutex_unlock(su_mutex);
  509. return ret;
  510. }
  511. static struct configfs_item_operations uvcg_control_class_item_ops = {
  512. .allow_link = uvcg_control_class_allow_link,
  513. .drop_link = uvcg_control_class_drop_link,
  514. };
  515. static struct config_item_type uvcg_control_class_type = {
  516. .ct_item_ops = &uvcg_control_class_item_ops,
  517. .ct_owner = THIS_MODULE,
  518. };
  519. static struct config_group *uvcg_control_class_default_groups[] = {
  520. &uvcg_control_class_fs.group,
  521. &uvcg_control_class_ss.group,
  522. NULL,
  523. };
  524. /* control/class */
  525. static struct uvcg_control_class_grp {
  526. struct config_group group;
  527. } uvcg_control_class_grp;
  528. static struct config_item_type uvcg_control_class_grp_type = {
  529. .ct_owner = THIS_MODULE,
  530. };
  531. static struct config_group *uvcg_control_default_groups[] = {
  532. &uvcg_control_header_grp.group,
  533. &uvcg_processing_grp.group,
  534. &uvcg_terminal_grp.group,
  535. &uvcg_control_class_grp.group,
  536. NULL,
  537. };
  538. /* control */
  539. static struct uvcg_control_grp {
  540. struct config_group group;
  541. } uvcg_control_grp;
  542. static struct config_item_type uvcg_control_grp_type = {
  543. .ct_owner = THIS_MODULE,
  544. };
  545. /* streaming/uncompressed */
  546. static struct uvcg_uncompressed_grp {
  547. struct config_group group;
  548. } uvcg_uncompressed_grp;
  549. /* streaming/mjpeg */
  550. static struct uvcg_mjpeg_grp {
  551. struct config_group group;
  552. } uvcg_mjpeg_grp;
  553. static struct config_item *fmt_parent[] = {
  554. &uvcg_uncompressed_grp.group.cg_item,
  555. &uvcg_mjpeg_grp.group.cg_item,
  556. };
  557. enum uvcg_format_type {
  558. UVCG_UNCOMPRESSED = 0,
  559. UVCG_MJPEG,
  560. };
  561. struct uvcg_format {
  562. struct config_group group;
  563. enum uvcg_format_type type;
  564. unsigned linked;
  565. unsigned num_frames;
  566. __u8 bmaControls[UVCG_STREAMING_CONTROL_SIZE];
  567. };
  568. static struct uvcg_format *to_uvcg_format(struct config_item *item)
  569. {
  570. return container_of(to_config_group(item), struct uvcg_format, group);
  571. }
  572. static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page)
  573. {
  574. struct f_uvc_opts *opts;
  575. struct config_item *opts_item;
  576. struct mutex *su_mutex = &f->group.cg_subsys->su_mutex;
  577. int result, i;
  578. char *pg = page;
  579. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  580. opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent;
  581. opts = to_f_uvc_opts(opts_item);
  582. mutex_lock(&opts->lock);
  583. result = sprintf(pg, "0x");
  584. pg += result;
  585. for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) {
  586. result += sprintf(pg, "%x\n", f->bmaControls[i]);
  587. pg = page + result;
  588. }
  589. mutex_unlock(&opts->lock);
  590. mutex_unlock(su_mutex);
  591. return result;
  592. }
  593. static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch,
  594. const char *page, size_t len)
  595. {
  596. struct f_uvc_opts *opts;
  597. struct config_item *opts_item;
  598. struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex;
  599. int ret = -EINVAL;
  600. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  601. opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent;
  602. opts = to_f_uvc_opts(opts_item);
  603. mutex_lock(&opts->lock);
  604. if (ch->linked || opts->refcnt) {
  605. ret = -EBUSY;
  606. goto end;
  607. }
  608. if (len < 4 || *page != '0' ||
  609. (*(page + 1) != 'x' && *(page + 1) != 'X'))
  610. goto end;
  611. ret = hex2bin(ch->bmaControls, page + 2, 1);
  612. if (ret < 0)
  613. goto end;
  614. ret = len;
  615. end:
  616. mutex_unlock(&opts->lock);
  617. mutex_unlock(su_mutex);
  618. return ret;
  619. }
  620. struct uvcg_format_ptr {
  621. struct uvcg_format *fmt;
  622. struct list_head entry;
  623. };
  624. /* streaming/header/<NAME> */
  625. struct uvcg_streaming_header {
  626. struct config_item item;
  627. struct uvc_input_header_descriptor desc;
  628. unsigned linked;
  629. struct list_head formats;
  630. unsigned num_fmt;
  631. };
  632. static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item)
  633. {
  634. return container_of(item, struct uvcg_streaming_header, item);
  635. }
  636. static int uvcg_streaming_header_allow_link(struct config_item *src,
  637. struct config_item *target)
  638. {
  639. struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
  640. struct config_item *opts_item;
  641. struct f_uvc_opts *opts;
  642. struct uvcg_streaming_header *src_hdr;
  643. struct uvcg_format *target_fmt = NULL;
  644. struct uvcg_format_ptr *format_ptr;
  645. int i, ret = -EINVAL;
  646. src_hdr = to_uvcg_streaming_header(src);
  647. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  648. opts_item = src->ci_parent->ci_parent->ci_parent;
  649. opts = to_f_uvc_opts(opts_item);
  650. mutex_lock(&opts->lock);
  651. if (src_hdr->linked) {
  652. ret = -EBUSY;
  653. goto out;
  654. }
  655. for (i = 0; i < ARRAY_SIZE(fmt_parent); ++i)
  656. if (target->ci_parent == fmt_parent[i])
  657. break;
  658. if (i == ARRAY_SIZE(fmt_parent))
  659. goto out;
  660. target_fmt = container_of(to_config_group(target), struct uvcg_format,
  661. group);
  662. if (!target_fmt)
  663. goto out;
  664. format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL);
  665. if (!format_ptr) {
  666. ret = -ENOMEM;
  667. goto out;
  668. }
  669. ret = 0;
  670. format_ptr->fmt = target_fmt;
  671. list_add_tail(&format_ptr->entry, &src_hdr->formats);
  672. ++src_hdr->num_fmt;
  673. out:
  674. mutex_unlock(&opts->lock);
  675. mutex_unlock(su_mutex);
  676. return ret;
  677. }
  678. static int uvcg_streaming_header_drop_link(struct config_item *src,
  679. struct config_item *target)
  680. {
  681. struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
  682. struct config_item *opts_item;
  683. struct f_uvc_opts *opts;
  684. struct uvcg_streaming_header *src_hdr;
  685. struct uvcg_format *target_fmt = NULL;
  686. struct uvcg_format_ptr *format_ptr, *tmp;
  687. int ret = -EINVAL;
  688. src_hdr = to_uvcg_streaming_header(src);
  689. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  690. opts_item = src->ci_parent->ci_parent->ci_parent;
  691. opts = to_f_uvc_opts(opts_item);
  692. mutex_lock(&opts->lock);
  693. target_fmt = container_of(to_config_group(target), struct uvcg_format,
  694. group);
  695. if (!target_fmt)
  696. goto out;
  697. list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry)
  698. if (format_ptr->fmt == target_fmt) {
  699. list_del(&format_ptr->entry);
  700. kfree(format_ptr);
  701. --src_hdr->num_fmt;
  702. break;
  703. }
  704. out:
  705. mutex_unlock(&opts->lock);
  706. mutex_unlock(su_mutex);
  707. return ret;
  708. }
  709. static struct configfs_item_operations uvcg_streaming_header_item_ops = {
  710. .allow_link = uvcg_streaming_header_allow_link,
  711. .drop_link = uvcg_streaming_header_drop_link,
  712. };
  713. #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv) \
  714. static ssize_t uvcg_streaming_header_##cname##_show( \
  715. struct config_item *item, char *page) \
  716. { \
  717. struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \
  718. struct f_uvc_opts *opts; \
  719. struct config_item *opts_item; \
  720. struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\
  721. int result; \
  722. \
  723. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  724. \
  725. opts_item = sh->item.ci_parent->ci_parent->ci_parent; \
  726. opts = to_f_uvc_opts(opts_item); \
  727. \
  728. mutex_lock(&opts->lock); \
  729. result = sprintf(page, "%d\n", conv(sh->desc.aname)); \
  730. mutex_unlock(&opts->lock); \
  731. \
  732. mutex_unlock(su_mutex); \
  733. return result; \
  734. } \
  735. \
  736. UVC_ATTR_RO(uvcg_streaming_header_, cname, aname)
  737. #define identity_conv(x) (x)
  738. UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv);
  739. UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv);
  740. UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod,
  741. identity_conv);
  742. UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv);
  743. UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv);
  744. #undef identity_conv
  745. #undef UVCG_STREAMING_HEADER_ATTR
  746. static struct configfs_attribute *uvcg_streaming_header_attrs[] = {
  747. &uvcg_streaming_header_attr_bm_info,
  748. &uvcg_streaming_header_attr_b_terminal_link,
  749. &uvcg_streaming_header_attr_b_still_capture_method,
  750. &uvcg_streaming_header_attr_b_trigger_support,
  751. &uvcg_streaming_header_attr_b_trigger_usage,
  752. NULL,
  753. };
  754. static struct config_item_type uvcg_streaming_header_type = {
  755. .ct_item_ops = &uvcg_streaming_header_item_ops,
  756. .ct_attrs = uvcg_streaming_header_attrs,
  757. .ct_owner = THIS_MODULE,
  758. };
  759. static struct config_item
  760. *uvcg_streaming_header_make(struct config_group *group, const char *name)
  761. {
  762. struct uvcg_streaming_header *h;
  763. h = kzalloc(sizeof(*h), GFP_KERNEL);
  764. if (!h)
  765. return ERR_PTR(-ENOMEM);
  766. INIT_LIST_HEAD(&h->formats);
  767. h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
  768. h->desc.bDescriptorSubType = UVC_VS_INPUT_HEADER;
  769. h->desc.bTerminalLink = 3;
  770. h->desc.bControlSize = UVCG_STREAMING_CONTROL_SIZE;
  771. config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type);
  772. return &h->item;
  773. }
  774. static void uvcg_streaming_header_drop(struct config_group *group,
  775. struct config_item *item)
  776. {
  777. struct uvcg_streaming_header *h = to_uvcg_streaming_header(item);
  778. kfree(h);
  779. }
  780. /* streaming/header */
  781. static struct uvcg_streaming_header_grp {
  782. struct config_group group;
  783. } uvcg_streaming_header_grp;
  784. static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
  785. .make_item = uvcg_streaming_header_make,
  786. .drop_item = uvcg_streaming_header_drop,
  787. };
  788. static struct config_item_type uvcg_streaming_header_grp_type = {
  789. .ct_group_ops = &uvcg_streaming_header_grp_ops,
  790. .ct_owner = THIS_MODULE,
  791. };
  792. /* streaming/<mode>/<format>/<NAME> */
  793. struct uvcg_frame {
  794. struct {
  795. u8 b_length;
  796. u8 b_descriptor_type;
  797. u8 b_descriptor_subtype;
  798. u8 b_frame_index;
  799. u8 bm_capabilities;
  800. u16 w_width;
  801. u16 w_height;
  802. u32 dw_min_bit_rate;
  803. u32 dw_max_bit_rate;
  804. u32 dw_max_video_frame_buffer_size;
  805. u32 dw_default_frame_interval;
  806. u8 b_frame_interval_type;
  807. } __attribute__((packed)) frame;
  808. u32 *dw_frame_interval;
  809. enum uvcg_format_type fmt_type;
  810. struct config_item item;
  811. };
  812. static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
  813. {
  814. return container_of(item, struct uvcg_frame, item);
  815. }
  816. #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \
  817. static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\
  818. { \
  819. struct uvcg_frame *f = to_uvcg_frame(item); \
  820. struct f_uvc_opts *opts; \
  821. struct config_item *opts_item; \
  822. struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
  823. int result; \
  824. \
  825. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  826. \
  827. opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
  828. opts = to_f_uvc_opts(opts_item); \
  829. \
  830. mutex_lock(&opts->lock); \
  831. result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \
  832. mutex_unlock(&opts->lock); \
  833. \
  834. mutex_unlock(su_mutex); \
  835. return result; \
  836. } \
  837. \
  838. static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \
  839. const char *page, size_t len)\
  840. { \
  841. struct uvcg_frame *f = to_uvcg_frame(item); \
  842. struct f_uvc_opts *opts; \
  843. struct config_item *opts_item; \
  844. struct uvcg_format *fmt; \
  845. struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
  846. int ret; \
  847. u##bits num; \
  848. \
  849. ret = kstrtou##bits(page, 0, &num); \
  850. if (ret) \
  851. return ret; \
  852. \
  853. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  854. \
  855. opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \
  856. opts = to_f_uvc_opts(opts_item); \
  857. fmt = to_uvcg_format(f->item.ci_parent); \
  858. \
  859. mutex_lock(&opts->lock); \
  860. if (fmt->linked || opts->refcnt) { \
  861. ret = -EBUSY; \
  862. goto end; \
  863. } \
  864. \
  865. f->frame.cname = to_little_endian(num); \
  866. ret = len; \
  867. end: \
  868. mutex_unlock(&opts->lock); \
  869. mutex_unlock(su_mutex); \
  870. return ret; \
  871. } \
  872. \
  873. UVC_ATTR(uvcg_frame_, cname, aname);
  874. #define noop_conversion(x) (x)
  875. UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
  876. noop_conversion, 8);
  877. UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
  878. UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16);
  879. UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32);
  880. UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32);
  881. UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize,
  882. le32_to_cpu, cpu_to_le32, 32);
  883. UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval,
  884. le32_to_cpu, cpu_to_le32, 32);
  885. #undef noop_conversion
  886. #undef UVCG_FRAME_ATTR
  887. static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item,
  888. char *page)
  889. {
  890. struct uvcg_frame *frm = to_uvcg_frame(item);
  891. struct f_uvc_opts *opts;
  892. struct config_item *opts_item;
  893. struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
  894. int result, i;
  895. char *pg = page;
  896. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  897. opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
  898. opts = to_f_uvc_opts(opts_item);
  899. mutex_lock(&opts->lock);
  900. for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
  901. result += sprintf(pg, "%d\n",
  902. le32_to_cpu(frm->dw_frame_interval[i]));
  903. pg = page + result;
  904. }
  905. mutex_unlock(&opts->lock);
  906. mutex_unlock(su_mutex);
  907. return result;
  908. }
  909. static inline int __uvcg_count_frm_intrv(char *buf, void *priv)
  910. {
  911. ++*((int *)priv);
  912. return 0;
  913. }
  914. static inline int __uvcg_fill_frm_intrv(char *buf, void *priv)
  915. {
  916. u32 num, **interv;
  917. int ret;
  918. ret = kstrtou32(buf, 0, &num);
  919. if (ret)
  920. return ret;
  921. interv = priv;
  922. **interv = cpu_to_le32(num);
  923. ++*interv;
  924. return 0;
  925. }
  926. static int __uvcg_iter_frm_intrv(const char *page, size_t len,
  927. int (*fun)(char *, void *), void *priv)
  928. {
  929. /* sign, base 2 representation, newline, terminator */
  930. char buf[1 + sizeof(u32) * 8 + 1 + 1];
  931. const char *pg = page;
  932. int i, ret;
  933. if (!fun)
  934. return -EINVAL;
  935. while (pg - page < len) {
  936. i = 0;
  937. while (i < sizeof(buf) && (pg - page < len) &&
  938. *pg != '\0' && *pg != '\n')
  939. buf[i++] = *pg++;
  940. if (i == sizeof(buf))
  941. return -EINVAL;
  942. while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
  943. ++pg;
  944. buf[i] = '\0';
  945. ret = fun(buf, priv);
  946. if (ret)
  947. return ret;
  948. }
  949. return 0;
  950. }
  951. static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item,
  952. const char *page, size_t len)
  953. {
  954. struct uvcg_frame *ch = to_uvcg_frame(item);
  955. struct f_uvc_opts *opts;
  956. struct config_item *opts_item;
  957. struct uvcg_format *fmt;
  958. struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
  959. int ret = 0, n = 0;
  960. u32 *frm_intrv, *tmp;
  961. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  962. opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
  963. opts = to_f_uvc_opts(opts_item);
  964. fmt = to_uvcg_format(ch->item.ci_parent);
  965. mutex_lock(&opts->lock);
  966. if (fmt->linked || opts->refcnt) {
  967. ret = -EBUSY;
  968. goto end;
  969. }
  970. ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
  971. if (ret)
  972. goto end;
  973. tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
  974. if (!frm_intrv) {
  975. ret = -ENOMEM;
  976. goto end;
  977. }
  978. ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
  979. if (ret) {
  980. kfree(frm_intrv);
  981. goto end;
  982. }
  983. kfree(ch->dw_frame_interval);
  984. ch->dw_frame_interval = frm_intrv;
  985. ch->frame.b_frame_interval_type = n;
  986. ret = len;
  987. end:
  988. mutex_unlock(&opts->lock);
  989. mutex_unlock(su_mutex);
  990. return ret;
  991. }
  992. UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
  993. static struct configfs_attribute *uvcg_frame_attrs[] = {
  994. &uvcg_frame_attr_bm_capabilities,
  995. &uvcg_frame_attr_w_width,
  996. &uvcg_frame_attr_w_height,
  997. &uvcg_frame_attr_dw_min_bit_rate,
  998. &uvcg_frame_attr_dw_max_bit_rate,
  999. &uvcg_frame_attr_dw_max_video_frame_buffer_size,
  1000. &uvcg_frame_attr_dw_default_frame_interval,
  1001. &uvcg_frame_attr_dw_frame_interval,
  1002. NULL,
  1003. };
  1004. static struct config_item_type uvcg_frame_type = {
  1005. .ct_attrs = uvcg_frame_attrs,
  1006. .ct_owner = THIS_MODULE,
  1007. };
  1008. static struct config_item *uvcg_frame_make(struct config_group *group,
  1009. const char *name)
  1010. {
  1011. struct uvcg_frame *h;
  1012. struct uvcg_format *fmt;
  1013. struct f_uvc_opts *opts;
  1014. struct config_item *opts_item;
  1015. h = kzalloc(sizeof(*h), GFP_KERNEL);
  1016. if (!h)
  1017. return ERR_PTR(-ENOMEM);
  1018. h->frame.b_descriptor_type = USB_DT_CS_INTERFACE;
  1019. h->frame.b_frame_index = 1;
  1020. h->frame.w_width = cpu_to_le16(640);
  1021. h->frame.w_height = cpu_to_le16(360);
  1022. h->frame.dw_min_bit_rate = cpu_to_le32(18432000);
  1023. h->frame.dw_max_bit_rate = cpu_to_le32(55296000);
  1024. h->frame.dw_max_video_frame_buffer_size = cpu_to_le32(460800);
  1025. h->frame.dw_default_frame_interval = cpu_to_le32(666666);
  1026. opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
  1027. opts = to_f_uvc_opts(opts_item);
  1028. mutex_lock(&opts->lock);
  1029. fmt = to_uvcg_format(&group->cg_item);
  1030. if (fmt->type == UVCG_UNCOMPRESSED) {
  1031. h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED;
  1032. h->fmt_type = UVCG_UNCOMPRESSED;
  1033. } else if (fmt->type == UVCG_MJPEG) {
  1034. h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
  1035. h->fmt_type = UVCG_MJPEG;
  1036. } else {
  1037. mutex_unlock(&opts->lock);
  1038. kfree(h);
  1039. return ERR_PTR(-EINVAL);
  1040. }
  1041. ++fmt->num_frames;
  1042. mutex_unlock(&opts->lock);
  1043. config_item_init_type_name(&h->item, name, &uvcg_frame_type);
  1044. return &h->item;
  1045. }
  1046. static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
  1047. {
  1048. struct uvcg_frame *h = to_uvcg_frame(item);
  1049. struct uvcg_format *fmt;
  1050. struct f_uvc_opts *opts;
  1051. struct config_item *opts_item;
  1052. opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
  1053. opts = to_f_uvc_opts(opts_item);
  1054. mutex_lock(&opts->lock);
  1055. fmt = to_uvcg_format(&group->cg_item);
  1056. --fmt->num_frames;
  1057. kfree(h);
  1058. mutex_unlock(&opts->lock);
  1059. }
  1060. /* streaming/uncompressed/<NAME> */
  1061. struct uvcg_uncompressed {
  1062. struct uvcg_format fmt;
  1063. struct uvc_format_uncompressed desc;
  1064. };
  1065. static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item)
  1066. {
  1067. return container_of(
  1068. container_of(to_config_group(item), struct uvcg_format, group),
  1069. struct uvcg_uncompressed, fmt);
  1070. }
  1071. static struct configfs_group_operations uvcg_uncompressed_group_ops = {
  1072. .make_item = uvcg_frame_make,
  1073. .drop_item = uvcg_frame_drop,
  1074. };
  1075. static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item,
  1076. char *page)
  1077. {
  1078. struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
  1079. struct f_uvc_opts *opts;
  1080. struct config_item *opts_item;
  1081. struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
  1082. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  1083. opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
  1084. opts = to_f_uvc_opts(opts_item);
  1085. mutex_lock(&opts->lock);
  1086. memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
  1087. mutex_unlock(&opts->lock);
  1088. mutex_unlock(su_mutex);
  1089. return sizeof(ch->desc.guidFormat);
  1090. }
  1091. static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item,
  1092. const char *page, size_t len)
  1093. {
  1094. struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item);
  1095. struct f_uvc_opts *opts;
  1096. struct config_item *opts_item;
  1097. struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
  1098. int ret;
  1099. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  1100. opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
  1101. opts = to_f_uvc_opts(opts_item);
  1102. mutex_lock(&opts->lock);
  1103. if (ch->fmt.linked || opts->refcnt) {
  1104. ret = -EBUSY;
  1105. goto end;
  1106. }
  1107. memcpy(ch->desc.guidFormat, page,
  1108. min(sizeof(ch->desc.guidFormat), len));
  1109. ret = sizeof(ch->desc.guidFormat);
  1110. end:
  1111. mutex_unlock(&opts->lock);
  1112. mutex_unlock(su_mutex);
  1113. return ret;
  1114. }
  1115. UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat);
  1116. #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv) \
  1117. static ssize_t uvcg_uncompressed_##cname##_show( \
  1118. struct config_item *item, char *page) \
  1119. { \
  1120. struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \
  1121. struct f_uvc_opts *opts; \
  1122. struct config_item *opts_item; \
  1123. struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
  1124. int result; \
  1125. \
  1126. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1127. \
  1128. opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
  1129. opts = to_f_uvc_opts(opts_item); \
  1130. \
  1131. mutex_lock(&opts->lock); \
  1132. result = sprintf(page, "%d\n", conv(u->desc.aname)); \
  1133. mutex_unlock(&opts->lock); \
  1134. \
  1135. mutex_unlock(su_mutex); \
  1136. return result; \
  1137. } \
  1138. \
  1139. UVC_ATTR_RO(uvcg_uncompressed_, cname, aname);
  1140. #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv) \
  1141. static ssize_t uvcg_uncompressed_##cname##_show( \
  1142. struct config_item *item, char *page) \
  1143. { \
  1144. struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \
  1145. struct f_uvc_opts *opts; \
  1146. struct config_item *opts_item; \
  1147. struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
  1148. int result; \
  1149. \
  1150. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1151. \
  1152. opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
  1153. opts = to_f_uvc_opts(opts_item); \
  1154. \
  1155. mutex_lock(&opts->lock); \
  1156. result = sprintf(page, "%d\n", conv(u->desc.aname)); \
  1157. mutex_unlock(&opts->lock); \
  1158. \
  1159. mutex_unlock(su_mutex); \
  1160. return result; \
  1161. } \
  1162. \
  1163. static ssize_t \
  1164. uvcg_uncompressed_##cname##_store(struct config_item *item, \
  1165. const char *page, size_t len) \
  1166. { \
  1167. struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \
  1168. struct f_uvc_opts *opts; \
  1169. struct config_item *opts_item; \
  1170. struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
  1171. int ret; \
  1172. u8 num; \
  1173. \
  1174. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1175. \
  1176. opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
  1177. opts = to_f_uvc_opts(opts_item); \
  1178. \
  1179. mutex_lock(&opts->lock); \
  1180. if (u->fmt.linked || opts->refcnt) { \
  1181. ret = -EBUSY; \
  1182. goto end; \
  1183. } \
  1184. \
  1185. ret = kstrtou8(page, 0, &num); \
  1186. if (ret) \
  1187. goto end; \
  1188. \
  1189. if (num > 255) { \
  1190. ret = -EINVAL; \
  1191. goto end; \
  1192. } \
  1193. u->desc.aname = num; \
  1194. ret = len; \
  1195. end: \
  1196. mutex_unlock(&opts->lock); \
  1197. mutex_unlock(su_mutex); \
  1198. return ret; \
  1199. } \
  1200. \
  1201. UVC_ATTR(uvcg_uncompressed_, cname, aname);
  1202. #define identity_conv(x) (x)
  1203. UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv);
  1204. UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex,
  1205. identity_conv);
  1206. UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
  1207. UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
  1208. UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
  1209. #undef identity_conv
  1210. #undef UVCG_UNCOMPRESSED_ATTR
  1211. #undef UVCG_UNCOMPRESSED_ATTR_RO
  1212. static inline ssize_t
  1213. uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page)
  1214. {
  1215. struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
  1216. return uvcg_format_bma_controls_show(&unc->fmt, page);
  1217. }
  1218. static inline ssize_t
  1219. uvcg_uncompressed_bma_controls_store(struct config_item *item,
  1220. const char *page, size_t len)
  1221. {
  1222. struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item);
  1223. return uvcg_format_bma_controls_store(&unc->fmt, page, len);
  1224. }
  1225. UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls);
  1226. static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
  1227. &uvcg_uncompressed_attr_guid_format,
  1228. &uvcg_uncompressed_attr_b_bits_per_pixel,
  1229. &uvcg_uncompressed_attr_b_default_frame_index,
  1230. &uvcg_uncompressed_attr_b_aspect_ratio_x,
  1231. &uvcg_uncompressed_attr_b_aspect_ratio_y,
  1232. &uvcg_uncompressed_attr_bm_interface_flags,
  1233. &uvcg_uncompressed_attr_bma_controls,
  1234. NULL,
  1235. };
  1236. static struct config_item_type uvcg_uncompressed_type = {
  1237. .ct_group_ops = &uvcg_uncompressed_group_ops,
  1238. .ct_attrs = uvcg_uncompressed_attrs,
  1239. .ct_owner = THIS_MODULE,
  1240. };
  1241. static struct config_group *uvcg_uncompressed_make(struct config_group *group,
  1242. const char *name)
  1243. {
  1244. static char guid[] = {
  1245. 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00,
  1246. 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
  1247. };
  1248. struct uvcg_uncompressed *h;
  1249. h = kzalloc(sizeof(*h), GFP_KERNEL);
  1250. if (!h)
  1251. return ERR_PTR(-ENOMEM);
  1252. h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE;
  1253. h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
  1254. h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED;
  1255. memcpy(h->desc.guidFormat, guid, sizeof(guid));
  1256. h->desc.bBitsPerPixel = 16;
  1257. h->desc.bDefaultFrameIndex = 1;
  1258. h->desc.bAspectRatioX = 0;
  1259. h->desc.bAspectRatioY = 0;
  1260. h->desc.bmInterfaceFlags = 0;
  1261. h->desc.bCopyProtect = 0;
  1262. h->fmt.type = UVCG_UNCOMPRESSED;
  1263. config_group_init_type_name(&h->fmt.group, name,
  1264. &uvcg_uncompressed_type);
  1265. return &h->fmt.group;
  1266. }
  1267. static void uvcg_uncompressed_drop(struct config_group *group,
  1268. struct config_item *item)
  1269. {
  1270. struct uvcg_uncompressed *h = to_uvcg_uncompressed(item);
  1271. kfree(h);
  1272. }
  1273. static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
  1274. .make_group = uvcg_uncompressed_make,
  1275. .drop_item = uvcg_uncompressed_drop,
  1276. };
  1277. static struct config_item_type uvcg_uncompressed_grp_type = {
  1278. .ct_group_ops = &uvcg_uncompressed_grp_ops,
  1279. .ct_owner = THIS_MODULE,
  1280. };
  1281. /* streaming/mjpeg/<NAME> */
  1282. struct uvcg_mjpeg {
  1283. struct uvcg_format fmt;
  1284. struct uvc_format_mjpeg desc;
  1285. };
  1286. static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item)
  1287. {
  1288. return container_of(
  1289. container_of(to_config_group(item), struct uvcg_format, group),
  1290. struct uvcg_mjpeg, fmt);
  1291. }
  1292. static struct configfs_group_operations uvcg_mjpeg_group_ops = {
  1293. .make_item = uvcg_frame_make,
  1294. .drop_item = uvcg_frame_drop,
  1295. };
  1296. #define UVCG_MJPEG_ATTR_RO(cname, aname, conv) \
  1297. static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
  1298. { \
  1299. struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \
  1300. struct f_uvc_opts *opts; \
  1301. struct config_item *opts_item; \
  1302. struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
  1303. int result; \
  1304. \
  1305. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1306. \
  1307. opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
  1308. opts = to_f_uvc_opts(opts_item); \
  1309. \
  1310. mutex_lock(&opts->lock); \
  1311. result = sprintf(page, "%d\n", conv(u->desc.aname)); \
  1312. mutex_unlock(&opts->lock); \
  1313. \
  1314. mutex_unlock(su_mutex); \
  1315. return result; \
  1316. } \
  1317. \
  1318. UVC_ATTR_RO(uvcg_mjpeg_, cname, aname)
  1319. #define UVCG_MJPEG_ATTR(cname, aname, conv) \
  1320. static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\
  1321. { \
  1322. struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \
  1323. struct f_uvc_opts *opts; \
  1324. struct config_item *opts_item; \
  1325. struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
  1326. int result; \
  1327. \
  1328. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1329. \
  1330. opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
  1331. opts = to_f_uvc_opts(opts_item); \
  1332. \
  1333. mutex_lock(&opts->lock); \
  1334. result = sprintf(page, "%d\n", conv(u->desc.aname)); \
  1335. mutex_unlock(&opts->lock); \
  1336. \
  1337. mutex_unlock(su_mutex); \
  1338. return result; \
  1339. } \
  1340. \
  1341. static ssize_t \
  1342. uvcg_mjpeg_##cname##_store(struct config_item *item, \
  1343. const char *page, size_t len) \
  1344. { \
  1345. struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \
  1346. struct f_uvc_opts *opts; \
  1347. struct config_item *opts_item; \
  1348. struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
  1349. int ret; \
  1350. u8 num; \
  1351. \
  1352. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1353. \
  1354. opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
  1355. opts = to_f_uvc_opts(opts_item); \
  1356. \
  1357. mutex_lock(&opts->lock); \
  1358. if (u->fmt.linked || opts->refcnt) { \
  1359. ret = -EBUSY; \
  1360. goto end; \
  1361. } \
  1362. \
  1363. ret = kstrtou8(page, 0, &num); \
  1364. if (ret) \
  1365. goto end; \
  1366. \
  1367. if (num > 255) { \
  1368. ret = -EINVAL; \
  1369. goto end; \
  1370. } \
  1371. u->desc.aname = num; \
  1372. ret = len; \
  1373. end: \
  1374. mutex_unlock(&opts->lock); \
  1375. mutex_unlock(su_mutex); \
  1376. return ret; \
  1377. } \
  1378. \
  1379. UVC_ATTR(uvcg_mjpeg_, cname, aname)
  1380. #define identity_conv(x) (x)
  1381. UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex,
  1382. identity_conv);
  1383. UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv);
  1384. UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
  1385. UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
  1386. UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
  1387. #undef identity_conv
  1388. #undef UVCG_MJPEG_ATTR
  1389. #undef UVCG_MJPEG_ATTR_RO
  1390. static inline ssize_t
  1391. uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page)
  1392. {
  1393. struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
  1394. return uvcg_format_bma_controls_show(&u->fmt, page);
  1395. }
  1396. static inline ssize_t
  1397. uvcg_mjpeg_bma_controls_store(struct config_item *item,
  1398. const char *page, size_t len)
  1399. {
  1400. struct uvcg_mjpeg *u = to_uvcg_mjpeg(item);
  1401. return uvcg_format_bma_controls_store(&u->fmt, page, len);
  1402. }
  1403. UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls);
  1404. static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
  1405. &uvcg_mjpeg_attr_b_default_frame_index,
  1406. &uvcg_mjpeg_attr_bm_flags,
  1407. &uvcg_mjpeg_attr_b_aspect_ratio_x,
  1408. &uvcg_mjpeg_attr_b_aspect_ratio_y,
  1409. &uvcg_mjpeg_attr_bm_interface_flags,
  1410. &uvcg_mjpeg_attr_bma_controls,
  1411. NULL,
  1412. };
  1413. static struct config_item_type uvcg_mjpeg_type = {
  1414. .ct_group_ops = &uvcg_mjpeg_group_ops,
  1415. .ct_attrs = uvcg_mjpeg_attrs,
  1416. .ct_owner = THIS_MODULE,
  1417. };
  1418. static struct config_group *uvcg_mjpeg_make(struct config_group *group,
  1419. const char *name)
  1420. {
  1421. struct uvcg_mjpeg *h;
  1422. h = kzalloc(sizeof(*h), GFP_KERNEL);
  1423. if (!h)
  1424. return ERR_PTR(-ENOMEM);
  1425. h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE;
  1426. h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
  1427. h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG;
  1428. h->desc.bDefaultFrameIndex = 1;
  1429. h->desc.bAspectRatioX = 0;
  1430. h->desc.bAspectRatioY = 0;
  1431. h->desc.bmInterfaceFlags = 0;
  1432. h->desc.bCopyProtect = 0;
  1433. h->fmt.type = UVCG_MJPEG;
  1434. config_group_init_type_name(&h->fmt.group, name,
  1435. &uvcg_mjpeg_type);
  1436. return &h->fmt.group;
  1437. }
  1438. static void uvcg_mjpeg_drop(struct config_group *group,
  1439. struct config_item *item)
  1440. {
  1441. struct uvcg_mjpeg *h = to_uvcg_mjpeg(item);
  1442. kfree(h);
  1443. }
  1444. static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
  1445. .make_group = uvcg_mjpeg_make,
  1446. .drop_item = uvcg_mjpeg_drop,
  1447. };
  1448. static struct config_item_type uvcg_mjpeg_grp_type = {
  1449. .ct_group_ops = &uvcg_mjpeg_grp_ops,
  1450. .ct_owner = THIS_MODULE,
  1451. };
  1452. /* streaming/color_matching/default */
  1453. static struct uvcg_default_color_matching {
  1454. struct config_group group;
  1455. } uvcg_default_color_matching;
  1456. static inline struct uvcg_default_color_matching
  1457. *to_uvcg_default_color_matching(struct config_item *item)
  1458. {
  1459. return container_of(to_config_group(item),
  1460. struct uvcg_default_color_matching, group);
  1461. }
  1462. #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv) \
  1463. static ssize_t uvcg_default_color_matching_##cname##_show( \
  1464. struct config_item *item, char *page) \
  1465. { \
  1466. struct uvcg_default_color_matching *dc = \
  1467. to_uvcg_default_color_matching(item); \
  1468. struct f_uvc_opts *opts; \
  1469. struct config_item *opts_item; \
  1470. struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; \
  1471. struct uvc_color_matching_descriptor *cd; \
  1472. int result; \
  1473. \
  1474. mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
  1475. \
  1476. opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent; \
  1477. opts = to_f_uvc_opts(opts_item); \
  1478. cd = &opts->uvc_color_matching; \
  1479. \
  1480. mutex_lock(&opts->lock); \
  1481. result = sprintf(page, "%d\n", conv(cd->aname)); \
  1482. mutex_unlock(&opts->lock); \
  1483. \
  1484. mutex_unlock(su_mutex); \
  1485. return result; \
  1486. } \
  1487. \
  1488. UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname)
  1489. #define identity_conv(x) (x)
  1490. UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries,
  1491. identity_conv);
  1492. UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics,
  1493. bTransferCharacteristics, identity_conv);
  1494. UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients,
  1495. identity_conv);
  1496. #undef identity_conv
  1497. #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR
  1498. static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
  1499. &uvcg_default_color_matching_attr_b_color_primaries,
  1500. &uvcg_default_color_matching_attr_b_transfer_characteristics,
  1501. &uvcg_default_color_matching_attr_b_matrix_coefficients,
  1502. NULL,
  1503. };
  1504. static struct config_item_type uvcg_default_color_matching_type = {
  1505. .ct_attrs = uvcg_default_color_matching_attrs,
  1506. .ct_owner = THIS_MODULE,
  1507. };
  1508. /* struct uvcg_color_matching {}; */
  1509. static struct config_group *uvcg_color_matching_default_groups[] = {
  1510. &uvcg_default_color_matching.group,
  1511. NULL,
  1512. };
  1513. /* streaming/color_matching */
  1514. static struct uvcg_color_matching_grp {
  1515. struct config_group group;
  1516. } uvcg_color_matching_grp;
  1517. static struct config_item_type uvcg_color_matching_grp_type = {
  1518. .ct_owner = THIS_MODULE,
  1519. };
  1520. /* streaming/class/{fs|hs|ss} */
  1521. static struct uvcg_streaming_class {
  1522. struct config_group group;
  1523. } uvcg_streaming_class_fs, uvcg_streaming_class_hs, uvcg_streaming_class_ss;
  1524. static inline struct uvc_descriptor_header
  1525. ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
  1526. {
  1527. struct uvcg_streaming_class *cl = container_of(to_config_group(i),
  1528. struct uvcg_streaming_class, group);
  1529. if (cl == &uvcg_streaming_class_fs)
  1530. return &o->uvc_fs_streaming_cls;
  1531. if (cl == &uvcg_streaming_class_hs)
  1532. return &o->uvc_hs_streaming_cls;
  1533. if (cl == &uvcg_streaming_class_ss)
  1534. return &o->uvc_ss_streaming_cls;
  1535. return NULL;
  1536. }
  1537. enum uvcg_strm_type {
  1538. UVCG_HEADER = 0,
  1539. UVCG_FORMAT,
  1540. UVCG_FRAME
  1541. };
  1542. /*
  1543. * Iterate over a hierarchy of streaming descriptors' config items.
  1544. * The items are created by the user with configfs.
  1545. *
  1546. * It "processes" the header pointed to by @priv1, then for each format
  1547. * that follows the header "processes" the format itself and then for
  1548. * each frame inside a format "processes" the frame.
  1549. *
  1550. * As a "processing" function the @fun is used.
  1551. *
  1552. * __uvcg_iter_strm_cls() is used in two context: first, to calculate
  1553. * the amount of memory needed for an array of streaming descriptors
  1554. * and second, to actually fill the array.
  1555. *
  1556. * @h: streaming header pointer
  1557. * @priv2: an "inout" parameter (the caller might want to see the changes to it)
  1558. * @priv3: an "inout" parameter (the caller might want to see the changes to it)
  1559. * @fun: callback function for processing each level of the hierarchy
  1560. */
  1561. static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
  1562. void *priv2, void *priv3,
  1563. int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type))
  1564. {
  1565. struct uvcg_format_ptr *f;
  1566. struct config_group *grp;
  1567. struct config_item *item;
  1568. struct uvcg_frame *frm;
  1569. int ret, i, j;
  1570. if (!fun)
  1571. return -EINVAL;
  1572. i = j = 0;
  1573. ret = fun(h, priv2, priv3, 0, UVCG_HEADER);
  1574. if (ret)
  1575. return ret;
  1576. list_for_each_entry(f, &h->formats, entry) {
  1577. ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT);
  1578. if (ret)
  1579. return ret;
  1580. grp = &f->fmt->group;
  1581. list_for_each_entry(item, &grp->cg_children, ci_entry) {
  1582. frm = to_uvcg_frame(item);
  1583. ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
  1584. if (ret)
  1585. return ret;
  1586. }
  1587. }
  1588. return ret;
  1589. }
  1590. /*
  1591. * Count how many bytes are needed for an array of streaming descriptors.
  1592. *
  1593. * @priv1: pointer to a header, format or frame
  1594. * @priv2: inout parameter, accumulated size of the array
  1595. * @priv3: inout parameter, accumulated number of the array elements
  1596. * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls
  1597. */
  1598. static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
  1599. enum uvcg_strm_type type)
  1600. {
  1601. size_t *size = priv2;
  1602. size_t *count = priv3;
  1603. switch (type) {
  1604. case UVCG_HEADER: {
  1605. struct uvcg_streaming_header *h = priv1;
  1606. *size += sizeof(h->desc);
  1607. /* bmaControls */
  1608. *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE;
  1609. }
  1610. break;
  1611. case UVCG_FORMAT: {
  1612. struct uvcg_format *fmt = priv1;
  1613. if (fmt->type == UVCG_UNCOMPRESSED) {
  1614. struct uvcg_uncompressed *u =
  1615. container_of(fmt, struct uvcg_uncompressed,
  1616. fmt);
  1617. *size += sizeof(u->desc);
  1618. } else if (fmt->type == UVCG_MJPEG) {
  1619. struct uvcg_mjpeg *m =
  1620. container_of(fmt, struct uvcg_mjpeg, fmt);
  1621. *size += sizeof(m->desc);
  1622. } else {
  1623. return -EINVAL;
  1624. }
  1625. }
  1626. break;
  1627. case UVCG_FRAME: {
  1628. struct uvcg_frame *frm = priv1;
  1629. int sz = sizeof(frm->dw_frame_interval);
  1630. *size += sizeof(frm->frame);
  1631. *size += frm->frame.b_frame_interval_type * sz;
  1632. }
  1633. break;
  1634. }
  1635. ++*count;
  1636. return 0;
  1637. }
  1638. /*
  1639. * Fill an array of streaming descriptors.
  1640. *
  1641. * @priv1: pointer to a header, format or frame
  1642. * @priv2: inout parameter, pointer into a block of memory
  1643. * @priv3: inout parameter, pointer to a 2-dimensional array
  1644. */
  1645. static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
  1646. enum uvcg_strm_type type)
  1647. {
  1648. void **dest = priv2;
  1649. struct uvc_descriptor_header ***array = priv3;
  1650. size_t sz;
  1651. **array = *dest;
  1652. ++*array;
  1653. switch (type) {
  1654. case UVCG_HEADER: {
  1655. struct uvc_input_header_descriptor *ihdr = *dest;
  1656. struct uvcg_streaming_header *h = priv1;
  1657. struct uvcg_format_ptr *f;
  1658. memcpy(*dest, &h->desc, sizeof(h->desc));
  1659. *dest += sizeof(h->desc);
  1660. sz = UVCG_STREAMING_CONTROL_SIZE;
  1661. list_for_each_entry(f, &h->formats, entry) {
  1662. memcpy(*dest, f->fmt->bmaControls, sz);
  1663. *dest += sz;
  1664. }
  1665. ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz;
  1666. ihdr->bNumFormats = h->num_fmt;
  1667. }
  1668. break;
  1669. case UVCG_FORMAT: {
  1670. struct uvcg_format *fmt = priv1;
  1671. if (fmt->type == UVCG_UNCOMPRESSED) {
  1672. struct uvc_format_uncompressed *unc = *dest;
  1673. struct uvcg_uncompressed *u =
  1674. container_of(fmt, struct uvcg_uncompressed,
  1675. fmt);
  1676. memcpy(*dest, &u->desc, sizeof(u->desc));
  1677. *dest += sizeof(u->desc);
  1678. unc->bNumFrameDescriptors = fmt->num_frames;
  1679. unc->bFormatIndex = n + 1;
  1680. } else if (fmt->type == UVCG_MJPEG) {
  1681. struct uvc_format_mjpeg *mjp = *dest;
  1682. struct uvcg_mjpeg *m =
  1683. container_of(fmt, struct uvcg_mjpeg, fmt);
  1684. memcpy(*dest, &m->desc, sizeof(m->desc));
  1685. *dest += sizeof(m->desc);
  1686. mjp->bNumFrameDescriptors = fmt->num_frames;
  1687. mjp->bFormatIndex = n + 1;
  1688. } else {
  1689. return -EINVAL;
  1690. }
  1691. }
  1692. break;
  1693. case UVCG_FRAME: {
  1694. struct uvcg_frame *frm = priv1;
  1695. struct uvc_descriptor_header *h = *dest;
  1696. sz = sizeof(frm->frame);
  1697. memcpy(*dest, &frm->frame, sz);
  1698. *dest += sz;
  1699. sz = frm->frame.b_frame_interval_type *
  1700. sizeof(*frm->dw_frame_interval);
  1701. memcpy(*dest, frm->dw_frame_interval, sz);
  1702. *dest += sz;
  1703. if (frm->fmt_type == UVCG_UNCOMPRESSED)
  1704. h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(
  1705. frm->frame.b_frame_interval_type);
  1706. else if (frm->fmt_type == UVCG_MJPEG)
  1707. h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
  1708. frm->frame.b_frame_interval_type);
  1709. }
  1710. break;
  1711. }
  1712. return 0;
  1713. }
  1714. static int uvcg_streaming_class_allow_link(struct config_item *src,
  1715. struct config_item *target)
  1716. {
  1717. struct config_item *streaming, *header;
  1718. struct f_uvc_opts *opts;
  1719. struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
  1720. struct uvc_descriptor_header ***class_array, **cl_arr;
  1721. struct uvcg_streaming_header *target_hdr;
  1722. void *data, *data_save;
  1723. size_t size = 0, count = 0;
  1724. int ret = -EINVAL;
  1725. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  1726. streaming = src->ci_parent->ci_parent;
  1727. header = config_group_find_item(to_config_group(streaming), "header");
  1728. if (!header || target->ci_parent != header)
  1729. goto out;
  1730. opts = to_f_uvc_opts(streaming->ci_parent);
  1731. mutex_lock(&opts->lock);
  1732. class_array = __uvcg_get_stream_class_arr(src, opts);
  1733. if (!class_array || *class_array || opts->refcnt) {
  1734. ret = -EBUSY;
  1735. goto unlock;
  1736. }
  1737. target_hdr = to_uvcg_streaming_header(target);
  1738. ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm);
  1739. if (ret)
  1740. goto unlock;
  1741. count += 2; /* color_matching, NULL */
  1742. *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL);
  1743. if (!*class_array) {
  1744. ret = -ENOMEM;
  1745. goto unlock;
  1746. }
  1747. data = data_save = kzalloc(size, GFP_KERNEL);
  1748. if (!data) {
  1749. kfree(*class_array);
  1750. *class_array = NULL;
  1751. ret = PTR_ERR(data);
  1752. goto unlock;
  1753. }
  1754. cl_arr = *class_array;
  1755. ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr,
  1756. __uvcg_fill_strm);
  1757. if (ret) {
  1758. kfree(*class_array);
  1759. *class_array = NULL;
  1760. /*
  1761. * __uvcg_fill_strm() called from __uvcg_iter_stream_cls()
  1762. * might have advanced the "data", so use a backup copy
  1763. */
  1764. kfree(data_save);
  1765. goto unlock;
  1766. }
  1767. *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching;
  1768. ++target_hdr->linked;
  1769. ret = 0;
  1770. unlock:
  1771. mutex_unlock(&opts->lock);
  1772. out:
  1773. mutex_unlock(su_mutex);
  1774. return ret;
  1775. }
  1776. static int uvcg_streaming_class_drop_link(struct config_item *src,
  1777. struct config_item *target)
  1778. {
  1779. struct config_item *streaming, *header;
  1780. struct f_uvc_opts *opts;
  1781. struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex;
  1782. struct uvc_descriptor_header ***class_array;
  1783. struct uvcg_streaming_header *target_hdr;
  1784. int ret = -EINVAL;
  1785. mutex_lock(su_mutex); /* for navigating configfs hierarchy */
  1786. streaming = src->ci_parent->ci_parent;
  1787. header = config_group_find_item(to_config_group(streaming), "header");
  1788. if (!header || target->ci_parent != header)
  1789. goto out;
  1790. opts = to_f_uvc_opts(streaming->ci_parent);
  1791. mutex_lock(&opts->lock);
  1792. class_array = __uvcg_get_stream_class_arr(src, opts);
  1793. if (!class_array || !*class_array)
  1794. goto unlock;
  1795. if (opts->refcnt) {
  1796. ret = -EBUSY;
  1797. goto unlock;
  1798. }
  1799. target_hdr = to_uvcg_streaming_header(target);
  1800. --target_hdr->linked;
  1801. kfree(**class_array);
  1802. kfree(*class_array);
  1803. *class_array = NULL;
  1804. ret = 0;
  1805. unlock:
  1806. mutex_unlock(&opts->lock);
  1807. out:
  1808. mutex_unlock(su_mutex);
  1809. return ret;
  1810. }
  1811. static struct configfs_item_operations uvcg_streaming_class_item_ops = {
  1812. .allow_link = uvcg_streaming_class_allow_link,
  1813. .drop_link = uvcg_streaming_class_drop_link,
  1814. };
  1815. static struct config_item_type uvcg_streaming_class_type = {
  1816. .ct_item_ops = &uvcg_streaming_class_item_ops,
  1817. .ct_owner = THIS_MODULE,
  1818. };
  1819. static struct config_group *uvcg_streaming_class_default_groups[] = {
  1820. &uvcg_streaming_class_fs.group,
  1821. &uvcg_streaming_class_hs.group,
  1822. &uvcg_streaming_class_ss.group,
  1823. NULL,
  1824. };
  1825. /* streaming/class */
  1826. static struct uvcg_streaming_class_grp {
  1827. struct config_group group;
  1828. } uvcg_streaming_class_grp;
  1829. static struct config_item_type uvcg_streaming_class_grp_type = {
  1830. .ct_owner = THIS_MODULE,
  1831. };
  1832. static struct config_group *uvcg_streaming_default_groups[] = {
  1833. &uvcg_streaming_header_grp.group,
  1834. &uvcg_uncompressed_grp.group,
  1835. &uvcg_mjpeg_grp.group,
  1836. &uvcg_color_matching_grp.group,
  1837. &uvcg_streaming_class_grp.group,
  1838. NULL,
  1839. };
  1840. /* streaming */
  1841. static struct uvcg_streaming_grp {
  1842. struct config_group group;
  1843. } uvcg_streaming_grp;
  1844. static struct config_item_type uvcg_streaming_grp_type = {
  1845. .ct_owner = THIS_MODULE,
  1846. };
  1847. static struct config_group *uvcg_default_groups[] = {
  1848. &uvcg_control_grp.group,
  1849. &uvcg_streaming_grp.group,
  1850. NULL,
  1851. };
  1852. static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item)
  1853. {
  1854. return container_of(to_config_group(item), struct f_uvc_opts,
  1855. func_inst.group);
  1856. }
  1857. static void uvc_attr_release(struct config_item *item)
  1858. {
  1859. struct f_uvc_opts *opts = to_f_uvc_opts(item);
  1860. usb_put_function_instance(&opts->func_inst);
  1861. }
  1862. static struct configfs_item_operations uvc_item_ops = {
  1863. .release = uvc_attr_release,
  1864. };
  1865. #define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \
  1866. static ssize_t f_uvc_opts_##cname##_show( \
  1867. struct config_item *item, char *page) \
  1868. { \
  1869. struct f_uvc_opts *opts = to_f_uvc_opts(item); \
  1870. int result; \
  1871. \
  1872. mutex_lock(&opts->lock); \
  1873. result = sprintf(page, "%d\n", conv(opts->cname)); \
  1874. mutex_unlock(&opts->lock); \
  1875. \
  1876. return result; \
  1877. } \
  1878. \
  1879. static ssize_t \
  1880. f_uvc_opts_##cname##_store(struct config_item *item, \
  1881. const char *page, size_t len) \
  1882. { \
  1883. struct f_uvc_opts *opts = to_f_uvc_opts(item); \
  1884. int ret; \
  1885. uxx num; \
  1886. \
  1887. mutex_lock(&opts->lock); \
  1888. if (opts->refcnt) { \
  1889. ret = -EBUSY; \
  1890. goto end; \
  1891. } \
  1892. \
  1893. ret = str2u(page, 0, &num); \
  1894. if (ret) \
  1895. goto end; \
  1896. \
  1897. if (num > limit) { \
  1898. ret = -EINVAL; \
  1899. goto end; \
  1900. } \
  1901. opts->cname = vnoc(num); \
  1902. ret = len; \
  1903. end: \
  1904. mutex_unlock(&opts->lock); \
  1905. return ret; \
  1906. } \
  1907. \
  1908. UVC_ATTR(f_uvc_opts_, cname, cname)
  1909. #define identity_conv(x) (x)
  1910. UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv,
  1911. kstrtou8, u8, identity_conv, 16);
  1912. UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu,
  1913. kstrtou16, u16, le16_to_cpu, 3072);
  1914. UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv,
  1915. kstrtou8, u8, identity_conv, 15);
  1916. #undef identity_conv
  1917. #undef UVCG_OPTS_ATTR
  1918. static struct configfs_attribute *uvc_attrs[] = {
  1919. &f_uvc_opts_attr_streaming_interval,
  1920. &f_uvc_opts_attr_streaming_maxpacket,
  1921. &f_uvc_opts_attr_streaming_maxburst,
  1922. NULL,
  1923. };
  1924. static struct config_item_type uvc_func_type = {
  1925. .ct_item_ops = &uvc_item_ops,
  1926. .ct_attrs = uvc_attrs,
  1927. .ct_owner = THIS_MODULE,
  1928. };
  1929. static inline void uvcg_init_group(struct config_group *g,
  1930. struct config_group **default_groups,
  1931. const char *name,
  1932. struct config_item_type *type)
  1933. {
  1934. g->default_groups = default_groups;
  1935. config_group_init_type_name(g, name, type);
  1936. }
  1937. int uvcg_attach_configfs(struct f_uvc_opts *opts)
  1938. {
  1939. config_group_init_type_name(&uvcg_control_header_grp.group,
  1940. "header",
  1941. &uvcg_control_header_grp_type);
  1942. config_group_init_type_name(&uvcg_default_processing.group,
  1943. "default",
  1944. &uvcg_default_processing_type);
  1945. uvcg_init_group(&uvcg_processing_grp.group,
  1946. uvcg_processing_default_groups,
  1947. "processing",
  1948. &uvcg_processing_grp_type);
  1949. config_group_init_type_name(&uvcg_default_camera.group,
  1950. "default",
  1951. &uvcg_default_camera_type);
  1952. uvcg_init_group(&uvcg_camera_grp.group,
  1953. uvcg_camera_default_groups,
  1954. "camera",
  1955. &uvcg_camera_grp_type);
  1956. config_group_init_type_name(&uvcg_default_output.group,
  1957. "default",
  1958. &uvcg_default_output_type);
  1959. uvcg_init_group(&uvcg_output_grp.group,
  1960. uvcg_output_default_groups,
  1961. "output",
  1962. &uvcg_output_grp_type);
  1963. uvcg_init_group(&uvcg_terminal_grp.group,
  1964. uvcg_terminal_default_groups,
  1965. "terminal",
  1966. &uvcg_terminal_grp_type);
  1967. config_group_init_type_name(&uvcg_control_class_fs.group,
  1968. "fs",
  1969. &uvcg_control_class_type);
  1970. config_group_init_type_name(&uvcg_control_class_ss.group,
  1971. "ss",
  1972. &uvcg_control_class_type);
  1973. uvcg_init_group(&uvcg_control_class_grp.group,
  1974. uvcg_control_class_default_groups,
  1975. "class",
  1976. &uvcg_control_class_grp_type);
  1977. uvcg_init_group(&uvcg_control_grp.group,
  1978. uvcg_control_default_groups,
  1979. "control",
  1980. &uvcg_control_grp_type);
  1981. config_group_init_type_name(&uvcg_streaming_header_grp.group,
  1982. "header",
  1983. &uvcg_streaming_header_grp_type);
  1984. config_group_init_type_name(&uvcg_uncompressed_grp.group,
  1985. "uncompressed",
  1986. &uvcg_uncompressed_grp_type);
  1987. config_group_init_type_name(&uvcg_mjpeg_grp.group,
  1988. "mjpeg",
  1989. &uvcg_mjpeg_grp_type);
  1990. config_group_init_type_name(&uvcg_default_color_matching.group,
  1991. "default",
  1992. &uvcg_default_color_matching_type);
  1993. uvcg_init_group(&uvcg_color_matching_grp.group,
  1994. uvcg_color_matching_default_groups,
  1995. "color_matching",
  1996. &uvcg_color_matching_grp_type);
  1997. config_group_init_type_name(&uvcg_streaming_class_fs.group,
  1998. "fs",
  1999. &uvcg_streaming_class_type);
  2000. config_group_init_type_name(&uvcg_streaming_class_hs.group,
  2001. "hs",
  2002. &uvcg_streaming_class_type);
  2003. config_group_init_type_name(&uvcg_streaming_class_ss.group,
  2004. "ss",
  2005. &uvcg_streaming_class_type);
  2006. uvcg_init_group(&uvcg_streaming_class_grp.group,
  2007. uvcg_streaming_class_default_groups,
  2008. "class",
  2009. &uvcg_streaming_class_grp_type);
  2010. uvcg_init_group(&uvcg_streaming_grp.group,
  2011. uvcg_streaming_default_groups,
  2012. "streaming",
  2013. &uvcg_streaming_grp_type);
  2014. uvcg_init_group(&opts->func_inst.group,
  2015. uvcg_default_groups,
  2016. "",
  2017. &uvc_func_type);
  2018. return 0;
  2019. }