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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/string.h>
22 #include <linux/slab.h>
23 #include "pvrusb2-sysfs.h"
24 #include "pvrusb2-hdw.h"
25 #include "pvrusb2-debug.h"
26 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
27 #include "pvrusb2-debugifc.h"
28 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
30 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
33 struct pvr2_channel channel
;
34 struct device
*class_dev
;
35 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
36 struct pvr2_sysfs_debugifc
*debugifc
;
37 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
38 struct pvr2_sysfs_ctl_item
*item_first
;
39 struct pvr2_sysfs_ctl_item
*item_last
;
40 struct device_attribute attr_v4l_minor_number
;
41 struct device_attribute attr_v4l_radio_minor_number
;
42 struct device_attribute attr_unit_number
;
43 struct device_attribute attr_bus_info
;
44 struct device_attribute attr_hdw_name
;
45 struct device_attribute attr_hdw_desc
;
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
;
50 int hdw_name_created_ok
;
51 int hdw_desc_created_ok
;
54 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
55 struct pvr2_sysfs_debugifc
{
56 struct device_attribute attr_debugcmd
;
57 struct device_attribute attr_debuginfo
;
58 int debugcmd_created_ok
;
59 int debuginfo_created_ok
;
61 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
63 struct pvr2_sysfs_ctl_item
{
64 struct device_attribute attr_name
;
65 struct device_attribute attr_type
;
66 struct device_attribute attr_min
;
67 struct device_attribute attr_max
;
68 struct device_attribute attr_def
;
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
;
75 struct pvr2_sysfs
*chptr
;
76 struct pvr2_sysfs_ctl_item
*item_next
;
77 struct attribute
*attr_gen
[8];
78 struct attribute_group grp
;
83 struct pvr2_sysfs_class
{
87 static ssize_t
show_name(struct device
*class_dev
,
88 struct device_attribute
*attr
,
91 struct pvr2_sysfs_ctl_item
*cip
;
93 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_name
);
94 name
= pvr2_ctrl_get_desc(cip
->cptr
);
95 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
96 cip
->chptr
, cip
->ctl_id
, name
);
97 if (!name
) return -EINVAL
;
98 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
101 static ssize_t
show_type(struct device
*class_dev
,
102 struct device_attribute
*attr
,
105 struct pvr2_sysfs_ctl_item
*cip
;
107 enum pvr2_ctl_type tp
;
108 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_type
);
109 tp
= pvr2_ctrl_get_type(cip
->cptr
);
111 case pvr2_ctl_int
: name
= "integer"; break;
112 case pvr2_ctl_enum
: name
= "enum"; break;
113 case pvr2_ctl_bitmask
: name
= "bitmask"; break;
114 case pvr2_ctl_bool
: name
= "boolean"; break;
115 default: name
= "?"; break;
117 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
118 cip
->chptr
, cip
->ctl_id
, name
);
119 if (!name
) return -EINVAL
;
120 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
123 static ssize_t
show_min(struct device
*class_dev
,
124 struct device_attribute
*attr
,
127 struct pvr2_sysfs_ctl_item
*cip
;
129 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_min
);
130 val
= pvr2_ctrl_get_min(cip
->cptr
);
131 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
132 cip
->chptr
, cip
->ctl_id
, val
);
133 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
136 static ssize_t
show_max(struct device
*class_dev
,
137 struct device_attribute
*attr
,
140 struct pvr2_sysfs_ctl_item
*cip
;
142 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_max
);
143 val
= pvr2_ctrl_get_max(cip
->cptr
);
144 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
145 cip
->chptr
, cip
->ctl_id
, val
);
146 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
149 static ssize_t
show_def(struct device
*class_dev
,
150 struct device_attribute
*attr
,
153 struct pvr2_sysfs_ctl_item
*cip
;
156 unsigned int cnt
= 0;
157 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_def
);
158 ret
= pvr2_ctrl_get_def(cip
->cptr
, &val
);
159 if (ret
< 0) return ret
;
160 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
161 buf
, PAGE_SIZE
- 1, &cnt
);
162 pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
163 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
168 static ssize_t
show_val_norm(struct device
*class_dev
,
169 struct device_attribute
*attr
,
172 struct pvr2_sysfs_ctl_item
*cip
;
175 unsigned int cnt
= 0;
176 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
177 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
178 if (ret
< 0) return ret
;
179 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
180 buf
, PAGE_SIZE
- 1, &cnt
);
181 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
182 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
187 static ssize_t
show_val_custom(struct device
*class_dev
,
188 struct device_attribute
*attr
,
191 struct pvr2_sysfs_ctl_item
*cip
;
194 unsigned int cnt
= 0;
195 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
196 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
197 if (ret
< 0) return ret
;
198 ret
= pvr2_ctrl_custom_value_to_sym(cip
->cptr
, ~0, val
,
199 buf
, PAGE_SIZE
- 1, &cnt
);
200 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
201 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
206 static ssize_t
show_enum(struct device
*class_dev
,
207 struct device_attribute
*attr
,
210 struct pvr2_sysfs_ctl_item
*cip
;
212 unsigned int bcnt
, ccnt
, ecnt
;
213 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_enum
);
214 ecnt
= pvr2_ctrl_get_cnt(cip
->cptr
);
216 for (val
= 0; val
< ecnt
; val
++) {
217 pvr2_ctrl_get_valname(cip
->cptr
, val
, buf
+ bcnt
,
218 PAGE_SIZE
- bcnt
, &ccnt
);
221 if (bcnt
>= PAGE_SIZE
) break;
225 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
226 cip
->chptr
, cip
->ctl_id
);
230 static ssize_t
show_bits(struct device
*class_dev
,
231 struct device_attribute
*attr
,
234 struct pvr2_sysfs_ctl_item
*cip
;
236 unsigned int bcnt
, ccnt
;
237 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_bits
);
238 valid_bits
= pvr2_ctrl_get_mask(cip
->cptr
);
240 for (msk
= 1; valid_bits
; msk
<<= 1) {
241 if (!(msk
& valid_bits
)) continue;
243 pvr2_ctrl_get_valname(cip
->cptr
, msk
, buf
+ bcnt
,
244 PAGE_SIZE
- bcnt
, &ccnt
);
246 if (bcnt
>= PAGE_SIZE
) break;
250 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
251 cip
->chptr
, cip
->ctl_id
);
255 static int store_val_any(struct pvr2_sysfs_ctl_item
*cip
, int customfl
,
256 const char *buf
,unsigned int count
)
261 ret
= pvr2_ctrl_custom_sym_to_value(cip
->cptr
, buf
, count
,
264 ret
= pvr2_ctrl_sym_to_value(cip
->cptr
, buf
, count
,
267 if (ret
< 0) return ret
;
268 ret
= pvr2_ctrl_set_mask_value(cip
->cptr
, mask
, val
);
269 pvr2_hdw_commit_ctl(cip
->chptr
->channel
.hdw
);
273 static ssize_t
store_val_norm(struct device
*class_dev
,
274 struct device_attribute
*attr
,
275 const char *buf
, size_t count
)
277 struct pvr2_sysfs_ctl_item
*cip
;
279 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
280 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
281 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
282 ret
= store_val_any(cip
, 0, buf
, count
);
283 if (!ret
) ret
= count
;
287 static ssize_t
store_val_custom(struct device
*class_dev
,
288 struct device_attribute
*attr
,
289 const char *buf
, size_t count
)
291 struct pvr2_sysfs_ctl_item
*cip
;
293 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
294 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
295 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
296 ret
= store_val_any(cip
, 1, buf
, count
);
297 if (!ret
) ret
= count
;
301 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
303 struct pvr2_sysfs_ctl_item
*cip
;
304 struct pvr2_ctrl
*cptr
;
305 unsigned int cnt
,acnt
;
308 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
311 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
313 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
316 cip
->ctl_id
= ctl_id
;
319 cip
->item_next
= NULL
;
320 if (sfp
->item_last
) {
321 sfp
->item_last
->item_next
= cip
;
323 sfp
->item_first
= cip
;
325 sfp
->item_last
= cip
;
327 cip
->attr_name
.attr
.name
= "name";
328 cip
->attr_name
.attr
.mode
= S_IRUGO
;
329 cip
->attr_name
.show
= show_name
;
331 cip
->attr_type
.attr
.name
= "type";
332 cip
->attr_type
.attr
.mode
= S_IRUGO
;
333 cip
->attr_type
.show
= show_type
;
335 cip
->attr_min
.attr
.name
= "min_val";
336 cip
->attr_min
.attr
.mode
= S_IRUGO
;
337 cip
->attr_min
.show
= show_min
;
339 cip
->attr_max
.attr
.name
= "max_val";
340 cip
->attr_max
.attr
.mode
= S_IRUGO
;
341 cip
->attr_max
.show
= show_max
;
343 cip
->attr_def
.attr
.name
= "def_val";
344 cip
->attr_def
.attr
.mode
= S_IRUGO
;
345 cip
->attr_def
.show
= show_def
;
347 cip
->attr_val
.attr
.name
= "cur_val";
348 cip
->attr_val
.attr
.mode
= S_IRUGO
;
350 cip
->attr_custom
.attr
.name
= "custom_val";
351 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
353 cip
->attr_enum
.attr
.name
= "enum_val";
354 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
355 cip
->attr_enum
.show
= show_enum
;
357 cip
->attr_bits
.attr
.name
= "bit_val";
358 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
359 cip
->attr_bits
.show
= show_bits
;
361 if (pvr2_ctrl_is_writable(cptr
)) {
362 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
363 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
367 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
368 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
369 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
370 cip
->attr_gen
[acnt
++] = &cip
->attr_def
.attr
;
371 cip
->attr_val
.show
= show_val_norm
;
372 cip
->attr_val
.store
= store_val_norm
;
373 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
374 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
375 cip
->attr_custom
.show
= show_val_custom
;
376 cip
->attr_custom
.store
= store_val_custom
;
378 switch (pvr2_ctrl_get_type(cptr
)) {
380 // Control is an enumeration
381 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
384 // Control is an integer
385 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
386 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
388 case pvr2_ctl_bitmask
:
389 // Control is an bitmask
390 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
395 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
396 pvr2_ctrl_get_name(cptr
));
398 cip
->grp
.name
= cip
->name
;
399 cip
->grp
.attrs
= cip
->attr_gen
;
401 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
403 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
404 "sysfs_create_group error: %d",
408 cip
->created_ok
= !0;
411 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
412 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
414 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
416 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
417 const char *, size_t count
);
419 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
421 struct pvr2_sysfs_debugifc
*dip
;
424 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
426 sysfs_attr_init(&dip
->attr_debugcmd
.attr
);
427 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
428 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
429 dip
->attr_debugcmd
.show
= debugcmd_show
;
430 dip
->attr_debugcmd
.store
= debugcmd_store
;
431 sysfs_attr_init(&dip
->attr_debuginfo
.attr
);
432 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
433 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
434 dip
->attr_debuginfo
.show
= debuginfo_show
;
436 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
438 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
439 "device_create_file error: %d",
442 dip
->debugcmd_created_ok
= !0;
444 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
446 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
447 "device_create_file error: %d",
450 dip
->debuginfo_created_ok
= !0;
455 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
457 if (!sfp
->debugifc
) return;
458 if (sfp
->debugifc
->debuginfo_created_ok
) {
459 device_remove_file(sfp
->class_dev
,
460 &sfp
->debugifc
->attr_debuginfo
);
462 if (sfp
->debugifc
->debugcmd_created_ok
) {
463 device_remove_file(sfp
->class_dev
,
464 &sfp
->debugifc
->attr_debugcmd
);
466 kfree(sfp
->debugifc
);
467 sfp
->debugifc
= NULL
;
469 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
472 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
474 unsigned int idx
,cnt
;
475 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
476 for (idx
= 0; idx
< cnt
; idx
++) {
477 pvr2_sysfs_add_control(sfp
,idx
);
482 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
484 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
485 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
486 cip2
= cip1
->item_next
;
487 if (cip1
->created_ok
) {
488 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
490 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
496 static void pvr2_sysfs_class_release(struct class *class)
498 struct pvr2_sysfs_class
*clp
;
499 clp
= container_of(class,struct pvr2_sysfs_class
,class);
500 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
505 static void pvr2_sysfs_release(struct device
*class_dev
)
507 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
512 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
515 if (!sfp
->class_dev
) return;
516 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
517 pvr2_sysfs_tear_down_debugifc(sfp
);
518 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
519 pvr2_sysfs_tear_down_controls(sfp
);
520 if (sfp
->hdw_desc_created_ok
) {
521 device_remove_file(sfp
->class_dev
,
522 &sfp
->attr_hdw_desc
);
524 if (sfp
->hdw_name_created_ok
) {
525 device_remove_file(sfp
->class_dev
,
526 &sfp
->attr_hdw_name
);
528 if (sfp
->bus_info_created_ok
) {
529 device_remove_file(sfp
->class_dev
,
530 &sfp
->attr_bus_info
);
532 if (sfp
->v4l_minor_number_created_ok
) {
533 device_remove_file(sfp
->class_dev
,
534 &sfp
->attr_v4l_minor_number
);
536 if (sfp
->v4l_radio_minor_number_created_ok
) {
537 device_remove_file(sfp
->class_dev
,
538 &sfp
->attr_v4l_radio_minor_number
);
540 if (sfp
->unit_number_created_ok
) {
541 device_remove_file(sfp
->class_dev
,
542 &sfp
->attr_unit_number
);
544 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
545 dev_set_drvdata(sfp
->class_dev
, NULL
);
546 dev
= sfp
->class_dev
->parent
;
547 sfp
->class_dev
->parent
= NULL
;
549 device_unregister(sfp
->class_dev
);
550 sfp
->class_dev
= NULL
;
554 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
555 struct device_attribute
*attr
, char *buf
)
557 struct pvr2_sysfs
*sfp
;
558 sfp
= dev_get_drvdata(class_dev
);
559 if (!sfp
) return -EINVAL
;
560 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
561 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
562 pvr2_v4l_type_video
));
566 static ssize_t
bus_info_show(struct device
*class_dev
,
567 struct device_attribute
*attr
, char *buf
)
569 struct pvr2_sysfs
*sfp
;
570 sfp
= dev_get_drvdata(class_dev
);
571 if (!sfp
) return -EINVAL
;
572 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
573 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
577 static ssize_t
hdw_name_show(struct device
*class_dev
,
578 struct device_attribute
*attr
, char *buf
)
580 struct pvr2_sysfs
*sfp
;
581 sfp
= dev_get_drvdata(class_dev
);
582 if (!sfp
) return -EINVAL
;
583 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
584 pvr2_hdw_get_type(sfp
->channel
.hdw
));
588 static ssize_t
hdw_desc_show(struct device
*class_dev
,
589 struct device_attribute
*attr
, char *buf
)
591 struct pvr2_sysfs
*sfp
;
592 sfp
= dev_get_drvdata(class_dev
);
593 if (!sfp
) return -EINVAL
;
594 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
595 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
599 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
600 struct device_attribute
*attr
,
603 struct pvr2_sysfs
*sfp
;
604 sfp
= dev_get_drvdata(class_dev
);
605 if (!sfp
) return -EINVAL
;
606 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
607 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
608 pvr2_v4l_type_radio
));
612 static ssize_t
unit_number_show(struct device
*class_dev
,
613 struct device_attribute
*attr
, char *buf
)
615 struct pvr2_sysfs
*sfp
;
616 sfp
= dev_get_drvdata(class_dev
);
617 if (!sfp
) return -EINVAL
;
618 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
619 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
623 static void class_dev_create(struct pvr2_sysfs
*sfp
,
624 struct pvr2_sysfs_class
*class_ptr
)
626 struct usb_device
*usb_dev
;
627 struct device
*class_dev
;
630 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
631 if (!usb_dev
) return;
632 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
633 if (!class_dev
) return;
635 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
637 class_dev
->class = &class_ptr
->class;
639 dev_set_name(class_dev
, "%s",
640 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
642 class_dev
->parent
= get_device(&usb_dev
->dev
);
644 sfp
->class_dev
= class_dev
;
645 dev_set_drvdata(class_dev
, sfp
);
646 ret
= device_register(class_dev
);
648 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
649 "device_register failed");
654 sysfs_attr_init(&sfp
->attr_v4l_minor_number
.attr
);
655 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
656 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
657 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
658 sfp
->attr_v4l_minor_number
.store
= NULL
;
659 ret
= device_create_file(sfp
->class_dev
,
660 &sfp
->attr_v4l_minor_number
);
662 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
663 "device_create_file error: %d",
666 sfp
->v4l_minor_number_created_ok
= !0;
669 sysfs_attr_init(&sfp
->attr_v4l_radio_minor_number
.attr
);
670 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
671 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
672 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
673 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
674 ret
= device_create_file(sfp
->class_dev
,
675 &sfp
->attr_v4l_radio_minor_number
);
677 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
678 "device_create_file error: %d",
681 sfp
->v4l_radio_minor_number_created_ok
= !0;
684 sysfs_attr_init(&sfp
->attr_unit_number
.attr
);
685 sfp
->attr_unit_number
.attr
.name
= "unit_number";
686 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
687 sfp
->attr_unit_number
.show
= unit_number_show
;
688 sfp
->attr_unit_number
.store
= NULL
;
689 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
691 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
692 "device_create_file error: %d",
695 sfp
->unit_number_created_ok
= !0;
698 sysfs_attr_init(&sfp
->attr_bus_info
.attr
);
699 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
700 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
701 sfp
->attr_bus_info
.show
= bus_info_show
;
702 sfp
->attr_bus_info
.store
= NULL
;
703 ret
= device_create_file(sfp
->class_dev
,
704 &sfp
->attr_bus_info
);
706 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
707 "device_create_file error: %d",
710 sfp
->bus_info_created_ok
= !0;
713 sysfs_attr_init(&sfp
->attr_hdw_name
.attr
);
714 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
715 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
716 sfp
->attr_hdw_name
.show
= hdw_name_show
;
717 sfp
->attr_hdw_name
.store
= NULL
;
718 ret
= device_create_file(sfp
->class_dev
,
719 &sfp
->attr_hdw_name
);
721 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
722 "device_create_file error: %d",
725 sfp
->hdw_name_created_ok
= !0;
728 sysfs_attr_init(&sfp
->attr_hdw_desc
.attr
);
729 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
730 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
731 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
732 sfp
->attr_hdw_desc
.store
= NULL
;
733 ret
= device_create_file(sfp
->class_dev
,
734 &sfp
->attr_hdw_desc
);
736 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
737 "device_create_file error: %d",
740 sfp
->hdw_desc_created_ok
= !0;
743 pvr2_sysfs_add_controls(sfp
);
744 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
745 pvr2_sysfs_add_debugifc(sfp
);
746 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
750 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
752 struct pvr2_sysfs
*sfp
;
753 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
754 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
755 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
756 class_dev_destroy(sfp
);
757 pvr2_channel_done(&sfp
->channel
);
762 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
763 struct pvr2_sysfs_class
*class_ptr
)
765 struct pvr2_sysfs
*sfp
;
766 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
767 if (!sfp
) return sfp
;
768 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
769 pvr2_channel_init(&sfp
->channel
,mp
);
770 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
772 class_dev_create(sfp
,class_ptr
);
778 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
780 struct pvr2_sysfs_class
*clp
;
781 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
782 if (!clp
) return clp
;
783 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
785 clp
->class.name
= "pvrusb2";
786 clp
->class.class_release
= pvr2_sysfs_class_release
;
787 clp
->class.dev_release
= pvr2_sysfs_release
;
788 if (class_register(&clp
->class)) {
790 "Registration failed for pvr2_sysfs_class id=%p",clp
);
798 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
800 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp
);
801 class_unregister(&clp
->class);
805 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
806 static ssize_t
debuginfo_show(struct device
*class_dev
,
807 struct device_attribute
*attr
, char *buf
)
809 struct pvr2_sysfs
*sfp
;
810 sfp
= dev_get_drvdata(class_dev
);
811 if (!sfp
) return -EINVAL
;
812 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
813 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
817 static ssize_t
debugcmd_show(struct device
*class_dev
,
818 struct device_attribute
*attr
, char *buf
)
820 struct pvr2_sysfs
*sfp
;
821 sfp
= dev_get_drvdata(class_dev
);
822 if (!sfp
) return -EINVAL
;
823 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
827 static ssize_t
debugcmd_store(struct device
*class_dev
,
828 struct device_attribute
*attr
,
829 const char *buf
, size_t count
)
831 struct pvr2_sysfs
*sfp
;
834 sfp
= dev_get_drvdata(class_dev
);
835 if (!sfp
) return -EINVAL
;
837 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
838 if (ret
< 0) return ret
;
841 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
845 Stuff for Emacs to see, in order to encourage consistent editing style:
846 *** Local Variables: ***
848 *** fill-column: 75 ***
850 *** c-basic-offset: 8 ***