From d55bd529e2b95e487852ac54625800ffbbd69e1f Mon Sep 17 00:00:00 2001
From: Jared Boone <jboone@earfeast.com>
Date: Tue, 4 Nov 2014 13:05:07 -0800
Subject: [PATCH 06/68] RFFC507x: De-singleton the driver code.

---
 firmware/common/hackrf_core.c          |   2 +
 firmware/common/hackrf_core.h          |   2 +
 firmware/common/rf_path.c              |  28 ++---
 firmware/common/rffc5071.c             | 191 ++++++++++++++++-----------------
 firmware/common/rffc5071.h             |  33 +++---
 firmware/common/rffc5071_drv.c         |  11 +-
 firmware/common/rffc5071_drv.h         |  14 ++-
 firmware/common/rffc5071_regs.def      |  15 +--
 firmware/common/tuning.c               |   6 +-
 firmware/hackrf_usb/usb_api_register.c |   4 +-
 firmware/mixertx/mixertx.c             |   2 +-
 11 files changed, 158 insertions(+), 150 deletions(-)

--- a/firmware/common/hackrf_core.c
+++ b/firmware/common/hackrf_core.c
@@ -41,6 +41,8 @@
 
 max2837_driver_t max2837;
 
+rffc5071_driver_t rffc5072;
+
 void delay(uint32_t duration)
 {
 	uint32_t i;
--- a/firmware/common/hackrf_core.h
+++ b/firmware/common/hackrf_core.h
@@ -35,6 +35,7 @@
 #include "si5351c_drv.h"
 
 #include "max2837_drv.h"
+#include "rffc5071_drv.h"
 
 /* hardware identification number */
 #define BOARD_ID_JELLYBEAN  0
@@ -356,6 +357,7 @@
 
 void delay(uint32_t duration);
 extern max2837_driver_t max2837;
+extern rffc5071_driver_t rffc5072;
 
 extern si5351c_driver_t clock_gen;
 
--- a/firmware/common/rf_path.c
+++ b/firmware/common/rf_path.c
@@ -149,16 +149,16 @@
 		gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
 
 	if (ctrl & SWITCHCTRL_ANT_PWR) {
-		rffc5071_set_gpo(0x00); /* turn on antenna power by clearing GPO1 */
+		rffc5071_set_gpo(&rffc5072, 0x00); /* turn on antenna power by clearing GPO1 */
 	} else {
-		rffc5071_set_gpo(0x01); /* turn off antenna power by setting GPO1 */
+		rffc5071_set_gpo(&rffc5072, 0x01); /* turn off antenna power by setting GPO1 */
 	}
 }
 #endif
 
 static void switchctrl_set(const uint8_t gpo) {
 #ifdef JAWBREAKER
-	rffc5071_set_gpo(gpo);
+	rffc5071_set_gpo(&rffc5072, gpo);
 #elif HACKRF_ONE
 	switchctrl_set_hackrf_one(gpo);
 #else
@@ -215,7 +215,7 @@
 	max2837_setup(&max2837);
 	max2837_start(&max2837);
 	
-	rffc5071_setup();
+	rffc5071_setup(&rffc5072);
 	switchctrl_set(switchctrl);
 }
 
@@ -229,11 +229,11 @@
 			/* TX amplifier is in path, be sure to enable TX amplifier. */
 			switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
 		}
-		rffc5071_tx();
+		rffc5071_tx(&rffc5072);
 		if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
-			rffc5071_disable();
+			rffc5071_disable(&rffc5072);
 		} else {
-			rffc5071_enable();
+			rffc5071_enable(&rffc5072);
 		}
 		ssp1_set_mode_max5864();
 		max5864_tx();
@@ -248,11 +248,11 @@
 			/* RX amplifier is in path, be sure to enable RX amplifier. */
 			switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
 		}
-		rffc5071_rx();
+		rffc5071_rx(&rffc5072);
 		if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
-			rffc5071_disable();
+			rffc5071_disable(&rffc5072);
 		} else {
-			rffc5071_enable();
+			rffc5071_enable(&rffc5072);
 		}
 		ssp1_set_mode_max5864();
 		max5864_rx();
@@ -269,7 +269,7 @@
 		rf_path_set_lna(0);
 		/* Set RF path to receive direction when "off" */
 		switchctrl &= ~SWITCHCTRL_TX;
-		rffc5071_disable();
+		rffc5071_disable(&rffc5072);
 		ssp1_set_mode_max5864();
 		max5864_standby();
 		ssp1_set_mode_max2837();
@@ -286,18 +286,18 @@
 	default:
 	case RF_PATH_FILTER_BYPASS:
 		switchctrl |= SWITCHCTRL_MIX_BYPASS;
-		rffc5071_disable();
+		rffc5071_disable(&rffc5072);
 		break;
 		
 	case RF_PATH_FILTER_LOW_PASS:
 		switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
-		rffc5071_enable();
+		rffc5071_enable(&rffc5072);
 		break;
 		
 	case RF_PATH_FILTER_HIGH_PASS:
 		switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
 		switchctrl |= SWITCHCTRL_HP;
-		rffc5071_enable();
+		rffc5071_enable(&rffc5072);
 		break;
 	}
 
--- a/firmware/common/rffc5071.c
+++ b/firmware/common/rffc5071.c
@@ -46,7 +46,7 @@
 #endif
 
 /* Default register values. */
-static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = { 
+static const uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = { 
 	0xbefa,   /* 00 */
 	0x4064,   /* 01 */
 	0x9055,   /* 02 */
@@ -79,135 +79,130 @@
 	0x1000,   /* 1D */
 	0x0005,   /* 1E */ };
 
-uint16_t rffc5071_regs[RFFC5071_NUM_REGS];
-
-/* Mark all regsisters dirty so all will be written at init. */
-uint32_t rffc5071_regs_dirty = 0x7fffffff;
-
 /* Set up all registers according to defaults specified in docs. */
-void rffc5071_init(void)
+void rffc5071_init(rffc5071_driver_t* const drv)
 {
 	LOG("# rffc5071_init\n");
-	memcpy(rffc5071_regs, rffc5071_regs_default, sizeof(rffc5071_regs));
-	rffc5071_regs_dirty = 0x7fffffff;
+	memcpy(drv->regs, rffc5071_regs_default, sizeof(drv->regs));
+	drv->regs_dirty = 0x7fffffff;
 
 	/* Write default register values to chip. */
-	rffc5071_regs_commit();
+	rffc5071_regs_commit(drv);
 }
 
 /*
  * Set up pins for GPIO and SPI control, configure SSP peripheral for SPI, and
  * set our own default register configuration.
  */
-void rffc5071_setup(void)
+void rffc5071_setup(rffc5071_driver_t* const drv)
 {
-	rffc5071_init();
+	rffc5071_init(drv);
 	LOG("# rffc5071_setup\n");
 
-	rffc5071_pin_config();
+	rffc5071_pin_config(drv);
 
 	/* initial setup */
 	/* put zeros in freq contol registers */
-	set_RFFC5071_P2N(0);
-	set_RFFC5071_P2LODIV(0);
-	set_RFFC5071_P2PRESC(0);
-	set_RFFC5071_P2VCOSEL(0);
-
-	set_RFFC5071_P2N(0);
-	set_RFFC5071_P2LODIV(0);
-	set_RFFC5071_P2PRESC(0);
-	set_RFFC5071_P2VCOSEL(0);
-
-	set_RFFC5071_P2N(0);
-	set_RFFC5071_P2LODIV(0);
-	set_RFFC5071_P2PRESC(0);
-	set_RFFC5071_P2VCOSEL(0);
+	set_RFFC5071_P2N(drv, 0);
+	set_RFFC5071_P2LODIV(drv, 0);
+	set_RFFC5071_P2PRESC(drv, 0);
+	set_RFFC5071_P2VCOSEL(drv, 0);
+
+	set_RFFC5071_P2N(drv, 0);
+	set_RFFC5071_P2LODIV(drv, 0);
+	set_RFFC5071_P2PRESC(drv, 0);
+	set_RFFC5071_P2VCOSEL(drv, 0);
+
+	set_RFFC5071_P2N(drv, 0);
+	set_RFFC5071_P2LODIV(drv, 0);
+	set_RFFC5071_P2PRESC(drv, 0);
+	set_RFFC5071_P2VCOSEL(drv, 0);
 
 	/* set ENBL and MODE to be configured via 3-wire interface,
 	 * not control pins. */
-	set_RFFC5071_SIPIN(1);
+	set_RFFC5071_SIPIN(drv, 1);
 
 	/* GPOs are active at all times */
-	set_RFFC5071_GATE(1);
+	set_RFFC5071_GATE(drv, 1);
 
-	rffc5071_regs_commit();
+	rffc5071_regs_commit(drv);
 }
 
-uint16_t rffc5071_reg_read(uint8_t r)
+uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r)
 {
 	/* Readback register is not cached. */
 	if (r == RFFC5071_READBACK_REG)
-		return rffc5071_spi_read(r);
+		return rffc5071_spi_read(drv, r);
 
 	/* Discard uncommited write when reading. This shouldn't
 	 * happen, and probably has not been tested. */
-	if ((rffc5071_regs_dirty >> r) & 0x1) {
-		rffc5071_regs[r] = rffc5071_spi_read(r);
+	if ((drv->regs_dirty >> r) & 0x1) {
+		drv->regs[r] = rffc5071_spi_read(drv, r);
 	};
-	return rffc5071_regs[r];
+	return drv->regs[r];
 }
 
-void rffc5071_reg_write(uint8_t r, uint16_t v)
+void rffc5071_reg_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v)
 {
-	rffc5071_regs[r] = v;
-	rffc5071_spi_write(r, v);
-	RFFC5071_REG_SET_CLEAN(r);
+	drv->regs[r] = v;
+	rffc5071_spi_write(drv, r, v);
+	RFFC5071_REG_SET_CLEAN(drv, r);
 }
 
-static inline void rffc5071_reg_commit(uint8_t r)
+static inline void rffc5071_reg_commit(rffc5071_driver_t* const drv, uint8_t r)
 {
-	rffc5071_reg_write(r,rffc5071_regs[r]);
+	rffc5071_reg_write(drv, r, drv->regs[r]);
 }
 
-void rffc5071_regs_commit(void)
+void rffc5071_regs_commit(rffc5071_driver_t* const drv)
 {
 	int r;
 	for(r = 0; r < RFFC5071_NUM_REGS; r++) {
-		if ((rffc5071_regs_dirty >> r) & 0x1) {
-			rffc5071_reg_commit(r);
+		if ((drv->regs_dirty >> r) & 0x1) {
+			rffc5071_reg_commit(drv, r);
 		}
 	}
 }
 
-void rffc5071_tx(void) {
+void rffc5071_tx(rffc5071_driver_t* const drv) {
 	LOG("# rffc5071_tx\n");
-	set_RFFC5071_ENBL(0);
-	set_RFFC5071_FULLD(0);
-	set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */
-	rffc5071_regs_commit();
+	set_RFFC5071_ENBL(drv, 0);
+	set_RFFC5071_FULLD(drv, 0);
+	set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
+	rffc5071_regs_commit(drv);
 }
 
-void rffc5071_rx(void) {
+void rffc5071_rx(rffc5071_driver_t* const drv) {
 	LOG("# rfc5071_rx\n");
-	set_RFFC5071_ENBL(0);
-	set_RFFC5071_FULLD(0);
-	set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */
-	rffc5071_regs_commit();
+	set_RFFC5071_ENBL(drv, 0);
+	set_RFFC5071_FULLD(drv, 0);
+	set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
+	rffc5071_regs_commit(drv);
 }
 
 /*
  * This function turns on both mixer (full-duplex) on the RFFC5071, but our
  * current hardware designs do not support full-duplex operation.
  */
-void rffc5071_rxtx(void) {
+void rffc5071_rxtx(rffc5071_driver_t* const drv) {
 	LOG("# rfc5071_rxtx\n");
-	set_RFFC5071_ENBL(0);
-	set_RFFC5071_FULLD(1); /* mixer 1 and mixer 2 (RXTX) */
-	rffc5071_regs_commit();
+	set_RFFC5071_ENBL(drv, 0);
+	set_RFFC5071_FULLD(drv, 1); /* mixer 1 and mixer 2 (RXTX) */
+	rffc5071_regs_commit(drv);
 
-	rffc5071_enable();
+	rffc5071_enable(drv);
 }
 
-void rffc5071_disable(void)  {
+void rffc5071_disable(rffc5071_driver_t* const drv)  {
 	LOG("# rfc5071_disable\n");
-	set_RFFC5071_ENBL(0);
-	rffc5071_regs_commit();
+	set_RFFC5071_ENBL(drv, 0);
+	rffc5071_regs_commit(drv);
 }
 
-void rffc5071_enable(void)  {
+void rffc5071_enable(rffc5071_driver_t* const drv)  {
 	LOG("# rfc5071_enable\n");
-	set_RFFC5071_ENBL(1);
-	rffc5071_regs_commit();
+	set_RFFC5071_ENBL(drv, 1);
+	rffc5071_regs_commit(drv);
 }
 
 #define LO_MAX 5400
@@ -215,7 +210,7 @@
 #define FREQ_ONE_MHZ (1000*1000)
 
 /* configure frequency synthesizer in integer mode (lo in MHz) */
-uint64_t rffc5071_config_synth_int(uint16_t lo) {
+uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) {
 	uint8_t lodiv;
 	uint16_t fvco;
 	uint8_t fbkdiv;
@@ -244,10 +239,10 @@
 	 * and will be unaffected. */
 	if (fvco > 3200) {
 		fbkdiv = 4;
-		set_RFFC5071_PLLCPL(3);
+		set_RFFC5071_PLLCPL(drv, 3);
 	} else {
 		fbkdiv = 2;
-		set_RFFC5071_PLLCPL(2);
+		set_RFFC5071_PLLCPL(drv, 2);
 	}
 
 	uint64_t tmp_n = ((uint64_t)fvco << 29ULL) / (fbkdiv*REF_FREQ) ;
@@ -262,59 +257,59 @@
 			lo, n_lo, lodiv, fvco, fbkdiv, n, tune_freq);
 
 	/* Path 1 */
-	set_RFFC5071_P1LODIV(n_lo);
-	set_RFFC5071_P1N(n);
-	set_RFFC5071_P1PRESC(fbkdiv >> 1);
-	set_RFFC5071_P1NMSB(p1nmsb);
-	set_RFFC5071_P1NLSB(p1nlsb);
+	set_RFFC5071_P1LODIV(drv, n_lo);
+	set_RFFC5071_P1N(drv, n);
+	set_RFFC5071_P1PRESC(drv, fbkdiv >> 1);
+	set_RFFC5071_P1NMSB(drv, p1nmsb);
+	set_RFFC5071_P1NLSB(drv, p1nlsb);
 
 	/* Path 2 */
-	set_RFFC5071_P2LODIV(n_lo);
-	set_RFFC5071_P2N(n);
-	set_RFFC5071_P2PRESC(fbkdiv >> 1);
-	set_RFFC5071_P2NMSB(p1nmsb);
-	set_RFFC5071_P2NLSB(p1nlsb);
+	set_RFFC5071_P2LODIV(drv, n_lo);
+	set_RFFC5071_P2N(drv, n);
+	set_RFFC5071_P2PRESC(drv, fbkdiv >> 1);
+	set_RFFC5071_P2NMSB(drv, p1nmsb);
+	set_RFFC5071_P2NLSB(drv, p1nlsb);
 
-	rffc5071_regs_commit();
+	rffc5071_regs_commit(drv);
 
 	return tune_freq_hz;
 }
 
 /* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */
-uint64_t rffc5071_set_frequency(uint16_t mhz) {
+uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz) {
 	uint32_t tune_freq;
 
-	rffc5071_disable();
-	tune_freq = rffc5071_config_synth_int(mhz);
-	rffc5071_enable();
+	rffc5071_disable(drv);
+	tune_freq = rffc5071_config_synth_int(drv, mhz);
+	rffc5071_enable(drv);
 
 	return tune_freq;
 }
 
-void rffc5071_set_gpo(uint8_t gpo)
+void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t gpo)
 {
 	/* We set GPO for both paths just in case. */
-	set_RFFC5071_P1GPO(gpo);
-	set_RFFC5071_P2GPO(gpo);
+	set_RFFC5071_P1GPO(drv, gpo);
+	set_RFFC5071_P2GPO(drv, gpo);
 
-	rffc5071_regs_commit();
+	rffc5071_regs_commit(drv);
 }
 
 #ifdef TEST
 int main(int ac, char **av)
 {
-	rffc5071_setup();
-	rffc5071_tx(0);
-	rffc5071_set_frequency(500, 0);
-	rffc5071_set_frequency(525, 0);
-	rffc5071_set_frequency(550, 0);
-	rffc5071_set_frequency(1500, 0);
-	rffc5071_set_frequency(1525, 0);
-	rffc5071_set_frequency(1550, 0);
-	rffc5071_disable();
-	rffc5071_rx(0);
-	rffc5071_disable();
-	rffc5071_rxtx();
-	rffc5071_disable();
+	rffc5071_setup(drv);
+	rffc5071_tx(drv, 0);
+	rffc5071_set_frequency(drv, 500, 0);
+	rffc5071_set_frequency(drv, 525, 0);
+	rffc5071_set_frequency(drv, 550, 0);
+	rffc5071_set_frequency(drv, 1500, 0);
+	rffc5071_set_frequency(drv, 1525, 0);
+	rffc5071_set_frequency(drv, 1550, 0);
+	rffc5071_disable(drv);
+	rffc5071_rx(drv, 0);
+	rffc5071_disable(drv);
+	rffc5071_rxtx(drv);
+	rffc5071_disable(drv);
 }
 #endif //TEST
--- a/firmware/common/rffc5071.h
+++ b/firmware/common/rffc5071.h
@@ -23,43 +23,38 @@
 #ifndef __RFFC5071_H
 #define __RFFC5071_H
 
-/* 31 registers, each containing 16 bits of data. */
-#define RFFC5071_NUM_REGS 31
+#include <stdint.h>
 
-extern uint16_t rffc5071_regs[RFFC5071_NUM_REGS];
-extern uint32_t rffc5071_regs_dirty;
-
-#define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL<<r)
-#define RFFC5071_REG_SET_DIRTY(r) rffc5071_regs_dirty |= (1UL<<r)
+#include "rffc5071_drv.h"
 
 /* Initialize chip. Call _setup() externally, as it calls _init(). */
-extern void rffc5071_init(void);
-extern void rffc5071_setup(void);
+extern void rffc5071_init(rffc5071_driver_t* const drv);
+extern void rffc5071_setup(rffc5071_driver_t* const drv);
 
 /* Read a register via SPI. Save a copy to memory and return
  * value. Discard any uncommited changes and mark CLEAN. */
-extern uint16_t rffc5071_reg_read(uint8_t r);
+extern uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r);
 
 /* Write value to register via SPI and save a copy to memory. Mark
  * CLEAN. */
-extern void rffc5071_reg_write(uint8_t r, uint16_t v);
+extern void rffc5071_reg_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v);
 
 /* Write all dirty registers via SPI from memory. Mark all clean. Some
  * operations require registers to be written in a certain order. Use
  * provided routines for those operations. */
-extern void rffc5071_regs_commit(void);
+extern void rffc5071_regs_commit(rffc5071_driver_t* const drv);
 
 /* Set frequency (MHz). */
-extern uint64_t rffc5071_set_frequency(uint16_t mhz);
+extern uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz);
 
 /* Set up rx only, tx only, or full duplex. Chip should be disabled
  * before _tx, _rx, or _rxtx are called. */
-extern void rffc5071_tx(void);
-extern void rffc5071_rx(void);
-extern void rffc5071_rxtx(void);
-extern void rffc5071_enable(void);
-extern void rffc5071_disable(void);
+extern void rffc5071_tx(rffc5071_driver_t* const drv);
+extern void rffc5071_rx(rffc5071_driver_t* const drv);
+extern void rffc5071_rxtx(rffc5071_driver_t* const drv);
+extern void rffc5071_enable(rffc5071_driver_t* const drv);
+extern void rffc5071_disable(rffc5071_driver_t* const drv);
 
-extern void rffc5071_set_gpo(uint8_t);
+extern void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t);
 
 #endif // __RFFC5071_H
--- a/firmware/common/rffc5071_drv.c
+++ b/firmware/common/rffc5071_drv.c
@@ -31,7 +31,8 @@
 #include "hackrf_core.h"
 #endif
 
-void rffc5071_pin_config() {
+void rffc5071_pin_config(rffc5071_driver_t* const drv) {
+	(void)drv;
 #if !defined TEST
 	/* Configure GPIO pins. */
 	scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
@@ -69,7 +70,8 @@
  *   next 7 bits are register address.
  * Then receive 16 bits (register value).
  */
-uint16_t rffc5071_spi_read(uint8_t r) {
+uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r) {
+	(void)drv;
 
 	int bits = 9;
 	int msb = 1 << (bits -1);
@@ -166,8 +168,9 @@
  *   next 7 bits are register address,
  *   next 16 bits are register value.
  */
-void rffc5071_spi_write(uint8_t r, uint16_t v) {
-
+void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v) {
+	(void)drv;
+	
 #if DEBUG
 	LOG("0x%04x -> reg%d\n", v, r);
 #else
--- a/firmware/common/rffc5071_drv.h
+++ b/firmware/common/rffc5071_drv.h
@@ -23,9 +23,17 @@
 #ifndef __RFFC5071_DRV_H
 #define __RFFC5071_DRV_H
 
-void rffc5071_pin_config();
+/* 31 registers, each containing 16 bits of data. */
+#define RFFC5071_NUM_REGS 31
 
-uint16_t rffc5071_spi_read(uint8_t r);
-void rffc5071_spi_write(uint8_t r, uint16_t v);
+typedef struct {
+	uint16_t regs[RFFC5071_NUM_REGS];
+	uint32_t regs_dirty;
+} rffc5071_driver_t;
+
+void rffc5071_pin_config(rffc5071_driver_t* const drv);
+
+uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r);
+void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v);
 
 #endif // __RFFC5071_DRV_H
--- a/firmware/common/rffc5071_regs.def
+++ b/firmware/common/rffc5071_regs.def
@@ -23,6 +23,9 @@
 #ifndef __RFFC5071_REGS_DEF
 #define __RFFC5071_REGS_DEF
 
+#define RFFC5071_REG_SET_CLEAN(_d, _r) (_d->regs_dirty &= ~(1UL<<_r))
+#define RFFC5071_REG_SET_DIRTY(_d, _r) (_d->regs_dirty |= (1UL<<_r))
+
 #define RFFC5071_READBACK_REG 31
 
 /* Generate static inline accessors that operate on the global
@@ -38,13 +41,13 @@
 /* n=name, r=regnum, o=offset (bits from LSB) of LSB of field,
  * l=length (bits) */
 #define __MREG__(n,r,o,l) \
-static inline uint16_t get_##n(void) { \
-        return (rffc5071_regs[r] >> o) & ((1L<<l)-1); \
+static inline uint16_t get_##n(rffc5071_driver_t* const _d) { \
+        return (_d->regs[r] >> o) & ((1L<<l)-1); \
 } \
-static inline void set_##n(uint16_t v) {      \
-	rffc5071_regs[r] &= (uint16_t)(~(((1L<<l)-1)<<o));	\
-	rffc5071_regs[r] |= (uint16_t)(((v&((1L<<l)-1))<<o));	\
-	RFFC5071_REG_SET_DIRTY(r);				\
+static inline void set_##n(rffc5071_driver_t* const _d, uint16_t v) {      \
+	_d->regs[r] &= (uint16_t)(~(((1L<<l)-1)<<o));	\
+	_d->regs[r] |= (uint16_t)(((v&((1L<<l)-1))<<o));	\
+	RFFC5071_REG_SET_DIRTY(_d, r);				\
 }
 
 /* REG 00 (0): LF */
--- a/firmware/common/tuning.c
+++ b/firmware/common/tuning.c
@@ -72,7 +72,7 @@
 		max2837_freq_nominal_hz = 2650000000 - (freq / 7);
 		RFFC5071_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
 		/* Set Freq and read real freq */
-		real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz);
+		real_RFFC5071_freq_hz = rffc5071_set_frequency(&rffc5072, RFFC5071_freq_mhz);
 		max2837_set_frequency(&max2837, real_RFFC5071_freq_hz - freq);
 		sgpio_cpld_stream_rx_set_q_invert(1);
 	}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) )
@@ -97,7 +97,7 @@
 		rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS);
 		RFFC5071_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ);
 		/* Set Freq and read real freq */
-		real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz);
+		real_RFFC5071_freq_hz = rffc5071_set_frequency(&rffc5072, RFFC5071_freq_mhz);
 		max2837_set_frequency(&max2837, freq - real_RFFC5071_freq_hz);
 		sgpio_cpld_stream_rx_set_q_invert(0);
 	}else
@@ -137,7 +137,7 @@
 		sgpio_cpld_stream_rx_set_q_invert(0);
 	}
 	if (path != RF_PATH_FILTER_BYPASS) {
-		(void)rffc5071_set_frequency(lo_freq_hz / FREQ_ONE_MHZ);
+		(void)rffc5071_set_frequency(&rffc5072, lo_freq_hz / FREQ_ONE_MHZ);
 	}
 	return true;
 }
--- a/firmware/hackrf_usb/usb_api_register.c
+++ b/firmware/hackrf_usb/usb_api_register.c
@@ -115,7 +115,7 @@
 	{
 		if( endpoint->setup.index < RFFC5071_NUM_REGS ) 
 		{
-			rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value);
+			rffc5071_reg_write(&rffc5072, endpoint->setup.index, endpoint->setup.value);
 			usb_transfer_schedule_ack(endpoint->in);
 			return USB_REQUEST_STATUS_OK;
 		}
@@ -134,7 +134,7 @@
 	{
 		if( endpoint->setup.index < RFFC5071_NUM_REGS ) 
 		{
-			value = rffc5071_reg_read(endpoint->setup.index);
+			value = rffc5071_reg_read(&rffc5072, endpoint->setup.index);
 			endpoint->buffer[0] = value & 0xff;
 			endpoint->buffer[1] = value >> 8;
 			usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,
--- a/firmware/mixertx/mixertx.c
+++ b/firmware/mixertx/mixertx.c
@@ -44,7 +44,7 @@
 
 	ssp1_set_mode_max2837();
 	max2837_setup(&max2837);
-	rffc5071_setup();
+	rffc5071_setup(&rffc5072);
 	gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
 
 	max2837_set_frequency(&max2837, freq);
