From 55a280a09905567b61e4cf7c7aecfa971947131c Mon Sep 17 00:00:00 2001
From: Ashish Chaudhari <ashish@ettus.com>
Date: Tue, 4 Aug 2015 16:15:58 -0500
Subject: x300: Used new soft register API for X300 registers

---
 host/lib/usrp/x300/x300_adc_dac_utils.cpp |  68 +++++++-------
 host/lib/usrp/x300/x300_impl.cpp          | 143 +++++++++++++-----------------
 host/lib/usrp/x300/x300_impl.hpp          |  52 ++---------
 host/lib/usrp/x300/x300_regs.hpp          | 109 +++++++++++++++++++----
 4 files changed, 196 insertions(+), 176 deletions(-)

(limited to 'host')

diff --git a/host/lib/usrp/x300/x300_adc_dac_utils.cpp b/host/lib/usrp/x300/x300_adc_dac_utils.cpp
index 2dadea26e..b1483b3a5 100644
--- a/host/lib/usrp/x300/x300_adc_dac_utils.cpp
+++ b/host/lib/usrp/x300/x300_adc_dac_utils.cpp
@@ -18,6 +18,8 @@
 #include "x300_impl.hpp"
 #include <boost/date_time/posix_time/posix_time_io.hpp>
 
+using namespace uhd::usrp::x300;
+
 /***********************************************************************
  * DAC: Reset and synchronization operations
  **********************************************************************/
@@ -101,8 +103,8 @@ void x300_impl::self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_m
 
         //Turn on ramp pattern test
         perif.adc->set_test_word("ramp", "ramp");
-        perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
-        perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+        perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+        perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
     }
     boost::this_thread::sleep(boost::posix_time::milliseconds(ramp_time_ms));
 
@@ -110,19 +112,19 @@ void x300_impl::self_test_adcs(mboard_members_t& mb, boost::uint32_t ramp_time_m
     std::string status_str;
     for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
         radio_perifs_t &perif = mb.radio_perifs[r];
-        perif.misc_ins->refresh();
+        perif.regmap->misc_ins_reg.refresh();
 
         std::string i_status, q_status;
-        if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED))
-            if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR))
+        if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED))
+            if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR))
                 i_status = "Bit Errors!";
             else
                 i_status = "Good";
         else
             i_status = "Not Locked!";
 
-        if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED))
-            if (perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR))
+        if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED))
+            if (perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR))
                 q_status = "Bit Errors!";
             else
                 q_status = "Good";
@@ -193,9 +195,9 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
     while (iter++ < NUM_RETRIES) {
         for (boost::uint32_t dly_tap = 0; dly_tap < NUM_DELAY_STEPS; dly_tap++) {
             //Apply delay
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_VAL, dly_tap);
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 1);
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 0);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, dly_tap);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
 
             boost::uint32_t err_code = 0;
 
@@ -204,12 +206,12 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
             perif.adc->set_test_word("ramp", "ones");
             //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
             //and count deviations from the expected value
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
             //10ms @ 200MHz = 2 million samples
             boost::this_thread::sleep(boost::posix_time::milliseconds(10));
-            if (perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER0_I_LOCKED)) {
-                err_code += perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER0_I_ERROR);
+            if (perif.regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_LOCKED)) {
+                err_code += perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_I_ERROR);
             } else {
                 err_code += 100;    //Increment error code by 100 to indicate no lock
             }
@@ -219,12 +221,12 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
             perif.adc->set_test_word("ones", "ramp");
             //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
             //and count deviations from the expected value
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
-            perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+            perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
             //10ms @ 200MHz = 2 million samples
             boost::this_thread::sleep(boost::posix_time::milliseconds(10));
-            if (perif.misc_ins->read(radio_misc_ins_reg::ADC_CHECKER0_Q_LOCKED)) {
-                err_code += perif.misc_ins->get(radio_misc_ins_reg::ADC_CHECKER0_Q_ERROR);
+            if (perif.regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_LOCKED)) {
+                err_code += perif.regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER0_Q_ERROR);
             } else {
                 err_code += 100;    //Increment error code by 100 to indicate no lock
             }
@@ -258,7 +260,7 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
         }
     }
     perif.adc->set_test_word("normal", "normal");
-    perif.misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
+    perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
 
     if (win_start == -1) {
         throw uhd::runtime_error("self_cal_adc_capture_delay: Self calibration failed. Convergence error.");
@@ -269,9 +271,9 @@ void x300_impl::self_cal_adc_capture_delay(mboard_members_t& mb, const size_t ra
     }
 
     boost::uint32_t ideal_tap = (win_stop + win_start) / 2;
-    perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_VAL, ideal_tap);
-    perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 1);
-    perif.misc_outs->write(radio_misc_outs_reg::ADC_DATA_DLY_STB, 0);
+    perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_VAL, ideal_tap);
+    perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 1);
+    perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_DATA_DLY_STB, 0);
 
     if (print_status) {
         double tap_delay = (1.0e12 / mb.clock->get_master_clock_rate()) / (2*32); //in ps
@@ -300,7 +302,7 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
     for (size_t i = 0; i < NUM_DELAY_STEPS; i++) {
         //Delay the ADC clock (will set both Ch0 and Ch1 delays)
         double delay = mb.clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, delay_incr*i + delay_start);
-        wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK, 0.1);
+        wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, 0.1);
 
         boost::uint32_t err_code = 0;
         for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
@@ -312,12 +314,12 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
             mb.radio_perifs[r].adc->set_test_word("ramp", "ones");
             //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
             //and count deviations from the expected value
-            mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
-            mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+            mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+            mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
             //50ms @ 200MHz = 10 million samples
             boost::this_thread::sleep(boost::posix_time::milliseconds(50));
-            if (mb.radio_perifs[r].misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_I_LOCKED)) {
-                err_code += mb.radio_perifs[r].misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_I_ERROR);
+            if (mb.radio_perifs[r].regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_LOCKED)) {
+                err_code += mb.radio_perifs[r].regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_I_ERROR);
             } else {
                 err_code += 100;    //Increment error code by 100 to indicate no lock
             }
@@ -327,12 +329,12 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
             mb.radio_perifs[r].adc->set_test_word("ones", "ramp");
             //Turn on the pattern checker in the FPGA. It will lock when it sees a zero
             //and count deviations from the expected value
-            mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
-            mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 1);
+            mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
+            mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 1);
             //50ms @ 200MHz = 10 million samples
             boost::this_thread::sleep(boost::posix_time::milliseconds(50));
-            if (mb.radio_perifs[r].misc_ins->read(radio_misc_ins_reg::ADC_CHECKER1_Q_LOCKED)) {
-                err_code += mb.radio_perifs[r].misc_ins->get(radio_misc_ins_reg::ADC_CHECKER1_Q_ERROR);
+            if (mb.radio_perifs[r].regmap->misc_ins_reg.read(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_LOCKED)) {
+                err_code += mb.radio_perifs[r].regmap->misc_ins_reg.get(radio_regmap_t::misc_ins_reg_t::ADC_CHECKER1_Q_ERROR);
             } else {
                 err_code += 100;    //Increment error code by 100 to indicate no lock
             }
@@ -392,7 +394,7 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
         UHD_MSG(status) << "Validating..." << std::flush;
         //Apply delay
         win_center = mb.clock->set_clock_delay(X300_CLOCK_WHICH_ADC0, win_center);  //Sets ADC0 and ADC1
-        wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK, 0.1);
+        wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, 0.1);
         //Validate
         self_test_adcs(mb, 2000);
     } else {
@@ -403,7 +405,7 @@ double x300_impl::self_cal_adc_xfer_delay(mboard_members_t& mb, bool apply_delay
     //Teardown
     for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
         mb.radio_perifs[r].adc->set_test_word("normal", "normal");
-        mb.radio_perifs[r].misc_outs->write(radio_misc_outs_reg::ADC_CHECKER_ENABLED, 0);
+        mb.radio_perifs[r].regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::ADC_CHECKER_ENABLED, 0);
     }
     UHD_MSG(status) << (boost::format(" done (FPGA->ADC=%.3fns%s, Window=%.3fns)\n") %
         (win_center-fpga_clk_delay) % (cycle_slip?" +cyc":"") % win_length);
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index f0332691d..437fec82d 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -46,6 +46,7 @@ using namespace uhd;
 using namespace uhd::usrp;
 using namespace uhd::transport;
 using namespace uhd::niusrprio;
+using namespace uhd::usrp::x300;
 namespace asio = boost::asio;
 
 /***********************************************************************
@@ -512,6 +513,9 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
     this->check_fpga_compat(mb_path, mb);
     this->check_fw_compat(mb_path, mb.zpu_ctrl);
 
+    mb.fw_regmap = boost::make_shared<fw_regmap_t>();
+    mb.fw_regmap->initialize(*mb.zpu_ctrl.get(), true);
+
     //store which FPGA image is loaded
     mb.loaded_fpga_image = get_fpga_option(mb.zpu_ctrl);
 
@@ -663,7 +667,6 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
     UHD_MSG(status) << "Setup RF frontend clocking..." << std::endl;
 
     //Initialize clock control registers. NOTE: This does not configure the LMK yet.
-    initialize_clock_control(mb);
     mb.clock = x300_clock_ctrl::make(mb.zpu_spi,
         1 /*slaveno*/,
         mb.hw_rev,
@@ -842,7 +845,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
     // and do the misc mboard sensors
     ////////////////////////////////////////////////////////////////////
     _tree->create<sensor_value_t>(mb_path / "sensors" / "ref_locked")
-        .publish(boost::bind(&x300_impl::get_ref_locked, this, mb.zpu_ctrl));
+        .publish(boost::bind(&x300_impl::get_ref_locked, this, mb));
 
     ////////////////////////////////////////////////////////////////////
     // do some post-init tasks
@@ -860,6 +863,14 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
     _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_fe_spec);
     _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_fe_spec);
 
+    mb.regmap_db = boost::make_shared<uhd::soft_regmap_db_t>();
+    mb.regmap_db->add(*mb.fw_regmap);
+    mb.regmap_db->add(*mb.radio_perifs[0].regmap);
+    mb.regmap_db->add(*mb.radio_perifs[1].regmap);
+
+    _tree->create<uhd::soft_regmap_accessor_t::sptr>(mb_path / "registers")
+        .set(mb.regmap_db);
+
     mb.initialization_done = true;
 }
 
@@ -870,12 +881,12 @@ x300_impl::~x300_impl(void)
         BOOST_FOREACH(mboard_members_t &mb, _mb)
         {
             //Disable/reset ADC/DAC
-            mb.radio_perifs[0].misc_outs->set(radio_misc_outs_reg::ADC_RESET, 1);
-            mb.radio_perifs[0].misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 0);
-            mb.radio_perifs[0].misc_outs->set(radio_misc_outs_reg::DAC_ENABLED, 0);
-            mb.radio_perifs[0].misc_outs->flush();
-            mb.radio_perifs[1].misc_outs->set(radio_misc_outs_reg::DAC_ENABLED, 0);
-            mb.radio_perifs[1].misc_outs->flush();
+            mb.radio_perifs[0].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
+            mb.radio_perifs[0].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
+            mb.radio_perifs[0].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
+            mb.radio_perifs[0].regmap->misc_outs_reg.flush();
+            mb.radio_perifs[1].regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 0);
+            mb.radio_perifs[1].regmap->misc_outs_reg.flush();
 
             //kill the claimer task and unclaim the device
             mb.claimer_task.reset();
@@ -913,21 +924,19 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name, con
     both_xports_t xport = this->make_transport(mb_i, dest, X300_RADIO_DEST_PREFIX_CTRL, device_addr_t(), ctrl_sid);
     perif.ctrl = radio_ctrl_core_3000::make(mb.if_pkt_is_big_endian, xport.recv, xport.send, ctrl_sid, slot_name);
 
-    perif.misc_outs = boost::make_shared<radio_misc_outs_reg>();
-    perif.misc_ins = boost::make_shared<radio_misc_ins_reg>();
-    perif.misc_outs->initialize(*perif.ctrl, true);
-    perif.misc_ins->initialize(*perif.ctrl);
+    perif.regmap = boost::make_shared<radio_regmap_t>(radio_index);
+    perif.regmap->initialize(*perif.ctrl, true);
 
     //Only Radio0 has the ADC/DAC reset bits. Those bits are reserved for Radio1
     if (radio_index == 0) {
-        perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 1);
-        perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 0);
-        perif.misc_outs->flush();
-        perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 0);
-        perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 1);
-        perif.misc_outs->flush();
+        perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
+        perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
+        perif.regmap->misc_outs_reg.flush();
+        perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 0);
+        perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 1);
+        perif.regmap->misc_outs_reg.flush();
     }
-    perif.misc_outs->write(radio_misc_outs_reg::DAC_ENABLED, 1);
+    perif.regmap->misc_outs_reg.write(radio_regmap_t::misc_outs_reg_t::DAC_ENABLED, 1);
 
     this->register_loopback_self_test(perif.ctrl);
 
@@ -1345,32 +1354,9 @@ void x300_impl::register_loopback_self_test(wb_iface::sptr iface)
  * clock and time control logic
  **********************************************************************/
 
-void x300_impl::update_clock_control(mboard_members_t &mb)
-{
-    const size_t reg = mb.clock_control_regs_clock_source
-        | (mb.clock_control_regs_pps_select << 2)
-        | (mb.clock_control_regs_pps_out_enb << 4)
-        | (mb.clock_control_regs_tcxo_enb << 5)
-        | (mb.clock_control_regs_gpsdo_pwr << 6)
-    ;
-    mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL), reg);
-}
-
-void x300_impl::initialize_clock_control(mboard_members_t &mb)
-{
-    //Initialize clock control register soft copies
-    mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL;
-    mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL;
-    mb.clock_control_regs_pps_out_enb = 0;
-    mb.clock_control_regs_tcxo_enb = 1;
-    mb.clock_control_regs_gpsdo_pwr = 1;    //GPSDO power always ON
-    this->update_clock_control(mb);
-}
-
 void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb)
 {
-    mb.clock_control_regs_pps_out_enb = enb? 1 : 0;
-    this->update_clock_control(mb);
+    mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::fw_regmap_t::clk_ctrl_reg_t::PPS_OUT_EN, enb?1:0);
 }
 
 void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source)
@@ -1381,19 +1367,19 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
     const bool reconfigure_clks = (mb.current_refclk_src != "internal") or (source != "internal");
     if (reconfigure_clks) {
         //Update the clock MUX on the motherboard to select the requested source
-        mb.clock_control_regs_clock_source = 0;
-        mb.clock_control_regs_tcxo_enb = 0;
         if (source == "internal") {
-            mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL;
-            mb.clock_control_regs_tcxo_enb = 1;
+            mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL);
+            mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 1);
         } else if (source == "external") {
-            mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL;
+            mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL);
+            mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0);
         } else if (source == "gpsdo") {
-            mb.clock_control_regs_clock_source = ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO;
+            mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::CLK_SOURCE, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO);
+            mb.fw_regmap->clock_ctrl_reg.set(fw_regmap_t::clk_ctrl_reg_t::TCXO_EN, 0);
         } else {
             throw uhd::key_error("update_clock_source: unknown source: " + source);
         }
-        this->update_clock_control(mb);
+        mb.fw_regmap->clock_ctrl_reg.flush();
 
         //Reset the LMK to make sure it re-locks to the new reference
         mb.clock->reset_clocks();
@@ -1408,7 +1394,7 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
     //The programming code in x300_clock_ctrl is not compatible with revs <= 4 and may
     //lead to locking issues. So, disable the ref-locked check for older (unsupported) boards.
     if (mb.hw_rev > 4) {
-        if (not wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK, timeout)) {
+        if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::LMK_LOCK, timeout)) {
             //failed to lock on reference
             if (mb.initialization_done) {
                 throw uhd::runtime_error((boost::format("Reference Clock PLL failed to lock to %s source.") % source).str());
@@ -1426,7 +1412,7 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
         mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0);
 
         //Wait for radio clock PLL to lock
-        if (not wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_RADIO_CLK_LOCK, 0.01)) {
+        if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK, 0.01)) {
             throw uhd::runtime_error((boost::format("Reference Clock PLL in FPGA failed to lock to %s source.") % source).str());
         }
 
@@ -1435,20 +1421,20 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
         mb.zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_SW_RST), 0);
 
         //Wait for the ADC IDELAYCTRL to be ready
-        if (not wait_for_clk_locked(mb.zpu_ctrl, ZPU_RB_CLK_STATUS_IDELAYCTRL_LOCK, 0.01)) {
+        if (not wait_for_clk_locked(mb, fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK, 0.01)) {
             throw uhd::runtime_error((boost::format("ADC Calibration Clock in FPGA failed to lock to %s source.") % source).str());
         }
 
         // Reset ADCs and DACs
         for (size_t r = 0; r < mboard_members_t::NUM_RADIOS; r++) {
             radio_perifs_t &perif = mb.radio_perifs[r];
-            if (perif.misc_outs && r==0) {  //ADC/DAC reset lines only exist in Radio0
-                perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 1);
-                perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 0);
-                perif.misc_outs->flush();
-                perif.misc_outs->set(radio_misc_outs_reg::ADC_RESET, 0);
-                perif.misc_outs->set(radio_misc_outs_reg::DAC_RESET_N, 1);
-                perif.misc_outs->flush();
+            if (perif.regmap && r==0) {  //ADC/DAC reset lines only exist in Radio0
+                perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 1);
+                perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 0);
+                perif.regmap->misc_outs_reg.flush();
+                perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::ADC_RESET, 0);
+                perif.regmap->misc_outs_reg.set(radio_regmap_t::misc_outs_reg_t::DAC_RESET_N, 1);
+                perif.regmap->misc_outs_reg.flush();
             }
             if (perif.adc) perif.adc->reset();
             if (perif.dac) perif.dac->reset();
@@ -1462,61 +1448,54 @@ void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &sou
 void x300_impl::update_time_source(mboard_members_t &mb, const std::string &source)
 {
     if (source == "internal") {
-        mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL;
+        mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_INTERNAL);
     } else if (source == "external") {
-        mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_EXTERNAL;
+        mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_EXTERNAL);
     } else if (source == "gpsdo") {
-        mb.clock_control_regs_pps_select = ZPU_SR_CLOCK_CTRL_PPS_SRC_GPSDO;
+        mb.fw_regmap->clock_ctrl_reg.write(fw_regmap_t::clk_ctrl_reg_t::PPS_SELECT, fw_regmap_t::clk_ctrl_reg_t::SRC_GPSDO);
     } else {
         throw uhd::key_error("update_time_source: unknown source: " + source);
     }
 
-    this->update_clock_control(mb);
-
     //check for valid pps
-    if (!is_pps_present(mb.zpu_ctrl))
+    if (!is_pps_present(mb))
     {
         // TODO - Implement intelligent PPS detection
         /* throw uhd::runtime_error((boost::format("The %d PPS was not detected.  Please check the PPS source and try again.") % source).str()); */
     }
 }
 
-static bool get_clk_locked(wb_iface::sptr ctrl, boost::uint32_t which)
-{
-    return (ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) & which) != 0;
-}
-
-bool x300_impl::wait_for_clk_locked(wb_iface::sptr ctrl, boost::uint32_t which, double timeout)
+bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout)
 {
     boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::milliseconds(timeout * 1000.0);
     do {
-        if (get_clk_locked(ctrl, which))
+        if (mb.fw_regmap->clock_status_reg.read(which)==1)
             return true;
         boost::this_thread::sleep(boost::posix_time::milliseconds(1));
     } while (boost::get_system_time() < timeout_time);
 
     //Check one last time
-    return get_clk_locked(ctrl, which);
+    return (mb.fw_regmap->clock_status_reg.read(which)==1);
 }
 
-sensor_value_t x300_impl::get_ref_locked(wb_iface::sptr ctrl)
+sensor_value_t x300_impl::get_ref_locked(mboard_members_t& mb)
 {
-    const bool lock = get_clk_locked(ctrl, ZPU_RB_CLK_STATUS_LMK_LOCK) &&
-                      get_clk_locked(ctrl, ZPU_RB_CLK_STATUS_RADIO_CLK_LOCK) &&
-                      get_clk_locked(ctrl, ZPU_RB_CLK_STATUS_IDELAYCTRL_LOCK);
+    mb.fw_regmap->clock_status_reg.refresh();
+    const bool lock = (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::LMK_LOCK)==1) &&
+                      (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::RADIO_CLK_LOCK)==1) &&
+                      (mb.fw_regmap->clock_status_reg.get(fw_regmap_t::clk_status_reg_t::IDELAYCTRL_LOCK)==1);
     return sensor_value_t("Ref", lock, "locked", "unlocked");
 }
 
-bool x300_impl::is_pps_present(wb_iface::sptr ctrl)
+bool x300_impl::is_pps_present(mboard_members_t& mb)
 {
     // The ZPU_RB_CLK_STATUS_PPS_DETECT bit toggles with each rising edge of the PPS.
     // We monitor it for up to 1.5 seconds looking for it to toggle.
-    boost::uint32_t pps_detect = ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) & ZPU_RB_CLK_STATUS_PPS_DETECT;
+    boost::uint32_t pps_detect = mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT);
     for (int i = 0; i < 15; i++)
     {
         boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-        boost::uint32_t clk_status = ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS));
-        if (pps_detect != (clk_status & ZPU_RB_CLK_STATUS_PPS_DETECT))
+        if (pps_detect != mb.fw_regmap->clock_status_reg.read(fw_regmap_t::clk_status_reg_t::PPS_DETECT))
             return true;
     }
     return false;
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 20cd4d754..78c497ad9 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -49,7 +49,6 @@
 #include <uhd/transport/nirio/niusrprio_session.h>
 #include <uhd/transport/vrt_if_packet.hpp>
 #include "recv_packet_demuxer_3000.hpp"
-#include <uhd/utils/soft_register.hpp>
 #include "x300_regs.hpp"
 
 static const std::string X300_FW_FILE_NAME  = "usrp_x300_fw.bin";
@@ -173,39 +172,6 @@ public:
 private:
     boost::shared_ptr<async_md_type> _async_md;
 
-    class radio_misc_outs_reg : public uhd::soft_reg32_wo_t {
-    public:
-        UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED,          /*width*/ 1, /*shift*/ 0);  //[0]
-        UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N,          /*width*/ 1, /*shift*/ 1);  //[1]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET,            /*width*/ 1, /*shift*/ 2);  //[2]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB,     /*width*/ 1, /*shift*/ 3);  //[3]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL,     /*width*/ 5, /*shift*/ 4);  //[8:4]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER_ENABLED,  /*width*/ 1, /*shift*/ 9);  //[9]
-
-        radio_misc_outs_reg(): uhd::soft_reg32_wo_t(TOREG(SR_MISC_OUTS)) {
-            //Initial values
-            set(DAC_ENABLED, 0);
-            set(DAC_RESET_N, 0);
-            set(ADC_RESET, 0);
-            set(ADC_DATA_DLY_STB, 0);
-            set(ADC_DATA_DLY_VAL, 16);
-            set(ADC_CHECKER_ENABLED, 0);
-        }
-    };
-    class radio_misc_ins_reg : public uhd::soft_reg32_ro_t {
-    public:
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 0);  //[0]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 1);  //[1]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 2);  //[2]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 3);  //[3]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_ERROR,  /*width*/ 1, /*shift*/ 4);  //[4]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_ERROR,  /*width*/ 1, /*shift*/ 5);  //[5]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_ERROR,  /*width*/ 1, /*shift*/ 6);  //[6]
-        UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_ERROR,  /*width*/ 1, /*shift*/ 7);  //[7]
-
-        radio_misc_ins_reg(): uhd::soft_reg32_ro_t(RB32_MISC_INS) { }
-    };
-
     //perifs in the radio core
     struct radio_perifs_t
     {
@@ -223,8 +189,7 @@ private:
         rx_frontend_core_200::sptr rx_fe;
         tx_frontend_core_200::sptr tx_fe;
         //Registers
-        radio_misc_outs_reg::sptr misc_outs;
-        radio_misc_ins_reg::sptr misc_ins;
+        uhd::usrp::x300::radio_regmap_t::sptr regmap;
     };
 
     //overflow recovery impl
@@ -266,18 +231,15 @@ private:
         uhd::gps_ctrl::sptr gps;
         gpio_core_200::sptr fp_gpio;
 
-        //clock control register bits
-        int clock_control_regs_clock_source;
-        int clock_control_regs_pps_select;
-        int clock_control_regs_pps_out_enb;
-        int clock_control_regs_tcxo_enb;
-        int clock_control_regs_gpsdo_pwr;
+        uhd::usrp::x300::fw_regmap_t::sptr fw_regmap;
 
         //which FPGA image is loaded
         std::string loaded_fpga_image;
 
         size_t hw_rev;
         std::string current_refclk_src;
+
+        uhd::soft_regmap_db_t::sptr regmap_db;
     };
     std::vector<mboard_members_t> _mb;
 
@@ -391,9 +353,9 @@ private:
     void update_clock_source(mboard_members_t&, const std::string &);
     void update_time_source(mboard_members_t&, const std::string &);
 
-    uhd::sensor_value_t get_ref_locked(uhd::wb_iface::sptr);
-    bool wait_for_clk_locked(uhd::wb_iface::sptr, boost::uint32_t which, double timeout);
-    bool is_pps_present(uhd::wb_iface::sptr);
+    uhd::sensor_value_t get_ref_locked(mboard_members_t& mb);
+    bool wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout);
+    bool is_pps_present(mboard_members_t& mb);
 
     void set_db_eeprom(uhd::i2c_iface::sptr i2c, const size_t, const uhd::usrp::dboard_eeprom_t &);
     void set_mb_eeprom(uhd::i2c_iface::sptr i2c, const uhd::usrp::mboard_eeprom_t &);
diff --git a/host/lib/usrp/x300/x300_regs.hpp b/host/lib/usrp/x300/x300_regs.hpp
index 6e92a6dbc..350845f28 100644
--- a/host/lib/usrp/x300/x300_regs.hpp
+++ b/host/lib/usrp/x300/x300_regs.hpp
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 #include <boost/cstdint.hpp>
+#include <uhd/utils/soft_register.hpp>
 
 #define TOREG(x) ((x)*4)
 
@@ -76,28 +77,12 @@ localparam ZPU_SR_ETHINT1    = 56;
 #define ZPU_SR_SW_RST_RADIO_CLK_PLL     (1<<2)
 #define ZPU_SR_SW_RST_ADC_IDELAYCTRL    (1<<3)
 
-//clock controls
-#define ZPU_SR_CLOCK_CTRL_CLK_SRC_EXTERNAL 0x00
-#define ZPU_SR_CLOCK_CTRL_CLK_SRC_INTERNAL 0x02
-#define ZPU_SR_CLOCK_CTRL_CLK_SRC_GPSDO    0x03
-#define ZPU_SR_CLOCK_CTRL_PPS_SRC_EXTERNAL 0x00
-#define ZPU_SR_CLOCK_CTRL_PPS_SRC_INTERNAL 0x02
-#define ZPU_SR_CLOCK_CTRL_PPS_SRC_GPSDO    0x03
-
 localparam ZPU_RB_SPI        = 2;
 localparam ZPU_RB_CLK_STATUS = 3;
 localparam ZPU_RB_COMPAT_NUM = 6;
 localparam ZPU_RB_ETH_TYPE0  = 4;
 localparam ZPU_RB_ETH_TYPE1  = 5;
 
-//clock status
-#define ZPU_RB_CLK_STATUS_LMK_STATUS        (0x3 << 0)
-#define ZPU_RB_CLK_STATUS_LMK_LOCK          (0x1 << 2)
-#define ZPU_RB_CLK_STATUS_LMK_HOLDOVER      (0x1 << 3)
-#define ZPU_RB_CLK_STATUS_PPS_DETECT        (0x1 << 4)
-#define ZPU_RB_CLK_STATUS_RADIO_CLK_LOCK    (0x1 << 5)
-#define ZPU_RB_CLK_STATUS_IDELAYCTRL_LOCK   (0x1 << 6)
-
 //spi slaves on radio
 #define DB_DAC_SEN      (1 << 7)
 #define DB_ADC_SEN      (1 << 6)
@@ -202,5 +187,97 @@ static const uint32_t PCIE_ZPU_READ_CLOBBER     = 0x80000000;
 static const uint32_t PCIE_ZPU_STATUS_BUSY      = 0x1;
 static const uint32_t PCIE_ZPU_STATUS_SUSPENDED = 0x80000000;
 
+//-------------------------------------------------------------------
+// Register Maps
+//-------------------------------------------------------------------
+namespace uhd { namespace usrp { namespace x300 {
+    class fw_regmap_t : public uhd::soft_regmap_t {
+    public:
+        typedef boost::shared_ptr<fw_regmap_t> sptr;
+
+        class clk_ctrl_reg_t : public uhd::soft_reg32_wo_t {
+        public:
+            UHD_DEFINE_SOFT_REG_FIELD(CLK_SOURCE,   /*width*/ 2, /*shift*/ 0);  //[1:0]
+            UHD_DEFINE_SOFT_REG_FIELD(PPS_SELECT,   /*width*/ 2, /*shift*/ 2);  //[3:2]
+            UHD_DEFINE_SOFT_REG_FIELD(PPS_OUT_EN,   /*width*/ 1, /*shift*/ 4);  //[4]
+            UHD_DEFINE_SOFT_REG_FIELD(TCXO_EN,      /*width*/ 1, /*shift*/ 5);  //[5]
+            UHD_DEFINE_SOFT_REG_FIELD(GPSDO_PWR_EN, /*width*/ 1, /*shift*/ 6);  //[6]
+
+            static const boost::uint32_t SRC_EXTERNAL = 0x0;
+            static const boost::uint32_t SRC_INTERNAL = 0x2;
+            static const boost::uint32_t SRC_GPSDO    = 0x3;
+
+            clk_ctrl_reg_t(): uhd::soft_reg32_wo_t(SR_ADDR(SET0_BASE, ZPU_SR_CLOCK_CTRL)) {
+                //Initial values
+                set(CLK_SOURCE, SRC_INTERNAL);
+                set(PPS_SELECT, SRC_INTERNAL);
+                set(PPS_OUT_EN, 0);
+                set(TCXO_EN, 1);
+                set(GPSDO_PWR_EN, 1);   //GPSDO power always ON
+            }
+        } clock_ctrl_reg;
+
+        class clk_status_reg_t : public uhd::soft_reg32_ro_t {
+        public:
+            UHD_DEFINE_SOFT_REG_FIELD(LMK_STATUS,       /*width*/ 2, /*shift*/ 0);  //[1:0]
+            UHD_DEFINE_SOFT_REG_FIELD(LMK_LOCK,         /*width*/ 1, /*shift*/ 2);  //[2]
+            UHD_DEFINE_SOFT_REG_FIELD(LMK_HOLDOVER,     /*width*/ 1, /*shift*/ 3);  //[3]
+            UHD_DEFINE_SOFT_REG_FIELD(PPS_DETECT,       /*width*/ 1, /*shift*/ 4);  //[4]
+            UHD_DEFINE_SOFT_REG_FIELD(RADIO_CLK_LOCK,   /*width*/ 1, /*shift*/ 5);  //[5]
+            UHD_DEFINE_SOFT_REG_FIELD(IDELAYCTRL_LOCK,  /*width*/ 1, /*shift*/ 6);  //[6]
+
+            clk_status_reg_t(): uhd::soft_reg32_ro_t(SR_ADDR(SET0_BASE, ZPU_RB_CLK_STATUS)) {}
+        } clock_status_reg;
+
+        fw_regmap_t() : soft_regmap_t("fw_regmap") {
+            add_to_map(clock_ctrl_reg, "clock_ctrl_reg", PUBLIC);
+            add_to_map(clock_status_reg, "clock_status_reg", PUBLIC);
+        }
+    };
+
+    class radio_regmap_t : public uhd::soft_regmap_t {
+    public:
+        typedef boost::shared_ptr<radio_regmap_t> sptr;
+        class misc_outs_reg_t : public uhd::soft_reg32_wo_t {
+        public:
+            UHD_DEFINE_SOFT_REG_FIELD(DAC_ENABLED,          /*width*/ 1, /*shift*/ 0);  //[0]
+            UHD_DEFINE_SOFT_REG_FIELD(DAC_RESET_N,          /*width*/ 1, /*shift*/ 1);  //[1]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_RESET,            /*width*/ 1, /*shift*/ 2);  //[2]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_STB,     /*width*/ 1, /*shift*/ 3);  //[3]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_DATA_DLY_VAL,     /*width*/ 5, /*shift*/ 4);  //[8:4]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER_ENABLED,  /*width*/ 1, /*shift*/ 9);  //[9]
+
+            misc_outs_reg_t(): uhd::soft_reg32_wo_t(TOREG(SR_MISC_OUTS)) {
+                //Initial values
+                set(DAC_ENABLED, 0);
+                set(DAC_RESET_N, 0);
+                set(ADC_RESET, 0);
+                set(ADC_DATA_DLY_STB, 0);
+                set(ADC_DATA_DLY_VAL, 16);
+                set(ADC_CHECKER_ENABLED, 0);
+            }
+        } misc_outs_reg;
+
+        class misc_ins_reg_t : public uhd::soft_reg32_ro_t {
+        public:
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_LOCKED, /*width*/ 1, /*shift*/ 0);  //[0]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_LOCKED, /*width*/ 1, /*shift*/ 1);  //[1]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_LOCKED, /*width*/ 1, /*shift*/ 2);  //[2]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_LOCKED, /*width*/ 1, /*shift*/ 3);  //[3]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_Q_ERROR,  /*width*/ 1, /*shift*/ 4);  //[4]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER0_I_ERROR,  /*width*/ 1, /*shift*/ 5);  //[5]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_Q_ERROR,  /*width*/ 1, /*shift*/ 6);  //[6]
+            UHD_DEFINE_SOFT_REG_FIELD(ADC_CHECKER1_I_ERROR,  /*width*/ 1, /*shift*/ 7);  //[7]
+
+            misc_ins_reg_t(): uhd::soft_reg32_ro_t(RB32_MISC_INS) { }
+        } misc_ins_reg;
+
+        radio_regmap_t(int radio_num) : soft_regmap_t("radio" + boost::lexical_cast<std::string>(radio_num) + "_regmap") {
+            add_to_map(misc_outs_reg, "misc_outs_reg", PUBLIC);
+            add_to_map(misc_ins_reg, "misc_ins_reg", PUBLIC);
+        }
+    };
+
+}}}
 
 #endif /* INCLUDED_X300_REGS_HPP */
-- 
cgit v1.2.3