diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2016-02-07 21:48:40 +0000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2016-04-08 18:46:46 +0100 |
commit | 5ac0166388ac9a493491a30fbc3570f23950dc51 (patch) | |
tree | 8fe2019a8d3376042d1f92b7a2127bd73d3c97e3 /utils/regtools/qeditor/backend.cpp | |
parent | cc4c9b70bcac048fc388d0f553b7621f52449526 (diff) | |
download | rockbox-5ac0166388ac9a493491a30fbc3570f23950dc51.tar.gz rockbox-5ac0166388ac9a493491a30fbc3570f23950dc51.zip |
qeditor: port to the new hwstub library and add features
This commit adds support for the version of the hwstub library, which requires
a lot of changes. It also adds some editing features, such as register access
and much better editing of fields using the mouse (double click on a field
to be able to resize and move it).
Change-Id: I3c4e4cc855cb44911c72bc8127bad841b68efe52
Diffstat (limited to 'utils/regtools/qeditor/backend.cpp')
-rw-r--r-- | utils/regtools/qeditor/backend.cpp | 553 |
1 files changed, 401 insertions, 152 deletions
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp index 5f006b0aa7..a8264c6e50 100644 --- a/utils/regtools/qeditor/backend.cpp +++ b/utils/regtools/qeditor/backend.cpp | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <QTextStream> | 22 | #include <QTextStream> |
23 | #include <QDebug> | 23 | #include <QDebug> |
24 | #include <QFileInfo> | 24 | #include <QFileInfo> |
25 | #include <QFont> | ||
25 | #include "backend.h" | 26 | #include "backend.h" |
26 | 27 | ||
27 | /** | 28 | /** |
@@ -337,110 +338,436 @@ QString FileIoBackend::GetFileName() | |||
337 | 338 | ||
338 | #ifdef HAVE_HWSTUB | 339 | #ifdef HAVE_HWSTUB |
339 | /** | 340 | /** |
340 | * HWStubDevice | 341 | * HWStubManager |
341 | */ | 342 | */ |
342 | HWStubDevice::HWStubDevice(struct libusb_device *dev) | 343 | HWStubManager *HWStubManager::g_inst = nullptr; |
344 | |||
345 | HWStubManager::HWStubManager() | ||
343 | { | 346 | { |
344 | Init(dev); | 347 | Add("Default", QString::fromStdString(hwstub::uri::default_uri().full_uri())); |
345 | } | 348 | } |
346 | 349 | ||
347 | HWStubDevice::HWStubDevice(const HWStubDevice *dev) | 350 | HWStubManager::~HWStubManager() |
348 | { | 351 | { |
349 | Init(dev->m_dev); | ||
350 | } | 352 | } |
351 | 353 | ||
352 | void HWStubDevice::Init(struct libusb_device *dev) | 354 | HWStubManager *HWStubManager::Get() |
353 | { | 355 | { |
354 | libusb_ref_device(dev); | 356 | if(g_inst == nullptr) |
355 | m_dev = dev; | 357 | g_inst = new HWStubManager(); |
356 | m_handle = 0; | 358 | return g_inst; |
357 | m_hwdev = 0; | ||
358 | m_valid = Probe(); | ||
359 | } | 359 | } |
360 | 360 | ||
361 | HWStubDevice::~HWStubDevice() | 361 | bool HWStubManager::Add(const QString& name, const QString& uri) |
362 | { | ||
363 | struct Context ctx; | ||
364 | ctx.name = name; | ||
365 | ctx.uri = uri; | ||
366 | ctx.context = hwstub::uri::create_context(uri.toStdString()); | ||
367 | if(!ctx.context) | ||
368 | return false; | ||
369 | ctx.context->start_polling(); | ||
370 | beginInsertRows(QModelIndex(), m_list.size(), m_list.size()); | ||
371 | m_list.push_back(ctx); | ||
372 | endInsertRows(); | ||
373 | return true; | ||
374 | } | ||
375 | |||
376 | void HWStubManager::Clear() | ||
362 | { | 377 | { |
363 | Close(); | 378 | m_list.clear(); |
364 | libusb_unref_device(m_dev); | ||
365 | } | 379 | } |
366 | 380 | ||
367 | int HWStubDevice::GetBusNumber() | 381 | int HWStubManager::rowCount(const QModelIndex& parent) const |
368 | { | 382 | { |
369 | return libusb_get_bus_number(m_dev); | 383 | Q_UNUSED(parent); |
384 | return m_list.size(); | ||
370 | } | 385 | } |
371 | 386 | ||
372 | int HWStubDevice::GetDevAddress() | 387 | int HWStubManager::columnCount(const QModelIndex& parent) const |
373 | { | 388 | { |
374 | return libusb_get_device_address(m_dev); | 389 | Q_UNUSED(parent); |
390 | return 2; | ||
375 | } | 391 | } |
376 | 392 | ||
377 | bool HWStubDevice::Probe() | 393 | std::shared_ptr< hwstub::context > HWStubManager::GetContext(int row) |
378 | { | 394 | { |
379 | if(!Open()) | 395 | if(row < 0 || (size_t)row >= m_list.size()) |
380 | return false; | 396 | return std::shared_ptr< hwstub::context >(); |
381 | // get target | 397 | else |
382 | int ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_TARGET, &m_hwdev_target, sizeof(m_hwdev_target)); | 398 | return m_list[row].context; |
383 | if(ret != sizeof(m_hwdev_target)) | 399 | } |
384 | goto Lerr; | 400 | |
385 | // get STMP information | 401 | QVariant HWStubManager::data(const QModelIndex& index, int role) const |
386 | if(m_hwdev_target.dID == HWSTUB_TARGET_STMP) | 402 | { |
403 | if(index.row() < 0 || (size_t)index.row() >= m_list.size()) | ||
404 | return QVariant(); | ||
405 | int section = index.column(); | ||
406 | const Context& ctx = m_list[index.row()]; | ||
407 | if(section == GetNameColumn()) | ||
387 | { | 408 | { |
388 | ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_STMP, &m_hwdev_stmp, sizeof(m_hwdev_stmp)); | 409 | if(role == Qt::DisplayRole || role == Qt::EditRole) |
389 | if(ret != sizeof(m_hwdev_stmp)) | 410 | return QVariant(ctx.name); |
390 | goto Lerr; | ||
391 | } | 411 | } |
392 | else if(m_hwdev_target.dID == HWSTUB_TARGET_PP) | 412 | else if(section == GetUriColumn()) |
393 | { | 413 | { |
394 | ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_PP, &m_hwdev_pp, sizeof(m_hwdev_pp)); | 414 | if(role == Qt::DisplayRole) |
395 | if(ret != sizeof(m_hwdev_pp)) | 415 | return QVariant(ctx.uri); |
396 | goto Lerr; | ||
397 | } | 416 | } |
398 | Close(); | 417 | return QVariant(); |
399 | return true; | 418 | } |
400 | 419 | ||
401 | Lerr: | 420 | QVariant HWStubManager::headerData(int section, Qt::Orientation orientation, int role) const |
402 | Close(); | 421 | { |
403 | return false; | 422 | if(orientation == Qt::Vertical) |
423 | return QVariant(); | ||
424 | if(role != Qt::DisplayRole) | ||
425 | return QVariant(); | ||
426 | if(section == GetNameColumn()) | ||
427 | return QVariant("Name"); | ||
428 | else if(section == GetUriColumn()) | ||
429 | return QVariant("URI"); | ||
430 | return QVariant(); | ||
431 | } | ||
432 | |||
433 | Qt::ItemFlags HWStubManager::flags(const QModelIndex& index) const | ||
434 | { | ||
435 | Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; | ||
436 | int section = index.column(); | ||
437 | if(section == GetNameColumn()) | ||
438 | flags |= Qt::ItemIsEditable; | ||
439 | return flags; | ||
404 | } | 440 | } |
405 | 441 | ||
406 | bool HWStubDevice::Open() | 442 | bool HWStubManager::setData(const QModelIndex& index, const QVariant& value, int role) |
407 | { | 443 | { |
408 | if(libusb_open(m_dev, &m_handle)) | 444 | if(role != Qt::EditRole) |
409 | return false; | 445 | return false; |
410 | m_hwdev = hwstub_open(m_handle); | 446 | if(index.row() < 0 || (size_t)index.row() >= m_list.size()) |
411 | if(m_hwdev == 0) | ||
412 | { | ||
413 | libusb_close(m_handle); | ||
414 | m_handle = 0; | ||
415 | return false; | 447 | return false; |
416 | } | 448 | if(index.column() != GetNameColumn()) |
449 | return false; | ||
450 | m_list[index.row()].name = value.toString(); | ||
451 | emit dataChanged(index, index); | ||
417 | return true; | 452 | return true; |
418 | } | 453 | } |
419 | 454 | ||
420 | void HWStubDevice::Close() | 455 | int HWStubManager::GetNameColumn() const |
421 | { | 456 | { |
422 | if(m_hwdev) | 457 | return 0; |
423 | hwstub_release(m_hwdev); | ||
424 | m_hwdev = 0; | ||
425 | if(m_handle) | ||
426 | libusb_close(m_handle); | ||
427 | m_handle = 0; | ||
428 | } | 458 | } |
429 | 459 | ||
430 | bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer) | 460 | int HWStubManager::GetUriColumn() const |
461 | { | ||
462 | return 1; | ||
463 | } | ||
464 | |||
465 | QString HWStubManager::GetFriendlyName(std::shared_ptr< hwstub::device > device) | ||
466 | { | ||
467 | /* try to open the device */ | ||
468 | std::shared_ptr< hwstub::handle > handle; | ||
469 | hwstub::error err = device->open(handle); | ||
470 | if(err != hwstub::error::SUCCESS) | ||
471 | goto Lfallback; | ||
472 | /* get target descriptor */ | ||
473 | struct hwstub_target_desc_t target_desc; | ||
474 | err = handle->get_target_desc(target_desc); | ||
475 | if(err != hwstub::error::SUCCESS) | ||
476 | goto Lfallback; | ||
477 | return QString::fromStdString(target_desc.bName); | ||
478 | |||
479 | /* fallback: don't open the device */ | ||
480 | Lfallback: | ||
481 | hwstub::usb::device *udev = dynamic_cast< hwstub::usb::device* >(device.get()); | ||
482 | if(udev) | ||
483 | { | ||
484 | return QString("USB Bus %1 Device %2: ID %3:%4") | ||
485 | .arg(udev->get_bus_number()).arg(udev->get_address(), 3, 10, QChar('0')) | ||
486 | .arg(udev->get_vid(), 4, 16, QChar('0')).arg(udev->get_pid(), 4, 16, QChar('0')); | ||
487 | } | ||
488 | else | ||
489 | return QString("<Unknown device>"); | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * HWStubContextModel | ||
494 | */ | ||
495 | HWStubContextModel::HWStubContextModel(QObject *parent) | ||
496 | :QAbstractTableModel(parent), m_has_dummy(false) | ||
497 | { | ||
498 | } | ||
499 | |||
500 | HWStubContextModel::~HWStubContextModel() | ||
501 | { | ||
502 | SetContext(std::shared_ptr< hwstub::context >()); | ||
503 | } | ||
504 | |||
505 | void HWStubContextModel::SetContext(std::shared_ptr< hwstub::context > context) | ||
506 | { | ||
507 | int first_row = m_has_dummy ? 1: 0; | ||
508 | /* clear previous model if any */ | ||
509 | if(m_list.size() > 0) | ||
510 | { | ||
511 | beginRemoveRows(QModelIndex(), first_row, first_row + m_list.size() - 1); | ||
512 | m_list.clear(); | ||
513 | endRemoveRows(); | ||
514 | } | ||
515 | /* don't forget to unregister callback if context still exists */ | ||
516 | std::shared_ptr< hwstub::context > ctx = m_context.lock(); | ||
517 | if(ctx) | ||
518 | ctx->unregister_callback(m_callback_ref); | ||
519 | /* get new context */ | ||
520 | m_context = context; | ||
521 | if(context) | ||
522 | { | ||
523 | /* register new callback */ | ||
524 | m_callback_ref = context->register_callback( | ||
525 | std::bind(&HWStubContextModel::OnDevChangeLow, this, std::placeholders::_1, | ||
526 | std::placeholders::_2, std::placeholders::_3)); | ||
527 | /* get dev list */ | ||
528 | std::vector< std::shared_ptr< hwstub::device > > list; | ||
529 | hwstub::error err = context->get_device_list(list); | ||
530 | if(err == hwstub::error::SUCCESS) | ||
531 | { | ||
532 | beginInsertRows(QModelIndex(), first_row, first_row + list.size() - 1); | ||
533 | for(auto& d : list) | ||
534 | { | ||
535 | Device dev; | ||
536 | dev.name = GetFriendlyName(d); | ||
537 | dev.device = d; | ||
538 | m_list.push_back(dev); | ||
539 | } | ||
540 | endInsertRows(); | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | |||
545 | void HWStubContextModel::EnableDummy(bool en, const QString& text) | ||
546 | { | ||
547 | /* if needed, create/remove raw */ | ||
548 | if(m_has_dummy && !en) | ||
549 | { | ||
550 | /* remove row */ | ||
551 | beginRemoveRows(QModelIndex(), 0, 0); | ||
552 | m_has_dummy = false; | ||
553 | endRemoveRows(); | ||
554 | } | ||
555 | else if(!m_has_dummy && en) | ||
556 | { | ||
557 | /* add row */ | ||
558 | beginInsertRows(QModelIndex(), 0, 0); | ||
559 | m_has_dummy = true; | ||
560 | m_dummy_text = text; | ||
561 | endInsertRows(); | ||
562 | } | ||
563 | else if(en) | ||
564 | { | ||
565 | /* text change only */ | ||
566 | emit dataChanged(index(0, GetNameColumn()), index(0, GetNameColumn())); | ||
567 | } | ||
568 | } | ||
569 | |||
570 | int HWStubContextModel::rowCount(const QModelIndex& parent) const | ||
571 | { | ||
572 | Q_UNUSED(parent); | ||
573 | return m_list.size() + (m_has_dummy ? 1 : 0); | ||
574 | } | ||
575 | |||
576 | int HWStubContextModel::columnCount(const QModelIndex& parent) const | ||
577 | { | ||
578 | Q_UNUSED(parent); | ||
579 | return 1; | ||
580 | } | ||
581 | |||
582 | QVariant HWStubContextModel::data(const QModelIndex& index, int role) const | ||
583 | { | ||
584 | int first_row = m_has_dummy ? 1: 0; | ||
585 | /* special case for dummy */ | ||
586 | if(m_has_dummy && index.row() == 0) | ||
587 | { | ||
588 | int section = index.column(); | ||
589 | if(section == GetNameColumn()) | ||
590 | { | ||
591 | if(role == Qt::DisplayRole) | ||
592 | return QVariant(m_dummy_text); | ||
593 | else if(role == Qt::FontRole) | ||
594 | { | ||
595 | QFont font; | ||
596 | font.setItalic(true); | ||
597 | return QVariant(font); | ||
598 | } | ||
599 | } | ||
600 | return QVariant(); | ||
601 | } | ||
602 | |||
603 | if(index.row() < first_row || (size_t)index.row() >= first_row + m_list.size()) | ||
604 | return QVariant(); | ||
605 | int section = index.column(); | ||
606 | if(section == GetNameColumn()) | ||
607 | { | ||
608 | if(role == Qt::DisplayRole) | ||
609 | return QVariant(m_list[index.row() - first_row].name); | ||
610 | } | ||
611 | return QVariant(); | ||
612 | } | ||
613 | |||
614 | QVariant HWStubContextModel::headerData(int section, Qt::Orientation orientation, int role) const | ||
615 | { | ||
616 | if(orientation == Qt::Vertical) | ||
617 | return QVariant(); | ||
618 | if(role != Qt::DisplayRole) | ||
619 | return QVariant(); | ||
620 | if(section == GetNameColumn()) | ||
621 | return QVariant("Friendly name"); | ||
622 | return QVariant(); | ||
623 | } | ||
624 | |||
625 | Qt::ItemFlags HWStubContextModel::flags(const QModelIndex& index) const | ||
626 | { | ||
627 | Q_UNUSED(index); | ||
628 | return Qt::ItemIsSelectable | Qt::ItemIsEnabled; | ||
629 | } | ||
630 | |||
631 | int HWStubContextModel::GetNameColumn() const | ||
632 | { | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | std::shared_ptr< hwstub::device > HWStubContextModel::GetDevice(int row) | ||
637 | { | ||
638 | int first_row = m_has_dummy ? 1: 0; | ||
639 | /* special case for dummy */ | ||
640 | if(row < first_row || (size_t)row >= first_row + m_list.size()) | ||
641 | return std::shared_ptr< hwstub::device >(); | ||
642 | else | ||
643 | return m_list[row - first_row].device; | ||
644 | } | ||
645 | |||
646 | QString HWStubContextModel::GetFriendlyName(std::shared_ptr< hwstub::device > device) | ||
431 | { | 647 | { |
432 | if(!m_hwdev) | 648 | return HWStubManager::GetFriendlyName(device); |
649 | } | ||
650 | |||
651 | namespace | ||
652 | { | ||
653 | struct dev_change_t | ||
654 | { | ||
655 | std::shared_ptr< hwstub::context > ctx; | ||
656 | bool arrived; | ||
657 | std::shared_ptr< hwstub::device > device; | ||
658 | }; | ||
659 | } | ||
660 | |||
661 | void HWStubContextModel::OnDevChangeLow(std::shared_ptr< hwstub::context > ctx, | ||
662 | bool arrived, std::shared_ptr< hwstub::device > device) | ||
663 | { | ||
664 | /* calling Qt function from non-Qt thread is unsafe. Since the polling thread | ||
665 | * is a pthread, the safest way to use Qt invoke mecanism to make it run | ||
666 | * on the event loop */ | ||
667 | dev_change_t *evt = new dev_change_t; | ||
668 | evt->ctx = ctx; | ||
669 | evt->arrived = arrived; | ||
670 | evt->device = device; | ||
671 | QMetaObject::invokeMethod(this, "OnDevChangeUnsafe", Q_ARG(void *, (void *)evt)); | ||
672 | } | ||
673 | |||
674 | void HWStubContextModel::OnDevChangeUnsafe(void *data) | ||
675 | { | ||
676 | dev_change_t *evt = (dev_change_t *)data; | ||
677 | OnDevChange(evt->ctx, evt->arrived, evt->device); | ||
678 | delete evt; | ||
679 | } | ||
680 | |||
681 | void HWStubContextModel::OnDevChange(std::shared_ptr< hwstub::context > ctx, bool arrived, | ||
682 | std::shared_ptr< hwstub::device > device) | ||
683 | { | ||
684 | int first_row = m_has_dummy ? 1: 0; | ||
685 | Q_UNUSED(ctx); | ||
686 | if(arrived) | ||
687 | { | ||
688 | Device dev; | ||
689 | dev.name = GetFriendlyName(device); | ||
690 | dev.device = device; | ||
691 | beginInsertRows(QModelIndex(), first_row + m_list.size(), | ||
692 | first_row + m_list.size()); | ||
693 | m_list.push_back(dev); | ||
694 | endInsertRows(); | ||
695 | } | ||
696 | else | ||
697 | { | ||
698 | /* find device in the list */ | ||
699 | auto it = m_list.begin(); | ||
700 | int idx = 0; | ||
701 | for(; it != m_list.end(); ++it, ++idx) | ||
702 | if(it->device == device) | ||
703 | break; | ||
704 | if(it == m_list.end()) | ||
705 | return; | ||
706 | /* remove it */ | ||
707 | beginRemoveRows(QModelIndex(), first_row + idx, first_row + idx); | ||
708 | m_list.erase(it); | ||
709 | endRemoveRows(); | ||
710 | } | ||
711 | } | ||
712 | |||
713 | /** | ||
714 | * HWStubDevice | ||
715 | */ | ||
716 | HWStubDevice::HWStubDevice(std::shared_ptr< hwstub::device > device) | ||
717 | { | ||
718 | m_valid = Probe(device); | ||
719 | } | ||
720 | |||
721 | HWStubDevice::~HWStubDevice() | ||
722 | { | ||
723 | } | ||
724 | |||
725 | bool HWStubDevice::Probe(std::shared_ptr<hwstub::device> device) | ||
726 | { | ||
727 | if(!device) | ||
433 | return false; | 728 | return false; |
434 | int ret = hwstub_rw_mem_atomic(m_hwdev, 1, addr, buffer, length); | 729 | hwstub::error err = device->open(m_handle); |
435 | return ret >= 0 && (size_t)ret == length; | 730 | if(err != hwstub::error::SUCCESS) |
731 | return false; | ||
732 | // get target information | ||
733 | err = m_handle->get_target_desc(m_hwdev_target); | ||
734 | if(err != hwstub::error::SUCCESS) | ||
735 | return false; | ||
736 | // get STMP/PP information | ||
737 | if(m_hwdev_target.dID == HWSTUB_TARGET_STMP) | ||
738 | { | ||
739 | err = m_handle->get_stmp_desc(m_hwdev_stmp); | ||
740 | if(err != hwstub::error::SUCCESS) | ||
741 | return false; | ||
742 | } | ||
743 | else if(m_hwdev_target.dID == HWSTUB_TARGET_PP) | ||
744 | { | ||
745 | err = m_handle->get_pp_desc(m_hwdev_pp); | ||
746 | if(err != hwstub::error::SUCCESS) | ||
747 | return false; | ||
748 | } | ||
749 | else if(m_hwdev_target.dID == HWSTUB_TARGET_JZ) | ||
750 | { | ||
751 | err = m_handle->get_jz_desc(m_hwdev_jz); | ||
752 | if(err != hwstub::error::SUCCESS) | ||
753 | return false; | ||
754 | } | ||
755 | m_name = HWStubManager::GetFriendlyName(device); | ||
756 | return true; | ||
757 | } | ||
758 | |||
759 | bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer) | ||
760 | { | ||
761 | size_t len = length; | ||
762 | hwstub::error err = m_handle->read(addr, buffer, len, true); | ||
763 | return err == hwstub::error::SUCCESS && len == length; | ||
436 | } | 764 | } |
437 | 765 | ||
438 | bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer) | 766 | bool HWStubDevice::WriteMem(soc_addr_t addr, size_t length, void *buffer) |
439 | { | 767 | { |
440 | if(!m_hwdev) | 768 | size_t len = length; |
441 | return false; | 769 | hwstub::error err = m_handle->write(addr, buffer, len, true); |
442 | int ret = hwstub_rw_mem_atomic(m_hwdev, 0, addr, buffer, length); | 770 | return err == hwstub::error::SUCCESS && len == length; |
443 | return ret >= 0 && (size_t)ret == length; | ||
444 | } | 771 | } |
445 | 772 | ||
446 | bool HWStubDevice::IsValid() | 773 | bool HWStubDevice::IsValid() |
@@ -448,6 +775,10 @@ bool HWStubDevice::IsValid() | |||
448 | return m_valid; | 775 | return m_valid; |
449 | } | 776 | } |
450 | 777 | ||
778 | QString HWStubDevice::GetFriendlyName() | ||
779 | { | ||
780 | return m_name; | ||
781 | } | ||
451 | 782 | ||
452 | /** | 783 | /** |
453 | * HWStubIoBackend | 784 | * HWStubIoBackend |
@@ -456,7 +787,7 @@ bool HWStubDevice::IsValid() | |||
456 | HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) | 787 | HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) |
457 | { | 788 | { |
458 | m_dev = dev; | 789 | m_dev = dev; |
459 | m_dev->Open(); | 790 | |
460 | struct hwstub_target_desc_t target = m_dev->GetTargetInfo(); | 791 | struct hwstub_target_desc_t target = m_dev->GetTargetInfo(); |
461 | if(target.dID == HWSTUB_TARGET_STMP) | 792 | if(target.dID == HWSTUB_TARGET_STMP) |
462 | { | 793 | { |
@@ -470,6 +801,13 @@ HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev) | |||
470 | else | 801 | else |
471 | m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0')); | 802 | m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0')); |
472 | } | 803 | } |
804 | else if(target.dID == HWSTUB_TARGET_JZ) | ||
805 | { | ||
806 | struct hwstub_jz_desc_t jz = m_dev->GetJZInfo(); | ||
807 | m_soc = QString("jz%1").arg(jz.wChipID, 4, 16, QChar('0')); | ||
808 | if(jz.bRevision != 0) | ||
809 | m_soc.append(QChar(jz.bRevision).toLower()); | ||
810 | } | ||
473 | else if(target.dID == HWSTUB_TARGET_RK27) | 811 | else if(target.dID == HWSTUB_TARGET_RK27) |
474 | m_soc = "rk27x"; | 812 | m_soc = "rk27x"; |
475 | else if(target.dID == HWSTUB_TARGET_PP) | 813 | else if(target.dID == HWSTUB_TARGET_PP) |
@@ -549,95 +887,6 @@ bool HWStubIoBackend::Reload() | |||
549 | return true; | 887 | return true; |
550 | } | 888 | } |
551 | 889 | ||
552 | /** | ||
553 | * HWStubBackendHelper | ||
554 | */ | ||
555 | HWStubBackendHelper::HWStubBackendHelper() | ||
556 | { | ||
557 | #ifdef LIBUSB_NO_HOTPLUG | ||
558 | m_hotplug = false; | ||
559 | #else | ||
560 | m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG); | ||
561 | if(m_hotplug) | ||
562 | { | ||
563 | int evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | | ||
564 | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT; | ||
565 | m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback( | ||
566 | NULL, (libusb_hotplug_event)evt, LIBUSB_HOTPLUG_ENUMERATE, | ||
567 | LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, | ||
568 | &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), | ||
569 | &m_hotplug_handle); | ||
570 | } | ||
571 | #endif /* LIBUSB_NO_HOTPLUG */ | ||
572 | } | ||
573 | |||
574 | HWStubBackendHelper::~HWStubBackendHelper() | ||
575 | { | ||
576 | #ifndef LIBUSB_NO_HOTPLUG | ||
577 | if(m_hotplug) | ||
578 | libusb_hotplug_deregister_callback(NULL, m_hotplug_handle); | ||
579 | #endif /* LIBUSB_NO_HOTPLUG */ | ||
580 | } | ||
581 | |||
582 | QList< HWStubDevice* > HWStubBackendHelper::GetDevList() | ||
583 | { | ||
584 | QList< HWStubDevice* > list; | ||
585 | libusb_device **dev_list; | ||
586 | ssize_t cnt = hwstub_get_device_list(NULL, &dev_list); | ||
587 | for(int i = 0; i < cnt; i++) | ||
588 | { | ||
589 | HWStubDevice *dev = new HWStubDevice(dev_list[i]); | ||
590 | /* filter out non-hwstub devices */ | ||
591 | if(dev->IsValid()) | ||
592 | list.push_back(dev); | ||
593 | else | ||
594 | delete dev; | ||
595 | } | ||
596 | libusb_free_device_list(dev_list, 1); | ||
597 | return list; | ||
598 | } | ||
599 | |||
600 | #ifndef LIBUSB_NO_HOTPLUG | ||
601 | void HWStubBackendHelper::OnHotPlug(bool arrived, struct libusb_device *dev) | ||
602 | { | ||
603 | /* signal it */ | ||
604 | emit OnDevListChanged(arrived, dev); | ||
605 | } | ||
606 | |||
607 | int HWStubBackendHelper::HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev, | ||
608 | libusb_hotplug_event event, void *user_data) | ||
609 | { | ||
610 | Q_UNUSED(ctx); | ||
611 | HWStubBackendHelper *helper = reinterpret_cast< HWStubBackendHelper* >(user_data); | ||
612 | switch(event) | ||
613 | { | ||
614 | case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: helper->OnHotPlug(true, dev); break; | ||
615 | case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: helper->OnHotPlug(false, dev); break; | ||
616 | default: break; | ||
617 | } | ||
618 | return 0; | ||
619 | } | ||
620 | #endif /* LIBUSB_NO_HOTPLUG */ | ||
621 | |||
622 | bool HWStubBackendHelper::HasHotPlugSupport() | ||
623 | { | ||
624 | return m_hotplug; | ||
625 | } | ||
626 | |||
627 | namespace | ||
628 | { | ||
629 | class lib_usb_init | ||
630 | { | ||
631 | public: | ||
632 | lib_usb_init() | ||
633 | { | ||
634 | libusb_init(NULL); | ||
635 | } | ||
636 | }; | ||
637 | |||
638 | lib_usb_init __lib_usb_init; | ||
639 | } | ||
640 | |||
641 | #endif /* HAVE_HWSTUB */ | 890 | #endif /* HAVE_HWSTUB */ |
642 | 891 | ||
643 | /** | 892 | /** |