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_enum;
69 struct device_attribute attr_bits;
70 struct device_attribute attr_val;
71 struct device_attribute attr_custom;
72 struct pvr2_ctrl *cptr;
73 struct pvr2_sysfs *chptr;
74 struct pvr2_sysfs_ctl_item *item_next;
75 struct attribute *attr_gen[7];
76 struct attribute_group grp;
81 struct pvr2_sysfs_class {
85 static ssize_t show_name(int id,struct device *class_dev,char *buf)
87 struct pvr2_ctrl *cptr;
88 struct pvr2_sysfs *sfp;
91 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
92 if (!sfp) return -EINVAL;
93 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
94 if (!cptr) return -EINVAL;
96 name = pvr2_ctrl_get_desc(cptr);
97 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
99 if (!name) return -EINVAL;
101 return scnprintf(buf,PAGE_SIZE,"%s\n",name);
104 static ssize_t show_type(int id,struct device *class_dev,char *buf)
106 struct pvr2_ctrl *cptr;
107 struct pvr2_sysfs *sfp;
109 enum pvr2_ctl_type tp;
111 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
112 if (!sfp) return -EINVAL;
113 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
114 if (!cptr) return -EINVAL;
116 tp = pvr2_ctrl_get_type(cptr);
118 case pvr2_ctl_int: name = "integer"; break;
119 case pvr2_ctl_enum: name = "enum"; break;
120 case pvr2_ctl_bitmask: name = "bitmask"; break;
121 case pvr2_ctl_bool: name = "boolean"; break;
122 default: name = "?"; break;
124 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name);
126 if (!name) return -EINVAL;
128 return scnprintf(buf,PAGE_SIZE,"%s\n",name);
131 static ssize_t show_min(int id,struct device *class_dev,char *buf)
133 struct pvr2_ctrl *cptr;
134 struct pvr2_sysfs *sfp;
137 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
138 if (!sfp) return -EINVAL;
139 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
140 if (!cptr) return -EINVAL;
141 val = pvr2_ctrl_get_min(cptr);
143 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val);
145 return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
148 static ssize_t show_max(int id,struct device *class_dev,char *buf)
150 struct pvr2_ctrl *cptr;
151 struct pvr2_sysfs *sfp;
154 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
155 if (!sfp) return -EINVAL;
156 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
157 if (!cptr) return -EINVAL;
158 val = pvr2_ctrl_get_max(cptr);
160 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val);
162 return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
165 static ssize_t show_val_norm(int id,struct device *class_dev,char *buf)
167 struct pvr2_ctrl *cptr;
168 struct pvr2_sysfs *sfp;
170 unsigned int cnt = 0;
172 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
173 if (!sfp) return -EINVAL;
174 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
175 if (!cptr) return -EINVAL;
177 ret = pvr2_ctrl_get_value(cptr,&val);
178 if (ret < 0) return ret;
180 ret = pvr2_ctrl_value_to_sym(cptr,~0,val,
181 buf,PAGE_SIZE-1,&cnt);
183 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
189 static ssize_t show_val_custom(int id,struct device *class_dev,char *buf)
191 struct pvr2_ctrl *cptr;
192 struct pvr2_sysfs *sfp;
194 unsigned int cnt = 0;
196 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
197 if (!sfp) return -EINVAL;
198 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
199 if (!cptr) return -EINVAL;
201 ret = pvr2_ctrl_get_value(cptr,&val);
202 if (ret < 0) return ret;
204 ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val,
205 buf,PAGE_SIZE-1,&cnt);
207 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
213 static ssize_t show_enum(int id,struct device *class_dev,char *buf)
215 struct pvr2_ctrl *cptr;
216 struct pvr2_sysfs *sfp;
218 unsigned int bcnt,ccnt,ecnt;
220 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
221 if (!sfp) return -EINVAL;
222 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
223 if (!cptr) return -EINVAL;
224 ecnt = pvr2_ctrl_get_cnt(cptr);
226 for (val = 0; val < ecnt; val++) {
227 pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
230 if (bcnt >= PAGE_SIZE) break;
234 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
238 static ssize_t show_bits(int id,struct device *class_dev,char *buf)
240 struct pvr2_ctrl *cptr;
241 struct pvr2_sysfs *sfp;
243 unsigned int bcnt,ccnt;
245 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
246 if (!sfp) return -EINVAL;
247 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
248 if (!cptr) return -EINVAL;
249 valid_bits = pvr2_ctrl_get_mask(cptr);
251 for (msk = 1; valid_bits; msk <<= 1) {
252 if (!(msk & valid_bits)) continue;
254 pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
256 if (bcnt >= PAGE_SIZE) break;
260 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id);
264 static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp,
265 const char *buf,unsigned int count)
267 struct pvr2_ctrl *cptr;
271 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
273 ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val);
275 ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val);
277 if (ret < 0) return ret;
278 ret = pvr2_ctrl_set_mask_value(cptr,mask,val);
279 pvr2_hdw_commit_ctl(sfp->channel.hdw);
283 static ssize_t store_val_norm(int id,struct device *class_dev,
284 const char *buf,size_t count)
286 struct pvr2_sysfs *sfp;
288 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
289 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
290 sfp,id,(int)count,buf);
291 ret = store_val_any(id,0,sfp,buf,count);
292 if (!ret) ret = count;
296 static ssize_t store_val_custom(int id,struct device *class_dev,
297 const char *buf,size_t count)
299 struct pvr2_sysfs *sfp;
301 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
302 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
303 sfp,id,(int)count,buf);
304 ret = store_val_any(id,1,sfp,buf,count);
305 if (!ret) ret = count;
310 Mike Isely <isely@pobox.com> 30-April-2005
312 This next batch of horrible preprocessor hackery is needed because the
313 kernel's device_attribute mechanism fails to pass the actual
314 attribute through to the show / store functions, which means we have no
315 way to package up any attribute-specific parameters, like for example the
316 control id. So we work around this brain-damage by encoding the control
317 id into the show / store functions themselves and pick the function based
318 on the control id we're setting up. These macros try to ease the pain.
322 #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
323 static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
324 struct device_attribute *attr, char *buf) \
325 { return sf_name(ctl_id,class_dev,buf); }
327 #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
328 static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
329 struct device_attribute *attr, const char *buf, size_t count) \
330 { return sf_name(ctl_id,class_dev,buf,count); }
332 #define CREATE_BATCH(ctl_id) \
333 CREATE_SHOW_INSTANCE(show_name,ctl_id) \
334 CREATE_SHOW_INSTANCE(show_type,ctl_id) \
335 CREATE_SHOW_INSTANCE(show_min,ctl_id) \
336 CREATE_SHOW_INSTANCE(show_max,ctl_id) \
337 CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
338 CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
339 CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
340 CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
341 CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
342 CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
405 struct pvr2_sysfs_func_set {
406 ssize_t (*show_name)(struct device *,
407 struct device_attribute *attr, char *);
408 ssize_t (*show_type)(struct device *,
409 struct device_attribute *attr, char *);
410 ssize_t (*show_min)(struct device *,
411 struct device_attribute *attr, char *);
412 ssize_t (*show_max)(struct device *,
413 struct device_attribute *attr, char *);
414 ssize_t (*show_enum)(struct device *,
415 struct device_attribute *attr, char *);
416 ssize_t (*show_bits)(struct device *,
417 struct device_attribute *attr, char *);
418 ssize_t (*show_val_norm)(struct device *,
419 struct device_attribute *attr, char *);
420 ssize_t (*store_val_norm)(struct device *,
421 struct device_attribute *attr,
422 const char *,size_t);
423 ssize_t (*show_val_custom)(struct device *,
424 struct device_attribute *attr, char *);
425 ssize_t (*store_val_custom)(struct device *,
426 struct device_attribute *attr,
427 const char *,size_t);
430 #define INIT_BATCH(ctl_id) \
432 .show_name = show_name_##ctl_id, \
433 .show_type = show_type_##ctl_id, \
434 .show_min = show_min_##ctl_id, \
435 .show_max = show_max_##ctl_id, \
436 .show_enum = show_enum_##ctl_id, \
437 .show_bits = show_bits_##ctl_id, \
438 .show_val_norm = show_val_norm_##ctl_id, \
439 .store_val_norm = store_val_norm_##ctl_id, \
440 .show_val_custom = show_val_custom_##ctl_id, \
441 .store_val_custom = store_val_custom_##ctl_id, \
444 static struct pvr2_sysfs_func_set funcs[] = {
508 static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
510 struct pvr2_sysfs_ctl_item *cip;
511 struct pvr2_sysfs_func_set *fp;
512 struct pvr2_ctrl *cptr;
513 unsigned int cnt,acnt;
516 if ((ctl_id < 0) || (ctl_id >= ARRAY_SIZE(funcs))) {
521 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
524 cip = kzalloc(sizeof(*cip),GFP_KERNEL);
526 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
531 cip->item_next = NULL;
532 if (sfp->item_last) {
533 sfp->item_last->item_next = cip;
535 sfp->item_first = cip;
537 sfp->item_last = cip;
539 cip->attr_name.attr.name = "name";
540 cip->attr_name.attr.mode = S_IRUGO;
541 cip->attr_name.show = fp->show_name;
543 cip->attr_type.attr.name = "type";
544 cip->attr_type.attr.mode = S_IRUGO;
545 cip->attr_type.show = fp->show_type;
547 cip->attr_min.attr.name = "min_val";
548 cip->attr_min.attr.mode = S_IRUGO;
549 cip->attr_min.show = fp->show_min;
551 cip->attr_max.attr.name = "max_val";
552 cip->attr_max.attr.mode = S_IRUGO;
553 cip->attr_max.show = fp->show_max;
555 cip->attr_val.attr.name = "cur_val";
556 cip->attr_val.attr.mode = S_IRUGO;
558 cip->attr_custom.attr.name = "custom_val";
559 cip->attr_custom.attr.mode = S_IRUGO;
561 cip->attr_enum.attr.name = "enum_val";
562 cip->attr_enum.attr.mode = S_IRUGO;
563 cip->attr_enum.show = fp->show_enum;
565 cip->attr_bits.attr.name = "bit_val";
566 cip->attr_bits.attr.mode = S_IRUGO;
567 cip->attr_bits.show = fp->show_bits;
569 if (pvr2_ctrl_is_writable(cptr)) {
570 cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
571 cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
575 cip->attr_gen[acnt++] = &cip->attr_name.attr;
576 cip->attr_gen[acnt++] = &cip->attr_type.attr;
577 cip->attr_gen[acnt++] = &cip->attr_val.attr;
578 cip->attr_val.show = fp->show_val_norm;
579 cip->attr_val.store = fp->store_val_norm;
580 if (pvr2_ctrl_has_custom_symbols(cptr)) {
581 cip->attr_gen[acnt++] = &cip->attr_custom.attr;
582 cip->attr_custom.show = fp->show_val_custom;
583 cip->attr_custom.store = fp->store_val_custom;
585 switch (pvr2_ctrl_get_type(cptr)) {
587 // Control is an enumeration
588 cip->attr_gen[acnt++] = &cip->attr_enum.attr;
591 // Control is an integer
592 cip->attr_gen[acnt++] = &cip->attr_min.attr;
593 cip->attr_gen[acnt++] = &cip->attr_max.attr;
595 case pvr2_ctl_bitmask:
596 // Control is an bitmask
597 cip->attr_gen[acnt++] = &cip->attr_bits.attr;
602 cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
603 pvr2_ctrl_get_name(cptr));
605 cip->grp.name = cip->name;
606 cip->grp.attrs = cip->attr_gen;
608 ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
610 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
611 "sysfs_create_group error: %d",
615 cip->created_ok = !0;
618 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
619 static ssize_t debuginfo_show(struct device *, struct device_attribute *,
621 static ssize_t debugcmd_show(struct device *, struct device_attribute *,
623 static ssize_t debugcmd_store(struct device *, struct device_attribute *,
624 const char *, size_t count);
626 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
628 struct pvr2_sysfs_debugifc *dip;
631 dip = kzalloc(sizeof(*dip),GFP_KERNEL);
633 dip->attr_debugcmd.attr.name = "debugcmd";
634 dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
635 dip->attr_debugcmd.show = debugcmd_show;
636 dip->attr_debugcmd.store = debugcmd_store;
637 dip->attr_debuginfo.attr.name = "debuginfo";
638 dip->attr_debuginfo.attr.mode = S_IRUGO;
639 dip->attr_debuginfo.show = debuginfo_show;
641 ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd);
643 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
644 "device_create_file error: %d",
647 dip->debugcmd_created_ok = !0;
649 ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo);
651 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
652 "device_create_file error: %d",
655 dip->debuginfo_created_ok = !0;
660 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
662 if (!sfp->debugifc) return;
663 if (sfp->debugifc->debuginfo_created_ok) {
664 device_remove_file(sfp->class_dev,
665 &sfp->debugifc->attr_debuginfo);
667 if (sfp->debugifc->debugcmd_created_ok) {
668 device_remove_file(sfp->class_dev,
669 &sfp->debugifc->attr_debugcmd);
671 kfree(sfp->debugifc);
672 sfp->debugifc = NULL;
674 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
677 static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
679 unsigned int idx,cnt;
680 cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
681 for (idx = 0; idx < cnt; idx++) {
682 pvr2_sysfs_add_control(sfp,idx);
687 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
689 struct pvr2_sysfs_ctl_item *cip1,*cip2;
690 for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
691 cip2 = cip1->item_next;
692 if (cip1->created_ok) {
693 sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
695 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
701 static void pvr2_sysfs_class_release(struct class *class)
703 struct pvr2_sysfs_class *clp;
704 clp = container_of(class,struct pvr2_sysfs_class,class);
705 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
710 static void pvr2_sysfs_release(struct device *class_dev)
712 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
717 static void class_dev_destroy(struct pvr2_sysfs *sfp)
719 if (!sfp->class_dev) return;
720 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
721 pvr2_sysfs_tear_down_debugifc(sfp);
722 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
723 pvr2_sysfs_tear_down_controls(sfp);
724 if (sfp->hdw_desc_created_ok) {
725 device_remove_file(sfp->class_dev,
726 &sfp->attr_hdw_desc);
728 if (sfp->hdw_name_created_ok) {
729 device_remove_file(sfp->class_dev,
730 &sfp->attr_hdw_name);
732 if (sfp->bus_info_created_ok) {
733 device_remove_file(sfp->class_dev,
734 &sfp->attr_bus_info);
736 if (sfp->v4l_minor_number_created_ok) {
737 device_remove_file(sfp->class_dev,
738 &sfp->attr_v4l_minor_number);
740 if (sfp->v4l_radio_minor_number_created_ok) {
741 device_remove_file(sfp->class_dev,
742 &sfp->attr_v4l_radio_minor_number);
744 if (sfp->unit_number_created_ok) {
745 device_remove_file(sfp->class_dev,
746 &sfp->attr_unit_number);
748 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
749 sfp->class_dev->driver_data = NULL;
750 device_unregister(sfp->class_dev);
751 sfp->class_dev = NULL;
755 static ssize_t v4l_minor_number_show(struct device *class_dev,
756 struct device_attribute *attr, char *buf)
758 struct pvr2_sysfs *sfp;
759 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
760 if (!sfp) return -EINVAL;
761 return scnprintf(buf,PAGE_SIZE,"%d\n",
762 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
763 pvr2_v4l_type_video));
767 static ssize_t bus_info_show(struct device *class_dev,
768 struct device_attribute *attr, char *buf)
770 struct pvr2_sysfs *sfp;
771 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
772 if (!sfp) return -EINVAL;
773 return scnprintf(buf,PAGE_SIZE,"%s\n",
774 pvr2_hdw_get_bus_info(sfp->channel.hdw));
778 static ssize_t hdw_name_show(struct device *class_dev,
779 struct device_attribute *attr, char *buf)
781 struct pvr2_sysfs *sfp;
782 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
783 if (!sfp) return -EINVAL;
784 return scnprintf(buf,PAGE_SIZE,"%s\n",
785 pvr2_hdw_get_type(sfp->channel.hdw));
789 static ssize_t hdw_desc_show(struct device *class_dev,
790 struct device_attribute *attr, char *buf)
792 struct pvr2_sysfs *sfp;
793 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
794 if (!sfp) return -EINVAL;
795 return scnprintf(buf,PAGE_SIZE,"%s\n",
796 pvr2_hdw_get_desc(sfp->channel.hdw));
800 static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
801 struct device_attribute *attr,
804 struct pvr2_sysfs *sfp;
805 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
806 if (!sfp) return -EINVAL;
807 return scnprintf(buf,PAGE_SIZE,"%d\n",
808 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
809 pvr2_v4l_type_radio));
813 static ssize_t unit_number_show(struct device *class_dev,
814 struct device_attribute *attr, char *buf)
816 struct pvr2_sysfs *sfp;
817 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
818 if (!sfp) return -EINVAL;
819 return scnprintf(buf,PAGE_SIZE,"%d\n",
820 pvr2_hdw_get_unit_number(sfp->channel.hdw));
824 static void class_dev_create(struct pvr2_sysfs *sfp,
825 struct pvr2_sysfs_class *class_ptr)
827 struct usb_device *usb_dev;
828 struct device *class_dev;
831 usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
832 if (!usb_dev) return;
833 class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL);
834 if (!class_dev) return;
836 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
838 class_dev->class = &class_ptr->class;
839 if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
840 snprintf(class_dev->bus_id, BUS_ID_SIZE, "sn-%lu",
841 pvr2_hdw_get_sn(sfp->channel.hdw));
842 } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
843 snprintf(class_dev->bus_id, BUS_ID_SIZE, "unit-%c",
844 pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
850 class_dev->parent = &usb_dev->dev;
852 sfp->class_dev = class_dev;
853 class_dev->driver_data = sfp;
854 ret = device_register(class_dev);
856 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
857 "device_register failed");
862 sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
863 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
864 sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
865 sfp->attr_v4l_minor_number.store = NULL;
866 ret = device_create_file(sfp->class_dev,
867 &sfp->attr_v4l_minor_number);
869 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
870 "device_create_file error: %d",
873 sfp->v4l_minor_number_created_ok = !0;
876 sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
877 sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
878 sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
879 sfp->attr_v4l_radio_minor_number.store = NULL;
880 ret = device_create_file(sfp->class_dev,
881 &sfp->attr_v4l_radio_minor_number);
883 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
884 "device_create_file error: %d",
887 sfp->v4l_radio_minor_number_created_ok = !0;
890 sfp->attr_unit_number.attr.name = "unit_number";
891 sfp->attr_unit_number.attr.mode = S_IRUGO;
892 sfp->attr_unit_number.show = unit_number_show;
893 sfp->attr_unit_number.store = NULL;
894 ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number);
896 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
897 "device_create_file error: %d",
900 sfp->unit_number_created_ok = !0;
903 sfp->attr_bus_info.attr.name = "bus_info_str";
904 sfp->attr_bus_info.attr.mode = S_IRUGO;
905 sfp->attr_bus_info.show = bus_info_show;
906 sfp->attr_bus_info.store = NULL;
907 ret = device_create_file(sfp->class_dev,
908 &sfp->attr_bus_info);
910 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
911 "device_create_file error: %d",
914 sfp->bus_info_created_ok = !0;
917 sfp->attr_hdw_name.attr.name = "device_hardware_type";
918 sfp->attr_hdw_name.attr.mode = S_IRUGO;
919 sfp->attr_hdw_name.show = hdw_name_show;
920 sfp->attr_hdw_name.store = NULL;
921 ret = device_create_file(sfp->class_dev,
922 &sfp->attr_hdw_name);
924 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
925 "device_create_file error: %d",
928 sfp->hdw_name_created_ok = !0;
931 sfp->attr_hdw_desc.attr.name = "device_hardware_description";
932 sfp->attr_hdw_desc.attr.mode = S_IRUGO;
933 sfp->attr_hdw_desc.show = hdw_desc_show;
934 sfp->attr_hdw_desc.store = NULL;
935 ret = device_create_file(sfp->class_dev,
936 &sfp->attr_hdw_desc);
938 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
939 "device_create_file error: %d",
942 sfp->hdw_desc_created_ok = !0;
945 pvr2_sysfs_add_controls(sfp);
946 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
947 pvr2_sysfs_add_debugifc(sfp);
948 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
952 static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
954 struct pvr2_sysfs *sfp;
955 sfp = container_of(chp,struct pvr2_sysfs,channel);
956 if (!sfp->channel.mc_head->disconnect_flag) return;
957 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
958 class_dev_destroy(sfp);
959 pvr2_channel_done(&sfp->channel);
964 struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
965 struct pvr2_sysfs_class *class_ptr)
967 struct pvr2_sysfs *sfp;
968 sfp = kzalloc(sizeof(*sfp),GFP_KERNEL);
969 if (!sfp) return sfp;
970 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
971 pvr2_channel_init(&sfp->channel,mp);
972 sfp->channel.check_func = pvr2_sysfs_internal_check;
974 class_dev_create(sfp,class_ptr);
980 struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
982 struct pvr2_sysfs_class *clp;
983 clp = kzalloc(sizeof(*clp),GFP_KERNEL);
984 if (!clp) return clp;
985 pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp);
986 clp->class.name = "pvrusb2";
987 clp->class.class_release = pvr2_sysfs_class_release;
988 clp->class.dev_release = pvr2_sysfs_release;
989 if (class_register(&clp->class)) {
991 "Registration failed for pvr2_sysfs_class id=%p",clp);
999 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
1001 class_unregister(&clp->class);
1005 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
1006 static ssize_t debuginfo_show(struct device *class_dev,
1007 struct device_attribute *attr, char *buf)
1009 struct pvr2_sysfs *sfp;
1010 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
1011 if (!sfp) return -EINVAL;
1012 pvr2_hdw_trigger_module_log(sfp->channel.hdw);
1013 return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
1017 static ssize_t debugcmd_show(struct device *class_dev,
1018 struct device_attribute *attr, char *buf)
1020 struct pvr2_sysfs *sfp;
1021 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
1022 if (!sfp) return -EINVAL;
1023 return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
1027 static ssize_t debugcmd_store(struct device *class_dev,
1028 struct device_attribute *attr,
1029 const char *buf, size_t count)
1031 struct pvr2_sysfs *sfp;
1034 sfp = (struct pvr2_sysfs *)class_dev->driver_data;
1035 if (!sfp) return -EINVAL;
1037 ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
1038 if (ret < 0) return ret;
1041 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
1045 Stuff for Emacs to see, in order to encourage consistent editing style:
1046 *** Local Variables: ***
1048 *** fill-column: 75 ***
1049 *** tab-width: 8 ***
1050 *** c-basic-offset: 8 ***