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 */ 16 17 #include <linux/string.h> 18 #include <linux/slab.h> 19 #include "pvrusb2-sysfs.h" 20 #include "pvrusb2-hdw.h" 21 #include "pvrusb2-debug.h" 22 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 23 #include "pvrusb2-debugifc.h" 24 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 25 26 #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) 27 28 struct pvr2_sysfs { 29 struct pvr2_channel channel; 30 struct device *class_dev; 31 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 32 struct pvr2_sysfs_debugifc *debugifc; 33 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 34 struct pvr2_sysfs_ctl_item *item_first; 35 struct pvr2_sysfs_ctl_item *item_last; 36 struct device_attribute attr_v4l_minor_number; 37 struct device_attribute attr_v4l_radio_minor_number; 38 struct device_attribute attr_unit_number; 39 struct device_attribute attr_bus_info; 40 struct device_attribute attr_hdw_name; 41 struct device_attribute attr_hdw_desc; 42 int v4l_minor_number_created_ok; 43 int v4l_radio_minor_number_created_ok; 44 int unit_number_created_ok; 45 int bus_info_created_ok; 46 int hdw_name_created_ok; 47 int hdw_desc_created_ok; 48 }; 49 50 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 51 struct pvr2_sysfs_debugifc { 52 struct device_attribute attr_debugcmd; 53 struct device_attribute attr_debuginfo; 54 int debugcmd_created_ok; 55 int debuginfo_created_ok; 56 }; 57 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 58 59 struct pvr2_sysfs_ctl_item { 60 struct device_attribute attr_name; 61 struct device_attribute attr_type; 62 struct device_attribute attr_min; 63 struct device_attribute attr_max; 64 struct device_attribute attr_def; 65 struct device_attribute attr_enum; 66 struct device_attribute attr_bits; 67 struct device_attribute attr_val; 68 struct device_attribute attr_custom; 69 struct pvr2_ctrl *cptr; 70 int ctl_id; 71 struct pvr2_sysfs *chptr; 72 struct pvr2_sysfs_ctl_item *item_next; 73 struct attribute *attr_gen[8]; 74 struct attribute_group grp; 75 int created_ok; 76 char name[80]; 77 }; 78 79 struct pvr2_sysfs_class { 80 struct class class; 81 }; 82 83 static ssize_t show_name(struct device *class_dev, 84 struct device_attribute *attr, 85 char *buf) 86 { 87 struct pvr2_sysfs_ctl_item *cip; 88 const char *name; 89 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name); 90 name = pvr2_ctrl_get_desc(cip->cptr); 91 pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s", 92 cip->chptr, cip->ctl_id, name); 93 if (!name) return -EINVAL; 94 return scnprintf(buf, PAGE_SIZE, "%s\n", name); 95 } 96 97 static ssize_t show_type(struct device *class_dev, 98 struct device_attribute *attr, 99 char *buf) 100 { 101 struct pvr2_sysfs_ctl_item *cip; 102 const char *name; 103 enum pvr2_ctl_type tp; 104 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type); 105 tp = pvr2_ctrl_get_type(cip->cptr); 106 switch (tp) { 107 case pvr2_ctl_int: name = "integer"; break; 108 case pvr2_ctl_enum: name = "enum"; break; 109 case pvr2_ctl_bitmask: name = "bitmask"; break; 110 case pvr2_ctl_bool: name = "boolean"; break; 111 default: name = "?"; break; 112 } 113 pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s", 114 cip->chptr, cip->ctl_id, name); 115 return scnprintf(buf, PAGE_SIZE, "%s\n", name); 116 } 117 118 static ssize_t show_min(struct device *class_dev, 119 struct device_attribute *attr, 120 char *buf) 121 { 122 struct pvr2_sysfs_ctl_item *cip; 123 long val; 124 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min); 125 val = pvr2_ctrl_get_min(cip->cptr); 126 pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld", 127 cip->chptr, cip->ctl_id, val); 128 return scnprintf(buf, PAGE_SIZE, "%ld\n", val); 129 } 130 131 static ssize_t show_max(struct device *class_dev, 132 struct device_attribute *attr, 133 char *buf) 134 { 135 struct pvr2_sysfs_ctl_item *cip; 136 long val; 137 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max); 138 val = pvr2_ctrl_get_max(cip->cptr); 139 pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld", 140 cip->chptr, cip->ctl_id, val); 141 return scnprintf(buf, PAGE_SIZE, "%ld\n", val); 142 } 143 144 static ssize_t show_def(struct device *class_dev, 145 struct device_attribute *attr, 146 char *buf) 147 { 148 struct pvr2_sysfs_ctl_item *cip; 149 int val; 150 int ret; 151 unsigned int cnt = 0; 152 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def); 153 ret = pvr2_ctrl_get_def(cip->cptr, &val); 154 if (ret < 0) return ret; 155 ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val, 156 buf, PAGE_SIZE - 1, &cnt); 157 pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)", 158 cip->chptr, cip->ctl_id, cnt, buf, val); 159 buf[cnt] = '\n'; 160 return cnt + 1; 161 } 162 163 static ssize_t show_val_norm(struct device *class_dev, 164 struct device_attribute *attr, 165 char *buf) 166 { 167 struct pvr2_sysfs_ctl_item *cip; 168 int val; 169 int ret; 170 unsigned int cnt = 0; 171 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); 172 ret = pvr2_ctrl_get_value(cip->cptr, &val); 173 if (ret < 0) return ret; 174 ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val, 175 buf, PAGE_SIZE - 1, &cnt); 176 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", 177 cip->chptr, cip->ctl_id, cnt, buf, val); 178 buf[cnt] = '\n'; 179 return cnt+1; 180 } 181 182 static ssize_t show_val_custom(struct device *class_dev, 183 struct device_attribute *attr, 184 char *buf) 185 { 186 struct pvr2_sysfs_ctl_item *cip; 187 int val; 188 int ret; 189 unsigned int cnt = 0; 190 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); 191 ret = pvr2_ctrl_get_value(cip->cptr, &val); 192 if (ret < 0) return ret; 193 ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val, 194 buf, PAGE_SIZE - 1, &cnt); 195 pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", 196 cip->chptr, cip->ctl_id, cnt, buf, val); 197 buf[cnt] = '\n'; 198 return cnt+1; 199 } 200 201 static ssize_t show_enum(struct device *class_dev, 202 struct device_attribute *attr, 203 char *buf) 204 { 205 struct pvr2_sysfs_ctl_item *cip; 206 long val; 207 unsigned int bcnt, ccnt, ecnt; 208 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum); 209 ecnt = pvr2_ctrl_get_cnt(cip->cptr); 210 bcnt = 0; 211 for (val = 0; val < ecnt; val++) { 212 pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt, 213 PAGE_SIZE - bcnt, &ccnt); 214 if (!ccnt) continue; 215 bcnt += ccnt; 216 if (bcnt >= PAGE_SIZE) break; 217 buf[bcnt] = '\n'; 218 bcnt++; 219 } 220 pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)", 221 cip->chptr, cip->ctl_id); 222 return bcnt; 223 } 224 225 static ssize_t show_bits(struct device *class_dev, 226 struct device_attribute *attr, 227 char *buf) 228 { 229 struct pvr2_sysfs_ctl_item *cip; 230 int valid_bits, msk; 231 unsigned int bcnt, ccnt; 232 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits); 233 valid_bits = pvr2_ctrl_get_mask(cip->cptr); 234 bcnt = 0; 235 for (msk = 1; valid_bits; msk <<= 1) { 236 if (!(msk & valid_bits)) continue; 237 valid_bits &= ~msk; 238 pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt, 239 PAGE_SIZE - bcnt, &ccnt); 240 bcnt += ccnt; 241 if (bcnt >= PAGE_SIZE) break; 242 buf[bcnt] = '\n'; 243 bcnt++; 244 } 245 pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)", 246 cip->chptr, cip->ctl_id); 247 return bcnt; 248 } 249 250 static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl, 251 const char *buf,unsigned int count) 252 { 253 int ret; 254 int mask,val; 255 if (customfl) { 256 ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count, 257 &mask, &val); 258 } else { 259 ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count, 260 &mask, &val); 261 } 262 if (ret < 0) return ret; 263 ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val); 264 pvr2_hdw_commit_ctl(cip->chptr->channel.hdw); 265 return ret; 266 } 267 268 static ssize_t store_val_norm(struct device *class_dev, 269 struct device_attribute *attr, 270 const char *buf, size_t count) 271 { 272 struct pvr2_sysfs_ctl_item *cip; 273 int ret; 274 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); 275 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"", 276 cip->chptr, cip->ctl_id, (int)count, buf); 277 ret = store_val_any(cip, 0, buf, count); 278 if (!ret) ret = count; 279 return ret; 280 } 281 282 static ssize_t store_val_custom(struct device *class_dev, 283 struct device_attribute *attr, 284 const char *buf, size_t count) 285 { 286 struct pvr2_sysfs_ctl_item *cip; 287 int ret; 288 cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); 289 pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"", 290 cip->chptr, cip->ctl_id, (int)count, buf); 291 ret = store_val_any(cip, 1, buf, count); 292 if (!ret) ret = count; 293 return ret; 294 } 295 296 static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) 297 { 298 struct pvr2_sysfs_ctl_item *cip; 299 struct pvr2_ctrl *cptr; 300 unsigned int cnt,acnt; 301 int ret; 302 303 cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); 304 if (!cptr) return; 305 306 cip = kzalloc(sizeof(*cip),GFP_KERNEL); 307 if (!cip) return; 308 pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); 309 310 cip->cptr = cptr; 311 cip->ctl_id = ctl_id; 312 313 cip->chptr = sfp; 314 cip->item_next = NULL; 315 if (sfp->item_last) { 316 sfp->item_last->item_next = cip; 317 } else { 318 sfp->item_first = cip; 319 } 320 sfp->item_last = cip; 321 322 sysfs_attr_init(&cip->attr_name.attr); 323 cip->attr_name.attr.name = "name"; 324 cip->attr_name.attr.mode = S_IRUGO; 325 cip->attr_name.show = show_name; 326 327 sysfs_attr_init(&cip->attr_type.attr); 328 cip->attr_type.attr.name = "type"; 329 cip->attr_type.attr.mode = S_IRUGO; 330 cip->attr_type.show = show_type; 331 332 sysfs_attr_init(&cip->attr_min.attr); 333 cip->attr_min.attr.name = "min_val"; 334 cip->attr_min.attr.mode = S_IRUGO; 335 cip->attr_min.show = show_min; 336 337 sysfs_attr_init(&cip->attr_max.attr); 338 cip->attr_max.attr.name = "max_val"; 339 cip->attr_max.attr.mode = S_IRUGO; 340 cip->attr_max.show = show_max; 341 342 sysfs_attr_init(&cip->attr_def.attr); 343 cip->attr_def.attr.name = "def_val"; 344 cip->attr_def.attr.mode = S_IRUGO; 345 cip->attr_def.show = show_def; 346 347 sysfs_attr_init(&cip->attr_val.attr); 348 cip->attr_val.attr.name = "cur_val"; 349 cip->attr_val.attr.mode = S_IRUGO; 350 351 sysfs_attr_init(&cip->attr_custom.attr); 352 cip->attr_custom.attr.name = "custom_val"; 353 cip->attr_custom.attr.mode = S_IRUGO; 354 355 sysfs_attr_init(&cip->attr_enum.attr); 356 cip->attr_enum.attr.name = "enum_val"; 357 cip->attr_enum.attr.mode = S_IRUGO; 358 cip->attr_enum.show = show_enum; 359 360 sysfs_attr_init(&cip->attr_bits.attr); 361 cip->attr_bits.attr.name = "bit_val"; 362 cip->attr_bits.attr.mode = S_IRUGO; 363 cip->attr_bits.show = show_bits; 364 365 if (pvr2_ctrl_is_writable(cptr)) { 366 cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; 367 cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP; 368 } 369 370 acnt = 0; 371 cip->attr_gen[acnt++] = &cip->attr_name.attr; 372 cip->attr_gen[acnt++] = &cip->attr_type.attr; 373 cip->attr_gen[acnt++] = &cip->attr_val.attr; 374 cip->attr_gen[acnt++] = &cip->attr_def.attr; 375 cip->attr_val.show = show_val_norm; 376 cip->attr_val.store = store_val_norm; 377 if (pvr2_ctrl_has_custom_symbols(cptr)) { 378 cip->attr_gen[acnt++] = &cip->attr_custom.attr; 379 cip->attr_custom.show = show_val_custom; 380 cip->attr_custom.store = store_val_custom; 381 } 382 switch (pvr2_ctrl_get_type(cptr)) { 383 case pvr2_ctl_enum: 384 // Control is an enumeration 385 cip->attr_gen[acnt++] = &cip->attr_enum.attr; 386 break; 387 case pvr2_ctl_int: 388 // Control is an integer 389 cip->attr_gen[acnt++] = &cip->attr_min.attr; 390 cip->attr_gen[acnt++] = &cip->attr_max.attr; 391 break; 392 case pvr2_ctl_bitmask: 393 // Control is an bitmask 394 cip->attr_gen[acnt++] = &cip->attr_bits.attr; 395 break; 396 default: break; 397 } 398 399 cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s", 400 pvr2_ctrl_get_name(cptr)); 401 cip->name[cnt] = 0; 402 cip->grp.name = cip->name; 403 cip->grp.attrs = cip->attr_gen; 404 405 ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); 406 if (ret) { 407 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 408 "sysfs_create_group error: %d", 409 ret); 410 return; 411 } 412 cip->created_ok = !0; 413 } 414 415 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 416 static ssize_t debuginfo_show(struct device *, struct device_attribute *, 417 char *); 418 static ssize_t debugcmd_show(struct device *, struct device_attribute *, 419 char *); 420 static ssize_t debugcmd_store(struct device *, struct device_attribute *, 421 const char *, size_t count); 422 423 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) 424 { 425 struct pvr2_sysfs_debugifc *dip; 426 int ret; 427 428 dip = kzalloc(sizeof(*dip),GFP_KERNEL); 429 if (!dip) return; 430 sysfs_attr_init(&dip->attr_debugcmd.attr); 431 dip->attr_debugcmd.attr.name = "debugcmd"; 432 dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; 433 dip->attr_debugcmd.show = debugcmd_show; 434 dip->attr_debugcmd.store = debugcmd_store; 435 sysfs_attr_init(&dip->attr_debuginfo.attr); 436 dip->attr_debuginfo.attr.name = "debuginfo"; 437 dip->attr_debuginfo.attr.mode = S_IRUGO; 438 dip->attr_debuginfo.show = debuginfo_show; 439 sfp->debugifc = dip; 440 ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd); 441 if (ret < 0) { 442 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 443 "device_create_file error: %d", 444 ret); 445 } else { 446 dip->debugcmd_created_ok = !0; 447 } 448 ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo); 449 if (ret < 0) { 450 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 451 "device_create_file error: %d", 452 ret); 453 } else { 454 dip->debuginfo_created_ok = !0; 455 } 456 } 457 458 459 static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) 460 { 461 if (!sfp->debugifc) return; 462 if (sfp->debugifc->debuginfo_created_ok) { 463 device_remove_file(sfp->class_dev, 464 &sfp->debugifc->attr_debuginfo); 465 } 466 if (sfp->debugifc->debugcmd_created_ok) { 467 device_remove_file(sfp->class_dev, 468 &sfp->debugifc->attr_debugcmd); 469 } 470 kfree(sfp->debugifc); 471 sfp->debugifc = NULL; 472 } 473 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 474 475 476 static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp) 477 { 478 unsigned int idx,cnt; 479 cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw); 480 for (idx = 0; idx < cnt; idx++) { 481 pvr2_sysfs_add_control(sfp,idx); 482 } 483 } 484 485 486 static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) 487 { 488 struct pvr2_sysfs_ctl_item *cip1,*cip2; 489 for (cip1 = sfp->item_first; cip1; cip1 = cip2) { 490 cip2 = cip1->item_next; 491 if (cip1->created_ok) { 492 sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); 493 } 494 pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); 495 kfree(cip1); 496 } 497 } 498 499 500 static void pvr2_sysfs_class_release(struct class *class) 501 { 502 struct pvr2_sysfs_class *clp; 503 clp = container_of(class,struct pvr2_sysfs_class,class); 504 pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp); 505 kfree(clp); 506 } 507 508 509 static void pvr2_sysfs_release(struct device *class_dev) 510 { 511 pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev); 512 kfree(class_dev); 513 } 514 515 516 static void class_dev_destroy(struct pvr2_sysfs *sfp) 517 { 518 struct device *dev; 519 if (!sfp->class_dev) return; 520 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 521 pvr2_sysfs_tear_down_debugifc(sfp); 522 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 523 pvr2_sysfs_tear_down_controls(sfp); 524 if (sfp->hdw_desc_created_ok) { 525 device_remove_file(sfp->class_dev, 526 &sfp->attr_hdw_desc); 527 } 528 if (sfp->hdw_name_created_ok) { 529 device_remove_file(sfp->class_dev, 530 &sfp->attr_hdw_name); 531 } 532 if (sfp->bus_info_created_ok) { 533 device_remove_file(sfp->class_dev, 534 &sfp->attr_bus_info); 535 } 536 if (sfp->v4l_minor_number_created_ok) { 537 device_remove_file(sfp->class_dev, 538 &sfp->attr_v4l_minor_number); 539 } 540 if (sfp->v4l_radio_minor_number_created_ok) { 541 device_remove_file(sfp->class_dev, 542 &sfp->attr_v4l_radio_minor_number); 543 } 544 if (sfp->unit_number_created_ok) { 545 device_remove_file(sfp->class_dev, 546 &sfp->attr_unit_number); 547 } 548 pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); 549 dev_set_drvdata(sfp->class_dev, NULL); 550 dev = sfp->class_dev->parent; 551 sfp->class_dev->parent = NULL; 552 put_device(dev); 553 device_unregister(sfp->class_dev); 554 sfp->class_dev = NULL; 555 } 556 557 558 static ssize_t v4l_minor_number_show(struct device *class_dev, 559 struct device_attribute *attr, char *buf) 560 { 561 struct pvr2_sysfs *sfp; 562 sfp = dev_get_drvdata(class_dev); 563 if (!sfp) return -EINVAL; 564 return scnprintf(buf,PAGE_SIZE,"%d\n", 565 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw, 566 pvr2_v4l_type_video)); 567 } 568 569 570 static ssize_t bus_info_show(struct device *class_dev, 571 struct device_attribute *attr, char *buf) 572 { 573 struct pvr2_sysfs *sfp; 574 sfp = dev_get_drvdata(class_dev); 575 if (!sfp) return -EINVAL; 576 return scnprintf(buf,PAGE_SIZE,"%s\n", 577 pvr2_hdw_get_bus_info(sfp->channel.hdw)); 578 } 579 580 581 static ssize_t hdw_name_show(struct device *class_dev, 582 struct device_attribute *attr, char *buf) 583 { 584 struct pvr2_sysfs *sfp; 585 sfp = dev_get_drvdata(class_dev); 586 if (!sfp) return -EINVAL; 587 return scnprintf(buf,PAGE_SIZE,"%s\n", 588 pvr2_hdw_get_type(sfp->channel.hdw)); 589 } 590 591 592 static ssize_t hdw_desc_show(struct device *class_dev, 593 struct device_attribute *attr, char *buf) 594 { 595 struct pvr2_sysfs *sfp; 596 sfp = dev_get_drvdata(class_dev); 597 if (!sfp) return -EINVAL; 598 return scnprintf(buf,PAGE_SIZE,"%s\n", 599 pvr2_hdw_get_desc(sfp->channel.hdw)); 600 } 601 602 603 static ssize_t v4l_radio_minor_number_show(struct device *class_dev, 604 struct device_attribute *attr, 605 char *buf) 606 { 607 struct pvr2_sysfs *sfp; 608 sfp = dev_get_drvdata(class_dev); 609 if (!sfp) return -EINVAL; 610 return scnprintf(buf,PAGE_SIZE,"%d\n", 611 pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw, 612 pvr2_v4l_type_radio)); 613 } 614 615 616 static ssize_t unit_number_show(struct device *class_dev, 617 struct device_attribute *attr, char *buf) 618 { 619 struct pvr2_sysfs *sfp; 620 sfp = dev_get_drvdata(class_dev); 621 if (!sfp) return -EINVAL; 622 return scnprintf(buf,PAGE_SIZE,"%d\n", 623 pvr2_hdw_get_unit_number(sfp->channel.hdw)); 624 } 625 626 627 static void class_dev_create(struct pvr2_sysfs *sfp, 628 struct pvr2_sysfs_class *class_ptr) 629 { 630 struct usb_device *usb_dev; 631 struct device *class_dev; 632 int ret; 633 634 usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); 635 if (!usb_dev) return; 636 class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL); 637 if (!class_dev) return; 638 639 pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); 640 641 class_dev->class = &class_ptr->class; 642 643 dev_set_name(class_dev, "%s", 644 pvr2_hdw_get_device_identifier(sfp->channel.hdw)); 645 646 class_dev->parent = get_device(&usb_dev->dev); 647 648 sfp->class_dev = class_dev; 649 dev_set_drvdata(class_dev, sfp); 650 ret = device_register(class_dev); 651 if (ret) { 652 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 653 "device_register failed"); 654 put_device(class_dev); 655 return; 656 } 657 658 sysfs_attr_init(&sfp->attr_v4l_minor_number.attr); 659 sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; 660 sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; 661 sfp->attr_v4l_minor_number.show = v4l_minor_number_show; 662 sfp->attr_v4l_minor_number.store = NULL; 663 ret = device_create_file(sfp->class_dev, 664 &sfp->attr_v4l_minor_number); 665 if (ret < 0) { 666 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 667 "device_create_file error: %d", 668 ret); 669 } else { 670 sfp->v4l_minor_number_created_ok = !0; 671 } 672 673 sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr); 674 sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number"; 675 sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO; 676 sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show; 677 sfp->attr_v4l_radio_minor_number.store = NULL; 678 ret = device_create_file(sfp->class_dev, 679 &sfp->attr_v4l_radio_minor_number); 680 if (ret < 0) { 681 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 682 "device_create_file error: %d", 683 ret); 684 } else { 685 sfp->v4l_radio_minor_number_created_ok = !0; 686 } 687 688 sysfs_attr_init(&sfp->attr_unit_number.attr); 689 sfp->attr_unit_number.attr.name = "unit_number"; 690 sfp->attr_unit_number.attr.mode = S_IRUGO; 691 sfp->attr_unit_number.show = unit_number_show; 692 sfp->attr_unit_number.store = NULL; 693 ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number); 694 if (ret < 0) { 695 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 696 "device_create_file error: %d", 697 ret); 698 } else { 699 sfp->unit_number_created_ok = !0; 700 } 701 702 sysfs_attr_init(&sfp->attr_bus_info.attr); 703 sfp->attr_bus_info.attr.name = "bus_info_str"; 704 sfp->attr_bus_info.attr.mode = S_IRUGO; 705 sfp->attr_bus_info.show = bus_info_show; 706 sfp->attr_bus_info.store = NULL; 707 ret = device_create_file(sfp->class_dev, 708 &sfp->attr_bus_info); 709 if (ret < 0) { 710 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 711 "device_create_file error: %d", 712 ret); 713 } else { 714 sfp->bus_info_created_ok = !0; 715 } 716 717 sysfs_attr_init(&sfp->attr_hdw_name.attr); 718 sfp->attr_hdw_name.attr.name = "device_hardware_type"; 719 sfp->attr_hdw_name.attr.mode = S_IRUGO; 720 sfp->attr_hdw_name.show = hdw_name_show; 721 sfp->attr_hdw_name.store = NULL; 722 ret = device_create_file(sfp->class_dev, 723 &sfp->attr_hdw_name); 724 if (ret < 0) { 725 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 726 "device_create_file error: %d", 727 ret); 728 } else { 729 sfp->hdw_name_created_ok = !0; 730 } 731 732 sysfs_attr_init(&sfp->attr_hdw_desc.attr); 733 sfp->attr_hdw_desc.attr.name = "device_hardware_description"; 734 sfp->attr_hdw_desc.attr.mode = S_IRUGO; 735 sfp->attr_hdw_desc.show = hdw_desc_show; 736 sfp->attr_hdw_desc.store = NULL; 737 ret = device_create_file(sfp->class_dev, 738 &sfp->attr_hdw_desc); 739 if (ret < 0) { 740 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 741 "device_create_file error: %d", 742 ret); 743 } else { 744 sfp->hdw_desc_created_ok = !0; 745 } 746 747 pvr2_sysfs_add_controls(sfp); 748 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 749 pvr2_sysfs_add_debugifc(sfp); 750 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 751 } 752 753 754 static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) 755 { 756 struct pvr2_sysfs *sfp; 757 sfp = container_of(chp,struct pvr2_sysfs,channel); 758 if (!sfp->channel.mc_head->disconnect_flag) return; 759 pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp); 760 class_dev_destroy(sfp); 761 pvr2_channel_done(&sfp->channel); 762 kfree(sfp); 763 } 764 765 766 struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, 767 struct pvr2_sysfs_class *class_ptr) 768 { 769 struct pvr2_sysfs *sfp; 770 sfp = kzalloc(sizeof(*sfp),GFP_KERNEL); 771 if (!sfp) return sfp; 772 pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); 773 pvr2_channel_init(&sfp->channel,mp); 774 sfp->channel.check_func = pvr2_sysfs_internal_check; 775 776 class_dev_create(sfp,class_ptr); 777 return sfp; 778 } 779 780 781 782 struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) 783 { 784 struct pvr2_sysfs_class *clp; 785 clp = kzalloc(sizeof(*clp),GFP_KERNEL); 786 if (!clp) return clp; 787 pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p", 788 clp); 789 clp->class.name = "pvrusb2"; 790 clp->class.class_release = pvr2_sysfs_class_release; 791 clp->class.dev_release = pvr2_sysfs_release; 792 if (class_register(&clp->class)) { 793 pvr2_sysfs_trace( 794 "Registration failed for pvr2_sysfs_class id=%p",clp); 795 kfree(clp); 796 clp = NULL; 797 } 798 return clp; 799 } 800 801 802 void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) 803 { 804 pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp); 805 class_unregister(&clp->class); 806 } 807 808 809 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC 810 static ssize_t debuginfo_show(struct device *class_dev, 811 struct device_attribute *attr, char *buf) 812 { 813 struct pvr2_sysfs *sfp; 814 sfp = dev_get_drvdata(class_dev); 815 if (!sfp) return -EINVAL; 816 pvr2_hdw_trigger_module_log(sfp->channel.hdw); 817 return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE); 818 } 819 820 821 static ssize_t debugcmd_show(struct device *class_dev, 822 struct device_attribute *attr, char *buf) 823 { 824 struct pvr2_sysfs *sfp; 825 sfp = dev_get_drvdata(class_dev); 826 if (!sfp) return -EINVAL; 827 return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE); 828 } 829 830 831 static ssize_t debugcmd_store(struct device *class_dev, 832 struct device_attribute *attr, 833 const char *buf, size_t count) 834 { 835 struct pvr2_sysfs *sfp; 836 int ret; 837 838 sfp = dev_get_drvdata(class_dev); 839 if (!sfp) return -EINVAL; 840 841 ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count); 842 if (ret < 0) return ret; 843 return count; 844 } 845 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ 846