4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/string.h>
18 #include <linux/slab.h>
19 #include "pvrusb2-sysfs.h"
20 #include "pvrusb2-hdw.h"
21 #include "pvrusb2-debug.h"
22 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
23 #include "pvrusb2-debugifc.h"
24 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
26 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
29 struct pvr2_channel channel
;
30 struct device
*class_dev
;
31 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
32 struct pvr2_sysfs_debugifc
*debugifc
;
33 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
34 struct pvr2_sysfs_ctl_item
*item_first
;
35 struct pvr2_sysfs_ctl_item
*item_last
;
36 struct device_attribute attr_v4l_minor_number
;
37 struct device_attribute attr_v4l_radio_minor_number
;
38 struct device_attribute attr_unit_number
;
39 struct device_attribute attr_bus_info
;
40 struct device_attribute attr_hdw_name
;
41 struct device_attribute attr_hdw_desc
;
42 int v4l_minor_number_created_ok
;
43 int v4l_radio_minor_number_created_ok
;
44 int unit_number_created_ok
;
45 int bus_info_created_ok
;
46 int hdw_name_created_ok
;
47 int hdw_desc_created_ok
;
50 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
51 struct pvr2_sysfs_debugifc
{
52 struct device_attribute attr_debugcmd
;
53 struct device_attribute attr_debuginfo
;
54 int debugcmd_created_ok
;
55 int debuginfo_created_ok
;
57 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
59 struct pvr2_sysfs_ctl_item
{
60 struct device_attribute attr_name
;
61 struct device_attribute attr_type
;
62 struct device_attribute attr_min
;
63 struct device_attribute attr_max
;
64 struct device_attribute attr_def
;
65 struct device_attribute attr_enum
;
66 struct device_attribute attr_bits
;
67 struct device_attribute attr_val
;
68 struct device_attribute attr_custom
;
69 struct pvr2_ctrl
*cptr
;
71 struct pvr2_sysfs
*chptr
;
72 struct pvr2_sysfs_ctl_item
*item_next
;
73 struct attribute
*attr_gen
[8];
74 struct attribute_group grp
;
79 struct pvr2_sysfs_class
{
83 static ssize_t
show_name(struct device
*class_dev
,
84 struct device_attribute
*attr
,
87 struct pvr2_sysfs_ctl_item
*cip
;
89 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_name
);
90 name
= pvr2_ctrl_get_desc(cip
->cptr
);
91 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
92 cip
->chptr
, cip
->ctl_id
, name
);
93 if (!name
) return -EINVAL
;
94 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
97 static ssize_t
show_type(struct device
*class_dev
,
98 struct device_attribute
*attr
,
101 struct pvr2_sysfs_ctl_item
*cip
;
103 enum pvr2_ctl_type tp
;
104 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_type
);
105 tp
= pvr2_ctrl_get_type(cip
->cptr
);
107 case pvr2_ctl_int
: name
= "integer"; break;
108 case pvr2_ctl_enum
: name
= "enum"; break;
109 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
110 case pvr2_ctl_bool
: name
= "boolean"; break;
111 default: name
= "?"; break;
113 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
114 cip
->chptr
, cip
->ctl_id
, name
);
115 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
118 static ssize_t
show_min(struct device
*class_dev
,
119 struct device_attribute
*attr
,
122 struct pvr2_sysfs_ctl_item
*cip
;
124 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_min
);
125 val
= pvr2_ctrl_get_min(cip
->cptr
);
126 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
127 cip
->chptr
, cip
->ctl_id
, val
);
128 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
131 static ssize_t
show_max(struct device
*class_dev
,
132 struct device_attribute
*attr
,
135 struct pvr2_sysfs_ctl_item
*cip
;
137 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_max
);
138 val
= pvr2_ctrl_get_max(cip
->cptr
);
139 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
140 cip
->chptr
, cip
->ctl_id
, val
);
141 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
144 static ssize_t
show_def(struct device
*class_dev
,
145 struct device_attribute
*attr
,
148 struct pvr2_sysfs_ctl_item
*cip
;
151 unsigned int cnt
= 0;
152 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_def
);
153 ret
= pvr2_ctrl_get_def(cip
->cptr
, &val
);
154 if (ret
< 0) return ret
;
155 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
156 buf
, PAGE_SIZE
- 1, &cnt
);
157 pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
158 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
163 static ssize_t
show_val_norm(struct device
*class_dev
,
164 struct device_attribute
*attr
,
167 struct pvr2_sysfs_ctl_item
*cip
;
170 unsigned int cnt
= 0;
171 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
172 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
173 if (ret
< 0) return ret
;
174 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
175 buf
, PAGE_SIZE
- 1, &cnt
);
176 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
177 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
182 static ssize_t
show_val_custom(struct device
*class_dev
,
183 struct device_attribute
*attr
,
186 struct pvr2_sysfs_ctl_item
*cip
;
189 unsigned int cnt
= 0;
190 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
191 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
192 if (ret
< 0) return ret
;
193 ret
= pvr2_ctrl_custom_value_to_sym(cip
->cptr
, ~0, val
,
194 buf
, PAGE_SIZE
- 1, &cnt
);
195 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
196 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
201 static ssize_t
show_enum(struct device
*class_dev
,
202 struct device_attribute
*attr
,
205 struct pvr2_sysfs_ctl_item
*cip
;
207 unsigned int bcnt
, ccnt
, ecnt
;
208 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_enum
);
209 ecnt
= pvr2_ctrl_get_cnt(cip
->cptr
);
211 for (val
= 0; val
< ecnt
; val
++) {
212 pvr2_ctrl_get_valname(cip
->cptr
, val
, buf
+ bcnt
,
213 PAGE_SIZE
- bcnt
, &ccnt
);
216 if (bcnt
>= PAGE_SIZE
) break;
220 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
221 cip
->chptr
, cip
->ctl_id
);
225 static ssize_t
show_bits(struct device
*class_dev
,
226 struct device_attribute
*attr
,
229 struct pvr2_sysfs_ctl_item
*cip
;
231 unsigned int bcnt
, ccnt
;
232 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_bits
);
233 valid_bits
= pvr2_ctrl_get_mask(cip
->cptr
);
235 for (msk
= 1; valid_bits
; msk
<<= 1) {
236 if (!(msk
& valid_bits
)) continue;
238 pvr2_ctrl_get_valname(cip
->cptr
, msk
, buf
+ bcnt
,
239 PAGE_SIZE
- bcnt
, &ccnt
);
241 if (bcnt
>= PAGE_SIZE
) break;
245 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
246 cip
->chptr
, cip
->ctl_id
);
250 static int store_val_any(struct pvr2_sysfs_ctl_item
*cip
, int customfl
,
251 const char *buf
,unsigned int count
)
256 ret
= pvr2_ctrl_custom_sym_to_value(cip
->cptr
, buf
, count
,
259 ret
= pvr2_ctrl_sym_to_value(cip
->cptr
, buf
, count
,
262 if (ret
< 0) return ret
;
263 ret
= pvr2_ctrl_set_mask_value(cip
->cptr
, mask
, val
);
264 pvr2_hdw_commit_ctl(cip
->chptr
->channel
.hdw
);
268 static ssize_t
store_val_norm(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_val
);
275 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
276 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
277 ret
= store_val_any(cip
, 0, buf
, count
);
278 if (!ret
) ret
= count
;
282 static ssize_t
store_val_custom(struct device
*class_dev
,
283 struct device_attribute
*attr
,
284 const char *buf
, size_t count
)
286 struct pvr2_sysfs_ctl_item
*cip
;
288 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
289 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
290 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
291 ret
= store_val_any(cip
, 1, buf
, count
);
292 if (!ret
) ret
= count
;
296 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
298 struct pvr2_sysfs_ctl_item
*cip
;
299 struct pvr2_ctrl
*cptr
;
300 unsigned int cnt
,acnt
;
303 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
306 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
308 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
311 cip
->ctl_id
= ctl_id
;
314 cip
->item_next
= NULL
;
315 if (sfp
->item_last
) {
316 sfp
->item_last
->item_next
= cip
;
318 sfp
->item_first
= cip
;
320 sfp
->item_last
= cip
;
322 sysfs_attr_init(&cip
->attr_name
.attr
);
323 cip
->attr_name
.attr
.name
= "name";
324 cip
->attr_name
.attr
.mode
= S_IRUGO
;
325 cip
->attr_name
.show
= show_name
;
327 sysfs_attr_init(&cip
->attr_type
.attr
);
328 cip
->attr_type
.attr
.name
= "type";
329 cip
->attr_type
.attr
.mode
= S_IRUGO
;
330 cip
->attr_type
.show
= show_type
;
332 sysfs_attr_init(&cip
->attr_min
.attr
);
333 cip
->attr_min
.attr
.name
= "min_val";
334 cip
->attr_min
.attr
.mode
= S_IRUGO
;
335 cip
->attr_min
.show
= show_min
;
337 sysfs_attr_init(&cip
->attr_max
.attr
);
338 cip
->attr_max
.attr
.name
= "max_val";
339 cip
->attr_max
.attr
.mode
= S_IRUGO
;
340 cip
->attr_max
.show
= show_max
;
342 sysfs_attr_init(&cip
->attr_def
.attr
);
343 cip
->attr_def
.attr
.name
= "def_val";
344 cip
->attr_def
.attr
.mode
= S_IRUGO
;
345 cip
->attr_def
.show
= show_def
;
347 sysfs_attr_init(&cip
->attr_val
.attr
);
348 cip
->attr_val
.attr
.name
= "cur_val";
349 cip
->attr_val
.attr
.mode
= S_IRUGO
;
351 sysfs_attr_init(&cip
->attr_custom
.attr
);
352 cip
->attr_custom
.attr
.name
= "custom_val";
353 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
355 sysfs_attr_init(&cip
->attr_enum
.attr
);
356 cip
->attr_enum
.attr
.name
= "enum_val";
357 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
358 cip
->attr_enum
.show
= show_enum
;
360 sysfs_attr_init(&cip
->attr_bits
.attr
);
361 cip
->attr_bits
.attr
.name
= "bit_val";
362 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
363 cip
->attr_bits
.show
= show_bits
;
365 if (pvr2_ctrl_is_writable(cptr
)) {
366 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
367 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
371 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
372 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
373 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
374 cip
->attr_gen
[acnt
++] = &cip
->attr_def
.attr
;
375 cip
->attr_val
.show
= show_val_norm
;
376 cip
->attr_val
.store
= store_val_norm
;
377 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
378 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
379 cip
->attr_custom
.show
= show_val_custom
;
380 cip
->attr_custom
.store
= store_val_custom
;
382 switch (pvr2_ctrl_get_type(cptr
)) {
384 // Control is an enumeration
385 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
388 // Control is an integer
389 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
390 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
392 case pvr2_ctl_bitmask
:
393 // Control is an bitmask
394 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
399 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
400 pvr2_ctrl_get_name(cptr
));
402 cip
->grp
.name
= cip
->name
;
403 cip
->grp
.attrs
= cip
->attr_gen
;
405 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
407 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
408 "sysfs_create_group error: %d",
412 cip
->created_ok
= !0;
415 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
416 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
418 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
420 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
421 const char *, size_t count
);
423 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
425 struct pvr2_sysfs_debugifc
*dip
;
428 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
430 sysfs_attr_init(&dip
->attr_debugcmd
.attr
);
431 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
432 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
433 dip
->attr_debugcmd
.show
= debugcmd_show
;
434 dip
->attr_debugcmd
.store
= debugcmd_store
;
435 sysfs_attr_init(&dip
->attr_debuginfo
.attr
);
436 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
437 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
438 dip
->attr_debuginfo
.show
= debuginfo_show
;
440 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
442 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
443 "device_create_file error: %d",
446 dip
->debugcmd_created_ok
= !0;
448 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
450 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
451 "device_create_file error: %d",
454 dip
->debuginfo_created_ok
= !0;
459 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
461 if (!sfp
->debugifc
) return;
462 if (sfp
->debugifc
->debuginfo_created_ok
) {
463 device_remove_file(sfp
->class_dev
,
464 &sfp
->debugifc
->attr_debuginfo
);
466 if (sfp
->debugifc
->debugcmd_created_ok
) {
467 device_remove_file(sfp
->class_dev
,
468 &sfp
->debugifc
->attr_debugcmd
);
470 kfree(sfp
->debugifc
);
471 sfp
->debugifc
= NULL
;
473 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
476 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
478 unsigned int idx
,cnt
;
479 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
480 for (idx
= 0; idx
< cnt
; idx
++) {
481 pvr2_sysfs_add_control(sfp
,idx
);
486 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
488 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
489 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
490 cip2
= cip1
->item_next
;
491 if (cip1
->created_ok
) {
492 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
494 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
500 static void pvr2_sysfs_class_release(struct class *class)
502 struct pvr2_sysfs_class
*clp
;
503 clp
= container_of(class,struct pvr2_sysfs_class
,class);
504 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
509 static void pvr2_sysfs_release(struct device
*class_dev
)
511 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
516 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
519 if (!sfp
->class_dev
) return;
520 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
521 pvr2_sysfs_tear_down_debugifc(sfp
);
522 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
523 pvr2_sysfs_tear_down_controls(sfp
);
524 if (sfp
->hdw_desc_created_ok
) {
525 device_remove_file(sfp
->class_dev
,
526 &sfp
->attr_hdw_desc
);
528 if (sfp
->hdw_name_created_ok
) {
529 device_remove_file(sfp
->class_dev
,
530 &sfp
->attr_hdw_name
);
532 if (sfp
->bus_info_created_ok
) {
533 device_remove_file(sfp
->class_dev
,
534 &sfp
->attr_bus_info
);
536 if (sfp
->v4l_minor_number_created_ok
) {
537 device_remove_file(sfp
->class_dev
,
538 &sfp
->attr_v4l_minor_number
);
540 if (sfp
->v4l_radio_minor_number_created_ok
) {
541 device_remove_file(sfp
->class_dev
,
542 &sfp
->attr_v4l_radio_minor_number
);
544 if (sfp
->unit_number_created_ok
) {
545 device_remove_file(sfp
->class_dev
,
546 &sfp
->attr_unit_number
);
548 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
549 dev_set_drvdata(sfp
->class_dev
, NULL
);
550 dev
= sfp
->class_dev
->parent
;
551 sfp
->class_dev
->parent
= NULL
;
553 device_unregister(sfp
->class_dev
);
554 sfp
->class_dev
= NULL
;
558 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
559 struct device_attribute
*attr
, char *buf
)
561 struct pvr2_sysfs
*sfp
;
562 sfp
= dev_get_drvdata(class_dev
);
563 if (!sfp
) return -EINVAL
;
564 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
565 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
566 pvr2_v4l_type_video
));
570 static ssize_t
bus_info_show(struct device
*class_dev
,
571 struct device_attribute
*attr
, char *buf
)
573 struct pvr2_sysfs
*sfp
;
574 sfp
= dev_get_drvdata(class_dev
);
575 if (!sfp
) return -EINVAL
;
576 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
577 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
581 static ssize_t
hdw_name_show(struct device
*class_dev
,
582 struct device_attribute
*attr
, char *buf
)
584 struct pvr2_sysfs
*sfp
;
585 sfp
= dev_get_drvdata(class_dev
);
586 if (!sfp
) return -EINVAL
;
587 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
588 pvr2_hdw_get_type(sfp
->channel
.hdw
));
592 static ssize_t
hdw_desc_show(struct device
*class_dev
,
593 struct device_attribute
*attr
, char *buf
)
595 struct pvr2_sysfs
*sfp
;
596 sfp
= dev_get_drvdata(class_dev
);
597 if (!sfp
) return -EINVAL
;
598 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
599 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
603 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
604 struct device_attribute
*attr
,
607 struct pvr2_sysfs
*sfp
;
608 sfp
= dev_get_drvdata(class_dev
);
609 if (!sfp
) return -EINVAL
;
610 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
611 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
612 pvr2_v4l_type_radio
));
616 static ssize_t
unit_number_show(struct device
*class_dev
,
617 struct device_attribute
*attr
, char *buf
)
619 struct pvr2_sysfs
*sfp
;
620 sfp
= dev_get_drvdata(class_dev
);
621 if (!sfp
) return -EINVAL
;
622 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
623 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
627 static void class_dev_create(struct pvr2_sysfs
*sfp
,
628 struct pvr2_sysfs_class
*class_ptr
)
630 struct usb_device
*usb_dev
;
631 struct device
*class_dev
;
634 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
635 if (!usb_dev
) return;
636 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
637 if (!class_dev
) return;
639 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
641 class_dev
->class = &class_ptr
->class;
643 dev_set_name(class_dev
, "%s",
644 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
646 class_dev
->parent
= get_device(&usb_dev
->dev
);
648 sfp
->class_dev
= class_dev
;
649 dev_set_drvdata(class_dev
, sfp
);
650 ret
= device_register(class_dev
);
652 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
653 "device_register failed");
654 put_device(class_dev
);
658 sysfs_attr_init(&sfp
->attr_v4l_minor_number
.attr
);
659 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
660 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
661 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
662 sfp
->attr_v4l_minor_number
.store
= NULL
;
663 ret
= device_create_file(sfp
->class_dev
,
664 &sfp
->attr_v4l_minor_number
);
666 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
667 "device_create_file error: %d",
670 sfp
->v4l_minor_number_created_ok
= !0;
673 sysfs_attr_init(&sfp
->attr_v4l_radio_minor_number
.attr
);
674 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
675 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
676 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
677 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
678 ret
= device_create_file(sfp
->class_dev
,
679 &sfp
->attr_v4l_radio_minor_number
);
681 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
682 "device_create_file error: %d",
685 sfp
->v4l_radio_minor_number_created_ok
= !0;
688 sysfs_attr_init(&sfp
->attr_unit_number
.attr
);
689 sfp
->attr_unit_number
.attr
.name
= "unit_number";
690 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
691 sfp
->attr_unit_number
.show
= unit_number_show
;
692 sfp
->attr_unit_number
.store
= NULL
;
693 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
695 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
696 "device_create_file error: %d",
699 sfp
->unit_number_created_ok
= !0;
702 sysfs_attr_init(&sfp
->attr_bus_info
.attr
);
703 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
704 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
705 sfp
->attr_bus_info
.show
= bus_info_show
;
706 sfp
->attr_bus_info
.store
= NULL
;
707 ret
= device_create_file(sfp
->class_dev
,
708 &sfp
->attr_bus_info
);
710 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
711 "device_create_file error: %d",
714 sfp
->bus_info_created_ok
= !0;
717 sysfs_attr_init(&sfp
->attr_hdw_name
.attr
);
718 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
719 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
720 sfp
->attr_hdw_name
.show
= hdw_name_show
;
721 sfp
->attr_hdw_name
.store
= NULL
;
722 ret
= device_create_file(sfp
->class_dev
,
723 &sfp
->attr_hdw_name
);
725 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
726 "device_create_file error: %d",
729 sfp
->hdw_name_created_ok
= !0;
732 sysfs_attr_init(&sfp
->attr_hdw_desc
.attr
);
733 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
734 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
735 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
736 sfp
->attr_hdw_desc
.store
= NULL
;
737 ret
= device_create_file(sfp
->class_dev
,
738 &sfp
->attr_hdw_desc
);
740 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
741 "device_create_file error: %d",
744 sfp
->hdw_desc_created_ok
= !0;
747 pvr2_sysfs_add_controls(sfp
);
748 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
749 pvr2_sysfs_add_debugifc(sfp
);
750 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
754 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
756 struct pvr2_sysfs
*sfp
;
757 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
758 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
759 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
760 class_dev_destroy(sfp
);
761 pvr2_channel_done(&sfp
->channel
);
766 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
767 struct pvr2_sysfs_class
*class_ptr
)
769 struct pvr2_sysfs
*sfp
;
770 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
771 if (!sfp
) return sfp
;
772 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
773 pvr2_channel_init(&sfp
->channel
,mp
);
774 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
776 class_dev_create(sfp
,class_ptr
);
782 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
784 struct pvr2_sysfs_class
*clp
;
785 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
786 if (!clp
) return clp
;
787 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
789 clp
->class.name
= "pvrusb2";
790 clp
->class.class_release
= pvr2_sysfs_class_release
;
791 clp
->class.dev_release
= pvr2_sysfs_release
;
792 if (class_register(&clp
->class)) {
794 "Registration failed for pvr2_sysfs_class id=%p",clp
);
802 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
804 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp
);
805 class_unregister(&clp
->class);
809 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
810 static ssize_t
debuginfo_show(struct device
*class_dev
,
811 struct device_attribute
*attr
, char *buf
)
813 struct pvr2_sysfs
*sfp
;
814 sfp
= dev_get_drvdata(class_dev
);
815 if (!sfp
) return -EINVAL
;
816 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
817 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
821 static ssize_t
debugcmd_show(struct device
*class_dev
,
822 struct device_attribute
*attr
, char *buf
)
824 struct pvr2_sysfs
*sfp
;
825 sfp
= dev_get_drvdata(class_dev
);
826 if (!sfp
) return -EINVAL
;
827 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
831 static ssize_t
debugcmd_store(struct device
*class_dev
,
832 struct device_attribute
*attr
,
833 const char *buf
, size_t count
)
835 struct pvr2_sysfs
*sfp
;
838 sfp
= dev_get_drvdata(class_dev
);
839 if (!sfp
) return -EINVAL
;
841 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
842 if (ret
< 0) return ret
;
845 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */