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 sysfs_attr_init(&cip
->attr_name
.attr
);
328 cip
->attr_name
.attr
.name
= "name";
329 cip
->attr_name
.attr
.mode
= S_IRUGO
;
330 cip
->attr_name
.show
= show_name
;
332 sysfs_attr_init(&cip
->attr_type
.attr
);
333 cip
->attr_type
.attr
.name
= "type";
334 cip
->attr_type
.attr
.mode
= S_IRUGO
;
335 cip
->attr_type
.show
= show_type
;
337 sysfs_attr_init(&cip
->attr_min
.attr
);
338 cip
->attr_min
.attr
.name
= "min_val";
339 cip
->attr_min
.attr
.mode
= S_IRUGO
;
340 cip
->attr_min
.show
= show_min
;
342 sysfs_attr_init(&cip
->attr_max
.attr
);
343 cip
->attr_max
.attr
.name
= "max_val";
344 cip
->attr_max
.attr
.mode
= S_IRUGO
;
345 cip
->attr_max
.show
= show_max
;
347 sysfs_attr_init(&cip
->attr_def
.attr
);
348 cip
->attr_def
.attr
.name
= "def_val";
349 cip
->attr_def
.attr
.mode
= S_IRUGO
;
350 cip
->attr_def
.show
= show_def
;
352 sysfs_attr_init(&cip
->attr_val
.attr
);
353 cip
->attr_val
.attr
.name
= "cur_val";
354 cip
->attr_val
.attr
.mode
= S_IRUGO
;
356 sysfs_attr_init(&cip
->attr_custom
.attr
);
357 cip
->attr_custom
.attr
.name
= "custom_val";
358 cip
->attr_custom
.attr
.mode
= S_IRUGO
;
360 sysfs_attr_init(&cip
->attr_enum
.attr
);
361 cip
->attr_enum
.attr
.name
= "enum_val";
362 cip
->attr_enum
.attr
.mode
= S_IRUGO
;
363 cip
->attr_enum
.show
= show_enum
;
365 sysfs_attr_init(&cip
->attr_bits
.attr
);
366 cip
->attr_bits
.attr
.name
= "bit_val";
367 cip
->attr_bits
.attr
.mode
= S_IRUGO
;
368 cip
->attr_bits
.show
= show_bits
;
370 if (pvr2_ctrl_is_writable(cptr
)) {
371 cip
->attr_val
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
372 cip
->attr_custom
.attr
.mode
|= S_IWUSR
|S_IWGRP
;
376 cip
->attr_gen
[acnt
++] = &cip
->attr_name
.attr
;
377 cip
->attr_gen
[acnt
++] = &cip
->attr_type
.attr
;
378 cip
->attr_gen
[acnt
++] = &cip
->attr_val
.attr
;
379 cip
->attr_gen
[acnt
++] = &cip
->attr_def
.attr
;
380 cip
->attr_val
.show
= show_val_norm
;
381 cip
->attr_val
.store
= store_val_norm
;
382 if (pvr2_ctrl_has_custom_symbols(cptr
)) {
383 cip
->attr_gen
[acnt
++] = &cip
->attr_custom
.attr
;
384 cip
->attr_custom
.show
= show_val_custom
;
385 cip
->attr_custom
.store
= store_val_custom
;
387 switch (pvr2_ctrl_get_type(cptr
)) {
389 // Control is an enumeration
390 cip
->attr_gen
[acnt
++] = &cip
->attr_enum
.attr
;
393 // Control is an integer
394 cip
->attr_gen
[acnt
++] = &cip
->attr_min
.attr
;
395 cip
->attr_gen
[acnt
++] = &cip
->attr_max
.attr
;
397 case pvr2_ctl_bitmask
:
398 // Control is an bitmask
399 cip
->attr_gen
[acnt
++] = &cip
->attr_bits
.attr
;
404 cnt
= scnprintf(cip
->name
,sizeof(cip
->name
)-1,"ctl_%s",
405 pvr2_ctrl_get_name(cptr
));
407 cip
->grp
.name
= cip
->name
;
408 cip
->grp
.attrs
= cip
->attr_gen
;
410 ret
= sysfs_create_group(&sfp
->class_dev
->kobj
,&cip
->grp
);
412 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
413 "sysfs_create_group error: %d",
417 cip
->created_ok
= !0;
420 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
421 static ssize_t
debuginfo_show(struct device
*, struct device_attribute
*,
423 static ssize_t
debugcmd_show(struct device
*, struct device_attribute
*,
425 static ssize_t
debugcmd_store(struct device
*, struct device_attribute
*,
426 const char *, size_t count
);
428 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs
*sfp
)
430 struct pvr2_sysfs_debugifc
*dip
;
433 dip
= kzalloc(sizeof(*dip
),GFP_KERNEL
);
435 sysfs_attr_init(&dip
->attr_debugcmd
.attr
);
436 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
437 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
438 dip
->attr_debugcmd
.show
= debugcmd_show
;
439 dip
->attr_debugcmd
.store
= debugcmd_store
;
440 sysfs_attr_init(&dip
->attr_debuginfo
.attr
);
441 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
442 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
443 dip
->attr_debuginfo
.show
= debuginfo_show
;
445 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
447 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
448 "device_create_file error: %d",
451 dip
->debugcmd_created_ok
= !0;
453 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
455 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
456 "device_create_file error: %d",
459 dip
->debuginfo_created_ok
= !0;
464 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
466 if (!sfp
->debugifc
) return;
467 if (sfp
->debugifc
->debuginfo_created_ok
) {
468 device_remove_file(sfp
->class_dev
,
469 &sfp
->debugifc
->attr_debuginfo
);
471 if (sfp
->debugifc
->debugcmd_created_ok
) {
472 device_remove_file(sfp
->class_dev
,
473 &sfp
->debugifc
->attr_debugcmd
);
475 kfree(sfp
->debugifc
);
476 sfp
->debugifc
= NULL
;
478 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
481 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
483 unsigned int idx
,cnt
;
484 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
485 for (idx
= 0; idx
< cnt
; idx
++) {
486 pvr2_sysfs_add_control(sfp
,idx
);
491 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
493 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
494 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
495 cip2
= cip1
->item_next
;
496 if (cip1
->created_ok
) {
497 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
499 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
505 static void pvr2_sysfs_class_release(struct class *class)
507 struct pvr2_sysfs_class
*clp
;
508 clp
= container_of(class,struct pvr2_sysfs_class
,class);
509 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
514 static void pvr2_sysfs_release(struct device
*class_dev
)
516 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
521 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
524 if (!sfp
->class_dev
) return;
525 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
526 pvr2_sysfs_tear_down_debugifc(sfp
);
527 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
528 pvr2_sysfs_tear_down_controls(sfp
);
529 if (sfp
->hdw_desc_created_ok
) {
530 device_remove_file(sfp
->class_dev
,
531 &sfp
->attr_hdw_desc
);
533 if (sfp
->hdw_name_created_ok
) {
534 device_remove_file(sfp
->class_dev
,
535 &sfp
->attr_hdw_name
);
537 if (sfp
->bus_info_created_ok
) {
538 device_remove_file(sfp
->class_dev
,
539 &sfp
->attr_bus_info
);
541 if (sfp
->v4l_minor_number_created_ok
) {
542 device_remove_file(sfp
->class_dev
,
543 &sfp
->attr_v4l_minor_number
);
545 if (sfp
->v4l_radio_minor_number_created_ok
) {
546 device_remove_file(sfp
->class_dev
,
547 &sfp
->attr_v4l_radio_minor_number
);
549 if (sfp
->unit_number_created_ok
) {
550 device_remove_file(sfp
->class_dev
,
551 &sfp
->attr_unit_number
);
553 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
554 dev_set_drvdata(sfp
->class_dev
, NULL
);
555 dev
= sfp
->class_dev
->parent
;
556 sfp
->class_dev
->parent
= NULL
;
558 device_unregister(sfp
->class_dev
);
559 sfp
->class_dev
= NULL
;
563 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
564 struct device_attribute
*attr
, char *buf
)
566 struct pvr2_sysfs
*sfp
;
567 sfp
= dev_get_drvdata(class_dev
);
568 if (!sfp
) return -EINVAL
;
569 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
570 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
571 pvr2_v4l_type_video
));
575 static ssize_t
bus_info_show(struct device
*class_dev
,
576 struct device_attribute
*attr
, char *buf
)
578 struct pvr2_sysfs
*sfp
;
579 sfp
= dev_get_drvdata(class_dev
);
580 if (!sfp
) return -EINVAL
;
581 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
582 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
586 static ssize_t
hdw_name_show(struct device
*class_dev
,
587 struct device_attribute
*attr
, char *buf
)
589 struct pvr2_sysfs
*sfp
;
590 sfp
= dev_get_drvdata(class_dev
);
591 if (!sfp
) return -EINVAL
;
592 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
593 pvr2_hdw_get_type(sfp
->channel
.hdw
));
597 static ssize_t
hdw_desc_show(struct device
*class_dev
,
598 struct device_attribute
*attr
, char *buf
)
600 struct pvr2_sysfs
*sfp
;
601 sfp
= dev_get_drvdata(class_dev
);
602 if (!sfp
) return -EINVAL
;
603 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
604 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
608 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
609 struct device_attribute
*attr
,
612 struct pvr2_sysfs
*sfp
;
613 sfp
= dev_get_drvdata(class_dev
);
614 if (!sfp
) return -EINVAL
;
615 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
616 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
617 pvr2_v4l_type_radio
));
621 static ssize_t
unit_number_show(struct device
*class_dev
,
622 struct device_attribute
*attr
, char *buf
)
624 struct pvr2_sysfs
*sfp
;
625 sfp
= dev_get_drvdata(class_dev
);
626 if (!sfp
) return -EINVAL
;
627 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
628 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
632 static void class_dev_create(struct pvr2_sysfs
*sfp
,
633 struct pvr2_sysfs_class
*class_ptr
)
635 struct usb_device
*usb_dev
;
636 struct device
*class_dev
;
639 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
640 if (!usb_dev
) return;
641 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
642 if (!class_dev
) return;
644 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
646 class_dev
->class = &class_ptr
->class;
648 dev_set_name(class_dev
, "%s",
649 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
651 class_dev
->parent
= get_device(&usb_dev
->dev
);
653 sfp
->class_dev
= class_dev
;
654 dev_set_drvdata(class_dev
, sfp
);
655 ret
= device_register(class_dev
);
657 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
658 "device_register failed");
659 put_device(class_dev
);
663 sysfs_attr_init(&sfp
->attr_v4l_minor_number
.attr
);
664 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
665 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
666 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
667 sfp
->attr_v4l_minor_number
.store
= NULL
;
668 ret
= device_create_file(sfp
->class_dev
,
669 &sfp
->attr_v4l_minor_number
);
671 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
672 "device_create_file error: %d",
675 sfp
->v4l_minor_number_created_ok
= !0;
678 sysfs_attr_init(&sfp
->attr_v4l_radio_minor_number
.attr
);
679 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
680 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
681 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
682 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
683 ret
= device_create_file(sfp
->class_dev
,
684 &sfp
->attr_v4l_radio_minor_number
);
686 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
687 "device_create_file error: %d",
690 sfp
->v4l_radio_minor_number_created_ok
= !0;
693 sysfs_attr_init(&sfp
->attr_unit_number
.attr
);
694 sfp
->attr_unit_number
.attr
.name
= "unit_number";
695 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
696 sfp
->attr_unit_number
.show
= unit_number_show
;
697 sfp
->attr_unit_number
.store
= NULL
;
698 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
700 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
701 "device_create_file error: %d",
704 sfp
->unit_number_created_ok
= !0;
707 sysfs_attr_init(&sfp
->attr_bus_info
.attr
);
708 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
709 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
710 sfp
->attr_bus_info
.show
= bus_info_show
;
711 sfp
->attr_bus_info
.store
= NULL
;
712 ret
= device_create_file(sfp
->class_dev
,
713 &sfp
->attr_bus_info
);
715 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
716 "device_create_file error: %d",
719 sfp
->bus_info_created_ok
= !0;
722 sysfs_attr_init(&sfp
->attr_hdw_name
.attr
);
723 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
724 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
725 sfp
->attr_hdw_name
.show
= hdw_name_show
;
726 sfp
->attr_hdw_name
.store
= NULL
;
727 ret
= device_create_file(sfp
->class_dev
,
728 &sfp
->attr_hdw_name
);
730 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
731 "device_create_file error: %d",
734 sfp
->hdw_name_created_ok
= !0;
737 sysfs_attr_init(&sfp
->attr_hdw_desc
.attr
);
738 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
739 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
740 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
741 sfp
->attr_hdw_desc
.store
= NULL
;
742 ret
= device_create_file(sfp
->class_dev
,
743 &sfp
->attr_hdw_desc
);
745 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
746 "device_create_file error: %d",
749 sfp
->hdw_desc_created_ok
= !0;
752 pvr2_sysfs_add_controls(sfp
);
753 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
754 pvr2_sysfs_add_debugifc(sfp
);
755 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
759 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
761 struct pvr2_sysfs
*sfp
;
762 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
763 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
764 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
765 class_dev_destroy(sfp
);
766 pvr2_channel_done(&sfp
->channel
);
771 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
772 struct pvr2_sysfs_class
*class_ptr
)
774 struct pvr2_sysfs
*sfp
;
775 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
776 if (!sfp
) return sfp
;
777 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
778 pvr2_channel_init(&sfp
->channel
,mp
);
779 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
781 class_dev_create(sfp
,class_ptr
);
787 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
789 struct pvr2_sysfs_class
*clp
;
790 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
791 if (!clp
) return clp
;
792 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
794 clp
->class.name
= "pvrusb2";
795 clp
->class.class_release
= pvr2_sysfs_class_release
;
796 clp
->class.dev_release
= pvr2_sysfs_release
;
797 if (class_register(&clp
->class)) {
799 "Registration failed for pvr2_sysfs_class id=%p",clp
);
807 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
809 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp
);
810 class_unregister(&clp
->class);
814 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
815 static ssize_t
debuginfo_show(struct device
*class_dev
,
816 struct device_attribute
*attr
, char *buf
)
818 struct pvr2_sysfs
*sfp
;
819 sfp
= dev_get_drvdata(class_dev
);
820 if (!sfp
) return -EINVAL
;
821 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
822 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
826 static ssize_t
debugcmd_show(struct device
*class_dev
,
827 struct device_attribute
*attr
, char *buf
)
829 struct pvr2_sysfs
*sfp
;
830 sfp
= dev_get_drvdata(class_dev
);
831 if (!sfp
) return -EINVAL
;
832 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
836 static ssize_t
debugcmd_store(struct device
*class_dev
,
837 struct device_attribute
*attr
,
838 const char *buf
, size_t count
)
840 struct pvr2_sysfs
*sfp
;
843 sfp
= dev_get_drvdata(class_dev
);
844 if (!sfp
) return -EINVAL
;
846 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
847 if (ret
< 0) return ret
;
850 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
854 Stuff for Emacs to see, in order to encourage consistent editing style:
855 *** Local Variables: ***
857 *** fill-column: 75 ***
859 *** c-basic-offset: 8 ***