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
[7];
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 dip
->attr_debugcmd
.attr
.name
= "debugcmd";
427 dip
->attr_debugcmd
.attr
.mode
= S_IRUGO
|S_IWUSR
|S_IWGRP
;
428 dip
->attr_debugcmd
.show
= debugcmd_show
;
429 dip
->attr_debugcmd
.store
= debugcmd_store
;
430 dip
->attr_debuginfo
.attr
.name
= "debuginfo";
431 dip
->attr_debuginfo
.attr
.mode
= S_IRUGO
;
432 dip
->attr_debuginfo
.show
= debuginfo_show
;
434 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debugcmd
);
436 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
437 "device_create_file error: %d",
440 dip
->debugcmd_created_ok
= !0;
442 ret
= device_create_file(sfp
->class_dev
,&dip
->attr_debuginfo
);
444 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
445 "device_create_file error: %d",
448 dip
->debuginfo_created_ok
= !0;
453 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs
*sfp
)
455 if (!sfp
->debugifc
) return;
456 if (sfp
->debugifc
->debuginfo_created_ok
) {
457 device_remove_file(sfp
->class_dev
,
458 &sfp
->debugifc
->attr_debuginfo
);
460 if (sfp
->debugifc
->debugcmd_created_ok
) {
461 device_remove_file(sfp
->class_dev
,
462 &sfp
->debugifc
->attr_debugcmd
);
464 kfree(sfp
->debugifc
);
465 sfp
->debugifc
= NULL
;
467 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
470 static void pvr2_sysfs_add_controls(struct pvr2_sysfs
*sfp
)
472 unsigned int idx
,cnt
;
473 cnt
= pvr2_hdw_get_ctrl_count(sfp
->channel
.hdw
);
474 for (idx
= 0; idx
< cnt
; idx
++) {
475 pvr2_sysfs_add_control(sfp
,idx
);
480 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs
*sfp
)
482 struct pvr2_sysfs_ctl_item
*cip1
,*cip2
;
483 for (cip1
= sfp
->item_first
; cip1
; cip1
= cip2
) {
484 cip2
= cip1
->item_next
;
485 if (cip1
->created_ok
) {
486 sysfs_remove_group(&sfp
->class_dev
->kobj
,&cip1
->grp
);
488 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1
);
494 static void pvr2_sysfs_class_release(struct class *class)
496 struct pvr2_sysfs_class
*clp
;
497 clp
= container_of(class,struct pvr2_sysfs_class
,class);
498 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp
);
503 static void pvr2_sysfs_release(struct device
*class_dev
)
505 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev
);
510 static void class_dev_destroy(struct pvr2_sysfs
*sfp
)
512 if (!sfp
->class_dev
) return;
513 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
514 pvr2_sysfs_tear_down_debugifc(sfp
);
515 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
516 pvr2_sysfs_tear_down_controls(sfp
);
517 if (sfp
->hdw_desc_created_ok
) {
518 device_remove_file(sfp
->class_dev
,
519 &sfp
->attr_hdw_desc
);
521 if (sfp
->hdw_name_created_ok
) {
522 device_remove_file(sfp
->class_dev
,
523 &sfp
->attr_hdw_name
);
525 if (sfp
->bus_info_created_ok
) {
526 device_remove_file(sfp
->class_dev
,
527 &sfp
->attr_bus_info
);
529 if (sfp
->v4l_minor_number_created_ok
) {
530 device_remove_file(sfp
->class_dev
,
531 &sfp
->attr_v4l_minor_number
);
533 if (sfp
->v4l_radio_minor_number_created_ok
) {
534 device_remove_file(sfp
->class_dev
,
535 &sfp
->attr_v4l_radio_minor_number
);
537 if (sfp
->unit_number_created_ok
) {
538 device_remove_file(sfp
->class_dev
,
539 &sfp
->attr_unit_number
);
541 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp
->class_dev
);
542 dev_set_drvdata(sfp
->class_dev
, NULL
);
543 device_unregister(sfp
->class_dev
);
544 sfp
->class_dev
= NULL
;
548 static ssize_t
v4l_minor_number_show(struct device
*class_dev
,
549 struct device_attribute
*attr
, char *buf
)
551 struct pvr2_sysfs
*sfp
;
552 sfp
= dev_get_drvdata(class_dev
);
553 if (!sfp
) return -EINVAL
;
554 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
555 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
556 pvr2_v4l_type_video
));
560 static ssize_t
bus_info_show(struct device
*class_dev
,
561 struct device_attribute
*attr
, char *buf
)
563 struct pvr2_sysfs
*sfp
;
564 sfp
= dev_get_drvdata(class_dev
);
565 if (!sfp
) return -EINVAL
;
566 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
567 pvr2_hdw_get_bus_info(sfp
->channel
.hdw
));
571 static ssize_t
hdw_name_show(struct device
*class_dev
,
572 struct device_attribute
*attr
, char *buf
)
574 struct pvr2_sysfs
*sfp
;
575 sfp
= dev_get_drvdata(class_dev
);
576 if (!sfp
) return -EINVAL
;
577 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
578 pvr2_hdw_get_type(sfp
->channel
.hdw
));
582 static ssize_t
hdw_desc_show(struct device
*class_dev
,
583 struct device_attribute
*attr
, char *buf
)
585 struct pvr2_sysfs
*sfp
;
586 sfp
= dev_get_drvdata(class_dev
);
587 if (!sfp
) return -EINVAL
;
588 return scnprintf(buf
,PAGE_SIZE
,"%s\n",
589 pvr2_hdw_get_desc(sfp
->channel
.hdw
));
593 static ssize_t
v4l_radio_minor_number_show(struct device
*class_dev
,
594 struct device_attribute
*attr
,
597 struct pvr2_sysfs
*sfp
;
598 sfp
= dev_get_drvdata(class_dev
);
599 if (!sfp
) return -EINVAL
;
600 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
601 pvr2_hdw_v4l_get_minor_number(sfp
->channel
.hdw
,
602 pvr2_v4l_type_radio
));
606 static ssize_t
unit_number_show(struct device
*class_dev
,
607 struct device_attribute
*attr
, char *buf
)
609 struct pvr2_sysfs
*sfp
;
610 sfp
= dev_get_drvdata(class_dev
);
611 if (!sfp
) return -EINVAL
;
612 return scnprintf(buf
,PAGE_SIZE
,"%d\n",
613 pvr2_hdw_get_unit_number(sfp
->channel
.hdw
));
617 static void class_dev_create(struct pvr2_sysfs
*sfp
,
618 struct pvr2_sysfs_class
*class_ptr
)
620 struct usb_device
*usb_dev
;
621 struct device
*class_dev
;
624 usb_dev
= pvr2_hdw_get_dev(sfp
->channel
.hdw
);
625 if (!usb_dev
) return;
626 class_dev
= kzalloc(sizeof(*class_dev
),GFP_KERNEL
);
627 if (!class_dev
) return;
629 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev
);
631 class_dev
->class = &class_ptr
->class;
632 dev_set_name(class_dev
, "%s",
633 pvr2_hdw_get_device_identifier(sfp
->channel
.hdw
));
635 class_dev
->parent
= &usb_dev
->dev
;
637 sfp
->class_dev
= class_dev
;
638 dev_set_drvdata(class_dev
, sfp
);
639 ret
= device_register(class_dev
);
641 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
642 "device_register failed");
647 sfp
->attr_v4l_minor_number
.attr
.name
= "v4l_minor_number";
648 sfp
->attr_v4l_minor_number
.attr
.mode
= S_IRUGO
;
649 sfp
->attr_v4l_minor_number
.show
= v4l_minor_number_show
;
650 sfp
->attr_v4l_minor_number
.store
= NULL
;
651 ret
= device_create_file(sfp
->class_dev
,
652 &sfp
->attr_v4l_minor_number
);
654 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
655 "device_create_file error: %d",
658 sfp
->v4l_minor_number_created_ok
= !0;
661 sfp
->attr_v4l_radio_minor_number
.attr
.name
= "v4l_radio_minor_number";
662 sfp
->attr_v4l_radio_minor_number
.attr
.mode
= S_IRUGO
;
663 sfp
->attr_v4l_radio_minor_number
.show
= v4l_radio_minor_number_show
;
664 sfp
->attr_v4l_radio_minor_number
.store
= NULL
;
665 ret
= device_create_file(sfp
->class_dev
,
666 &sfp
->attr_v4l_radio_minor_number
);
668 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
669 "device_create_file error: %d",
672 sfp
->v4l_radio_minor_number_created_ok
= !0;
675 sfp
->attr_unit_number
.attr
.name
= "unit_number";
676 sfp
->attr_unit_number
.attr
.mode
= S_IRUGO
;
677 sfp
->attr_unit_number
.show
= unit_number_show
;
678 sfp
->attr_unit_number
.store
= NULL
;
679 ret
= device_create_file(sfp
->class_dev
,&sfp
->attr_unit_number
);
681 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
682 "device_create_file error: %d",
685 sfp
->unit_number_created_ok
= !0;
688 sfp
->attr_bus_info
.attr
.name
= "bus_info_str";
689 sfp
->attr_bus_info
.attr
.mode
= S_IRUGO
;
690 sfp
->attr_bus_info
.show
= bus_info_show
;
691 sfp
->attr_bus_info
.store
= NULL
;
692 ret
= device_create_file(sfp
->class_dev
,
693 &sfp
->attr_bus_info
);
695 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
696 "device_create_file error: %d",
699 sfp
->bus_info_created_ok
= !0;
702 sfp
->attr_hdw_name
.attr
.name
= "device_hardware_type";
703 sfp
->attr_hdw_name
.attr
.mode
= S_IRUGO
;
704 sfp
->attr_hdw_name
.show
= hdw_name_show
;
705 sfp
->attr_hdw_name
.store
= NULL
;
706 ret
= device_create_file(sfp
->class_dev
,
707 &sfp
->attr_hdw_name
);
709 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
710 "device_create_file error: %d",
713 sfp
->hdw_name_created_ok
= !0;
716 sfp
->attr_hdw_desc
.attr
.name
= "device_hardware_description";
717 sfp
->attr_hdw_desc
.attr
.mode
= S_IRUGO
;
718 sfp
->attr_hdw_desc
.show
= hdw_desc_show
;
719 sfp
->attr_hdw_desc
.store
= NULL
;
720 ret
= device_create_file(sfp
->class_dev
,
721 &sfp
->attr_hdw_desc
);
723 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
724 "device_create_file error: %d",
727 sfp
->hdw_desc_created_ok
= !0;
730 pvr2_sysfs_add_controls(sfp
);
731 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
732 pvr2_sysfs_add_debugifc(sfp
);
733 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
737 static void pvr2_sysfs_internal_check(struct pvr2_channel
*chp
)
739 struct pvr2_sysfs
*sfp
;
740 sfp
= container_of(chp
,struct pvr2_sysfs
,channel
);
741 if (!sfp
->channel
.mc_head
->disconnect_flag
) return;
742 pvr2_trace(PVR2_TRACE_STRUCT
,"Destroying pvr2_sysfs id=%p",sfp
);
743 class_dev_destroy(sfp
);
744 pvr2_channel_done(&sfp
->channel
);
749 struct pvr2_sysfs
*pvr2_sysfs_create(struct pvr2_context
*mp
,
750 struct pvr2_sysfs_class
*class_ptr
)
752 struct pvr2_sysfs
*sfp
;
753 sfp
= kzalloc(sizeof(*sfp
),GFP_KERNEL
);
754 if (!sfp
) return sfp
;
755 pvr2_trace(PVR2_TRACE_STRUCT
,"Creating pvr2_sysfs id=%p",sfp
);
756 pvr2_channel_init(&sfp
->channel
,mp
);
757 sfp
->channel
.check_func
= pvr2_sysfs_internal_check
;
759 class_dev_create(sfp
,class_ptr
);
765 struct pvr2_sysfs_class
*pvr2_sysfs_class_create(void)
767 struct pvr2_sysfs_class
*clp
;
768 clp
= kzalloc(sizeof(*clp
),GFP_KERNEL
);
769 if (!clp
) return clp
;
770 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp
);
771 clp
->class.name
= "pvrusb2";
772 clp
->class.class_release
= pvr2_sysfs_class_release
;
773 clp
->class.dev_release
= pvr2_sysfs_release
;
774 if (class_register(&clp
->class)) {
776 "Registration failed for pvr2_sysfs_class id=%p",clp
);
784 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class
*clp
)
786 class_unregister(&clp
->class);
790 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
791 static ssize_t
debuginfo_show(struct device
*class_dev
,
792 struct device_attribute
*attr
, char *buf
)
794 struct pvr2_sysfs
*sfp
;
795 sfp
= dev_get_drvdata(class_dev
);
796 if (!sfp
) return -EINVAL
;
797 pvr2_hdw_trigger_module_log(sfp
->channel
.hdw
);
798 return pvr2_debugifc_print_info(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
802 static ssize_t
debugcmd_show(struct device
*class_dev
,
803 struct device_attribute
*attr
, char *buf
)
805 struct pvr2_sysfs
*sfp
;
806 sfp
= dev_get_drvdata(class_dev
);
807 if (!sfp
) return -EINVAL
;
808 return pvr2_debugifc_print_status(sfp
->channel
.hdw
,buf
,PAGE_SIZE
);
812 static ssize_t
debugcmd_store(struct device
*class_dev
,
813 struct device_attribute
*attr
,
814 const char *buf
, size_t count
)
816 struct pvr2_sysfs
*sfp
;
819 sfp
= dev_get_drvdata(class_dev
);
820 if (!sfp
) return -EINVAL
;
822 ret
= pvr2_debugifc_docmd(sfp
->channel
.hdw
,buf
,count
);
823 if (ret
< 0) return ret
;
826 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
830 Stuff for Emacs to see, in order to encourage consistent editing style:
831 *** Local Variables: ***
833 *** fill-column: 75 ***
835 *** c-basic-offset: 8 ***