1 // SPDX-License-Identifier: GPL-2.0-only
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
7 #include <linux/string.h>
8 #include <linux/slab.h>
9 #include "pvrusb2-sysfs.h"
10 #include "pvrusb2-hdw.h"
11 #include "pvrusb2-debug.h"
12 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
13 #include "pvrusb2-debugifc.h"
14 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
16 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
19 struct pvr2_channel channel
;
20 struct device
*class_dev
;
21 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
22 struct pvr2_sysfs_debugifc
*debugifc
;
23 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
24 struct pvr2_sysfs_ctl_item
*item_first
;
25 struct pvr2_sysfs_ctl_item
*item_last
;
26 struct device_attribute attr_v4l_minor_number
;
27 struct device_attribute attr_v4l_radio_minor_number
;
28 struct device_attribute attr_unit_number
;
29 struct device_attribute attr_bus_info
;
30 struct device_attribute attr_hdw_name
;
31 struct device_attribute attr_hdw_desc
;
32 int v4l_minor_number_created_ok
;
33 int v4l_radio_minor_number_created_ok
;
34 int unit_number_created_ok
;
35 int bus_info_created_ok
;
36 int hdw_name_created_ok
;
37 int hdw_desc_created_ok
;
40 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
41 struct pvr2_sysfs_debugifc
{
42 struct device_attribute attr_debugcmd
;
43 struct device_attribute attr_debuginfo
;
44 int debugcmd_created_ok
;
45 int debuginfo_created_ok
;
47 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
49 struct pvr2_sysfs_ctl_item
{
50 struct device_attribute attr_name
;
51 struct device_attribute attr_type
;
52 struct device_attribute attr_min
;
53 struct device_attribute attr_max
;
54 struct device_attribute attr_def
;
55 struct device_attribute attr_enum
;
56 struct device_attribute attr_bits
;
57 struct device_attribute attr_val
;
58 struct device_attribute attr_custom
;
59 struct pvr2_ctrl
*cptr
;
61 struct pvr2_sysfs
*chptr
;
62 struct pvr2_sysfs_ctl_item
*item_next
;
63 struct attribute
*attr_gen
[8];
64 struct attribute_group grp
;
69 struct pvr2_sysfs_class
{
73 static ssize_t
show_name(struct device
*class_dev
,
74 struct device_attribute
*attr
,
77 struct pvr2_sysfs_ctl_item
*cip
;
79 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_name
);
80 name
= pvr2_ctrl_get_desc(cip
->cptr
);
81 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
82 cip
->chptr
, cip
->ctl_id
, name
);
83 if (!name
) return -EINVAL
;
84 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
87 static ssize_t
show_type(struct device
*class_dev
,
88 struct device_attribute
*attr
,
91 struct pvr2_sysfs_ctl_item
*cip
;
93 enum pvr2_ctl_type tp
;
94 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_type
);
95 tp
= pvr2_ctrl_get_type(cip
->cptr
);
97 case pvr2_ctl_int
: name
= "integer"; break;
98 case pvr2_ctl_enum
: name
= "enum"; break;
99 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
100 case pvr2_ctl_bool
: name
= "boolean"; break;
101 default: name
= "?"; break;
103 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
104 cip
->chptr
, cip
->ctl_id
, name
);
105 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
108 static ssize_t
show_min(struct device
*class_dev
,
109 struct device_attribute
*attr
,
112 struct pvr2_sysfs_ctl_item
*cip
;
114 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_min
);
115 val
= pvr2_ctrl_get_min(cip
->cptr
);
116 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
117 cip
->chptr
, cip
->ctl_id
, val
);
118 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
121 static ssize_t
show_max(struct device
*class_dev
,
122 struct device_attribute
*attr
,
125 struct pvr2_sysfs_ctl_item
*cip
;
127 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_max
);
128 val
= pvr2_ctrl_get_max(cip
->cptr
);
129 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
130 cip
->chptr
, cip
->ctl_id
, val
);
131 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
134 static ssize_t
show_def(struct device
*class_dev
,
135 struct device_attribute
*attr
,
138 struct pvr2_sysfs_ctl_item
*cip
;
141 unsigned int cnt
= 0;
142 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_def
);
143 ret
= pvr2_ctrl_get_def(cip
->cptr
, &val
);
144 if (ret
< 0) return ret
;
145 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
146 buf
, PAGE_SIZE
- 1, &cnt
);
147 pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
148 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
153 static ssize_t
show_val_norm(struct device
*class_dev
,
154 struct device_attribute
*attr
,
157 struct pvr2_sysfs_ctl_item
*cip
;
160 unsigned int cnt
= 0;
161 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
162 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
163 if (ret
< 0) return ret
;
164 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
165 buf
, PAGE_SIZE
- 1, &cnt
);
166 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
167 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
172 static ssize_t
show_val_custom(struct device
*class_dev
,
173 struct device_attribute
*attr
,
176 struct pvr2_sysfs_ctl_item
*cip
;
179 unsigned int cnt
= 0;
180 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
181 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
182 if (ret
< 0) return ret
;
183 ret
= pvr2_ctrl_custom_value_to_sym(cip
->cptr
, ~0, val
,
184 buf
, PAGE_SIZE
- 1, &cnt
);
185 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
186 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
191 static ssize_t
show_enum(struct device
*class_dev
,
192 struct device_attribute
*attr
,
195 struct pvr2_sysfs_ctl_item
*cip
;
197 unsigned int bcnt
, ccnt
, ecnt
;
198 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_enum
);
199 ecnt
= pvr2_ctrl_get_cnt(cip
->cptr
);
201 for (val
= 0; val
< ecnt
; val
++) {
202 pvr2_ctrl_get_valname(cip
->cptr
, val
, buf
+ bcnt
,
203 PAGE_SIZE
- bcnt
, &ccnt
);
206 if (bcnt
>= PAGE_SIZE
) break;
210 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
211 cip
->chptr
, cip
->ctl_id
);
215 static ssize_t
show_bits(struct device
*class_dev
,
216 struct device_attribute
*attr
,
219 struct pvr2_sysfs_ctl_item
*cip
;
221 unsigned int bcnt
, ccnt
;
222 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_bits
);
223 valid_bits
= pvr2_ctrl_get_mask(cip
->cptr
);
225 for (msk
= 1; valid_bits
; msk
<<= 1) {
226 if (!(msk
& valid_bits
)) continue;
228 pvr2_ctrl_get_valname(cip
->cptr
, msk
, buf
+ bcnt
,
229 PAGE_SIZE
- bcnt
, &ccnt
);
231 if (bcnt
>= PAGE_SIZE
) break;
235 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
236 cip
->chptr
, cip
->ctl_id
);
240 static int store_val_any(struct pvr2_sysfs_ctl_item
*cip
, int customfl
,
241 const char *buf
,unsigned int count
)
246 ret
= pvr2_ctrl_custom_sym_to_value(cip
->cptr
, buf
, count
,
249 ret
= pvr2_ctrl_sym_to_value(cip
->cptr
, buf
, count
,
252 if (ret
< 0) return ret
;
253 ret
= pvr2_ctrl_set_mask_value(cip
->cptr
, mask
, val
);
254 pvr2_hdw_commit_ctl(cip
->chptr
->channel
.hdw
);
258 static ssize_t
store_val_norm(struct device
*class_dev
,
259 struct device_attribute
*attr
,
260 const char *buf
, size_t count
)
262 struct pvr2_sysfs_ctl_item
*cip
;
264 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
265 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
266 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
267 ret
= store_val_any(cip
, 0, buf
, count
);
268 if (!ret
) ret
= count
;
272 static ssize_t
store_val_custom(struct device
*class_dev
,
273 struct device_attribute
*attr
,
274 const char *buf
, size_t count
)
276 struct pvr2_sysfs_ctl_item
*cip
;
278 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
279 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
280 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
281 ret
= store_val_any(cip
, 1, buf
, count
);
282 if (!ret
) ret
= count
;
286 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
288 struct pvr2_sysfs_ctl_item
*cip
;
289 struct pvr2_ctrl
*cptr
;
290 unsigned int cnt
,acnt
;
293 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
296 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
298 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
301 cip
->ctl_id
= ctl_id
;
304 cip
->item_next
= NULL
;
305 if (sfp
->item_last
) {
306 sfp
->item_last
->item_next
= cip
;
308 sfp
->item_first
= cip
;
310 sfp
->item_last
= cip
;
312 sysfs_attr_init(&cip
->attr_name
.attr
);
313 cip
->attr_name
.attr
.name
= "name";
314 cip
->attr_name
.attr
.mode
= S_IRUGO
;
315 cip
->attr_name
.show
= show_name
;
317 sysfs_attr_init(&cip
->attr_type
.attr
);
318 cip
->attr_type
.attr
.name
= "type";
319 cip
->attr_type
.attr
.mode
= S_IRUGO
;
320 cip
->attr_type
.show
= show_type
;
322 sysfs_attr_init(&cip
->attr_min
.attr
);
323 cip
->attr_min
.attr
.name
= "min_val";
324 cip
->attr_min
.attr
.mode
= S_IRUGO
;
325 cip
->attr_min
.show
= show_min
;
327 sysfs_attr_init(&cip
->attr_max
.attr
);
328 cip
->attr_max
.attr
.name
= "max_val";
329 cip
->attr_max
.attr
.mode
= S_IRUGO
;
330 cip
->attr_max
.show
= show_max
;
332 sysfs_attr_init(&cip
->attr_def
.attr
);
333 cip
->attr_def
.attr
.name
= "def_val";
334 cip
->attr_def
.attr
.mode
= S_IRUGO
;
335 cip
->attr_def
.show
= show_def
;
337 sysfs_attr_init(&cip
->attr_val
.attr
);
338 cip
->attr_val
.attr
.name
= "cur_val";
339 cip
->attr_val
.attr
.mode
= S_IRUGO
;
341 sysfs_attr_init(&cip
->attr_custom
.attr
);
342 cip
->attr_custom
.attr
.name
= "custom_val";
343 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
345 sysfs_attr_init(&cip
->attr_enum
.attr
);
346 cip
->attr_enum
.attr
.name
= "enum_val";
347 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
348 cip
->attr_enum
.show
= show_enum
;
350 sysfs_attr_init(&cip
->attr_bits
.attr
);
351 cip
->attr_bits
.attr
.name
= "bit_val";
352 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
353 cip
->attr_bits
.show
= show_bits
;
355 if (pvr2_ctrl_is_writable(cptr
)) {
356 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
357 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
361 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
362 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
363 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
364 cip
->attr_gen
[acnt
++] = &cip
->attr_def
.attr
;
365 cip
->attr_val
.show
= show_val_norm
;
366 cip
->attr_val
.store
= store_val_norm
;
367 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
368 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
369 cip
->attr_custom
.show
= show_val_custom
;
370 cip
->attr_custom
.store
= store_val_custom
;
372 switch (pvr2_ctrl_get_type(cptr
)) {
374 // Control is an enumeration
375 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
378 // Control is an integer
379 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
380 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
382 case pvr2_ctl_bitmask
:
383 // Control is an bitmask
384 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
389 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
390 pvr2_ctrl_get_name(cptr
));
392 cip
->grp
.name
= cip
->name
;
393 cip
->grp
.attrs
= cip
->attr_gen
;
395 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
397 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
398 "sysfs_create_group error: %d",
402 cip
->created_ok
= !0;
405 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
406 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
408 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
410 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
411 const char *, size_t count
);
413 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
415 struct pvr2_sysfs_debugifc
*dip
;
418 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
420 sysfs_attr_init(&dip
->attr_debugcmd
.attr
);
421 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
422 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
423 dip
->attr_debugcmd
.show
= debugcmd_show
;
424 dip
->attr_debugcmd
.store
= debugcmd_store
;
425 sysfs_attr_init(&dip
->attr_debuginfo
.attr
);
426 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
427 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
428 dip
->attr_debuginfo
.show
= debuginfo_show
;
430 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
432 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
433 "device_create_file error: %d",
436 dip
->debugcmd_created_ok
= !0;
438 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
440 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
441 "device_create_file error: %d",
444 dip
->debuginfo_created_ok
= !0;
449 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
451 if (!sfp
->debugifc
) return;
452 if (sfp
->debugifc
->debuginfo_created_ok
) {
453 device_remove_file(sfp
->class_dev
,
454 &sfp
->debugifc
->attr_debuginfo
);
456 if (sfp
->debugifc
->debugcmd_created_ok
) {
457 device_remove_file(sfp
->class_dev
,
458 &sfp
->debugifc
->attr_debugcmd
);
460 kfree(sfp
->debugifc
);
461 sfp
->debugifc
= NULL
;
463 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
466 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
468 unsigned int idx
,cnt
;
469 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
470 for (idx
= 0; idx
< cnt
; idx
++) {
471 pvr2_sysfs_add_control(sfp
,idx
);
476 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
478 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
479 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
480 cip2
= cip1
->item_next
;
481 if (cip1
->created_ok
) {
482 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
484 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
490 static void pvr2_sysfs_class_release(struct class *class)
492 struct pvr2_sysfs_class
*clp
;
493 clp
= container_of(class,struct pvr2_sysfs_class
,class);
494 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
499 static void pvr2_sysfs_release(struct device
*class_dev
)
501 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
506 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
509 if (!sfp
->class_dev
) return;
510 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
511 pvr2_sysfs_tear_down_debugifc(sfp
);
512 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
513 pvr2_sysfs_tear_down_controls(sfp
);
514 if (sfp
->hdw_desc_created_ok
) {
515 device_remove_file(sfp
->class_dev
,
516 &sfp
->attr_hdw_desc
);
518 if (sfp
->hdw_name_created_ok
) {
519 device_remove_file(sfp
->class_dev
,
520 &sfp
->attr_hdw_name
);
522 if (sfp
->bus_info_created_ok
) {
523 device_remove_file(sfp
->class_dev
,
524 &sfp
->attr_bus_info
);
526 if (sfp
->v4l_minor_number_created_ok
) {
527 device_remove_file(sfp
->class_dev
,
528 &sfp
->attr_v4l_minor_number
);
530 if (sfp
->v4l_radio_minor_number_created_ok
) {
531 device_remove_file(sfp
->class_dev
,
532 &sfp
->attr_v4l_radio_minor_number
);
534 if (sfp
->unit_number_created_ok
) {
535 device_remove_file(sfp
->class_dev
,
536 &sfp
->attr_unit_number
);
538 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
539 dev_set_drvdata(sfp
->class_dev
, NULL
);
540 dev
= sfp
->class_dev
->parent
;
541 sfp
->class_dev
->parent
= NULL
;
543 device_unregister(sfp
->class_dev
);
544 sfp
->class_dev
= NULL
;
548 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
549 struct device_attribute
*attr
, char *buf
)
551 struct pvr2_sysfs
*sfp
;
552 sfp
= dev_get_drvdata(class_dev
);
553 if (!sfp
) return -EINVAL
;
554 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
555 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
556 pvr2_v4l_type_video
));
560 static ssize_t
bus_info_show(struct device
*class_dev
,
561 struct device_attribute
*attr
, char *buf
)
563 struct pvr2_sysfs
*sfp
;
564 sfp
= dev_get_drvdata(class_dev
);
565 if (!sfp
) return -EINVAL
;
566 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
567 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
571 static ssize_t
hdw_name_show(struct device
*class_dev
,
572 struct device_attribute
*attr
, char *buf
)
574 struct pvr2_sysfs
*sfp
;
575 sfp
= dev_get_drvdata(class_dev
);
576 if (!sfp
) return -EINVAL
;
577 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
578 pvr2_hdw_get_type(sfp
->channel
.hdw
));
582 static ssize_t
hdw_desc_show(struct device
*class_dev
,
583 struct device_attribute
*attr
, char *buf
)
585 struct pvr2_sysfs
*sfp
;
586 sfp
= dev_get_drvdata(class_dev
);
587 if (!sfp
) return -EINVAL
;
588 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
589 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
593 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
594 struct device_attribute
*attr
,
597 struct pvr2_sysfs
*sfp
;
598 sfp
= dev_get_drvdata(class_dev
);
599 if (!sfp
) return -EINVAL
;
600 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
601 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
602 pvr2_v4l_type_radio
));
606 static ssize_t
unit_number_show(struct device
*class_dev
,
607 struct device_attribute
*attr
, char *buf
)
609 struct pvr2_sysfs
*sfp
;
610 sfp
= dev_get_drvdata(class_dev
);
611 if (!sfp
) return -EINVAL
;
612 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
613 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
617 static void class_dev_create(struct pvr2_sysfs
*sfp
,
618 struct pvr2_sysfs_class
*class_ptr
)
620 struct usb_device
*usb_dev
;
621 struct device
*class_dev
;
624 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
625 if (!usb_dev
) return;
626 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
627 if (!class_dev
) return;
629 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
631 class_dev
->class = &class_ptr
->class;
633 dev_set_name(class_dev
, "%s",
634 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
636 class_dev
->parent
= get_device(&usb_dev
->dev
);
638 sfp
->class_dev
= class_dev
;
639 dev_set_drvdata(class_dev
, sfp
);
640 ret
= device_register(class_dev
);
642 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
643 "device_register failed");
644 put_device(class_dev
);
648 sysfs_attr_init(&sfp
->attr_v4l_minor_number
.attr
);
649 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
650 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
651 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
652 sfp
->attr_v4l_minor_number
.store
= NULL
;
653 ret
= device_create_file(sfp
->class_dev
,
654 &sfp
->attr_v4l_minor_number
);
656 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
657 "device_create_file error: %d",
660 sfp
->v4l_minor_number_created_ok
= !0;
663 sysfs_attr_init(&sfp
->attr_v4l_radio_minor_number
.attr
);
664 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
665 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
666 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
667 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
668 ret
= device_create_file(sfp
->class_dev
,
669 &sfp
->attr_v4l_radio_minor_number
);
671 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
672 "device_create_file error: %d",
675 sfp
->v4l_radio_minor_number_created_ok
= !0;
678 sysfs_attr_init(&sfp
->attr_unit_number
.attr
);
679 sfp
->attr_unit_number
.attr
.name
= "unit_number";
680 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
681 sfp
->attr_unit_number
.show
= unit_number_show
;
682 sfp
->attr_unit_number
.store
= NULL
;
683 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
685 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
686 "device_create_file error: %d",
689 sfp
->unit_number_created_ok
= !0;
692 sysfs_attr_init(&sfp
->attr_bus_info
.attr
);
693 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
694 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
695 sfp
->attr_bus_info
.show
= bus_info_show
;
696 sfp
->attr_bus_info
.store
= NULL
;
697 ret
= device_create_file(sfp
->class_dev
,
698 &sfp
->attr_bus_info
);
700 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
701 "device_create_file error: %d",
704 sfp
->bus_info_created_ok
= !0;
707 sysfs_attr_init(&sfp
->attr_hdw_name
.attr
);
708 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
709 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
710 sfp
->attr_hdw_name
.show
= hdw_name_show
;
711 sfp
->attr_hdw_name
.store
= NULL
;
712 ret
= device_create_file(sfp
->class_dev
,
713 &sfp
->attr_hdw_name
);
715 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
716 "device_create_file error: %d",
719 sfp
->hdw_name_created_ok
= !0;
722 sysfs_attr_init(&sfp
->attr_hdw_desc
.attr
);
723 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
724 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
725 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
726 sfp
->attr_hdw_desc
.store
= NULL
;
727 ret
= device_create_file(sfp
->class_dev
,
728 &sfp
->attr_hdw_desc
);
730 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
731 "device_create_file error: %d",
734 sfp
->hdw_desc_created_ok
= !0;
737 pvr2_sysfs_add_controls(sfp
);
738 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
739 pvr2_sysfs_add_debugifc(sfp
);
740 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
744 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
746 struct pvr2_sysfs
*sfp
;
747 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
748 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
749 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
750 class_dev_destroy(sfp
);
751 pvr2_channel_done(&sfp
->channel
);
756 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
757 struct pvr2_sysfs_class
*class_ptr
)
759 struct pvr2_sysfs
*sfp
;
760 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
761 if (!sfp
) return sfp
;
762 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
763 pvr2_channel_init(&sfp
->channel
,mp
);
764 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
766 class_dev_create(sfp
,class_ptr
);
772 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
774 struct pvr2_sysfs_class
*clp
;
775 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
776 if (!clp
) return clp
;
777 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
779 clp
->class.name
= "pvrusb2";
780 clp
->class.class_release
= pvr2_sysfs_class_release
;
781 clp
->class.dev_release
= pvr2_sysfs_release
;
782 if (class_register(&clp
->class)) {
784 "Registration failed for pvr2_sysfs_class id=%p",clp
);
792 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
794 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp
);
796 class_unregister(&clp
->class);
800 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
801 static ssize_t
debuginfo_show(struct device
*class_dev
,
802 struct device_attribute
*attr
, char *buf
)
804 struct pvr2_sysfs
*sfp
;
805 sfp
= dev_get_drvdata(class_dev
);
806 if (!sfp
) return -EINVAL
;
807 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
808 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
812 static ssize_t
debugcmd_show(struct device
*class_dev
,
813 struct device_attribute
*attr
, char *buf
)
815 struct pvr2_sysfs
*sfp
;
816 sfp
= dev_get_drvdata(class_dev
);
817 if (!sfp
) return -EINVAL
;
818 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
822 static ssize_t
debugcmd_store(struct device
*class_dev
,
823 struct device_attribute
*attr
,
824 const char *buf
, size_t count
)
826 struct pvr2_sysfs
*sfp
;
829 sfp
= dev_get_drvdata(class_dev
);
830 if (!sfp
) return -EINVAL
;
832 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
833 if (ret
< 0) return ret
;
836 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */