diff -p -r -u -N -X /tmp/diff.exclude.12740 -x myth.20757.0629a -x myth.20757.0629b myth.20757.0629a/mythtv/libs/libmythtv/cardutil.cpp myth.20757.0629b/mythtv/libs/libmythtv/cardutil.cpp
--- mythtv/libs/libmythtv/cardutil.cpp	2009-06-30 12:23:08.000000000 -0500
+++ mythtv/libs/libmythtv/cardutil.cpp	2009-06-30 18:50:26.000000000 -0500
@@ -233,20 +233,25 @@ QStringVec CardUtil::ProbeVideoDevices(c
             return devs;
         }
 
-        if (result == 20)
+        if (result == 50)
         {
             VERBOSE(VB_IMPORTANT, "CardUtil::ProbeVideoDevices: "
-                    "Warning: may be > 20 HDHomerun devices");
+                    "Warning: may be > 50 HDHomerun devices");
         }
 
-        // TODO FIXME -- figure out some way to return ip address as well
+        // Return "deviceid ipaddress" pairs
         for (int i = 0; i < result; i++)
         {
-            QString did = QString("%1").arg(result_list[i].device_id, 0, 16);
-            did = did.toUpper();
+            QString id = QString("%1").arg(result_list[i].device_id, 0, 16);
+            QString ip = QString("%1.%2.%3.%4")
+                                 .arg((result_list[i].ip_addr>>24) & 0xFF)
+                                 .arg((result_list[i].ip_addr>>16) & 0xFF)
+                                 .arg((result_list[i].ip_addr>> 8) & 0xFF)
+                                 .arg((result_list[i].ip_addr>> 0) & 0xFF);
 
-            devs.push_back(did + "-0");
-            devs.push_back(did + "-1");
+            QString hdhrdev = id.toUpper() + " " + ip;
+
+            devs.push_back(hdhrdev);
         }
     }
 #endif // USING_HDHOMERUN
diff -p -r -u -N -X /tmp/diff.exclude.12740 -x myth.20757.0629a -x myth.20757.0629b myth.20757.0629a/mythtv/libs/libmythtv/videosource.cpp myth.20757.0629b/mythtv/libs/libmythtv/videosource.cpp
--- mythtv/libs/libmythtv/videosource.cpp	2009-06-30 12:23:08.000000000 -0500
+++ mythtv/libs/libmythtv/videosource.cpp	2009-06-30 18:36:37.000000000 -0500
@@ -1411,93 +1411,203 @@ class DBOX2ConfigurationGroup : public V
     CaptureCard &parent;
  };
 
-class HDHomeRunIP : public TransLabelSetting
+// -----------------------
+// HDHomeRun Configuration
+// -----------------------
+
+HDHomeRunIP::HDHomeRunIP()
+{
+    setLabel(QObject::tr("IP Address"));
+    setEnabled(false);
+    connect(this, SIGNAL(valueChanged(const QString&)),
+            this, SLOT(updateDevices(const QString&)));
+    _oldValue="";
+};
+
+void HDHomeRunIP::setEnabled(bool e)
+{
+    TransLineEditSetting::setEnabled(e);
+    if (e) {
+        if (_oldValue != "")
+            setValue(_oldValue);
+        emit hasNewIP(getValue());
+    }
+    else
+        _oldValue = getValue(); 
+}
+
+void HDHomeRunIP::updateDevices(const QString& v)
 {
-  public:
-    HDHomeRunIP()
-    {
-        setLabel(QObject::tr("IP Address"));
-    };
+   if (isEnabled())
+   {
+       VERBOSE(VB_IMPORTANT, QString("Emitting hasNewIP(%1)").arg(v));
+       emit hasNewIP(v);
+   }
+}
+       
+HDHomeRunTunerIndex::HDHomeRunTunerIndex()
+{
+    setLabel(QObject::tr("Tuner"));
+    setEnabled(false);
+    addSelection("0");
+    addSelection("1");
+    connect(this, SIGNAL(valueChanged(const QString&)),
+            this, SLOT(updateDevices(const QString&)));
+    _oldValue="";
 };
 
-class HDHomeRunTuner : public TransLabelSetting
+void HDHomeRunTunerIndex::setEnabled(bool e)
 {
-  public:
-    HDHomeRunTuner()
-    {
-        setLabel(QObject::tr("Tuner"));
-    };
+    TransComboBoxSetting::setEnabled(e);
+    if (e) {
+        if (_oldValue != "")
+            setValue(_oldValue);
+        emit hasNewTuner(getValue());
+    }
+    else
+        _oldValue = getValue();
+}
+
+void HDHomeRunTunerIndex::updateDevices(const QString& v)
+{
+   if (isEnabled())
+   {
+       VERBOSE(VB_IMPORTANT, QString("Emitting hasNewTuner(%1)").arg(v));
+       emit hasNewTuner(v);
+   }
+}
+
+HDHomeRunDeviceID::HDHomeRunDeviceID(const CaptureCard &parent) :
+    LabelSetting(this),
+    CaptureCardDBStorage(this, parent, "videodevice")
+{
+    setLabel(QObject::tr("Mythtv Device ID"));
+    setHelpText(
+        QObject::tr(
+            "DevicedID and Tuner Number of available HDHomeRun devices."));
+}
+
+void HDHomeRunDeviceID::SetIP(const QString& ip)
+{
+   VERBOSE(VB_IMPORTANT, QString("Setting IP to %1").arg(ip));
+   _ip = ip;
+   setValue(QString("%1-%2").arg(_ip).arg(_tuner));
+   VERBOSE(VB_IMPORTANT, QString("Done Setting IP to %1").arg(ip));
+}
+
+void HDHomeRunDeviceID::SetTuner(const QString& tuner)
+{
+   VERBOSE(VB_IMPORTANT, QString("Setting Tuner to %1").arg(tuner));
+   _tuner = tuner;
+   setValue(QString("%1-%2").arg(_ip).arg(_tuner));
+   VERBOSE(VB_IMPORTANT, QString("Done Setting Tuner to %1").arg(tuner));
+}
+
+HDHomeRunDeviceIDList::HDHomeRunDeviceIDList(HDHomeRunDeviceID *deviceid,
+                                             HDHomeRunIP *cardip,
+                                             HDHomeRunTunerIndex *cardtuner,
+                                             HDHomeRunDeviceList *devicelist) :
+        _deviceid(deviceid),
+        _cardip(cardip),
+        _cardtuner(cardtuner),
+        _devicelist(devicelist)
+{
+    setLabel(QObject::tr("Available Devices"));
+    setHelpText(
+        QObject::tr(
+            "DevicedID and Tuner Number of available HDHomeRun devices."));
+
+    connect(this, SIGNAL(valueChanged(const QString&)),
+            this, SLOT(updateDevices(const QString&)));
+    _oldValue="";
 };
 
-class HDHomeRunDeviceID : public ComboBoxSetting, public CaptureCardDBStorage
+/// \brief Adds all available device-tuner combinations to list
+/// If current is >= 0 it will be considered available even
+/// if no device exists for it on the network
+void HDHomeRunDeviceIDList::fillSelections(QString current)
 {
-  public:
-    HDHomeRunDeviceID(const CaptureCard &parent) :
-        ComboBoxSetting(this),
-        CaptureCardDBStorage(this, parent, "videodevice")
-    {
-        setLabel(QObject::tr("Device ID"));
-        setHelpText(
-            QObject::tr(
-                "DevicedID and Tuner Number of available HDHomeRun devices."));
-        fillSelections("");
-    };
+    clearSelections();
 
-    /// \brief Adds all available device-tuner combinations to list
-    /// If current is >= 0 it will be considered available even
-    /// if no device exists for it on the network
-    void fillSelections(QString current)
-    {
-        clearSelections();
+    vector<QString> devs;
+    QMap<QString, bool> in_use;
 
-        // Get network visible devices
-        vector<QString> devs = CardUtil::ProbeVideoDevices("HDHOMERUN");
+    HDHomeRunDeviceList::iterator it;
 
-        // Add current if needed
-        if ((current != "") &&
-            (find(devs.begin(), devs.end(), current) == devs.end()))
+    VERBOSE(VB_IMPORTANT, QString("Filling List, current = '%1'").arg(current));
+    for (it = _devicelist->begin(); it != _devicelist->end(); it++)
+    {
+        if (it.value().discovered)
         {
-            devs.push_back(current);
-            stable_sort(devs.begin(), devs.end());
+            devs.push_back(it.key());
+            in_use[it.key()] = it.value().inuse;
         }
+    }
 
-        vector<QString> db = CardUtil::GetVideoDevices("HDHOMERUN");
+    devs.push_back("Manually Enter IP Address");
 
-        QMap<QString, bool> in_use;
-        QString sel = current;
-        for (uint i = 0; i < devs.size(); i++)
-        {
-            const QString dev = devs[i];
-            in_use[devs[i]] = find(db.begin(), db.end(), dev) != db.end();
-            if (sel == "" && !in_use[devs[i]])
-                sel = dev;
-        }
+    QString sel = "Manually Enter IP Address";
+    for (uint i = 0; i < devs.size(); i++)
+    {
+        const QString dev = devs[i];
+        if (current == dev)
+            sel = dev;
+    }
 
-        if (sel == "" && devs.size())
-            sel = devs[0];
+    QString usestr = QString(" -- ");
+    usestr += QObject::tr("Warning: already in use");
  
-        QString usestr = QString(" -- ");
-        usestr += QObject::tr("Warning: already in use");
-
-        for (uint i = 0; i < devs.size(); i++)
-        {
-            const QString dev = devs[i];
-            QString desc = dev + (in_use[devs[i]] ? usestr : "");
-            desc = (current == devs[i]) ? dev : desc;
-            addSelection(desc, dev, dev == sel);
-        }
+    for (uint i = 0; i < devs.size(); i++)
+    {
+        const QString dev = devs[i];
+        QString desc = dev + (in_use[devs[i]] ? usestr : "");
+        desc = (current == devs[i]) ? dev : desc;
+        addSelection(desc, dev, dev == sel);
     }
 
-    virtual void Load(void)
+    if (sel == "Manually Enter IP Address" && current != "")
     {
-        clearSelections();
-        addSelection("");
+        // Populate the proper values for IP address and tuner
+        QStringList selection = current.split("-");
+
+        _cardip->setOldValue(selection.first());
+        _cardtuner->setOldValue(selection.last());
+
+        _cardip->setValue(selection.first());
+        _cardtuner->setValue(selection.last());
+    }
+}
+
+void HDHomeRunDeviceIDList::Load(void)
+{
+    clearSelections();
+
+    fillSelections(_deviceid->getValue());
+}
 
-        CaptureCardDBStorage::Load();
+void HDHomeRunDeviceIDList::updateDevices(const QString& v)
+{
+    VERBOSE(VB_IMPORTANT, QString("Got signal with %1").arg(v));
+    if (v == "Manually Enter IP Address")
+    {
+        _cardip->setEnabled(true);
+        _cardtuner->setEnabled(true);
+        VERBOSE(VB_IMPORTANT, "Done");
+    } else if (v != "") {
+        if (_oldValue == "Manually Enter IP Address")
+        {
+            _cardip->setEnabled(false);
+            _cardtuner->setEnabled(false);
+        }
+        _deviceid->setValue(v);
+        // Update _cardip && cardtuner
 
-        fillSelections(getValue());
+        _cardip->setValue((*_devicelist)[v].cardip);
+        _cardtuner->setValue(QString("%1").arg((*_devicelist)[v].cardtuner));
     }
+    _oldValue = v;
 };
+    
 
 class IPTVHost : public LineEditSetting, public CaptureCardDBStorage
 {
@@ -1561,11 +1671,17 @@ HDHomeRunConfigurationGroup::HDHomeRunCo
     parent(a_parent)
 {
     setUseLabel(false);
+
+    // Fill Device list 
+    fillDeviceList();
+
     deviceid = new HDHomeRunDeviceID(parent);
-    addChild(deviceid);
     cardip = new HDHomeRunIP();
-    cardtuner = new HDHomeRunTuner();
+    cardtuner = new HDHomeRunTunerIndex();
+    deviceidlist = new HDHomeRunDeviceIDList(deviceid, cardip, cardtuner, &devicelist);
 
+    addChild(deviceidlist);
+    addChild(deviceid);
     addChild(cardip);
     addChild(cardtuner);
 
@@ -1578,39 +1694,119 @@ HDHomeRunConfigurationGroup::HDHomeRunCo
     addChild(buttonRecOpt);
 
     // Wish we could use something like editingFinished() here...
-    connect(deviceid,     SIGNAL(valueChanged(const QString&)),
-            this,         SLOT(  probeCard   (const QString&)));
+    //connect(deviceid,     SIGNAL(valueChanged(const QString&)),
+    //        this,         SLOT(  probeCard   (const QString&)));
     connect(buttonRecOpt, SIGNAL(pressed()),
             this,         SLOT(  HDHomeRunExtraPanel()));
 
-//    addChild(desc);
+    connect(cardip, SIGNAL(hasNewIP(const QString&)),
+            deviceid, SLOT(SetIP(const QString&)));
+    connect(cardtuner, SIGNAL(hasNewTuner(const QString&)),
+            deviceid, SLOT(SetTuner(const QString&)));
+
 };
 
-void HDHomeRunConfigurationGroup::probeCard(const QString &deviceid)
+void HDHomeRunConfigurationGroup::fillDeviceList()
+{
+    devicelist.clear();
+
+    // Find physical devices first
+    // ProbeVideoDevices returns "deviceid ip" pairs
+    vector<QString> devs = CardUtil::ProbeVideoDevices("HDHOMERUN");
+
+    vector<QString>::iterator it;
+
+    for (it = devs.begin(); it != devs.end(); ++it)
+    {
+        QString dev = *it;
+        QStringList devinfo = dev.split(" ");
+        QString devid = devinfo.first();
+        QString devip = devinfo.last();
+
+        HDHomeRunDevice tmpdevice;
+        tmpdevice.deviceid=devid;
+        tmpdevice.cardip=devip;
+        tmpdevice.inuse=false;
+        tmpdevice.discovered=true;
+
+        tmpdevice.cardtuner = "0";
+        tmpdevice.mythdeviceid = tmpdevice.deviceid + "-" + tmpdevice.cardtuner;
+        devicelist.insert(tmpdevice.mythdeviceid, tmpdevice);
+
+        tmpdevice.cardtuner = "1";
+        tmpdevice.mythdeviceid = tmpdevice.deviceid + "-" + tmpdevice.cardtuner;
+        devicelist.insert(tmpdevice.mythdeviceid, tmpdevice);
+    }
+
+    // Now find configured devices
+
+    // returns "xxxxxxxx-n" or "ip.ip.ip.ip-n" values
+    vector<QString> db = CardUtil::GetVideoDevices("HDHOMERUN");
+
+    for (it = db.begin(); it != db.end(); ++it)
+    {
+
+        QMap<QString, HDHomeRunDevice>::iterator dit;
+       
+        dit =  devicelist.find(*it);
+        if (dit == devicelist.end())
+        {
+            HDHomeRunDevice tmpdevice;
+            tmpdevice.mythdeviceid = *it;
+            tmpdevice.inuse=true;
+            tmpdevice.discovered=false;
+
+            if (probeCard(tmpdevice))
+                devicelist.insert(tmpdevice.mythdeviceid, tmpdevice);
+        }
+        else
+            dit.value().inuse = true;
+    }
+
+    // Debug dump of cards
+    QMap<QString, HDHomeRunDevice>::iterator debugit;
+    for (debugit = devicelist.begin(); debugit != devicelist.end(); debugit++)
+    {
+        VERBOSE(VB_IMPORTANT, QString("%1: %2 %3 %4 %5 %6 %7")
+                                     .arg(debugit.key())
+                                     .arg(debugit.value().mythdeviceid)
+                                     .arg(debugit.value().deviceid)
+                                     .arg(debugit.value().cardip)
+                                     .arg(debugit.value().cardtuner)
+                                     .arg(debugit.value().inuse)
+                                     .arg(debugit.value().discovered));
+    }
+}
+
+bool HDHomeRunConfigurationGroup::probeCard(HDHomeRunDevice& tmpdevice)
 {
 #ifdef USING_HDHOMERUN
     hdhomerun_device_t *thisdevice =
-        hdhomerun_device_create_from_str(deviceid.toLocal8Bit().constData());
+        hdhomerun_device_create_from_str(tmpdevice.mythdeviceid.toLocal8Bit().constData());
 
     if (thisdevice)
     {
+        uint device_id = hdhomerun_device_get_device_id(thisdevice);
         uint device_ip = hdhomerun_device_get_device_ip(thisdevice);
         uint tuner     = hdhomerun_device_get_tuner(thisdevice);
         hdhomerun_device_destroy(thisdevice);
 
-        QString ip = QString("%1.%2.%3.%4")
-                .arg((device_ip>>24) & 0xFF).arg((device_ip>>16) & 0xFF)
-                .arg((device_ip>> 8) & 0xFF).arg((device_ip>> 0) & 0xFF);
+        if (device_id == 0)
+            tmpdevice.deviceid = "NOTFOUND";
+        else
+            tmpdevice.deviceid = QString("%1").arg(device_id, 8, 16);
+
+        tmpdevice.deviceid = tmpdevice.deviceid.toUpper();
+
+        tmpdevice.cardip = QString("%1.%2.%3.%4")
+                                  .arg((device_ip>>24) & 0xFF).arg((device_ip>>16) & 0xFF)
+                                  .arg((device_ip>> 8) & 0xFF).arg((device_ip>> 0) & 0xFF);
 
-        cardip->setValue(ip);
-        cardtuner->setValue(QString("%1").arg(tuner));
-    }
-    else
-    {
-        cardip->setValue("Unknown");
-        cardtuner->setValue("Unknown");
+        tmpdevice.cardtuner = QString("%1").arg(tuner);
+        return true;
     }
 #endif // USING_HDHOMERUN
+    return false;
 }
 
 void HDHomeRunConfigurationGroup::HDHomeRunExtraPanel(void)
diff -p -r -u -N -X /tmp/diff.exclude.12740 -x myth.20757.0629a -x myth.20757.0629b myth.20757.0629a/mythtv/libs/libmythtv/videosource.h myth.20757.0629b/mythtv/libs/libmythtv/videosource.h
--- mythtv/libs/libmythtv/videosource.h	2009-06-30 12:23:08.000000000 -0500
+++ mythtv/libs/libmythtv/videosource.h	2009-06-30 18:34:43.000000000 -0500
@@ -442,9 +442,24 @@ public:
     static void fillSelections(SelectSetting* setting);
 };
 
+
+class HDHomeRunDevice
+{
+  public:
+    QString mythdeviceid;
+    QString deviceid;
+    QString cardip;
+    QString cardtuner;
+    bool    inuse;
+    bool    discovered;
+};
+
+typedef QMap<QString, HDHomeRunDevice> HDHomeRunDeviceList;
+ 
+class HDHomeRunDeviceIDList;
 class HDHomeRunDeviceID;
 class HDHomeRunIP;
-class HDHomeRunTuner;
+class HDHomeRunTunerIndex;
 class HDHomeRunConfigurationGroup : public VerticalConfigurationGroup
 {
     Q_OBJECT
@@ -455,16 +470,21 @@ class HDHomeRunConfigurationGroup : publ
     HDHomeRunConfigurationGroup(CaptureCard &parent);
 
   public slots:
-    void probeCard(const QString &device);
     void HDHomeRunExtraPanel(void);
 
   private:
-    HDHomeRunDeviceID *deviceid;
-    HDHomeRunIP       *cardip;
-    HDHomeRunTuner    *cardtuner;
+    HDHomeRunDeviceIDList *deviceidlist;
+    HDHomeRunDeviceID     *deviceid;
+    HDHomeRunIP           *cardip;
+    HDHomeRunTunerIndex   *cardtuner;
 
     CaptureCard       &parent;
     TransLabelSetting *desc;
+
+    void fillDeviceList();
+    bool probeCard(HDHomeRunDevice&);
+    HDHomeRunDeviceList devicelist;
+
 };
 
 class V4LConfigurationGroup : public VerticalConfigurationGroup
@@ -788,4 +808,88 @@ class CardInput : public QObject, public
     InputGroup         *inputgrp1;
 };
 
+class HDHomeRunDeviceID;
+class HDHomeRunTunerIndex;
+
+class HDHomeRunIP : public TransLineEditSetting
+{
+  Q_OBJECT
+  public:
+    HDHomeRunIP();
+
+    virtual void setEnabled(bool e);
+    void setOldValue(QString s) { _oldValue = s; };
+
+  signals:
+    void hasNewIP(const QString & v);
+
+  public slots:
+    void updateDevices(const QString& v);
+
+  private:
+      QString _oldValue;
+};
+
+class HDHomeRunTunerIndex : public TransComboBoxSetting
+{
+  Q_OBJECT
+  public:
+    HDHomeRunTunerIndex();
+
+    virtual void setEnabled(bool e);
+    void setOldValue(QString s) { _oldValue = s; };
+
+  signals:
+    void hasNewTuner(const QString & v);
+
+  public slots:
+    void updateDevices(const QString& v);
+
+  private:
+    QString _oldValue;
+};
+
+
+class HDHomeRunDeviceIDList : public TransComboBoxSetting
+{
+  Q_OBJECT
+  public:
+    HDHomeRunDeviceIDList(HDHomeRunDeviceID *deviceid,
+                          HDHomeRunIP *cardip,
+                          HDHomeRunTunerIndex *cardtuner,
+                          HDHomeRunDeviceList *devicelist);
+
+    void fillSelections(QString current);
+
+    virtual void Load(void);
+
+  public slots:
+    void updateDevices(const QString& v);
+
+  private:
+    HDHomeRunDeviceID   *_deviceid;
+    HDHomeRunIP         *_cardip;
+    HDHomeRunTunerIndex *_cardtuner;
+    HDHomeRunDeviceList *_devicelist;
+
+    QString              _oldValue;
+};
+
+class HDHomeRunDeviceID : public LabelSetting, public CaptureCardDBStorage
+{
+  Q_OBJECT
+  public:
+    HDHomeRunDeviceID(const CaptureCard &parent);
+
+  public slots:
+    void SetIP(const QString & ip);
+    void SetTuner(const QString & tuner);
+
+  private:
+    QString _ip;
+    QString _tuner;
+};
+
+
+
 #endif
