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