diff --git a/Transceiver52M/device/lms/LMSDevice.cpp b/Transceiver52M/device/lms/LMSDevice.cpp
index b004308..9306a21 100644
--- a/Transceiver52M/device/lms/LMSDevice.cpp
+++ b/Transceiver52M/device/lms/LMSDevice.cpp
@@ -41,24 +41,6 @@ constexpr double LMSDevice::masterClockRate;
 #define LMS_MIN_BW_SUPPORTED 2.5e6 /* 2.5mHz, minimum supported by LMS */
 #define LMS_CALIBRATE_BW_HZ OSMO_MAX(GSM_CARRIER_BW, LMS_MIN_BW_SUPPORTED)
 
-static int compat_LMS_VCTCXORead(lms_device_t *dev, uint16_t *val, bool memory)
-{
-#if HAVE_LMS_VCTCXO_EEPROM_SAVING
-	return LMS_VCTCXORead(dev, val, memory);
-#else
-	return LMS_VCTCXORead(dev, val);
-#endif
-}
-
-static int compat_LMS_VCTCXOWrite(lms_device_t *dev, uint16_t val, bool memory)
-{
-#if HAVE_LMS_VCTCXO_EEPROM_SAVING
-	return LMS_VCTCXOWrite(dev, val, memory);
-#else
-	return LMS_VCTCXOWrite(dev, val);
-#endif
-}
-
 LMSDevice::LMSDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chans, double lo_offset,
 		     const std::vector<std::string>& tx_paths,
 		     const std::vector<std::string>& rx_paths):
@@ -78,8 +60,14 @@ LMSDevice::LMSDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t c
 
 LMSDevice::~LMSDevice()
 {
+	unsigned int i;
 	LOGC(DDEV, INFO) << "Closing LMS device";
 	if (m_lms_dev) {
+		/* disable all channels */
+		for (i=0; i<chans; i++) {
+			LMS_EnableChannel(m_lms_dev, LMS_CH_RX, i, false);
+			LMS_EnableChannel(m_lms_dev, LMS_CH_TX, i, false);
+		}
 		LMS_Close(m_lms_dev);
 		m_lms_dev = NULL;
 	}
@@ -145,11 +133,10 @@ int info_list_find(lms_info_str_t* info_list, unsigned int count, const std::str
 
 int LMSDevice::open(const std::string &args, int ref, bool swap_channels)
 {
-	//lms_info_str_t dev_str;
 	lms_info_str_t* info_list;
-	lms_range_t range_lpfbw_rx, range_lpfbw_tx, range_sr;
-	float_type sr_host, sr_rf, lpfbw_rx, lpfbw_tx;
-	uint16_t dac_val;
+	const lms_dev_info_t* device_info;
+	lms_range_t range_sr;
+	float_type sr_host, sr_rf;
 	unsigned int i, n;
 	int rc, dev_id;
 
@@ -188,12 +175,58 @@ int LMSDevice::open(const std::string &args, int ref, bool swap_channels)
 
 	delete [] info_list;
 
+	device_info = LMS_GetDeviceInfo(m_lms_dev);
+
+	if ((ref != REF_EXTERNAL) && (ref != REF_INTERNAL))
+	{
+		LOGC(DDEV, ALERT) << "Invalid reference type";
+		goto out_close;
+	}
+
+	/* if reference clock is external setup must happen _before_ calling LMS_Init */
+        /* FIXME make external reference frequency configurable */
+	if (ref == REF_EXTERNAL) {
+		LOGC(DDEV, INFO) << "Setting External clock reference to 10MHz";
+		/* Assume an external 10 MHz reference clock */
+		if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, 10000000.0) < 0)
+			goto out_close;
+	}
+
 	LOGC(DDEV, INFO) << "Init LMS device";
 	if (LMS_Init(m_lms_dev) != 0) {
 		LOGC(DDEV, ERROR) << "LMS_Init() failed";
 		goto out_close;
 	}
 
+	/* LimeSDR-Mini does not have switches but needs soldering to select external/internal clock */
+	/* LimeNET-Micro also does not like selecting internal clock*/
+	/* also set device specific maximum tx levels selected by phasenoise measurements*/
+	if (strncmp(device_info->deviceName,"LimeSDR-USB",11)==0)
+	{
+	/* if reference clock is internal setup must happen _after_ calling LMS_Init */
+		if (ref == REF_INTERNAL) {
+			LOGC(DDEV, INFO) << "Setting Internal clock reference";
+		if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, -1) < 0)
+			goto out_close;
+		}
+		maxTxGainClamp = 73.0;
+	}
+	else
+		if (strncmp(device_info->deviceName,"LimeSDR-Mini",12)==0)
+			maxTxGainClamp = 66.0;
+		else
+			maxTxGainClamp = 71.0; /* "LimeNET-Micro", etc FIXME pciE based LMS boards?*/
+
+	/* enable all used channels */
+	for (i=0; i<chans; i++) {
+		if (LMS_EnableChannel(m_lms_dev, LMS_CH_RX, i, true) < 0)
+			goto out_close;
+
+		if (LMS_EnableChannel(m_lms_dev, LMS_CH_TX, i, true) < 0)
+			goto out_close;
+        }
+
+	/* set samplerate */
 	if (LMS_GetSampleRateRange(m_lms_dev, LMS_CH_RX, &range_sr))
 		goto out_close;
 	print_range("Sample Rate", &range_sr);
@@ -209,55 +242,10 @@ int LMSDevice::open(const std::string &args, int ref, bool swap_channels)
 	/* FIXME: make this device/model dependent, like UHDDevice:dev_param_map! */
 	ts_offset = static_cast<TIMESTAMP>(8.9e-5 * GSMRATE * tx_sps); /* time * sample_rate */
 
-	switch (ref) {
-	case REF_INTERNAL:
-		LOGC(DDEV, INFO) << "Setting Internal clock reference";
-		/* Ugly API: Selecting clock source implicit by writing to VCTCXO DAC ?!? */
-		if (compat_LMS_VCTCXORead(m_lms_dev, &dac_val, false) < 0)
-			goto out_close;
-		LOGC(DDEV, INFO) << "Setting VCTCXO to " << dac_val;
-		if (compat_LMS_VCTCXOWrite(m_lms_dev, dac_val, false) < 0)
-			goto out_close;
-		break;
-	case REF_EXTERNAL:
-		LOGC(DDEV, INFO) << "Setting External clock reference to " << 10000000.0;
-		/* Assume an external 10 MHz reference clock */
-		if (LMS_SetClockFreq(m_lms_dev, LMS_CLOCK_EXTREF, 10000000.0) < 0)
-			goto out_close;
-		break;
-	default:
-		LOGC(DDEV, ALERT) << "Invalid reference type";
-		goto out_close;
-	}
-
-	if (LMS_GetLPFBWRange(m_lms_dev, LMS_CH_RX, &range_lpfbw_rx))
-		goto out_close;
-	print_range("LPFBWRange Rx", &range_lpfbw_rx);
-	if (LMS_GetLPFBWRange(m_lms_dev, LMS_CH_RX, &range_lpfbw_tx))
-		goto out_close;
-	print_range("LPFBWRange Tx", &range_lpfbw_tx);
-	lpfbw_rx = OSMO_MIN(OSMO_MAX(1.4001e6, range_lpfbw_rx.min), range_lpfbw_rx.max);
-	lpfbw_tx = OSMO_MIN(OSMO_MAX(5.2e6, range_lpfbw_tx.min), range_lpfbw_tx.max);
-
-	LOGC(DDEV, INFO) << "LPFBW: Rx=" << lpfbw_rx << " Tx=" << lpfbw_tx;
-
+	/* configure antennas */
 	if (!set_antennas()) {
 		LOGC(DDEV, ALERT) << "LMS antenna setting failed";
-		return -1;
-	}
-
-	/* Perform Rx and Tx calibration */
-	for (i=0; i<chans; i++) {
-		LOGC(DDEV, INFO) << "Setting LPFBW chan " << i;
-		if (LMS_SetLPFBW(m_lms_dev, LMS_CH_RX, i, lpfbw_rx) < 0)
-			goto out_close;
-		if (LMS_SetLPFBW(m_lms_dev, LMS_CH_TX, i, lpfbw_tx) < 0)
-			goto out_close;
-		LOGC(DDEV, INFO) << "Calibrating chan " << i;
-		if (LMS_Calibrate(m_lms_dev, LMS_CH_RX, i, LMS_CALIBRATE_BW_HZ, 0) < 0)
-			goto out_close;
-		if (LMS_Calibrate(m_lms_dev, LMS_CH_TX, i, LMS_CALIBRATE_BW_HZ, 0) < 0)
-			goto out_close;
+		goto out_close;
 	}
 
 	samplesRead = 0;
@@ -286,16 +274,20 @@ bool LMSDevice::start()
 
 	/* configure the channels/streams */
 	for (i=0; i<chans; i++) {
-		if (LMS_EnableChannel(m_lms_dev, LMS_CH_RX, i, true) < 0)
+		/* set Gains for calibration/filter setup */
+		/* TX gain to maximum */
+		setTxGain(maxTxGain(), i);
+		/* RX gain to midpoint */
+		setRxGain(((minRxGain() + maxRxGain()) / 2), i);
+
+		/* set upRx and Tx filters */
+		if (!do_filters(i))
 			return false;
-
-		if (LMS_EnableChannel(m_lms_dev, LMS_CH_TX, i, true) < 0)
+		/* Perform Rx and Tx calibration */
+		if (!do_calib(i))
 			return false;
 
-		// Set gains to midpoint
-		setTxGain((minTxGain() + maxTxGain()) / 2, i);
-		setRxGain((minRxGain() + maxRxGain()) / 2, i);
-
+		/* configure Streams */
 		m_lms_stream_rx[i] = {};
 		m_lms_stream_rx[i].isTx = false;
 		m_lms_stream_rx[i].channel = i;
@@ -348,17 +340,53 @@ bool LMSDevice::stop()
 	for (i=0; i<chans; i++) {
 		LMS_DestroyStream(m_lms_dev, &m_lms_stream_tx[i]);
 		LMS_DestroyStream(m_lms_dev, &m_lms_stream_rx[i]);
-		LMS_EnableChannel(m_lms_dev, LMS_CH_RX, i, false);
-		LMS_EnableChannel(m_lms_dev, LMS_CH_TX, i, false);
-	}
+}
 
 	started = false;
 	return true;
 }
 
+/* do rx and tx calibration - depends on gain, freq and bw */
+bool LMSDevice::do_calib(size_t chan)
+{
+	LOGC(DDEV, INFO) << "Calibrating chan " << chan;
+	if (LMS_Calibrate(m_lms_dev, LMS_CH_RX, chan, LMS_CALIBRATE_BW_HZ, 0) < 0)
+		return false;
+	if (LMS_Calibrate(m_lms_dev, LMS_CH_TX, chan, LMS_CALIBRATE_BW_HZ, 0) < 0)
+		return false;
+	return true;
+}
+
+/* do filter config - depends on bw only? */
+bool LMSDevice::do_filters(size_t chan)
+{
+	lms_range_t range_lpfbw_rx, range_lpfbw_tx;
+	float_type lpfbw_rx, lpfbw_tx;
+
+	LOGC(DDEV, INFO) << "Setting filters on chan " << chan;
+	if (LMS_GetLPFBWRange(m_lms_dev, LMS_CH_RX, &range_lpfbw_rx))
+		return false;
+	print_range("LPFBWRange Rx", &range_lpfbw_rx);
+	if (LMS_GetLPFBWRange(m_lms_dev, LMS_CH_RX, &range_lpfbw_tx))
+		return false;
+	print_range("LPFBWRange Tx", &range_lpfbw_tx);
+
+	lpfbw_rx = OSMO_MIN(OSMO_MAX(1.4001e6, range_lpfbw_rx.min), range_lpfbw_rx.max);
+	lpfbw_tx = OSMO_MIN(OSMO_MAX(5.2e6, range_lpfbw_tx.min), range_lpfbw_tx.max);
+
+	LOGC(DDEV, INFO) << "LPFBW: Rx=" << lpfbw_rx << " Tx=" << lpfbw_tx;
+
+	LOGC(DDEV, INFO) << "Setting LPFBW chan " << chan;
+	if (LMS_SetLPFBW(m_lms_dev, LMS_CH_RX, chan, lpfbw_rx) < 0)
+		return false;
+	if (LMS_SetLPFBW(m_lms_dev, LMS_CH_TX, chan, lpfbw_tx) < 0)
+		return false;
+	return true;
+}
+
 double LMSDevice::maxTxGain()
 {
-	return 73.0;
+	return maxTxGainClamp;
 }
 
 double LMSDevice::minTxGain()
@@ -388,6 +416,9 @@ double LMSDevice::setTxGain(double dB, size_t chan)
 	if (LMS_SetGaindB(m_lms_dev, LMS_CH_TX, chan, dB) < 0)
 		LOGC(DDEV, ERR) << "chan " << chan <<": Error setting TX gain to " << dB << " dB";
 
+//FIXME crashes when called while stream is running
+//	do_calib(chan);
+
 	return dB;
 }
 
@@ -403,6 +434,9 @@ double LMSDevice::setRxGain(double dB, size_t chan)
 	if (LMS_SetGaindB(m_lms_dev, LMS_CH_RX, chan, dB) < 0)
 		LOGC(DDEV, ERR) << "chan "<< chan << ": Error setting RX gain to " << dB << " dB";
 
+//FIXME crashes when called while stream is running
+//	do_calib(chan);
+
 	return dB;
 }
 
@@ -548,11 +582,8 @@ bool LMSDevice::requiresRadioAlign()
 }
 
 GSM::Time LMSDevice::minLatency() {
-	/* Empirical data from a handful of
-	relatively recent machines shows that the B100 will underrun when
-	the transmit threshold is reduced to a time of 6 and a half frames,
-	so we set a minimum 7 frame threshold. */
-	return GSM::Time(6,7);
+	/* UNUSED on limesdr (only used on usrp1/2) */
+	return GSM::Time(0,0);
 }
 
 void LMSDevice::update_stream_stats(size_t chan, bool * underrun, bool * overrun)
diff --git a/Transceiver52M/device/lms/LMSDevice.h b/Transceiver52M/device/lms/LMSDevice.h
index fde2408..d1cb12a 100644
--- a/Transceiver52M/device/lms/LMSDevice.h
+++ b/Transceiver52M/device/lms/LMSDevice.h
@@ -64,7 +64,10 @@ private:
 	TIMESTAMP ts_initial, ts_offset;
 
 	double rxGain;
+	double maxTxGainClamp;
 
+	bool do_calib(size_t chan);
+	bool do_filters(size_t chan);
 	int get_ant_idx(const std::string & name, bool dir_tx, size_t chan);
 	bool flush_recv(size_t num_pkts);
 	void update_stream_stats(size_t chan, bool * underrun, bool * overrun);
