5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/string.h>
23 #include <linux/slab.h>
24 #include <asm/semaphore.h>
25 #include "pvrusb2-sysfs.h"
26 #include "pvrusb2-hdw.h"
27 #include "pvrusb2-debug.h"
28 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
29 #include "pvrusb2-debugifc.h"
30 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
32 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
35 struct pvr2_channel channel
;
36 struct class_device
*class_dev
;
37 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
38 struct pvr2_sysfs_debugifc
*debugifc
;
39 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
40 struct pvr2_sysfs_ctl_item
*item_first
;
41 struct pvr2_sysfs_ctl_item
*item_last
;
42 struct class_device_attribute attr_v4l_minor_number
;
43 struct class_device_attribute attr_v4l_radio_minor_number
;
44 struct class_device_attribute attr_unit_number
;
45 struct class_device_attribute attr_bus_info
;
46 int v4l_minor_number_created_ok
;
47 int v4l_radio_minor_number_created_ok
;
48 int unit_number_created_ok
;
49 int bus_info_created_ok
;
52 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
53 struct pvr2_sysfs_debugifc
{
54 struct class_device_attribute attr_debugcmd
;
55 struct class_device_attribute attr_debuginfo
;
56 int debugcmd_created_ok
;
57 int debuginfo_created_ok
;
59 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
61 struct pvr2_sysfs_ctl_item
{
62 struct class_device_attribute attr_name
;
63 struct class_device_attribute attr_type
;
64 struct class_device_attribute attr_min
;
65 struct class_device_attribute attr_max
;
66 struct class_device_attribute attr_enum
;
67 struct class_device_attribute attr_bits
;
68 struct class_device_attribute attr_val
;
69 struct class_device_attribute attr_custom
;
70 struct pvr2_ctrl
*cptr
;
71 struct pvr2_sysfs
*chptr
;
72 struct pvr2_sysfs_ctl_item
*item_next
;
73 struct attribute
*attr_gen
[7];
74 struct attribute_group grp
;
79 struct pvr2_sysfs_class
{
83 static ssize_t
show_name(int id
,struct class_device
*class_dev
,char *buf
)
85 struct pvr2_ctrl
*cptr
;
86 struct pvr2_sysfs
*sfp
;
89 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
90 if (!sfp
) return -EINVAL
;
91 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
92 if (!cptr
) return -EINVAL
;
94 name
= pvr2_ctrl_get_desc(cptr
);
95 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp
,id
,name
);
97 if (!name
) return -EINVAL
;
99 return scnprintf(buf
,PAGE_SIZE
,"%s\n",name
);
102 static ssize_t
show_type(int id
,struct class_device
*class_dev
,char *buf
)
104 struct pvr2_ctrl
*cptr
;
105 struct pvr2_sysfs
*sfp
;
107 enum pvr2_ctl_type tp
;
109 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
110 if (!sfp
) return -EINVAL
;
111 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
112 if (!cptr
) return -EINVAL
;
114 tp
= pvr2_ctrl_get_type(cptr
);
116 case pvr2_ctl_int
: name
= "integer"; break;
117 case pvr2_ctl_enum
: name
= "enum"; break;
118 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
119 case pvr2_ctl_bool
: name
= "boolean"; break;
120 default: name
= "?"; break;
122 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp
,id
,name
);
124 if (!name
) return -EINVAL
;
126 return scnprintf(buf
,PAGE_SIZE
,"%s\n",name
);
129 static ssize_t
show_min(int id
,struct class_device
*class_dev
,char *buf
)
131 struct pvr2_ctrl
*cptr
;
132 struct pvr2_sysfs
*sfp
;
135 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
136 if (!sfp
) return -EINVAL
;
137 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
138 if (!cptr
) return -EINVAL
;
139 val
= pvr2_ctrl_get_min(cptr
);
141 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp
,id
,val
);
143 return scnprintf(buf
,PAGE_SIZE
,"%ld\n",val
);
146 static ssize_t
show_max(int id
,struct class_device
*class_dev
,char *buf
)
148 struct pvr2_ctrl
*cptr
;
149 struct pvr2_sysfs
*sfp
;
152 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
153 if (!sfp
) return -EINVAL
;
154 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
155 if (!cptr
) return -EINVAL
;
156 val
= pvr2_ctrl_get_max(cptr
);
158 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp
,id
,val
);
160 return scnprintf(buf
,PAGE_SIZE
,"%ld\n",val
);
163 static ssize_t
show_val_norm(int id
,struct class_device
*class_dev
,char *buf
)
165 struct pvr2_ctrl
*cptr
;
166 struct pvr2_sysfs
*sfp
;
168 unsigned int cnt
= 0;
170 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
171 if (!sfp
) return -EINVAL
;
172 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
173 if (!cptr
) return -EINVAL
;
175 ret
= pvr2_ctrl_get_value(cptr
,&val
);
176 if (ret
< 0) return ret
;
178 ret
= pvr2_ctrl_value_to_sym(cptr
,~0,val
,
179 buf
,PAGE_SIZE
-1,&cnt
);
181 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
187 static ssize_t
show_val_custom(int id
,struct class_device
*class_dev
,char *buf
)
189 struct pvr2_ctrl
*cptr
;
190 struct pvr2_sysfs
*sfp
;
192 unsigned int cnt
= 0;
194 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
195 if (!sfp
) return -EINVAL
;
196 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
197 if (!cptr
) return -EINVAL
;
199 ret
= pvr2_ctrl_get_value(cptr
,&val
);
200 if (ret
< 0) return ret
;
202 ret
= pvr2_ctrl_custom_value_to_sym(cptr
,~0,val
,
203 buf
,PAGE_SIZE
-1,&cnt
);
205 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
211 static ssize_t
show_enum(int id
,struct class_device
*class_dev
,char *buf
)
213 struct pvr2_ctrl
*cptr
;
214 struct pvr2_sysfs
*sfp
;
216 unsigned int bcnt
,ccnt
,ecnt
;
218 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
219 if (!sfp
) return -EINVAL
;
220 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
221 if (!cptr
) return -EINVAL
;
222 ecnt
= pvr2_ctrl_get_cnt(cptr
);
224 for (val
= 0; val
< ecnt
; val
++) {
225 pvr2_ctrl_get_valname(cptr
,val
,buf
+bcnt
,PAGE_SIZE
-bcnt
,&ccnt
);
228 if (bcnt
>= PAGE_SIZE
) break;
232 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp
,id
);
236 static ssize_t
show_bits(int id
,struct class_device
*class_dev
,char *buf
)
238 struct pvr2_ctrl
*cptr
;
239 struct pvr2_sysfs
*sfp
;
241 unsigned int bcnt
,ccnt
;
243 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
244 if (!sfp
) return -EINVAL
;
245 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
246 if (!cptr
) return -EINVAL
;
247 valid_bits
= pvr2_ctrl_get_mask(cptr
);
249 for (msk
= 1; valid_bits
; msk
<<= 1) {
250 if (!(msk
& valid_bits
)) continue;
252 pvr2_ctrl_get_valname(cptr
,msk
,buf
+bcnt
,PAGE_SIZE
-bcnt
,&ccnt
);
254 if (bcnt
>= PAGE_SIZE
) break;
258 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp
,id
);
262 static int store_val_any(int id
,int customfl
,struct pvr2_sysfs
*sfp
,
263 const char *buf
,unsigned int count
)
265 struct pvr2_ctrl
*cptr
;
269 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
271 ret
= pvr2_ctrl_custom_sym_to_value(cptr
,buf
,count
,&mask
,&val
);
273 ret
= pvr2_ctrl_sym_to_value(cptr
,buf
,count
,&mask
,&val
);
275 if (ret
< 0) return ret
;
276 ret
= pvr2_ctrl_set_mask_value(cptr
,mask
,val
);
277 pvr2_hdw_commit_ctl(sfp
->channel
.hdw
);
281 static ssize_t
store_val_norm(int id
,struct class_device
*class_dev
,
282 const char *buf
,size_t count
)
284 struct pvr2_sysfs
*sfp
;
286 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
287 ret
= store_val_any(id
,0,sfp
,buf
,count
);
288 if (!ret
) ret
= count
;
292 static ssize_t
store_val_custom(int id
,struct class_device
*class_dev
,
293 const char *buf
,size_t count
)
295 struct pvr2_sysfs
*sfp
;
297 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
298 ret
= store_val_any(id
,1,sfp
,buf
,count
);
299 if (!ret
) ret
= count
;
304 Mike Isely <isely@pobox.com> 30-April-2005
306 This next batch of horrible preprocessor hackery is needed because the
307 kernel's class_device_attribute mechanism fails to pass the actual
308 attribute through to the show / store functions, which means we have no
309 way to package up any attribute-specific parameters, like for example the
310 control id. So we work around this brain-damage by encoding the control
311 id into the show / store functions themselves and pick the function based
312 on the control id we're setting up. These macros try to ease the pain.
316 #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
317 static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \
318 { return sf_name(ctl_id,class_dev,buf); }
320 #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
321 static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \
322 { return sf_name(ctl_id,class_dev,buf,count); }
324 #define CREATE_BATCH(ctl_id) \
325 CREATE_SHOW_INSTANCE(show_name,ctl_id) \
326 CREATE_SHOW_INSTANCE(show_type,ctl_id) \
327 CREATE_SHOW_INSTANCE(show_min,ctl_id) \
328 CREATE_SHOW_INSTANCE(show_max,ctl_id) \
329 CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
330 CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
331 CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
332 CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
333 CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
334 CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
397 struct pvr2_sysfs_func_set
{
398 ssize_t (*show_name
)(struct class_device
*,char *);
399 ssize_t (*show_type
)(struct class_device
*,char *);
400 ssize_t (*show_min
)(struct class_device
*,char *);
401 ssize_t (*show_max
)(struct class_device
*,char *);
402 ssize_t (*show_enum
)(struct class_device
*,char *);
403 ssize_t (*show_bits
)(struct class_device
*,char *);
404 ssize_t (*show_val_norm
)(struct class_device
*,char *);
405 ssize_t (*store_val_norm
)(struct class_device
*,
406 const char *,size_t);
407 ssize_t (*show_val_custom
)(struct class_device
*,char *);
408 ssize_t (*store_val_custom
)(struct class_device
*,
409 const char *,size_t);
412 #define INIT_BATCH(ctl_id) \
414 .show_name = show_name_##ctl_id, \
415 .show_type = show_type_##ctl_id, \
416 .show_min = show_min_##ctl_id, \
417 .show_max = show_max_##ctl_id, \
418 .show_enum = show_enum_##ctl_id, \
419 .show_bits = show_bits_##ctl_id, \
420 .show_val_norm = show_val_norm_##ctl_id, \
421 .store_val_norm = store_val_norm_##ctl_id, \
422 .show_val_custom = show_val_custom_##ctl_id, \
423 .store_val_custom = store_val_custom_##ctl_id, \
426 static struct pvr2_sysfs_func_set funcs[] = {
490 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
492 struct pvr2_sysfs_ctl_item
*cip
;
493 struct pvr2_sysfs_func_set
*fp
;
494 struct pvr2_ctrl
*cptr
;
495 unsigned int cnt
,acnt
;
498 if ((ctl_id
< 0) || (ctl_id
>= ARRAY_SIZE(funcs
))) {
503 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
506 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
508 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
513 cip
->item_next
= NULL
;
514 if (sfp
->item_last
) {
515 sfp
->item_last
->item_next
= cip
;
517 sfp
->item_first
= cip
;
519 sfp
->item_last
= cip
;
521 cip
->attr_name
.attr
.owner
= THIS_MODULE
;
522 cip
->attr_name
.attr
.name
= "name";
523 cip
->attr_name
.attr
.mode
= S_IRUGO
;
524 cip
->attr_name
.show
= fp
->show_name
;
526 cip
->attr_type
.attr
.owner
= THIS_MODULE
;
527 cip
->attr_type
.attr
.name
= "type";
528 cip
->attr_type
.attr
.mode
= S_IRUGO
;
529 cip
->attr_type
.show
= fp
->show_type
;
531 cip
->attr_min
.attr
.owner
= THIS_MODULE
;
532 cip
->attr_min
.attr
.name
= "min_val";
533 cip
->attr_min
.attr
.mode
= S_IRUGO
;
534 cip
->attr_min
.show
= fp
->show_min
;
536 cip
->attr_max
.attr
.owner
= THIS_MODULE
;
537 cip
->attr_max
.attr
.name
= "max_val";
538 cip
->attr_max
.attr
.mode
= S_IRUGO
;
539 cip
->attr_max
.show
= fp
->show_max
;
541 cip
->attr_val
.attr
.owner
= THIS_MODULE
;
542 cip
->attr_val
.attr
.name
= "cur_val";
543 cip
->attr_val
.attr
.mode
= S_IRUGO
;
545 cip
->attr_custom
.attr
.owner
= THIS_MODULE
;
546 cip
->attr_custom
.attr
.name
= "custom_val";
547 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
549 cip
->attr_enum
.attr
.owner
= THIS_MODULE
;
550 cip
->attr_enum
.attr
.name
= "enum_val";
551 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
552 cip
->attr_enum
.show
= fp
->show_enum
;
554 cip
->attr_bits
.attr
.owner
= THIS_MODULE
;
555 cip
->attr_bits
.attr
.name
= "bit_val";
556 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
557 cip
->attr_bits
.show
= fp
->show_bits
;
559 if (pvr2_ctrl_is_writable(cptr
)) {
560 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
561 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
565 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
566 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
567 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
568 cip
->attr_val
.show
= fp
->show_val_norm
;
569 cip
->attr_val
.store
= fp
->store_val_norm
;
570 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
571 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
572 cip
->attr_custom
.show
= fp
->show_val_custom
;
573 cip
->attr_custom
.store
= fp
->store_val_custom
;
575 switch (pvr2_ctrl_get_type(cptr
)) {
577 // Control is an enumeration
578 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
581 // Control is an integer
582 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
583 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
585 case pvr2_ctl_bitmask
:
586 // Control is an bitmask
587 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
592 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
593 pvr2_ctrl_get_name(cptr
));
595 cip
->grp
.name
= cip
->name
;
596 cip
->grp
.attrs
= cip
->attr_gen
;
598 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
600 printk(KERN_WARNING
"%s: sysfs_create_group error: %d\n",
604 cip
->created_ok
= !0;
607 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
608 static ssize_t
debuginfo_show(struct class_device
*,char *);
609 static ssize_t
debugcmd_show(struct class_device
*,char *);
610 static ssize_t
debugcmd_store(struct class_device
*,const char *,size_t count
);
612 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
614 struct pvr2_sysfs_debugifc
*dip
;
617 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
619 dip
->attr_debugcmd
.attr
.owner
= THIS_MODULE
;
620 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
621 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
622 dip
->attr_debugcmd
.show
= debugcmd_show
;
623 dip
->attr_debugcmd
.store
= debugcmd_store
;
624 dip
->attr_debuginfo
.attr
.owner
= THIS_MODULE
;
625 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
626 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
627 dip
->attr_debuginfo
.show
= debuginfo_show
;
629 ret
= class_device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
631 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
634 dip
->debugcmd_created_ok
= !0;
636 ret
= class_device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
638 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
641 dip
->debuginfo_created_ok
= !0;
646 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
648 if (!sfp
->debugifc
) return;
649 if (sfp
->debugifc
->debuginfo_created_ok
) {
650 class_device_remove_file(sfp
->class_dev
,
651 &sfp
->debugifc
->attr_debuginfo
);
653 if (sfp
->debugifc
->debugcmd_created_ok
) {
654 class_device_remove_file(sfp
->class_dev
,
655 &sfp
->debugifc
->attr_debugcmd
);
657 kfree(sfp
->debugifc
);
658 sfp
->debugifc
= NULL
;
660 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
663 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
665 unsigned int idx
,cnt
;
666 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
667 for (idx
= 0; idx
< cnt
; idx
++) {
668 pvr2_sysfs_add_control(sfp
,idx
);
673 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
675 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
676 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
677 cip2
= cip1
->item_next
;
678 if (cip1
->created_ok
) {
679 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
681 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
687 static void pvr2_sysfs_class_release(struct class *class)
689 struct pvr2_sysfs_class
*clp
;
690 clp
= container_of(class,struct pvr2_sysfs_class
,class);
691 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
696 static void pvr2_sysfs_release(struct class_device
*class_dev
)
698 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
703 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
705 if (!sfp
->class_dev
) return;
706 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
707 pvr2_sysfs_tear_down_debugifc(sfp
);
708 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
709 pvr2_sysfs_tear_down_controls(sfp
);
710 if (sfp
->bus_info_created_ok
) {
711 class_device_remove_file(sfp
->class_dev
,
712 &sfp
->attr_bus_info
);
714 if (sfp
->v4l_minor_number_created_ok
) {
715 class_device_remove_file(sfp
->class_dev
,
716 &sfp
->attr_v4l_minor_number
);
718 if (sfp
->v4l_radio_minor_number_created_ok
) {
719 class_device_remove_file(sfp
->class_dev
,
720 &sfp
->attr_v4l_radio_minor_number
);
722 if (sfp
->unit_number_created_ok
) {
723 class_device_remove_file(sfp
->class_dev
,
724 &sfp
->attr_unit_number
);
726 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
727 sfp
->class_dev
->class_data
= NULL
;
728 class_device_unregister(sfp
->class_dev
);
729 sfp
->class_dev
= NULL
;
733 static ssize_t
v4l_minor_number_show(struct class_device
*class_dev
,char *buf
)
735 struct pvr2_sysfs
*sfp
;
736 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
737 if (!sfp
) return -EINVAL
;
738 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
739 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
740 pvr2_v4l_type_video
));
744 static ssize_t
bus_info_show(struct class_device
*class_dev
,char *buf
)
746 struct pvr2_sysfs
*sfp
;
747 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
748 if (!sfp
) return -EINVAL
;
749 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
750 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
754 static ssize_t
v4l_radio_minor_number_show(struct class_device
*class_dev
,
757 struct pvr2_sysfs
*sfp
;
758 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
759 if (!sfp
) return -EINVAL
;
760 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
761 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
762 pvr2_v4l_type_radio
));
766 static ssize_t
unit_number_show(struct class_device
*class_dev
,char *buf
)
768 struct pvr2_sysfs
*sfp
;
769 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
770 if (!sfp
) return -EINVAL
;
771 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
772 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
776 static void class_dev_create(struct pvr2_sysfs
*sfp
,
777 struct pvr2_sysfs_class
*class_ptr
)
779 struct usb_device
*usb_dev
;
780 struct class_device
*class_dev
;
783 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
784 if (!usb_dev
) return;
785 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
786 if (!class_dev
) return;
788 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
790 class_dev
->class = &class_ptr
->class;
791 if (pvr2_hdw_get_sn(sfp
->channel
.hdw
)) {
792 snprintf(class_dev
->class_id
,BUS_ID_SIZE
,"sn-%lu",
793 pvr2_hdw_get_sn(sfp
->channel
.hdw
));
794 } else if (pvr2_hdw_get_unit_number(sfp
->channel
.hdw
) >= 0) {
795 snprintf(class_dev
->class_id
,BUS_ID_SIZE
,"unit-%c",
796 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
) + 'a');
802 class_dev
->dev
= &usb_dev
->dev
;
804 sfp
->class_dev
= class_dev
;
805 class_dev
->class_data
= sfp
;
806 ret
= class_device_register(class_dev
);
808 printk(KERN_ERR
"%s: class_device_register failed\n",
814 sfp
->attr_v4l_minor_number
.attr
.owner
= THIS_MODULE
;
815 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
816 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
817 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
818 sfp
->attr_v4l_minor_number
.store
= NULL
;
819 ret
= class_device_create_file(sfp
->class_dev
,
820 &sfp
->attr_v4l_minor_number
);
822 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
825 sfp
->v4l_minor_number_created_ok
= !0;
828 sfp
->attr_v4l_radio_minor_number
.attr
.owner
= THIS_MODULE
;
829 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
830 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
831 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
832 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
833 ret
= class_device_create_file(sfp
->class_dev
,
834 &sfp
->attr_v4l_radio_minor_number
);
836 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
839 sfp
->v4l_radio_minor_number_created_ok
= !0;
842 sfp
->attr_unit_number
.attr
.owner
= THIS_MODULE
;
843 sfp
->attr_unit_number
.attr
.name
= "unit_number";
844 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
845 sfp
->attr_unit_number
.show
= unit_number_show
;
846 sfp
->attr_unit_number
.store
= NULL
;
847 ret
= class_device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
849 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
852 sfp
->unit_number_created_ok
= !0;
855 sfp
->attr_bus_info
.attr
.owner
= THIS_MODULE
;
856 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
857 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
858 sfp
->attr_bus_info
.show
= bus_info_show
;
859 sfp
->attr_bus_info
.store
= NULL
;
860 ret
= class_device_create_file(sfp
->class_dev
,
861 &sfp
->attr_bus_info
);
863 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
866 sfp
->bus_info_created_ok
= !0;
869 pvr2_sysfs_add_controls(sfp
);
870 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
871 pvr2_sysfs_add_debugifc(sfp
);
872 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
876 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
878 struct pvr2_sysfs
*sfp
;
879 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
880 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
881 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
882 class_dev_destroy(sfp
);
883 pvr2_channel_done(&sfp
->channel
);
888 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
889 struct pvr2_sysfs_class
*class_ptr
)
891 struct pvr2_sysfs
*sfp
;
892 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
893 if (!sfp
) return sfp
;
894 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
895 pvr2_channel_init(&sfp
->channel
,mp
);
896 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
898 class_dev_create(sfp
,class_ptr
);
903 static int pvr2_sysfs_hotplug(struct class_device
*cd
,char **envp
,
904 int numenvp
,char *buf
,int size
)
906 /* Even though we don't do anything here, we still need this function
907 because sysfs will still try to call it. */
911 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
913 struct pvr2_sysfs_class
*clp
;
914 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
915 if (!clp
) return clp
;
916 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp
);
917 clp
->class.name
= "pvrusb2";
918 clp
->class.class_release
= pvr2_sysfs_class_release
;
919 clp
->class.release
= pvr2_sysfs_release
;
920 clp
->class.uevent
= pvr2_sysfs_hotplug
;
921 if (class_register(&clp
->class)) {
923 "Registration failed for pvr2_sysfs_class id=%p",clp
);
931 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
933 class_unregister(&clp
->class);
937 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
938 static ssize_t
debuginfo_show(struct class_device
*class_dev
,char *buf
)
940 struct pvr2_sysfs
*sfp
;
941 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
942 if (!sfp
) return -EINVAL
;
943 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
944 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
948 static ssize_t
debugcmd_show(struct class_device
*class_dev
,char *buf
)
950 struct pvr2_sysfs
*sfp
;
951 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
952 if (!sfp
) return -EINVAL
;
953 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
957 static ssize_t
debugcmd_store(struct class_device
*class_dev
,
958 const char *buf
,size_t count
)
960 struct pvr2_sysfs
*sfp
;
963 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
964 if (!sfp
) return -EINVAL
;
966 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
967 if (ret
< 0) return ret
;
970 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
974 Stuff for Emacs to see, in order to encourage consistent editing style:
975 *** Local Variables: ***
977 *** fill-column: 75 ***
979 *** c-basic-offset: 8 ***