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 "pvrusb2-sysfs.h"
25 #include "pvrusb2-hdw.h"
26 #include "pvrusb2-debug.h"
27 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
28 #include "pvrusb2-debugifc.h"
29 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
31 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
34 struct pvr2_channel channel
;
35 struct device
*class_dev
;
36 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
37 struct pvr2_sysfs_debugifc
*debugifc
;
38 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
39 struct pvr2_sysfs_ctl_item
*item_first
;
40 struct pvr2_sysfs_ctl_item
*item_last
;
41 struct device_attribute attr_v4l_minor_number
;
42 struct device_attribute attr_v4l_radio_minor_number
;
43 struct device_attribute attr_unit_number
;
44 struct device_attribute attr_bus_info
;
45 struct device_attribute attr_hdw_name
;
46 struct device_attribute attr_hdw_desc
;
47 int v4l_minor_number_created_ok
;
48 int v4l_radio_minor_number_created_ok
;
49 int unit_number_created_ok
;
50 int bus_info_created_ok
;
51 int hdw_name_created_ok
;
52 int hdw_desc_created_ok
;
55 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
56 struct pvr2_sysfs_debugifc
{
57 struct device_attribute attr_debugcmd
;
58 struct device_attribute attr_debuginfo
;
59 int debugcmd_created_ok
;
60 int debuginfo_created_ok
;
62 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
64 struct pvr2_sysfs_ctl_item
{
65 struct device_attribute attr_name
;
66 struct device_attribute attr_type
;
67 struct device_attribute attr_min
;
68 struct device_attribute attr_max
;
69 struct device_attribute attr_enum
;
70 struct device_attribute attr_bits
;
71 struct device_attribute attr_val
;
72 struct device_attribute attr_custom
;
73 struct pvr2_ctrl
*cptr
;
74 struct pvr2_sysfs
*chptr
;
75 struct pvr2_sysfs_ctl_item
*item_next
;
76 struct attribute
*attr_gen
[7];
77 struct attribute_group grp
;
82 struct pvr2_sysfs_class
{
86 static ssize_t
show_name(int id
,struct device
*class_dev
,char *buf
)
88 struct pvr2_ctrl
*cptr
;
89 struct pvr2_sysfs
*sfp
;
92 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
93 if (!sfp
) return -EINVAL
;
94 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
95 if (!cptr
) return -EINVAL
;
97 name
= pvr2_ctrl_get_desc(cptr
);
98 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp
,id
,name
);
100 if (!name
) return -EINVAL
;
102 return scnprintf(buf
,PAGE_SIZE
,"%s\n",name
);
105 static ssize_t
show_type(int id
,struct device
*class_dev
,char *buf
)
107 struct pvr2_ctrl
*cptr
;
108 struct pvr2_sysfs
*sfp
;
110 enum pvr2_ctl_type tp
;
112 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
113 if (!sfp
) return -EINVAL
;
114 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
115 if (!cptr
) return -EINVAL
;
117 tp
= pvr2_ctrl_get_type(cptr
);
119 case pvr2_ctl_int
: name
= "integer"; break;
120 case pvr2_ctl_enum
: name
= "enum"; break;
121 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
122 case pvr2_ctl_bool
: name
= "boolean"; break;
123 default: name
= "?"; break;
125 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp
,id
,name
);
127 if (!name
) return -EINVAL
;
129 return scnprintf(buf
,PAGE_SIZE
,"%s\n",name
);
132 static ssize_t
show_min(int id
,struct device
*class_dev
,char *buf
)
134 struct pvr2_ctrl
*cptr
;
135 struct pvr2_sysfs
*sfp
;
138 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
139 if (!sfp
) return -EINVAL
;
140 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
141 if (!cptr
) return -EINVAL
;
142 val
= pvr2_ctrl_get_min(cptr
);
144 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp
,id
,val
);
146 return scnprintf(buf
,PAGE_SIZE
,"%ld\n",val
);
149 static ssize_t
show_max(int id
,struct device
*class_dev
,char *buf
)
151 struct pvr2_ctrl
*cptr
;
152 struct pvr2_sysfs
*sfp
;
155 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
156 if (!sfp
) return -EINVAL
;
157 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
158 if (!cptr
) return -EINVAL
;
159 val
= pvr2_ctrl_get_max(cptr
);
161 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp
,id
,val
);
163 return scnprintf(buf
,PAGE_SIZE
,"%ld\n",val
);
166 static ssize_t
show_val_norm(int id
,struct device
*class_dev
,char *buf
)
168 struct pvr2_ctrl
*cptr
;
169 struct pvr2_sysfs
*sfp
;
171 unsigned int cnt
= 0;
173 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
174 if (!sfp
) return -EINVAL
;
175 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
176 if (!cptr
) return -EINVAL
;
178 ret
= pvr2_ctrl_get_value(cptr
,&val
);
179 if (ret
< 0) return ret
;
181 ret
= pvr2_ctrl_value_to_sym(cptr
,~0,val
,
182 buf
,PAGE_SIZE
-1,&cnt
);
184 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
190 static ssize_t
show_val_custom(int id
,struct device
*class_dev
,char *buf
)
192 struct pvr2_ctrl
*cptr
;
193 struct pvr2_sysfs
*sfp
;
195 unsigned int cnt
= 0;
197 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
198 if (!sfp
) return -EINVAL
;
199 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
200 if (!cptr
) return -EINVAL
;
202 ret
= pvr2_ctrl_get_value(cptr
,&val
);
203 if (ret
< 0) return ret
;
205 ret
= pvr2_ctrl_custom_value_to_sym(cptr
,~0,val
,
206 buf
,PAGE_SIZE
-1,&cnt
);
208 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
214 static ssize_t
show_enum(int id
,struct device
*class_dev
,char *buf
)
216 struct pvr2_ctrl
*cptr
;
217 struct pvr2_sysfs
*sfp
;
219 unsigned int bcnt
,ccnt
,ecnt
;
221 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
222 if (!sfp
) return -EINVAL
;
223 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
224 if (!cptr
) return -EINVAL
;
225 ecnt
= pvr2_ctrl_get_cnt(cptr
);
227 for (val
= 0; val
< ecnt
; val
++) {
228 pvr2_ctrl_get_valname(cptr
,val
,buf
+bcnt
,PAGE_SIZE
-bcnt
,&ccnt
);
231 if (bcnt
>= PAGE_SIZE
) break;
235 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp
,id
);
239 static ssize_t
show_bits(int id
,struct device
*class_dev
,char *buf
)
241 struct pvr2_ctrl
*cptr
;
242 struct pvr2_sysfs
*sfp
;
244 unsigned int bcnt
,ccnt
;
246 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
247 if (!sfp
) return -EINVAL
;
248 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
249 if (!cptr
) return -EINVAL
;
250 valid_bits
= pvr2_ctrl_get_mask(cptr
);
252 for (msk
= 1; valid_bits
; msk
<<= 1) {
253 if (!(msk
& valid_bits
)) continue;
255 pvr2_ctrl_get_valname(cptr
,msk
,buf
+bcnt
,PAGE_SIZE
-bcnt
,&ccnt
);
257 if (bcnt
>= PAGE_SIZE
) break;
261 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp
,id
);
265 static int store_val_any(int id
,int customfl
,struct pvr2_sysfs
*sfp
,
266 const char *buf
,unsigned int count
)
268 struct pvr2_ctrl
*cptr
;
272 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,id
);
274 ret
= pvr2_ctrl_custom_sym_to_value(cptr
,buf
,count
,&mask
,&val
);
276 ret
= pvr2_ctrl_sym_to_value(cptr
,buf
,count
,&mask
,&val
);
278 if (ret
< 0) return ret
;
279 ret
= pvr2_ctrl_set_mask_value(cptr
,mask
,val
);
280 pvr2_hdw_commit_ctl(sfp
->channel
.hdw
);
284 static ssize_t
store_val_norm(int id
,struct device
*class_dev
,
285 const char *buf
,size_t count
)
287 struct pvr2_sysfs
*sfp
;
289 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
290 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
292 ret
= store_val_any(id
,0,sfp
,buf
,count
);
293 if (!ret
) ret
= count
;
297 static ssize_t
store_val_custom(int id
,struct device
*class_dev
,
298 const char *buf
,size_t count
)
300 struct pvr2_sysfs
*sfp
;
302 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
303 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
305 ret
= store_val_any(id
,1,sfp
,buf
,count
);
306 if (!ret
) ret
= count
;
311 Mike Isely <isely@pobox.com> 30-April-2005
313 This next batch of horrible preprocessor hackery is needed because the
314 kernel's device_attribute mechanism fails to pass the actual
315 attribute through to the show / store functions, which means we have no
316 way to package up any attribute-specific parameters, like for example the
317 control id. So we work around this brain-damage by encoding the control
318 id into the show / store functions themselves and pick the function based
319 on the control id we're setting up. These macros try to ease the pain.
323 #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
324 static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
325 struct device_attribute *attr, char *buf) \
326 { return sf_name(ctl_id,class_dev,buf); }
328 #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
329 static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
330 struct device_attribute *attr, const char *buf, size_t count) \
331 { return sf_name(ctl_id,class_dev,buf,count); }
333 #define CREATE_BATCH(ctl_id) \
334 CREATE_SHOW_INSTANCE(show_name,ctl_id) \
335 CREATE_SHOW_INSTANCE(show_type,ctl_id) \
336 CREATE_SHOW_INSTANCE(show_min,ctl_id) \
337 CREATE_SHOW_INSTANCE(show_max,ctl_id) \
338 CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
339 CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
340 CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
341 CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
342 CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
343 CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
406 struct pvr2_sysfs_func_set
{
407 ssize_t (*show_name
)(struct device
*,
408 struct device_attribute
*attr
, char *);
409 ssize_t (*show_type
)(struct device
*,
410 struct device_attribute
*attr
, char *);
411 ssize_t (*show_min
)(struct device
*,
412 struct device_attribute
*attr
, char *);
413 ssize_t (*show_max
)(struct device
*,
414 struct device_attribute
*attr
, char *);
415 ssize_t (*show_enum
)(struct device
*,
416 struct device_attribute
*attr
, char *);
417 ssize_t (*show_bits
)(struct device
*,
418 struct device_attribute
*attr
, char *);
419 ssize_t (*show_val_norm
)(struct device
*,
420 struct device_attribute
*attr
, char *);
421 ssize_t (*store_val_norm
)(struct device
*,
422 struct device_attribute
*attr
,
423 const char *,size_t);
424 ssize_t (*show_val_custom
)(struct device
*,
425 struct device_attribute
*attr
, char *);
426 ssize_t (*store_val_custom
)(struct device
*,
427 struct device_attribute
*attr
,
428 const char *,size_t);
431 #define INIT_BATCH(ctl_id) \
433 .show_name = show_name_##ctl_id, \
434 .show_type = show_type_##ctl_id, \
435 .show_min = show_min_##ctl_id, \
436 .show_max = show_max_##ctl_id, \
437 .show_enum = show_enum_##ctl_id, \
438 .show_bits = show_bits_##ctl_id, \
439 .show_val_norm = show_val_norm_##ctl_id, \
440 .store_val_norm = store_val_norm_##ctl_id, \
441 .show_val_custom = show_val_custom_##ctl_id, \
442 .store_val_custom = store_val_custom_##ctl_id, \
445 static struct pvr2_sysfs_func_set funcs[] = {
509 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
511 struct pvr2_sysfs_ctl_item
*cip
;
512 struct pvr2_sysfs_func_set
*fp
;
513 struct pvr2_ctrl
*cptr
;
514 unsigned int cnt
,acnt
;
517 if ((ctl_id
< 0) || (ctl_id
>= ARRAY_SIZE(funcs
))) {
522 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
525 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
527 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
532 cip
->item_next
= NULL
;
533 if (sfp
->item_last
) {
534 sfp
->item_last
->item_next
= cip
;
536 sfp
->item_first
= cip
;
538 sfp
->item_last
= cip
;
540 cip
->attr_name
.attr
.name
= "name";
541 cip
->attr_name
.attr
.mode
= S_IRUGO
;
542 cip
->attr_name
.show
= fp
->show_name
;
544 cip
->attr_type
.attr
.name
= "type";
545 cip
->attr_type
.attr
.mode
= S_IRUGO
;
546 cip
->attr_type
.show
= fp
->show_type
;
548 cip
->attr_min
.attr
.name
= "min_val";
549 cip
->attr_min
.attr
.mode
= S_IRUGO
;
550 cip
->attr_min
.show
= fp
->show_min
;
552 cip
->attr_max
.attr
.name
= "max_val";
553 cip
->attr_max
.attr
.mode
= S_IRUGO
;
554 cip
->attr_max
.show
= fp
->show_max
;
556 cip
->attr_val
.attr
.name
= "cur_val";
557 cip
->attr_val
.attr
.mode
= S_IRUGO
;
559 cip
->attr_custom
.attr
.name
= "custom_val";
560 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
562 cip
->attr_enum
.attr
.name
= "enum_val";
563 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
564 cip
->attr_enum
.show
= fp
->show_enum
;
566 cip
->attr_bits
.attr
.name
= "bit_val";
567 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
568 cip
->attr_bits
.show
= fp
->show_bits
;
570 if (pvr2_ctrl_is_writable(cptr
)) {
571 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
572 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
576 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
577 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
578 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
579 cip
->attr_val
.show
= fp
->show_val_norm
;
580 cip
->attr_val
.store
= fp
->store_val_norm
;
581 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
582 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
583 cip
->attr_custom
.show
= fp
->show_val_custom
;
584 cip
->attr_custom
.store
= fp
->store_val_custom
;
586 switch (pvr2_ctrl_get_type(cptr
)) {
588 // Control is an enumeration
589 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
592 // Control is an integer
593 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
594 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
596 case pvr2_ctl_bitmask
:
597 // Control is an bitmask
598 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
603 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
604 pvr2_ctrl_get_name(cptr
));
606 cip
->grp
.name
= cip
->name
;
607 cip
->grp
.attrs
= cip
->attr_gen
;
609 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
611 printk(KERN_WARNING
"%s: sysfs_create_group error: %d\n",
615 cip
->created_ok
= !0;
618 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
619 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
621 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
623 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
624 const char *, size_t count
);
626 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
628 struct pvr2_sysfs_debugifc
*dip
;
631 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
633 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
634 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
635 dip
->attr_debugcmd
.show
= debugcmd_show
;
636 dip
->attr_debugcmd
.store
= debugcmd_store
;
637 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
638 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
639 dip
->attr_debuginfo
.show
= debuginfo_show
;
641 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
643 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
646 dip
->debugcmd_created_ok
= !0;
648 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
650 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
653 dip
->debuginfo_created_ok
= !0;
658 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
660 if (!sfp
->debugifc
) return;
661 if (sfp
->debugifc
->debuginfo_created_ok
) {
662 device_remove_file(sfp
->class_dev
,
663 &sfp
->debugifc
->attr_debuginfo
);
665 if (sfp
->debugifc
->debugcmd_created_ok
) {
666 device_remove_file(sfp
->class_dev
,
667 &sfp
->debugifc
->attr_debugcmd
);
669 kfree(sfp
->debugifc
);
670 sfp
->debugifc
= NULL
;
672 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
675 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
677 unsigned int idx
,cnt
;
678 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
679 for (idx
= 0; idx
< cnt
; idx
++) {
680 pvr2_sysfs_add_control(sfp
,idx
);
685 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
687 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
688 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
689 cip2
= cip1
->item_next
;
690 if (cip1
->created_ok
) {
691 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
693 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
699 static void pvr2_sysfs_class_release(struct class *class)
701 struct pvr2_sysfs_class
*clp
;
702 clp
= container_of(class,struct pvr2_sysfs_class
,class);
703 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
708 static void pvr2_sysfs_release(struct device
*class_dev
)
710 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
715 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
717 if (!sfp
->class_dev
) return;
718 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
719 pvr2_sysfs_tear_down_debugifc(sfp
);
720 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
721 pvr2_sysfs_tear_down_controls(sfp
);
722 if (sfp
->hdw_desc_created_ok
) {
723 device_remove_file(sfp
->class_dev
,
724 &sfp
->attr_hdw_desc
);
726 if (sfp
->hdw_name_created_ok
) {
727 device_remove_file(sfp
->class_dev
,
728 &sfp
->attr_hdw_name
);
730 if (sfp
->bus_info_created_ok
) {
731 device_remove_file(sfp
->class_dev
,
732 &sfp
->attr_bus_info
);
734 if (sfp
->v4l_minor_number_created_ok
) {
735 device_remove_file(sfp
->class_dev
,
736 &sfp
->attr_v4l_minor_number
);
738 if (sfp
->v4l_radio_minor_number_created_ok
) {
739 device_remove_file(sfp
->class_dev
,
740 &sfp
->attr_v4l_radio_minor_number
);
742 if (sfp
->unit_number_created_ok
) {
743 device_remove_file(sfp
->class_dev
,
744 &sfp
->attr_unit_number
);
746 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
747 sfp
->class_dev
->driver_data
= NULL
;
748 device_unregister(sfp
->class_dev
);
749 sfp
->class_dev
= NULL
;
753 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
754 struct device_attribute
*attr
, char *buf
)
756 struct pvr2_sysfs
*sfp
;
757 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
758 if (!sfp
) return -EINVAL
;
759 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
760 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
761 pvr2_v4l_type_video
));
765 static ssize_t
bus_info_show(struct device
*class_dev
,
766 struct device_attribute
*attr
, char *buf
)
768 struct pvr2_sysfs
*sfp
;
769 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
770 if (!sfp
) return -EINVAL
;
771 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
772 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
776 static ssize_t
hdw_name_show(struct device
*class_dev
,
777 struct device_attribute
*attr
, char *buf
)
779 struct pvr2_sysfs
*sfp
;
780 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
781 if (!sfp
) return -EINVAL
;
782 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
783 pvr2_hdw_get_type(sfp
->channel
.hdw
));
787 static ssize_t
hdw_desc_show(struct device
*class_dev
,
788 struct device_attribute
*attr
, char *buf
)
790 struct pvr2_sysfs
*sfp
;
791 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
792 if (!sfp
) return -EINVAL
;
793 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
794 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
798 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
799 struct device_attribute
*attr
,
802 struct pvr2_sysfs
*sfp
;
803 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
804 if (!sfp
) return -EINVAL
;
805 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
806 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
807 pvr2_v4l_type_radio
));
811 static ssize_t
unit_number_show(struct device
*class_dev
,
812 struct device_attribute
*attr
, char *buf
)
814 struct pvr2_sysfs
*sfp
;
815 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
816 if (!sfp
) return -EINVAL
;
817 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
818 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
822 static void class_dev_create(struct pvr2_sysfs
*sfp
,
823 struct pvr2_sysfs_class
*class_ptr
)
825 struct usb_device
*usb_dev
;
826 struct device
*class_dev
;
829 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
830 if (!usb_dev
) return;
831 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
832 if (!class_dev
) return;
834 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
836 class_dev
->class = &class_ptr
->class;
837 if (pvr2_hdw_get_sn(sfp
->channel
.hdw
)) {
838 snprintf(class_dev
->bus_id
, BUS_ID_SIZE
, "sn-%lu",
839 pvr2_hdw_get_sn(sfp
->channel
.hdw
));
840 } else if (pvr2_hdw_get_unit_number(sfp
->channel
.hdw
) >= 0) {
841 snprintf(class_dev
->bus_id
, BUS_ID_SIZE
, "unit-%c",
842 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
) + 'a');
848 class_dev
->parent
= &usb_dev
->dev
;
850 sfp
->class_dev
= class_dev
;
851 class_dev
->driver_data
= sfp
;
852 ret
= device_register(class_dev
);
854 printk(KERN_ERR
"%s: device_register failed\n",
860 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
861 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
862 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
863 sfp
->attr_v4l_minor_number
.store
= NULL
;
864 ret
= device_create_file(sfp
->class_dev
,
865 &sfp
->attr_v4l_minor_number
);
867 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
870 sfp
->v4l_minor_number_created_ok
= !0;
873 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
874 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
875 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
876 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
877 ret
= device_create_file(sfp
->class_dev
,
878 &sfp
->attr_v4l_radio_minor_number
);
880 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
883 sfp
->v4l_radio_minor_number_created_ok
= !0;
886 sfp
->attr_unit_number
.attr
.name
= "unit_number";
887 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
888 sfp
->attr_unit_number
.show
= unit_number_show
;
889 sfp
->attr_unit_number
.store
= NULL
;
890 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
892 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
895 sfp
->unit_number_created_ok
= !0;
898 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
899 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
900 sfp
->attr_bus_info
.show
= bus_info_show
;
901 sfp
->attr_bus_info
.store
= NULL
;
902 ret
= device_create_file(sfp
->class_dev
,
903 &sfp
->attr_bus_info
);
905 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
908 sfp
->bus_info_created_ok
= !0;
911 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
912 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
913 sfp
->attr_hdw_name
.show
= hdw_name_show
;
914 sfp
->attr_hdw_name
.store
= NULL
;
915 ret
= device_create_file(sfp
->class_dev
,
916 &sfp
->attr_hdw_name
);
918 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
921 sfp
->hdw_name_created_ok
= !0;
924 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
925 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
926 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
927 sfp
->attr_hdw_desc
.store
= NULL
;
928 ret
= device_create_file(sfp
->class_dev
,
929 &sfp
->attr_hdw_desc
);
931 printk(KERN_WARNING
"%s: device_create_file error: %d\n",
934 sfp
->hdw_desc_created_ok
= !0;
937 pvr2_sysfs_add_controls(sfp
);
938 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
939 pvr2_sysfs_add_debugifc(sfp
);
940 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
944 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
946 struct pvr2_sysfs
*sfp
;
947 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
948 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
949 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
950 class_dev_destroy(sfp
);
951 pvr2_channel_done(&sfp
->channel
);
956 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
957 struct pvr2_sysfs_class
*class_ptr
)
959 struct pvr2_sysfs
*sfp
;
960 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
961 if (!sfp
) return sfp
;
962 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
963 pvr2_channel_init(&sfp
->channel
,mp
);
964 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
966 class_dev_create(sfp
,class_ptr
);
972 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
974 struct pvr2_sysfs_class
*clp
;
975 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
976 if (!clp
) return clp
;
977 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp
);
978 clp
->class.name
= "pvrusb2";
979 clp
->class.class_release
= pvr2_sysfs_class_release
;
980 clp
->class.dev_release
= pvr2_sysfs_release
;
981 if (class_register(&clp
->class)) {
983 "Registration failed for pvr2_sysfs_class id=%p",clp
);
991 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
993 class_unregister(&clp
->class);
997 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
998 static ssize_t
debuginfo_show(struct device
*class_dev
,
999 struct device_attribute
*attr
, char *buf
)
1001 struct pvr2_sysfs
*sfp
;
1002 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
1003 if (!sfp
) return -EINVAL
;
1004 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
1005 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
1009 static ssize_t
debugcmd_show(struct device
*class_dev
,
1010 struct device_attribute
*attr
, char *buf
)
1012 struct pvr2_sysfs
*sfp
;
1013 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
1014 if (!sfp
) return -EINVAL
;
1015 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
1019 static ssize_t
debugcmd_store(struct device
*class_dev
,
1020 struct device_attribute
*attr
,
1021 const char *buf
, size_t count
)
1023 struct pvr2_sysfs
*sfp
;
1026 sfp
= (struct pvr2_sysfs
*)class_dev
->driver_data
;
1027 if (!sfp
) return -EINVAL
;
1029 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
1030 if (ret
< 0) return ret
;
1033 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
1037 Stuff for Emacs to see, in order to encourage consistent editing style:
1038 *** Local Variables: ***
1040 *** fill-column: 75 ***
1041 *** tab-width: 8 ***
1042 *** c-basic-offset: 8 ***