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 return scnprintf(buf
, PAGE_SIZE
, "%s\n", name
);
122 static ssize_t
show_min(struct device
*class_dev
,
123 struct device_attribute
*attr
,
126 struct pvr2_sysfs_ctl_item
*cip
;
128 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_min
);
129 val
= pvr2_ctrl_get_min(cip
->cptr
);
130 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
131 cip
->chptr
, cip
->ctl_id
, val
);
132 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
135 static ssize_t
show_max(struct device
*class_dev
,
136 struct device_attribute
*attr
,
139 struct pvr2_sysfs_ctl_item
*cip
;
141 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_max
);
142 val
= pvr2_ctrl_get_max(cip
->cptr
);
143 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
144 cip
->chptr
, cip
->ctl_id
, val
);
145 return scnprintf(buf
, PAGE_SIZE
, "%ld\n", val
);
148 static ssize_t
show_def(struct device
*class_dev
,
149 struct device_attribute
*attr
,
152 struct pvr2_sysfs_ctl_item
*cip
;
155 unsigned int cnt
= 0;
156 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_def
);
157 ret
= pvr2_ctrl_get_def(cip
->cptr
, &val
);
158 if (ret
< 0) return ret
;
159 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
160 buf
, PAGE_SIZE
- 1, &cnt
);
161 pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
162 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
167 static ssize_t
show_val_norm(struct device
*class_dev
,
168 struct device_attribute
*attr
,
171 struct pvr2_sysfs_ctl_item
*cip
;
174 unsigned int cnt
= 0;
175 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
176 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
177 if (ret
< 0) return ret
;
178 ret
= pvr2_ctrl_value_to_sym(cip
->cptr
, ~0, val
,
179 buf
, PAGE_SIZE
- 1, &cnt
);
180 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
181 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
186 static ssize_t
show_val_custom(struct device
*class_dev
,
187 struct device_attribute
*attr
,
190 struct pvr2_sysfs_ctl_item
*cip
;
193 unsigned int cnt
= 0;
194 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
195 ret
= pvr2_ctrl_get_value(cip
->cptr
, &val
);
196 if (ret
< 0) return ret
;
197 ret
= pvr2_ctrl_custom_value_to_sym(cip
->cptr
, ~0, val
,
198 buf
, PAGE_SIZE
- 1, &cnt
);
199 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
200 cip
->chptr
, cip
->ctl_id
, cnt
, buf
, val
);
205 static ssize_t
show_enum(struct device
*class_dev
,
206 struct device_attribute
*attr
,
209 struct pvr2_sysfs_ctl_item
*cip
;
211 unsigned int bcnt
, ccnt
, ecnt
;
212 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_enum
);
213 ecnt
= pvr2_ctrl_get_cnt(cip
->cptr
);
215 for (val
= 0; val
< ecnt
; val
++) {
216 pvr2_ctrl_get_valname(cip
->cptr
, val
, buf
+ bcnt
,
217 PAGE_SIZE
- bcnt
, &ccnt
);
220 if (bcnt
>= PAGE_SIZE
) break;
224 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
225 cip
->chptr
, cip
->ctl_id
);
229 static ssize_t
show_bits(struct device
*class_dev
,
230 struct device_attribute
*attr
,
233 struct pvr2_sysfs_ctl_item
*cip
;
235 unsigned int bcnt
, ccnt
;
236 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_bits
);
237 valid_bits
= pvr2_ctrl_get_mask(cip
->cptr
);
239 for (msk
= 1; valid_bits
; msk
<<= 1) {
240 if (!(msk
& valid_bits
)) continue;
242 pvr2_ctrl_get_valname(cip
->cptr
, msk
, buf
+ bcnt
,
243 PAGE_SIZE
- bcnt
, &ccnt
);
245 if (bcnt
>= PAGE_SIZE
) break;
249 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
250 cip
->chptr
, cip
->ctl_id
);
254 static int store_val_any(struct pvr2_sysfs_ctl_item
*cip
, int customfl
,
255 const char *buf
,unsigned int count
)
260 ret
= pvr2_ctrl_custom_sym_to_value(cip
->cptr
, buf
, count
,
263 ret
= pvr2_ctrl_sym_to_value(cip
->cptr
, buf
, count
,
266 if (ret
< 0) return ret
;
267 ret
= pvr2_ctrl_set_mask_value(cip
->cptr
, mask
, val
);
268 pvr2_hdw_commit_ctl(cip
->chptr
->channel
.hdw
);
272 static ssize_t
store_val_norm(struct device
*class_dev
,
273 struct device_attribute
*attr
,
274 const char *buf
, size_t count
)
276 struct pvr2_sysfs_ctl_item
*cip
;
278 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_val
);
279 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
280 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
281 ret
= store_val_any(cip
, 0, buf
, count
);
282 if (!ret
) ret
= count
;
286 static ssize_t
store_val_custom(struct device
*class_dev
,
287 struct device_attribute
*attr
,
288 const char *buf
, size_t count
)
290 struct pvr2_sysfs_ctl_item
*cip
;
292 cip
= container_of(attr
, struct pvr2_sysfs_ctl_item
, attr_custom
);
293 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
294 cip
->chptr
, cip
->ctl_id
, (int)count
, buf
);
295 ret
= store_val_any(cip
, 1, buf
, count
);
296 if (!ret
) ret
= count
;
300 static void pvr2_sysfs_add_control(struct pvr2_sysfs
*sfp
,int ctl_id
)
302 struct pvr2_sysfs_ctl_item
*cip
;
303 struct pvr2_ctrl
*cptr
;
304 unsigned int cnt
,acnt
;
307 cptr
= pvr2_hdw_get_ctrl_by_index(sfp
->channel
.hdw
,ctl_id
);
310 cip
= kzalloc(sizeof(*cip
),GFP_KERNEL
);
312 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip
);
315 cip
->ctl_id
= ctl_id
;
318 cip
->item_next
= NULL
;
319 if (sfp
->item_last
) {
320 sfp
->item_last
->item_next
= cip
;
322 sfp
->item_first
= cip
;
324 sfp
->item_last
= cip
;
326 sysfs_attr_init(&cip
->attr_name
.attr
);
327 cip
->attr_name
.attr
.name
= "name";
328 cip
->attr_name
.attr
.mode
= S_IRUGO
;
329 cip
->attr_name
.show
= show_name
;
331 sysfs_attr_init(&cip
->attr_type
.attr
);
332 cip
->attr_type
.attr
.name
= "type";
333 cip
->attr_type
.attr
.mode
= S_IRUGO
;
334 cip
->attr_type
.show
= show_type
;
336 sysfs_attr_init(&cip
->attr_min
.attr
);
337 cip
->attr_min
.attr
.name
= "min_val";
338 cip
->attr_min
.attr
.mode
= S_IRUGO
;
339 cip
->attr_min
.show
= show_min
;
341 sysfs_attr_init(&cip
->attr_max
.attr
);
342 cip
->attr_max
.attr
.name
= "max_val";
343 cip
->attr_max
.attr
.mode
= S_IRUGO
;
344 cip
->attr_max
.show
= show_max
;
346 sysfs_attr_init(&cip
->attr_def
.attr
);
347 cip
->attr_def
.attr
.name
= "def_val";
348 cip
->attr_def
.attr
.mode
= S_IRUGO
;
349 cip
->attr_def
.show
= show_def
;
351 sysfs_attr_init(&cip
->attr_val
.attr
);
352 cip
->attr_val
.attr
.name
= "cur_val";
353 cip
->attr_val
.attr
.mode
= S_IRUGO
;
355 sysfs_attr_init(&cip
->attr_custom
.attr
);
356 cip
->attr_custom
.attr
.name
= "custom_val";
357 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
359 sysfs_attr_init(&cip
->attr_enum
.attr
);
360 cip
->attr_enum
.attr
.name
= "enum_val";
361 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
362 cip
->attr_enum
.show
= show_enum
;
364 sysfs_attr_init(&cip
->attr_bits
.attr
);
365 cip
->attr_bits
.attr
.name
= "bit_val";
366 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
367 cip
->attr_bits
.show
= show_bits
;
369 if (pvr2_ctrl_is_writable(cptr
)) {
370 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
371 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
375 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
376 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
377 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
378 cip
->attr_gen
[acnt
++] = &cip
->attr_def
.attr
;
379 cip
->attr_val
.show
= show_val_norm
;
380 cip
->attr_val
.store
= store_val_norm
;
381 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
382 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
383 cip
->attr_custom
.show
= show_val_custom
;
384 cip
->attr_custom
.store
= store_val_custom
;
386 switch (pvr2_ctrl_get_type(cptr
)) {
388 // Control is an enumeration
389 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
392 // Control is an integer
393 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
394 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
396 case pvr2_ctl_bitmask
:
397 // Control is an bitmask
398 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
403 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
404 pvr2_ctrl_get_name(cptr
));
406 cip
->grp
.name
= cip
->name
;
407 cip
->grp
.attrs
= cip
->attr_gen
;
409 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
411 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
412 "sysfs_create_group error: %d",
416 cip
->created_ok
= !0;
419 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
420 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
422 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
424 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
425 const char *, size_t count
);
427 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
429 struct pvr2_sysfs_debugifc
*dip
;
432 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
434 sysfs_attr_init(&dip
->attr_debugcmd
.attr
);
435 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
436 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
437 dip
->attr_debugcmd
.show
= debugcmd_show
;
438 dip
->attr_debugcmd
.store
= debugcmd_store
;
439 sysfs_attr_init(&dip
->attr_debuginfo
.attr
);
440 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
441 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
442 dip
->attr_debuginfo
.show
= debuginfo_show
;
444 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
446 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
447 "device_create_file error: %d",
450 dip
->debugcmd_created_ok
= !0;
452 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
454 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
455 "device_create_file error: %d",
458 dip
->debuginfo_created_ok
= !0;
463 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
465 if (!sfp
->debugifc
) return;
466 if (sfp
->debugifc
->debuginfo_created_ok
) {
467 device_remove_file(sfp
->class_dev
,
468 &sfp
->debugifc
->attr_debuginfo
);
470 if (sfp
->debugifc
->debugcmd_created_ok
) {
471 device_remove_file(sfp
->class_dev
,
472 &sfp
->debugifc
->attr_debugcmd
);
474 kfree(sfp
->debugifc
);
475 sfp
->debugifc
= NULL
;
477 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
480 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
482 unsigned int idx
,cnt
;
483 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
484 for (idx
= 0; idx
< cnt
; idx
++) {
485 pvr2_sysfs_add_control(sfp
,idx
);
490 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
492 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
493 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
494 cip2
= cip1
->item_next
;
495 if (cip1
->created_ok
) {
496 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
498 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
504 static void pvr2_sysfs_class_release(struct class *class)
506 struct pvr2_sysfs_class
*clp
;
507 clp
= container_of(class,struct pvr2_sysfs_class
,class);
508 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
513 static void pvr2_sysfs_release(struct device
*class_dev
)
515 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
520 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
523 if (!sfp
->class_dev
) return;
524 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
525 pvr2_sysfs_tear_down_debugifc(sfp
);
526 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
527 pvr2_sysfs_tear_down_controls(sfp
);
528 if (sfp
->hdw_desc_created_ok
) {
529 device_remove_file(sfp
->class_dev
,
530 &sfp
->attr_hdw_desc
);
532 if (sfp
->hdw_name_created_ok
) {
533 device_remove_file(sfp
->class_dev
,
534 &sfp
->attr_hdw_name
);
536 if (sfp
->bus_info_created_ok
) {
537 device_remove_file(sfp
->class_dev
,
538 &sfp
->attr_bus_info
);
540 if (sfp
->v4l_minor_number_created_ok
) {
541 device_remove_file(sfp
->class_dev
,
542 &sfp
->attr_v4l_minor_number
);
544 if (sfp
->v4l_radio_minor_number_created_ok
) {
545 device_remove_file(sfp
->class_dev
,
546 &sfp
->attr_v4l_radio_minor_number
);
548 if (sfp
->unit_number_created_ok
) {
549 device_remove_file(sfp
->class_dev
,
550 &sfp
->attr_unit_number
);
552 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
553 dev_set_drvdata(sfp
->class_dev
, NULL
);
554 dev
= sfp
->class_dev
->parent
;
555 sfp
->class_dev
->parent
= NULL
;
557 device_unregister(sfp
->class_dev
);
558 sfp
->class_dev
= NULL
;
562 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
563 struct device_attribute
*attr
, char *buf
)
565 struct pvr2_sysfs
*sfp
;
566 sfp
= dev_get_drvdata(class_dev
);
567 if (!sfp
) return -EINVAL
;
568 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
569 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
570 pvr2_v4l_type_video
));
574 static ssize_t
bus_info_show(struct device
*class_dev
,
575 struct device_attribute
*attr
, char *buf
)
577 struct pvr2_sysfs
*sfp
;
578 sfp
= dev_get_drvdata(class_dev
);
579 if (!sfp
) return -EINVAL
;
580 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
581 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
585 static ssize_t
hdw_name_show(struct device
*class_dev
,
586 struct device_attribute
*attr
, char *buf
)
588 struct pvr2_sysfs
*sfp
;
589 sfp
= dev_get_drvdata(class_dev
);
590 if (!sfp
) return -EINVAL
;
591 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
592 pvr2_hdw_get_type(sfp
->channel
.hdw
));
596 static ssize_t
hdw_desc_show(struct device
*class_dev
,
597 struct device_attribute
*attr
, char *buf
)
599 struct pvr2_sysfs
*sfp
;
600 sfp
= dev_get_drvdata(class_dev
);
601 if (!sfp
) return -EINVAL
;
602 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
603 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
607 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
608 struct device_attribute
*attr
,
611 struct pvr2_sysfs
*sfp
;
612 sfp
= dev_get_drvdata(class_dev
);
613 if (!sfp
) return -EINVAL
;
614 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
615 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
616 pvr2_v4l_type_radio
));
620 static ssize_t
unit_number_show(struct device
*class_dev
,
621 struct device_attribute
*attr
, char *buf
)
623 struct pvr2_sysfs
*sfp
;
624 sfp
= dev_get_drvdata(class_dev
);
625 if (!sfp
) return -EINVAL
;
626 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
627 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
631 static void class_dev_create(struct pvr2_sysfs
*sfp
,
632 struct pvr2_sysfs_class
*class_ptr
)
634 struct usb_device
*usb_dev
;
635 struct device
*class_dev
;
638 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
639 if (!usb_dev
) return;
640 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
641 if (!class_dev
) return;
643 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
645 class_dev
->class = &class_ptr
->class;
647 dev_set_name(class_dev
, "%s",
648 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
650 class_dev
->parent
= get_device(&usb_dev
->dev
);
652 sfp
->class_dev
= class_dev
;
653 dev_set_drvdata(class_dev
, sfp
);
654 ret
= device_register(class_dev
);
656 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
657 "device_register failed");
658 put_device(class_dev
);
662 sysfs_attr_init(&sfp
->attr_v4l_minor_number
.attr
);
663 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
664 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
665 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
666 sfp
->attr_v4l_minor_number
.store
= NULL
;
667 ret
= device_create_file(sfp
->class_dev
,
668 &sfp
->attr_v4l_minor_number
);
670 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
671 "device_create_file error: %d",
674 sfp
->v4l_minor_number_created_ok
= !0;
677 sysfs_attr_init(&sfp
->attr_v4l_radio_minor_number
.attr
);
678 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
679 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
680 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
681 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
682 ret
= device_create_file(sfp
->class_dev
,
683 &sfp
->attr_v4l_radio_minor_number
);
685 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
686 "device_create_file error: %d",
689 sfp
->v4l_radio_minor_number_created_ok
= !0;
692 sysfs_attr_init(&sfp
->attr_unit_number
.attr
);
693 sfp
->attr_unit_number
.attr
.name
= "unit_number";
694 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
695 sfp
->attr_unit_number
.show
= unit_number_show
;
696 sfp
->attr_unit_number
.store
= NULL
;
697 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
699 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
700 "device_create_file error: %d",
703 sfp
->unit_number_created_ok
= !0;
706 sysfs_attr_init(&sfp
->attr_bus_info
.attr
);
707 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
708 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
709 sfp
->attr_bus_info
.show
= bus_info_show
;
710 sfp
->attr_bus_info
.store
= NULL
;
711 ret
= device_create_file(sfp
->class_dev
,
712 &sfp
->attr_bus_info
);
714 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
715 "device_create_file error: %d",
718 sfp
->bus_info_created_ok
= !0;
721 sysfs_attr_init(&sfp
->attr_hdw_name
.attr
);
722 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
723 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
724 sfp
->attr_hdw_name
.show
= hdw_name_show
;
725 sfp
->attr_hdw_name
.store
= NULL
;
726 ret
= device_create_file(sfp
->class_dev
,
727 &sfp
->attr_hdw_name
);
729 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
730 "device_create_file error: %d",
733 sfp
->hdw_name_created_ok
= !0;
736 sysfs_attr_init(&sfp
->attr_hdw_desc
.attr
);
737 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
738 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
739 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
740 sfp
->attr_hdw_desc
.store
= NULL
;
741 ret
= device_create_file(sfp
->class_dev
,
742 &sfp
->attr_hdw_desc
);
744 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
745 "device_create_file error: %d",
748 sfp
->hdw_desc_created_ok
= !0;
751 pvr2_sysfs_add_controls(sfp
);
752 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
753 pvr2_sysfs_add_debugifc(sfp
);
754 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
758 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
760 struct pvr2_sysfs
*sfp
;
761 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
762 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
763 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
764 class_dev_destroy(sfp
);
765 pvr2_channel_done(&sfp
->channel
);
770 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
771 struct pvr2_sysfs_class
*class_ptr
)
773 struct pvr2_sysfs
*sfp
;
774 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
775 if (!sfp
) return sfp
;
776 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
777 pvr2_channel_init(&sfp
->channel
,mp
);
778 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
780 class_dev_create(sfp
,class_ptr
);
786 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
788 struct pvr2_sysfs_class
*clp
;
789 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
790 if (!clp
) return clp
;
791 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
793 clp
->class.name
= "pvrusb2";
794 clp
->class.class_release
= pvr2_sysfs_class_release
;
795 clp
->class.dev_release
= pvr2_sysfs_release
;
796 if (class_register(&clp
->class)) {
798 "Registration failed for pvr2_sysfs_class id=%p",clp
);
806 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
808 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp
);
809 class_unregister(&clp
->class);
813 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
814 static ssize_t
debuginfo_show(struct device
*class_dev
,
815 struct device_attribute
*attr
, char *buf
)
817 struct pvr2_sysfs
*sfp
;
818 sfp
= dev_get_drvdata(class_dev
);
819 if (!sfp
) return -EINVAL
;
820 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
821 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
825 static ssize_t
debugcmd_show(struct device
*class_dev
,
826 struct device_attribute
*attr
, char *buf
)
828 struct pvr2_sysfs
*sfp
;
829 sfp
= dev_get_drvdata(class_dev
);
830 if (!sfp
) return -EINVAL
;
831 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
835 static ssize_t
debugcmd_store(struct device
*class_dev
,
836 struct device_attribute
*attr
,
837 const char *buf
, size_t count
)
839 struct pvr2_sysfs
*sfp
;
842 sfp
= dev_get_drvdata(class_dev
);
843 if (!sfp
) return -EINVAL
;
845 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
846 if (ret
< 0) return ret
;
849 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */