]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/media/usb/pvrusb2/pvrusb2-sysfs.c
HID: usbhid: Add HID_QUIRK_NOGET for Aten CS-1758 KVM switch
[mirror_ubuntu-artful-kernel.git] / drivers / media / usb / pvrusb2 / pvrusb2-sysfs.c
1 /*
2 *
3 *
4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
5 *
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
9 *
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.
14 *
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
18 *
19 */
20
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 */
29
30 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
31
32 struct pvr2_sysfs {
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;
52 };
53
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;
60 };
61 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
62
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;
74 int ctl_id;
75 struct pvr2_sysfs *chptr;
76 struct pvr2_sysfs_ctl_item *item_next;
77 struct attribute *attr_gen[8];
78 struct attribute_group grp;
79 int created_ok;
80 char name[80];
81 };
82
83 struct pvr2_sysfs_class {
84 struct class class;
85 };
86
87 static ssize_t show_name(struct device *class_dev,
88 struct device_attribute *attr,
89 char *buf)
90 {
91 struct pvr2_sysfs_ctl_item *cip;
92 const char *name;
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);
99 }
100
101 static ssize_t show_type(struct device *class_dev,
102 struct device_attribute *attr,
103 char *buf)
104 {
105 struct pvr2_sysfs_ctl_item *cip;
106 const char *name;
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);
110 switch (tp) {
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;
116 }
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);
120 }
121
122 static ssize_t show_min(struct device *class_dev,
123 struct device_attribute *attr,
124 char *buf)
125 {
126 struct pvr2_sysfs_ctl_item *cip;
127 long val;
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);
133 }
134
135 static ssize_t show_max(struct device *class_dev,
136 struct device_attribute *attr,
137 char *buf)
138 {
139 struct pvr2_sysfs_ctl_item *cip;
140 long val;
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);
146 }
147
148 static ssize_t show_def(struct device *class_dev,
149 struct device_attribute *attr,
150 char *buf)
151 {
152 struct pvr2_sysfs_ctl_item *cip;
153 int val;
154 int ret;
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);
163 buf[cnt] = '\n';
164 return cnt + 1;
165 }
166
167 static ssize_t show_val_norm(struct device *class_dev,
168 struct device_attribute *attr,
169 char *buf)
170 {
171 struct pvr2_sysfs_ctl_item *cip;
172 int val;
173 int ret;
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);
182 buf[cnt] = '\n';
183 return cnt+1;
184 }
185
186 static ssize_t show_val_custom(struct device *class_dev,
187 struct device_attribute *attr,
188 char *buf)
189 {
190 struct pvr2_sysfs_ctl_item *cip;
191 int val;
192 int ret;
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);
201 buf[cnt] = '\n';
202 return cnt+1;
203 }
204
205 static ssize_t show_enum(struct device *class_dev,
206 struct device_attribute *attr,
207 char *buf)
208 {
209 struct pvr2_sysfs_ctl_item *cip;
210 long val;
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);
214 bcnt = 0;
215 for (val = 0; val < ecnt; val++) {
216 pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt,
217 PAGE_SIZE - bcnt, &ccnt);
218 if (!ccnt) continue;
219 bcnt += ccnt;
220 if (bcnt >= PAGE_SIZE) break;
221 buf[bcnt] = '\n';
222 bcnt++;
223 }
224 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
225 cip->chptr, cip->ctl_id);
226 return bcnt;
227 }
228
229 static ssize_t show_bits(struct device *class_dev,
230 struct device_attribute *attr,
231 char *buf)
232 {
233 struct pvr2_sysfs_ctl_item *cip;
234 int valid_bits, msk;
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);
238 bcnt = 0;
239 for (msk = 1; valid_bits; msk <<= 1) {
240 if (!(msk & valid_bits)) continue;
241 valid_bits &= ~msk;
242 pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt,
243 PAGE_SIZE - bcnt, &ccnt);
244 bcnt += ccnt;
245 if (bcnt >= PAGE_SIZE) break;
246 buf[bcnt] = '\n';
247 bcnt++;
248 }
249 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
250 cip->chptr, cip->ctl_id);
251 return bcnt;
252 }
253
254 static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl,
255 const char *buf,unsigned int count)
256 {
257 int ret;
258 int mask,val;
259 if (customfl) {
260 ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count,
261 &mask, &val);
262 } else {
263 ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count,
264 &mask, &val);
265 }
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);
269 return ret;
270 }
271
272 static ssize_t store_val_norm(struct device *class_dev,
273 struct device_attribute *attr,
274 const char *buf, size_t count)
275 {
276 struct pvr2_sysfs_ctl_item *cip;
277 int ret;
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;
283 return ret;
284 }
285
286 static ssize_t store_val_custom(struct device *class_dev,
287 struct device_attribute *attr,
288 const char *buf, size_t count)
289 {
290 struct pvr2_sysfs_ctl_item *cip;
291 int ret;
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;
297 return ret;
298 }
299
300 static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
301 {
302 struct pvr2_sysfs_ctl_item *cip;
303 struct pvr2_ctrl *cptr;
304 unsigned int cnt,acnt;
305 int ret;
306
307 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
308 if (!cptr) return;
309
310 cip = kzalloc(sizeof(*cip),GFP_KERNEL);
311 if (!cip) return;
312 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
313
314 cip->cptr = cptr;
315 cip->ctl_id = ctl_id;
316
317 cip->chptr = sfp;
318 cip->item_next = NULL;
319 if (sfp->item_last) {
320 sfp->item_last->item_next = cip;
321 } else {
322 sfp->item_first = cip;
323 }
324 sfp->item_last = cip;
325
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;
330
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;
335
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;
340
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;
345
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;
350
351 sysfs_attr_init(&cip->attr_val.attr);
352 cip->attr_val.attr.name = "cur_val";
353 cip->attr_val.attr.mode = S_IRUGO;
354
355 sysfs_attr_init(&cip->attr_custom.attr);
356 cip->attr_custom.attr.name = "custom_val";
357 cip->attr_custom.attr.mode = S_IRUGO;
358
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;
363
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;
368
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;
372 }
373
374 acnt = 0;
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;
385 }
386 switch (pvr2_ctrl_get_type(cptr)) {
387 case pvr2_ctl_enum:
388 // Control is an enumeration
389 cip->attr_gen[acnt++] = &cip->attr_enum.attr;
390 break;
391 case pvr2_ctl_int:
392 // Control is an integer
393 cip->attr_gen[acnt++] = &cip->attr_min.attr;
394 cip->attr_gen[acnt++] = &cip->attr_max.attr;
395 break;
396 case pvr2_ctl_bitmask:
397 // Control is an bitmask
398 cip->attr_gen[acnt++] = &cip->attr_bits.attr;
399 break;
400 default: break;
401 }
402
403 cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
404 pvr2_ctrl_get_name(cptr));
405 cip->name[cnt] = 0;
406 cip->grp.name = cip->name;
407 cip->grp.attrs = cip->attr_gen;
408
409 ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
410 if (ret) {
411 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
412 "sysfs_create_group error: %d",
413 ret);
414 return;
415 }
416 cip->created_ok = !0;
417 }
418
419 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
420 static ssize_t debuginfo_show(struct device *, struct device_attribute *,
421 char *);
422 static ssize_t debugcmd_show(struct device *, struct device_attribute *,
423 char *);
424 static ssize_t debugcmd_store(struct device *, struct device_attribute *,
425 const char *, size_t count);
426
427 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
428 {
429 struct pvr2_sysfs_debugifc *dip;
430 int ret;
431
432 dip = kzalloc(sizeof(*dip),GFP_KERNEL);
433 if (!dip) return;
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;
443 sfp->debugifc = dip;
444 ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd);
445 if (ret < 0) {
446 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
447 "device_create_file error: %d",
448 ret);
449 } else {
450 dip->debugcmd_created_ok = !0;
451 }
452 ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo);
453 if (ret < 0) {
454 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
455 "device_create_file error: %d",
456 ret);
457 } else {
458 dip->debuginfo_created_ok = !0;
459 }
460 }
461
462
463 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
464 {
465 if (!sfp->debugifc) return;
466 if (sfp->debugifc->debuginfo_created_ok) {
467 device_remove_file(sfp->class_dev,
468 &sfp->debugifc->attr_debuginfo);
469 }
470 if (sfp->debugifc->debugcmd_created_ok) {
471 device_remove_file(sfp->class_dev,
472 &sfp->debugifc->attr_debugcmd);
473 }
474 kfree(sfp->debugifc);
475 sfp->debugifc = NULL;
476 }
477 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
478
479
480 static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
481 {
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);
486 }
487 }
488
489
490 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
491 {
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);
497 }
498 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
499 kfree(cip1);
500 }
501 }
502
503
504 static void pvr2_sysfs_class_release(struct class *class)
505 {
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);
509 kfree(clp);
510 }
511
512
513 static void pvr2_sysfs_release(struct device *class_dev)
514 {
515 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
516 kfree(class_dev);
517 }
518
519
520 static void class_dev_destroy(struct pvr2_sysfs *sfp)
521 {
522 struct device *dev;
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);
531 }
532 if (sfp->hdw_name_created_ok) {
533 device_remove_file(sfp->class_dev,
534 &sfp->attr_hdw_name);
535 }
536 if (sfp->bus_info_created_ok) {
537 device_remove_file(sfp->class_dev,
538 &sfp->attr_bus_info);
539 }
540 if (sfp->v4l_minor_number_created_ok) {
541 device_remove_file(sfp->class_dev,
542 &sfp->attr_v4l_minor_number);
543 }
544 if (sfp->v4l_radio_minor_number_created_ok) {
545 device_remove_file(sfp->class_dev,
546 &sfp->attr_v4l_radio_minor_number);
547 }
548 if (sfp->unit_number_created_ok) {
549 device_remove_file(sfp->class_dev,
550 &sfp->attr_unit_number);
551 }
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;
556 put_device(dev);
557 device_unregister(sfp->class_dev);
558 sfp->class_dev = NULL;
559 }
560
561
562 static ssize_t v4l_minor_number_show(struct device *class_dev,
563 struct device_attribute *attr, char *buf)
564 {
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));
571 }
572
573
574 static ssize_t bus_info_show(struct device *class_dev,
575 struct device_attribute *attr, char *buf)
576 {
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));
582 }
583
584
585 static ssize_t hdw_name_show(struct device *class_dev,
586 struct device_attribute *attr, char *buf)
587 {
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));
593 }
594
595
596 static ssize_t hdw_desc_show(struct device *class_dev,
597 struct device_attribute *attr, char *buf)
598 {
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));
604 }
605
606
607 static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
608 struct device_attribute *attr,
609 char *buf)
610 {
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));
617 }
618
619
620 static ssize_t unit_number_show(struct device *class_dev,
621 struct device_attribute *attr, char *buf)
622 {
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));
628 }
629
630
631 static void class_dev_create(struct pvr2_sysfs *sfp,
632 struct pvr2_sysfs_class *class_ptr)
633 {
634 struct usb_device *usb_dev;
635 struct device *class_dev;
636 int ret;
637
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;
642
643 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
644
645 class_dev->class = &class_ptr->class;
646
647 dev_set_name(class_dev, "%s",
648 pvr2_hdw_get_device_identifier(sfp->channel.hdw));
649
650 class_dev->parent = get_device(&usb_dev->dev);
651
652 sfp->class_dev = class_dev;
653 dev_set_drvdata(class_dev, sfp);
654 ret = device_register(class_dev);
655 if (ret) {
656 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
657 "device_register failed");
658 put_device(class_dev);
659 return;
660 }
661
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);
669 if (ret < 0) {
670 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
671 "device_create_file error: %d",
672 ret);
673 } else {
674 sfp->v4l_minor_number_created_ok = !0;
675 }
676
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);
684 if (ret < 0) {
685 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
686 "device_create_file error: %d",
687 ret);
688 } else {
689 sfp->v4l_radio_minor_number_created_ok = !0;
690 }
691
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);
698 if (ret < 0) {
699 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
700 "device_create_file error: %d",
701 ret);
702 } else {
703 sfp->unit_number_created_ok = !0;
704 }
705
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);
713 if (ret < 0) {
714 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
715 "device_create_file error: %d",
716 ret);
717 } else {
718 sfp->bus_info_created_ok = !0;
719 }
720
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);
728 if (ret < 0) {
729 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
730 "device_create_file error: %d",
731 ret);
732 } else {
733 sfp->hdw_name_created_ok = !0;
734 }
735
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);
743 if (ret < 0) {
744 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
745 "device_create_file error: %d",
746 ret);
747 } else {
748 sfp->hdw_desc_created_ok = !0;
749 }
750
751 pvr2_sysfs_add_controls(sfp);
752 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
753 pvr2_sysfs_add_debugifc(sfp);
754 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
755 }
756
757
758 static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
759 {
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);
766 kfree(sfp);
767 }
768
769
770 struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
771 struct pvr2_sysfs_class *class_ptr)
772 {
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;
779
780 class_dev_create(sfp,class_ptr);
781 return sfp;
782 }
783
784
785
786 struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
787 {
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",
792 clp);
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)) {
797 pvr2_sysfs_trace(
798 "Registration failed for pvr2_sysfs_class id=%p",clp);
799 kfree(clp);
800 clp = NULL;
801 }
802 return clp;
803 }
804
805
806 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
807 {
808 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp);
809 class_unregister(&clp->class);
810 }
811
812
813 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
814 static ssize_t debuginfo_show(struct device *class_dev,
815 struct device_attribute *attr, char *buf)
816 {
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);
822 }
823
824
825 static ssize_t debugcmd_show(struct device *class_dev,
826 struct device_attribute *attr, char *buf)
827 {
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);
832 }
833
834
835 static ssize_t debugcmd_store(struct device *class_dev,
836 struct device_attribute *attr,
837 const char *buf, size_t count)
838 {
839 struct pvr2_sysfs *sfp;
840 int ret;
841
842 sfp = dev_get_drvdata(class_dev);
843 if (!sfp) return -EINVAL;
844
845 ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
846 if (ret < 0) return ret;
847 return count;
848 }
849 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */