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 static ssize_t
show_name(struct device
*class_dev
,
70 struct device_attribute
*attr
,
73 struct pvr2_sysfs_ctl_item
*cip
;
75 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_name
);
76 name
= pvr2_ctrl_get_desc(cip
->cptr
);
77 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
78 cip
->chptr
, cip
->ctl_id
, name
);
79 if (!name
) return -EINVAL
;
80 return sysfs_emit(buf
, "%s\n", name
);
83 static ssize_t
show_type(struct device
*class_dev
,
84 struct device_attribute
*attr
,
87 struct pvr2_sysfs_ctl_item
*cip
;
89 enum pvr2_ctl_type tp
;
90 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_type
);
91 tp
= pvr2_ctrl_get_type(cip
->cptr
);
93 case pvr2_ctl_int
: name
= "integer"; break;
94 case pvr2_ctl_enum
: name
= "enum"; break;
95 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
96 case pvr2_ctl_bool
: name
= "boolean"; break;
97 default: name
= "?"; break;
99 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
100 cip
->chptr
, cip
->ctl_id
, name
);
101 return sysfs_emit(buf
, "%s\n", name
);
104 static ssize_t
show_min(struct device
*class_dev
,
105 struct device_attribute
*attr
,
108 struct pvr2_sysfs_ctl_item
*cip
;
110 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_min
);
111 val
= pvr2_ctrl_get_min(cip
->cptr
);
112 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
113 cip
->chptr
, cip
->ctl_id
, val
);
114 return sysfs_emit(buf
, "%ld\n", val
);
117 static ssize_t
show_max(struct device
*class_dev
,
118 struct device_attribute
*attr
,
121 struct pvr2_sysfs_ctl_item
*cip
;
123 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_max
);
124 val
= pvr2_ctrl_get_max(cip
->cptr
);
125 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
126 cip
->chptr
, cip
->ctl_id
, val
);
127 return sysfs_emit(buf
, "%ld\n", val
);
130 static ssize_t
show_def(struct device
*class_dev
,
131 struct device_attribute
*attr
,
134 struct pvr2_sysfs_ctl_item
*cip
;
137 unsigned int cnt
= 0;
138 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_def
);
139 ret
= pvr2_ctrl_get_def(cip
->cptr
, &val
);
140 if (ret
< 0) return ret
;
141 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
142 buf
, PAGE_SIZE
- 1, &cnt
);
143 pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
144 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
149 static ssize_t
show_val_norm(struct device
*class_dev
,
150 struct device_attribute
*attr
,
153 struct pvr2_sysfs_ctl_item
*cip
;
156 unsigned int cnt
= 0;
157 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
158 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
159 if (ret
< 0) return ret
;
160 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
161 buf
, PAGE_SIZE
- 1, &cnt
);
162 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
163 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
168 static ssize_t
show_val_custom(struct device
*class_dev
,
169 struct device_attribute
*attr
,
172 struct pvr2_sysfs_ctl_item
*cip
;
175 unsigned int cnt
= 0;
176 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
177 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
178 if (ret
< 0) return ret
;
179 ret
= pvr2_ctrl_custom_value_to_sym(cip
->cptr
, ~0, val
,
180 buf
, PAGE_SIZE
- 1, &cnt
);
181 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
182 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
187 static ssize_t
show_enum(struct device
*class_dev
,
188 struct device_attribute
*attr
,
191 struct pvr2_sysfs_ctl_item
*cip
;
193 unsigned int bcnt
, ccnt
, ecnt
;
194 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_enum
);
195 ecnt
= pvr2_ctrl_get_cnt(cip
->cptr
);
197 for (val
= 0; val
< ecnt
; val
++) {
198 pvr2_ctrl_get_valname(cip
->cptr
, val
, buf
+ bcnt
,
199 PAGE_SIZE
- bcnt
, &ccnt
);
202 if (bcnt
>= PAGE_SIZE
) break;
206 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
207 cip
->chptr
, cip
->ctl_id
);
211 static ssize_t
show_bits(struct device
*class_dev
,
212 struct device_attribute
*attr
,
215 struct pvr2_sysfs_ctl_item
*cip
;
217 unsigned int bcnt
, ccnt
;
218 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_bits
);
219 valid_bits
= pvr2_ctrl_get_mask(cip
->cptr
);
221 for (msk
= 1; valid_bits
; msk
<<= 1) {
222 if (!(msk
& valid_bits
)) continue;
224 pvr2_ctrl_get_valname(cip
->cptr
, msk
, buf
+ bcnt
,
225 PAGE_SIZE
- bcnt
, &ccnt
);
227 if (bcnt
>= PAGE_SIZE
) break;
231 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
232 cip
->chptr
, cip
->ctl_id
);
236 static int store_val_any(struct pvr2_sysfs_ctl_item
*cip
, int customfl
,
237 const char *buf
,unsigned int count
)
242 ret
= pvr2_ctrl_custom_sym_to_value(cip
->cptr
, buf
, count
,
245 ret
= pvr2_ctrl_sym_to_value(cip
->cptr
, buf
, count
,
248 if (ret
< 0) return ret
;
249 ret
= pvr2_ctrl_set_mask_value(cip
->cptr
, mask
, val
);
250 pvr2_hdw_commit_ctl(cip
->chptr
->channel
.hdw
);
254 static ssize_t
store_val_norm(struct device
*class_dev
,
255 struct device_attribute
*attr
,
256 const char *buf
, size_t count
)
258 struct pvr2_sysfs_ctl_item
*cip
;
260 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
261 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
262 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
263 ret
= store_val_any(cip
, 0, buf
, count
);
264 if (!ret
) ret
= count
;
268 static ssize_t
store_val_custom(struct device
*class_dev
,
269 struct device_attribute
*attr
,
270 const char *buf
, size_t count
)
272 struct pvr2_sysfs_ctl_item
*cip
;
274 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
275 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
276 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
277 ret
= store_val_any(cip
, 1, buf
, count
);
278 if (!ret
) ret
= count
;
282 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
284 struct pvr2_sysfs_ctl_item
*cip
;
285 struct pvr2_ctrl
*cptr
;
286 unsigned int cnt
,acnt
;
289 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
292 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
294 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
297 cip
->ctl_id
= ctl_id
;
300 cip
->item_next
= NULL
;
301 if (sfp
->item_last
) {
302 sfp
->item_last
->item_next
= cip
;
304 sfp
->item_first
= cip
;
306 sfp
->item_last
= cip
;
308 sysfs_attr_init(&cip
->attr_name
.attr
);
309 cip
->attr_name
.attr
.name
= "name";
310 cip
->attr_name
.attr
.mode
= S_IRUGO
;
311 cip
->attr_name
.show
= show_name
;
313 sysfs_attr_init(&cip
->attr_type
.attr
);
314 cip
->attr_type
.attr
.name
= "type";
315 cip
->attr_type
.attr
.mode
= S_IRUGO
;
316 cip
->attr_type
.show
= show_type
;
318 sysfs_attr_init(&cip
->attr_min
.attr
);
319 cip
->attr_min
.attr
.name
= "min_val";
320 cip
->attr_min
.attr
.mode
= S_IRUGO
;
321 cip
->attr_min
.show
= show_min
;
323 sysfs_attr_init(&cip
->attr_max
.attr
);
324 cip
->attr_max
.attr
.name
= "max_val";
325 cip
->attr_max
.attr
.mode
= S_IRUGO
;
326 cip
->attr_max
.show
= show_max
;
328 sysfs_attr_init(&cip
->attr_def
.attr
);
329 cip
->attr_def
.attr
.name
= "def_val";
330 cip
->attr_def
.attr
.mode
= S_IRUGO
;
331 cip
->attr_def
.show
= show_def
;
333 sysfs_attr_init(&cip
->attr_val
.attr
);
334 cip
->attr_val
.attr
.name
= "cur_val";
335 cip
->attr_val
.attr
.mode
= S_IRUGO
;
337 sysfs_attr_init(&cip
->attr_custom
.attr
);
338 cip
->attr_custom
.attr
.name
= "custom_val";
339 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
341 sysfs_attr_init(&cip
->attr_enum
.attr
);
342 cip
->attr_enum
.attr
.name
= "enum_val";
343 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
344 cip
->attr_enum
.show
= show_enum
;
346 sysfs_attr_init(&cip
->attr_bits
.attr
);
347 cip
->attr_bits
.attr
.name
= "bit_val";
348 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
349 cip
->attr_bits
.show
= show_bits
;
351 if (pvr2_ctrl_is_writable(cptr
)) {
352 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
353 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
357 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
358 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
359 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
360 cip
->attr_gen
[acnt
++] = &cip
->attr_def
.attr
;
361 cip
->attr_val
.show
= show_val_norm
;
362 cip
->attr_val
.store
= store_val_norm
;
363 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
364 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
365 cip
->attr_custom
.show
= show_val_custom
;
366 cip
->attr_custom
.store
= store_val_custom
;
368 switch (pvr2_ctrl_get_type(cptr
)) {
370 // Control is an enumeration
371 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
374 // Control is an integer
375 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
376 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
378 case pvr2_ctl_bitmask
:
379 // Control is an bitmask
380 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
385 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
386 pvr2_ctrl_get_name(cptr
));
388 cip
->grp
.name
= cip
->name
;
389 cip
->grp
.attrs
= cip
->attr_gen
;
391 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
393 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
394 "sysfs_create_group error: %d",
398 cip
->created_ok
= !0;
401 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
402 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
404 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
406 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
407 const char *, size_t count
);
409 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
411 struct pvr2_sysfs_debugifc
*dip
;
414 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
416 sysfs_attr_init(&dip
->attr_debugcmd
.attr
);
417 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
418 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
419 dip
->attr_debugcmd
.show
= debugcmd_show
;
420 dip
->attr_debugcmd
.store
= debugcmd_store
;
421 sysfs_attr_init(&dip
->attr_debuginfo
.attr
);
422 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
423 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
424 dip
->attr_debuginfo
.show
= debuginfo_show
;
426 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
428 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
429 "device_create_file error: %d",
432 dip
->debugcmd_created_ok
= !0;
434 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
436 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
437 "device_create_file error: %d",
440 dip
->debuginfo_created_ok
= !0;
445 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
447 if (!sfp
->debugifc
) return;
448 if (sfp
->debugifc
->debuginfo_created_ok
) {
449 device_remove_file(sfp
->class_dev
,
450 &sfp
->debugifc
->attr_debuginfo
);
452 if (sfp
->debugifc
->debugcmd_created_ok
) {
453 device_remove_file(sfp
->class_dev
,
454 &sfp
->debugifc
->attr_debugcmd
);
456 kfree(sfp
->debugifc
);
457 sfp
->debugifc
= NULL
;
459 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
462 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
464 unsigned int idx
,cnt
;
465 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
466 for (idx
= 0; idx
< cnt
; idx
++) {
467 pvr2_sysfs_add_control(sfp
,idx
);
472 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
474 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
475 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
476 cip2
= cip1
->item_next
;
477 if (cip1
->created_ok
) {
478 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
480 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
486 static void pvr2_sysfs_release(struct device
*class_dev
)
488 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
493 static struct class pvr2_class
= {
495 .dev_release
= pvr2_sysfs_release
,
499 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
502 if (!sfp
->class_dev
) return;
503 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
504 pvr2_sysfs_tear_down_debugifc(sfp
);
505 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
506 pvr2_sysfs_tear_down_controls(sfp
);
507 if (sfp
->hdw_desc_created_ok
) {
508 device_remove_file(sfp
->class_dev
,
509 &sfp
->attr_hdw_desc
);
511 if (sfp
->hdw_name_created_ok
) {
512 device_remove_file(sfp
->class_dev
,
513 &sfp
->attr_hdw_name
);
515 if (sfp
->bus_info_created_ok
) {
516 device_remove_file(sfp
->class_dev
,
517 &sfp
->attr_bus_info
);
519 if (sfp
->v4l_minor_number_created_ok
) {
520 device_remove_file(sfp
->class_dev
,
521 &sfp
->attr_v4l_minor_number
);
523 if (sfp
->v4l_radio_minor_number_created_ok
) {
524 device_remove_file(sfp
->class_dev
,
525 &sfp
->attr_v4l_radio_minor_number
);
527 if (sfp
->unit_number_created_ok
) {
528 device_remove_file(sfp
->class_dev
,
529 &sfp
->attr_unit_number
);
531 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
532 dev_set_drvdata(sfp
->class_dev
, NULL
);
533 dev
= sfp
->class_dev
->parent
;
534 sfp
->class_dev
->parent
= NULL
;
536 device_unregister(sfp
->class_dev
);
537 sfp
->class_dev
= NULL
;
541 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
542 struct device_attribute
*attr
, char *buf
)
544 struct pvr2_sysfs
*sfp
;
545 sfp
= dev_get_drvdata(class_dev
);
546 if (!sfp
) return -EINVAL
;
547 return sysfs_emit(buf
, "%d\n",
548 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
549 pvr2_v4l_type_video
));
553 static ssize_t
bus_info_show(struct device
*class_dev
,
554 struct device_attribute
*attr
, char *buf
)
556 struct pvr2_sysfs
*sfp
;
557 sfp
= dev_get_drvdata(class_dev
);
558 if (!sfp
) return -EINVAL
;
559 return sysfs_emit(buf
, "%s\n",
560 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
564 static ssize_t
hdw_name_show(struct device
*class_dev
,
565 struct device_attribute
*attr
, char *buf
)
567 struct pvr2_sysfs
*sfp
;
568 sfp
= dev_get_drvdata(class_dev
);
569 if (!sfp
) return -EINVAL
;
570 return sysfs_emit(buf
, "%s\n",
571 pvr2_hdw_get_type(sfp
->channel
.hdw
));
575 static ssize_t
hdw_desc_show(struct device
*class_dev
,
576 struct device_attribute
*attr
, char *buf
)
578 struct pvr2_sysfs
*sfp
;
579 sfp
= dev_get_drvdata(class_dev
);
580 if (!sfp
) return -EINVAL
;
581 return sysfs_emit(buf
, "%s\n",
582 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
586 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
587 struct device_attribute
*attr
,
590 struct pvr2_sysfs
*sfp
;
591 sfp
= dev_get_drvdata(class_dev
);
592 if (!sfp
) return -EINVAL
;
593 return sysfs_emit(buf
, "%d\n",
594 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
595 pvr2_v4l_type_radio
));
599 static ssize_t
unit_number_show(struct device
*class_dev
,
600 struct device_attribute
*attr
, char *buf
)
602 struct pvr2_sysfs
*sfp
;
603 sfp
= dev_get_drvdata(class_dev
);
604 if (!sfp
) return -EINVAL
;
605 return sysfs_emit(buf
, "%d\n",
606 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
610 static void class_dev_create(struct pvr2_sysfs
*sfp
)
612 struct usb_device
*usb_dev
;
613 struct device
*class_dev
;
616 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
617 if (!usb_dev
) return;
618 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
619 if (!class_dev
) return;
621 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
623 class_dev
->class = &pvr2_class
;
625 dev_set_name(class_dev
, "%s",
626 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
628 class_dev
->parent
= get_device(&usb_dev
->dev
);
630 sfp
->class_dev
= class_dev
;
631 dev_set_drvdata(class_dev
, sfp
);
632 ret
= device_register(class_dev
);
634 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
635 "device_register failed");
636 put_device(class_dev
);
640 sysfs_attr_init(&sfp
->attr_v4l_minor_number
.attr
);
641 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
642 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
643 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
644 sfp
->attr_v4l_minor_number
.store
= NULL
;
645 ret
= device_create_file(sfp
->class_dev
,
646 &sfp
->attr_v4l_minor_number
);
648 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
649 "device_create_file error: %d",
652 sfp
->v4l_minor_number_created_ok
= !0;
655 sysfs_attr_init(&sfp
->attr_v4l_radio_minor_number
.attr
);
656 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
657 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
658 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
659 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
660 ret
= device_create_file(sfp
->class_dev
,
661 &sfp
->attr_v4l_radio_minor_number
);
663 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
664 "device_create_file error: %d",
667 sfp
->v4l_radio_minor_number_created_ok
= !0;
670 sysfs_attr_init(&sfp
->attr_unit_number
.attr
);
671 sfp
->attr_unit_number
.attr
.name
= "unit_number";
672 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
673 sfp
->attr_unit_number
.show
= unit_number_show
;
674 sfp
->attr_unit_number
.store
= NULL
;
675 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
677 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
678 "device_create_file error: %d",
681 sfp
->unit_number_created_ok
= !0;
684 sysfs_attr_init(&sfp
->attr_bus_info
.attr
);
685 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
686 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
687 sfp
->attr_bus_info
.show
= bus_info_show
;
688 sfp
->attr_bus_info
.store
= NULL
;
689 ret
= device_create_file(sfp
->class_dev
,
690 &sfp
->attr_bus_info
);
692 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
693 "device_create_file error: %d",
696 sfp
->bus_info_created_ok
= !0;
699 sysfs_attr_init(&sfp
->attr_hdw_name
.attr
);
700 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
701 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
702 sfp
->attr_hdw_name
.show
= hdw_name_show
;
703 sfp
->attr_hdw_name
.store
= NULL
;
704 ret
= device_create_file(sfp
->class_dev
,
705 &sfp
->attr_hdw_name
);
707 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
708 "device_create_file error: %d",
711 sfp
->hdw_name_created_ok
= !0;
714 sysfs_attr_init(&sfp
->attr_hdw_desc
.attr
);
715 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
716 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
717 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
718 sfp
->attr_hdw_desc
.store
= NULL
;
719 ret
= device_create_file(sfp
->class_dev
,
720 &sfp
->attr_hdw_desc
);
722 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
723 "device_create_file error: %d",
726 sfp
->hdw_desc_created_ok
= !0;
729 pvr2_sysfs_add_controls(sfp
);
730 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
731 pvr2_sysfs_add_debugifc(sfp
);
732 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
736 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
738 struct pvr2_sysfs
*sfp
;
739 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
740 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
741 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
742 class_dev_destroy(sfp
);
743 pvr2_channel_done(&sfp
->channel
);
748 void pvr2_sysfs_create(struct pvr2_context
*mp
)
750 struct pvr2_sysfs
*sfp
;
751 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
754 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
755 pvr2_channel_init(&sfp
->channel
,mp
);
756 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
758 class_dev_create(sfp
);
762 void pvr2_sysfs_class_create(void)
764 if (class_register(&pvr2_class
))
765 pvr2_sysfs_trace("Registration failed for pvr2_sysfs_class");
769 void pvr2_sysfs_class_destroy(void)
771 class_unregister(&pvr2_class
);
775 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
776 static ssize_t
debuginfo_show(struct device
*class_dev
,
777 struct device_attribute
*attr
, char *buf
)
779 struct pvr2_sysfs
*sfp
;
780 sfp
= dev_get_drvdata(class_dev
);
781 if (!sfp
) return -EINVAL
;
782 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
783 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
787 static ssize_t
debugcmd_show(struct device
*class_dev
,
788 struct device_attribute
*attr
, char *buf
)
790 struct pvr2_sysfs
*sfp
;
791 sfp
= dev_get_drvdata(class_dev
);
792 if (!sfp
) return -EINVAL
;
793 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
797 static ssize_t
debugcmd_store(struct device
*class_dev
,
798 struct device_attribute
*attr
,
799 const char *buf
, size_t count
)
801 struct pvr2_sysfs
*sfp
;
804 sfp
= dev_get_drvdata(class_dev
);
805 if (!sfp
) return -EINVAL
;
807 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
808 if (ret
< 0) return ret
;
811 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */