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/config.h>
23 #include <linux/string.h>
24 #include <linux/slab.h>
25 #include <asm/semaphore.h>
26 #include "pvrusb2-sysfs.h"
27 #include "pvrusb2-hdw.h"
28 #include "pvrusb2-debug.h"
29 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
30 #include "pvrusb2-debugifc.h"
31 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
33 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
36 struct pvr2_channel channel
;
37 struct class_device
*class_dev
;
38 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
39 struct pvr2_sysfs_debugifc
*debugifc
;
40 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
41 struct pvr2_sysfs_ctl_item
*item_first
;
42 struct pvr2_sysfs_ctl_item
*item_last
;
43 struct sysfs_ops kops
;
44 struct kobj_type ktype
;
45 struct class_device_attribute attr_v4l_minor_number
;
46 struct class_device_attribute attr_unit_number
;
49 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
50 struct pvr2_sysfs_debugifc
{
51 struct class_device_attribute attr_debugcmd
;
52 struct class_device_attribute attr_debuginfo
;
54 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
56 struct pvr2_sysfs_ctl_item
{
57 struct class_device_attribute attr_name
;
58 struct class_device_attribute attr_type
;
59 struct class_device_attribute attr_min
;
60 struct class_device_attribute attr_max
;
61 struct class_device_attribute attr_enum
;
62 struct class_device_attribute attr_bits
;
63 struct class_device_attribute attr_val
;
64 struct class_device_attribute attr_custom
;
65 struct pvr2_ctrl
*cptr
;
66 struct pvr2_sysfs
*chptr
;
67 struct pvr2_sysfs_ctl_item
*item_next
;
68 struct attribute
*attr_gen
[7];
69 struct attribute_group grp
;
73 struct pvr2_sysfs_class
{
77 static ssize_t
show_name(int id
,struct class_device
*class_dev
,char *buf
)
79 struct pvr2_ctrl
*cptr
;
80 struct pvr2_sysfs
*sfp
;
83 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
84 if (!sfp
) return -EINVAL
;
85 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
86 if (!cptr
) return -EINVAL
;
88 name
= pvr2_ctrl_get_desc(cptr
);
89 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp
,id
,name
);
91 if (!name
) return -EINVAL
;
93 return scnprintf(buf
,PAGE_SIZE
,"%s\n",name
);
96 static ssize_t
show_type(int id
,struct class_device
*class_dev
,char *buf
)
98 struct pvr2_ctrl
*cptr
;
99 struct pvr2_sysfs
*sfp
;
101 enum pvr2_ctl_type tp
;
103 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
104 if (!sfp
) return -EINVAL
;
105 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
106 if (!cptr
) return -EINVAL
;
108 tp
= pvr2_ctrl_get_type(cptr
);
110 case pvr2_ctl_int
: name
= "integer"; break;
111 case pvr2_ctl_enum
: name
= "enum"; break;
112 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
113 case pvr2_ctl_bool
: name
= "boolean"; break;
114 default: name
= "?"; break;
116 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp
,id
,name
);
118 if (!name
) return -EINVAL
;
120 return scnprintf(buf
,PAGE_SIZE
,"%s\n",name
);
123 static ssize_t
show_min(int id
,struct class_device
*class_dev
,char *buf
)
125 struct pvr2_ctrl
*cptr
;
126 struct pvr2_sysfs
*sfp
;
129 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
130 if (!sfp
) return -EINVAL
;
131 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
132 if (!cptr
) return -EINVAL
;
133 val
= pvr2_ctrl_get_min(cptr
);
135 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp
,id
,val
);
137 return scnprintf(buf
,PAGE_SIZE
,"%ld\n",val
);
140 static ssize_t
show_max(int id
,struct class_device
*class_dev
,char *buf
)
142 struct pvr2_ctrl
*cptr
;
143 struct pvr2_sysfs
*sfp
;
146 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
147 if (!sfp
) return -EINVAL
;
148 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
149 if (!cptr
) return -EINVAL
;
150 val
= pvr2_ctrl_get_max(cptr
);
152 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp
,id
,val
);
154 return scnprintf(buf
,PAGE_SIZE
,"%ld\n",val
);
157 static ssize_t
show_val_norm(int id
,struct class_device
*class_dev
,char *buf
)
159 struct pvr2_ctrl
*cptr
;
160 struct pvr2_sysfs
*sfp
;
162 unsigned int cnt
= 0;
164 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
165 if (!sfp
) return -EINVAL
;
166 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
167 if (!cptr
) return -EINVAL
;
169 ret
= pvr2_ctrl_get_value(cptr
,&val
);
170 if (ret
< 0) return ret
;
172 ret
= pvr2_ctrl_value_to_sym(cptr
,~0,val
,
173 buf
,PAGE_SIZE
-1,&cnt
);
175 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
181 static ssize_t
show_val_custom(int id
,struct class_device
*class_dev
,char *buf
)
183 struct pvr2_ctrl
*cptr
;
184 struct pvr2_sysfs
*sfp
;
186 unsigned int cnt
= 0;
188 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
189 if (!sfp
) return -EINVAL
;
190 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
191 if (!cptr
) return -EINVAL
;
193 ret
= pvr2_ctrl_get_value(cptr
,&val
);
194 if (ret
< 0) return ret
;
196 ret
= pvr2_ctrl_custom_value_to_sym(cptr
,~0,val
,
197 buf
,PAGE_SIZE
-1,&cnt
);
199 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
205 static ssize_t
show_enum(int id
,struct class_device
*class_dev
,char *buf
)
207 struct pvr2_ctrl
*cptr
;
208 struct pvr2_sysfs
*sfp
;
210 unsigned int bcnt
,ccnt
,ecnt
;
212 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
213 if (!sfp
) return -EINVAL
;
214 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
215 if (!cptr
) return -EINVAL
;
216 ecnt
= pvr2_ctrl_get_cnt(cptr
);
218 for (val
= 0; val
< ecnt
; val
++) {
219 pvr2_ctrl_get_valname(cptr
,val
,buf
+bcnt
,PAGE_SIZE
-bcnt
,&ccnt
);
222 if (bcnt
>= PAGE_SIZE
) break;
226 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp
,id
);
230 static ssize_t
show_bits(int id
,struct class_device
*class_dev
,char *buf
)
232 struct pvr2_ctrl
*cptr
;
233 struct pvr2_sysfs
*sfp
;
235 unsigned int bcnt
,ccnt
;
237 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
238 if (!sfp
) return -EINVAL
;
239 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
240 if (!cptr
) return -EINVAL
;
241 valid_bits
= pvr2_ctrl_get_mask(cptr
);
243 for (msk
= 1; valid_bits
; msk
<<= 1) {
244 if (!(msk
& valid_bits
)) continue;
246 pvr2_ctrl_get_valname(cptr
,msk
,buf
+bcnt
,PAGE_SIZE
-bcnt
,&ccnt
);
248 if (bcnt
>= PAGE_SIZE
) break;
252 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp
,id
);
256 static int store_val_any(int id
,int customfl
,struct pvr2_sysfs
*sfp
,
257 const char *buf
,unsigned int count
)
259 struct pvr2_ctrl
*cptr
;
263 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
265 ret
= pvr2_ctrl_custom_sym_to_value(cptr
,buf
,count
,&mask
,&val
);
267 ret
= pvr2_ctrl_sym_to_value(cptr
,buf
,count
,&mask
,&val
);
269 if (ret
< 0) return ret
;
270 ret
= pvr2_ctrl_set_mask_value(cptr
,mask
,val
);
271 pvr2_hdw_commit_ctl(sfp
->channel
.hdw
);
275 static ssize_t
store_val_norm(int id
,struct class_device
*class_dev
,
276 const char *buf
,size_t count
)
278 struct pvr2_sysfs
*sfp
;
280 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
281 ret
= store_val_any(id
,0,sfp
,buf
,count
);
282 if (!ret
) ret
= count
;
286 static ssize_t
store_val_custom(int id
,struct class_device
*class_dev
,
287 const char *buf
,size_t count
)
289 struct pvr2_sysfs
*sfp
;
291 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
292 ret
= store_val_any(id
,1,sfp
,buf
,count
);
293 if (!ret
) ret
= count
;
298 Mike Isely <isely@pobox.com> 30-April-2005
300 This next batch of horrible preprocessor hackery is needed because the
301 kernel's class_device_attribute mechanism fails to pass the actual
302 attribute through to the show / store functions, which means we have no
303 way to package up any attribute-specific parameters, like for example the
304 control id. So we work around this brain-damage by encoding the control
305 id into the show / store functions themselves and pick the function based
306 on the control id we're setting up. These macros try to ease the pain.
310 #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
311 static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \
312 { return sf_name(ctl_id,class_dev,buf); }
314 #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
315 static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \
316 { return sf_name(ctl_id,class_dev,buf,count); }
318 #define CREATE_BATCH(ctl_id) \
319 CREATE_SHOW_INSTANCE(show_name,ctl_id) \
320 CREATE_SHOW_INSTANCE(show_type,ctl_id) \
321 CREATE_SHOW_INSTANCE(show_min,ctl_id) \
322 CREATE_SHOW_INSTANCE(show_max,ctl_id) \
323 CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
324 CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
325 CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
326 CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
327 CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
328 CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
391 struct pvr2_sysfs_func_set
{
392 ssize_t (*show_name
)(struct class_device
*,char *);
393 ssize_t (*show_type
)(struct class_device
*,char *);
394 ssize_t (*show_min
)(struct class_device
*,char *);
395 ssize_t (*show_max
)(struct class_device
*,char *);
396 ssize_t (*show_enum
)(struct class_device
*,char *);
397 ssize_t (*show_bits
)(struct class_device
*,char *);
398 ssize_t (*show_val_norm
)(struct class_device
*,char *);
399 ssize_t (*store_val_norm
)(struct class_device
*,
400 const char *,size_t);
401 ssize_t (*show_val_custom
)(struct class_device
*,char *);
402 ssize_t (*store_val_custom
)(struct class_device
*,
403 const char *,size_t);
406 #define INIT_BATCH(ctl_id) \
408 .show_name = show_name_##ctl_id, \
409 .show_type = show_type_##ctl_id, \
410 .show_min = show_min_##ctl_id, \
411 .show_max = show_max_##ctl_id, \
412 .show_enum = show_enum_##ctl_id, \
413 .show_bits = show_bits_##ctl_id, \
414 .show_val_norm = show_val_norm_##ctl_id, \
415 .store_val_norm = store_val_norm_##ctl_id, \
416 .show_val_custom = show_val_custom_##ctl_id, \
417 .store_val_custom = store_val_custom_##ctl_id, \
420 static struct pvr2_sysfs_func_set funcs[] = {
484 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
486 struct pvr2_sysfs_ctl_item
*cip
;
487 struct pvr2_sysfs_func_set
*fp
;
488 struct pvr2_ctrl
*cptr
;
489 unsigned int cnt
,acnt
;
491 if ((ctl_id
< 0) || (ctl_id
>= (sizeof(funcs
)/sizeof(funcs
[0])))) {
496 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
499 cip
= kmalloc(sizeof(*cip
),GFP_KERNEL
);
501 memset(cip
,0,sizeof(*cip
));
502 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
507 cip
->item_next
= NULL
;
508 if (sfp
->item_last
) {
509 sfp
->item_last
->item_next
= cip
;
511 sfp
->item_first
= cip
;
513 sfp
->item_last
= cip
;
515 cip
->attr_name
.attr
.owner
= THIS_MODULE
;
516 cip
->attr_name
.attr
.name
= "name";
517 cip
->attr_name
.attr
.mode
= S_IRUGO
;
518 cip
->attr_name
.show
= fp
->show_name
;
520 cip
->attr_type
.attr
.owner
= THIS_MODULE
;
521 cip
->attr_type
.attr
.name
= "type";
522 cip
->attr_type
.attr
.mode
= S_IRUGO
;
523 cip
->attr_type
.show
= fp
->show_type
;
525 cip
->attr_min
.attr
.owner
= THIS_MODULE
;
526 cip
->attr_min
.attr
.name
= "min_val";
527 cip
->attr_min
.attr
.mode
= S_IRUGO
;
528 cip
->attr_min
.show
= fp
->show_min
;
530 cip
->attr_max
.attr
.owner
= THIS_MODULE
;
531 cip
->attr_max
.attr
.name
= "max_val";
532 cip
->attr_max
.attr
.mode
= S_IRUGO
;
533 cip
->attr_max
.show
= fp
->show_max
;
535 cip
->attr_val
.attr
.owner
= THIS_MODULE
;
536 cip
->attr_val
.attr
.name
= "cur_val";
537 cip
->attr_val
.attr
.mode
= S_IRUGO
;
539 cip
->attr_custom
.attr
.owner
= THIS_MODULE
;
540 cip
->attr_custom
.attr
.name
= "custom_val";
541 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
543 cip
->attr_enum
.attr
.owner
= THIS_MODULE
;
544 cip
->attr_enum
.attr
.name
= "enum_val";
545 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
546 cip
->attr_enum
.show
= fp
->show_enum
;
548 cip
->attr_bits
.attr
.owner
= THIS_MODULE
;
549 cip
->attr_bits
.attr
.name
= "bit_val";
550 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
551 cip
->attr_bits
.show
= fp
->show_bits
;
553 if (pvr2_ctrl_is_writable(cptr
)) {
554 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
555 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
559 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
560 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
561 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
562 cip
->attr_val
.show
= fp
->show_val_norm
;
563 cip
->attr_val
.store
= fp
->store_val_norm
;
564 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
565 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
566 cip
->attr_custom
.show
= fp
->show_val_custom
;
567 cip
->attr_custom
.store
= fp
->store_val_custom
;
569 switch (pvr2_ctrl_get_type(cptr
)) {
571 // Control is an enumeration
572 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
575 // Control is an integer
576 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
577 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
579 case pvr2_ctl_bitmask
:
580 // Control is an bitmask
581 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
586 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
587 pvr2_ctrl_get_name(cptr
));
589 cip
->grp
.name
= cip
->name
;
590 cip
->grp
.attrs
= cip
->attr_gen
;
592 sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
595 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
596 static ssize_t
debuginfo_show(struct class_device
*,char *);
597 static ssize_t
debugcmd_show(struct class_device
*,char *);
598 static ssize_t
debugcmd_store(struct class_device
*,const char *,size_t count
);
600 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
602 struct pvr2_sysfs_debugifc
*dip
;
605 dip
= kmalloc(sizeof(*dip
),GFP_KERNEL
);
607 memset(dip
,0,sizeof(*dip
));
608 dip
->attr_debugcmd
.attr
.owner
= THIS_MODULE
;
609 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
610 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
611 dip
->attr_debugcmd
.show
= debugcmd_show
;
612 dip
->attr_debugcmd
.store
= debugcmd_store
;
613 dip
->attr_debuginfo
.attr
.owner
= THIS_MODULE
;
614 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
615 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
616 dip
->attr_debuginfo
.show
= debuginfo_show
;
618 ret
= class_device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
620 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
622 ret
= class_device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
624 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
629 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
631 if (!sfp
->debugifc
) return;
632 class_device_remove_file(sfp
->class_dev
,
633 &sfp
->debugifc
->attr_debuginfo
);
634 class_device_remove_file(sfp
->class_dev
,&sfp
->debugifc
->attr_debugcmd
);
635 kfree(sfp
->debugifc
);
636 sfp
->debugifc
= NULL
;
638 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
641 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
643 unsigned int idx
,cnt
;
644 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
645 for (idx
= 0; idx
< cnt
; idx
++) {
646 pvr2_sysfs_add_control(sfp
,idx
);
651 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
653 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
654 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
655 cip2
= cip1
->item_next
;
656 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
657 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
663 static void pvr2_sysfs_class_release(struct class *class)
665 struct pvr2_sysfs_class
*clp
;
666 clp
= container_of(class,struct pvr2_sysfs_class
,class);
667 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
672 static void pvr2_sysfs_release(struct class_device
*class_dev
)
674 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
679 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
681 if (!sfp
->class_dev
) return;
682 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
683 pvr2_sysfs_tear_down_debugifc(sfp
);
684 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
685 pvr2_sysfs_tear_down_controls(sfp
);
686 class_device_remove_file(sfp
->class_dev
,&sfp
->attr_v4l_minor_number
);
687 class_device_remove_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
688 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
689 sfp
->class_dev
->class_data
= NULL
;
690 class_device_unregister(sfp
->class_dev
);
691 sfp
->class_dev
= NULL
;
695 static ssize_t
v4l_minor_number_show(struct class_device
*class_dev
,char *buf
)
697 struct pvr2_sysfs
*sfp
;
698 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
699 if (!sfp
) return -EINVAL
;
700 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
701 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
));
705 static ssize_t
unit_number_show(struct class_device
*class_dev
,char *buf
)
707 struct pvr2_sysfs
*sfp
;
708 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
709 if (!sfp
) return -EINVAL
;
710 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
711 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
715 static void class_dev_create(struct pvr2_sysfs
*sfp
,
716 struct pvr2_sysfs_class
*class_ptr
)
718 struct usb_device
*usb_dev
;
719 struct class_device
*class_dev
;
722 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
723 if (!usb_dev
) return;
724 class_dev
= kmalloc(sizeof(*class_dev
),GFP_KERNEL
);
725 if (!class_dev
) return;
726 memset(class_dev
,0,sizeof(*class_dev
));
728 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
730 class_dev
->class = &class_ptr
->class;
731 if (pvr2_hdw_get_sn(sfp
->channel
.hdw
)) {
732 snprintf(class_dev
->class_id
,BUS_ID_SIZE
,"sn-%lu",
733 pvr2_hdw_get_sn(sfp
->channel
.hdw
));
734 } else if (pvr2_hdw_get_unit_number(sfp
->channel
.hdw
) >= 0) {
735 snprintf(class_dev
->class_id
,BUS_ID_SIZE
,"unit-%c",
736 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
) + 'a');
742 class_dev
->dev
= &usb_dev
->dev
;
744 sfp
->class_dev
= class_dev
;
745 class_dev
->class_data
= sfp
;
746 ret
= class_device_register(class_dev
);
748 printk(KERN_ERR
"%s: class_device_register failed\n",
754 sfp
->attr_v4l_minor_number
.attr
.owner
= THIS_MODULE
;
755 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
756 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
757 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
758 sfp
->attr_v4l_minor_number
.store
= NULL
;
759 ret
= class_device_create_file(sfp
->class_dev
,&sfp
->attr_v4l_minor_number
);
761 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
764 sfp
->attr_unit_number
.attr
.owner
= THIS_MODULE
;
765 sfp
->attr_unit_number
.attr
.name
= "unit_number";
766 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
767 sfp
->attr_unit_number
.show
= unit_number_show
;
768 sfp
->attr_unit_number
.store
= NULL
;
769 ret
= class_device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
771 printk(KERN_WARNING
"%s: class_device_create_file error: %d\n",
774 pvr2_sysfs_add_controls(sfp
);
775 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
776 pvr2_sysfs_add_debugifc(sfp
);
777 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
781 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
783 struct pvr2_sysfs
*sfp
;
784 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
785 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
786 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
787 class_dev_destroy(sfp
);
788 pvr2_channel_done(&sfp
->channel
);
793 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
794 struct pvr2_sysfs_class
*class_ptr
)
796 struct pvr2_sysfs
*sfp
;
797 sfp
= kmalloc(sizeof(*sfp
),GFP_KERNEL
);
798 if (!sfp
) return sfp
;
799 memset(sfp
,0,sizeof(*sfp
));
800 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
801 pvr2_channel_init(&sfp
->channel
,mp
);
802 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
804 class_dev_create(sfp
,class_ptr
);
809 static int pvr2_sysfs_hotplug(struct class_device
*cd
,char **envp
,
810 int numenvp
,char *buf
,int size
)
812 /* Even though we don't do anything here, we still need this function
813 because sysfs will still try to call it. */
817 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
819 struct pvr2_sysfs_class
*clp
;
820 clp
= kmalloc(sizeof(*clp
),GFP_KERNEL
);
821 if (!clp
) return clp
;
822 memset(clp
,0,sizeof(*clp
));
823 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp
);
824 clp
->class.name
= "pvrusb2";
825 clp
->class.class_release
= pvr2_sysfs_class_release
;
826 clp
->class.release
= pvr2_sysfs_release
;
827 clp
->class.uevent
= pvr2_sysfs_hotplug
;
828 if (class_register(&clp
->class)) {
830 "Registration failed for pvr2_sysfs_class id=%p",clp
);
838 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
840 class_unregister(&clp
->class);
844 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
845 static ssize_t
debuginfo_show(struct class_device
*class_dev
,char *buf
)
847 struct pvr2_sysfs
*sfp
;
848 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
849 if (!sfp
) return -EINVAL
;
850 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
851 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
855 static ssize_t
debugcmd_show(struct class_device
*class_dev
,char *buf
)
857 struct pvr2_sysfs
*sfp
;
858 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
859 if (!sfp
) return -EINVAL
;
860 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
864 static ssize_t
debugcmd_store(struct class_device
*class_dev
,
865 const char *buf
,size_t count
)
867 struct pvr2_sysfs
*sfp
;
870 sfp
= (struct pvr2_sysfs
*)class_dev
->class_data
;
871 if (!sfp
) return -EINVAL
;
873 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
874 if (ret
< 0) return ret
;
877 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
881 Stuff for Emacs to see, in order to encourage consistent editing style:
882 *** Local Variables: ***
884 *** fill-column: 75 ***
886 *** c-basic-offset: 8 ***