uvc_configfs.c 63 KB

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