/* ieee802154_mcr20a.c - NXP MCR20A driver */

/*
 * Copyright (c) 2017 PHYTEC Messtechnik GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define SYS_LOG_LEVEL CONFIG_SYS_LOG_IEEE802154_DRIVER_LEVEL
#define SYS_LOG_DOMAIN "dev/mcr20a"
#include <logging/sys_log.h>

#include <errno.h>

#include <kernel.h>
#include <arch/cpu.h>

#include <board.h>
#include <device.h>
#include <init.h>
#include <net/net_if.h>
#include <net/net_pkt.h>

#include <misc/byteorder.h>
#include <string.h>
#include <rand32.h>

#include <gpio.h>

#include <net/ieee802154_radio.h>

#include "ieee802154_mcr20a.h"
#include "MCR20Overwrites.h"

/*
 * max. TX duraton = (PR + SFD + FLI + PDU + FCS)
 *                 + RX_warmup + cca + TX_warmup
 * TODO: Calculate the value from frame length.
 * Invalid for the SLOTTED mode.
 */
#define _MAX_PKT_TX_DURATION		(133 + 9 + 8 + 9)

#if (SYS_LOG_LEVEL == 4)
/* Prevent timer overflow during SYS_LOG_* output */
#define _MACACKWAITDURATION		(864 / 16 + 11625)
#define MCR20A_SEQ_SYNC_TIMEOUT		(200)
#else
#define MCR20A_SEQ_SYNC_TIMEOUT		(20)
#define _MACACKWAITDURATION		(864 / 16) /* 864us * 62500Hz */
#endif

/* AUTOACK should be enabled by default, disable it only for testing */
#define MCR20A_AUTOACK_ENABLED		(true)

#define MCR20A_FCS_LENGTH		(2)
#define MCR20A_PSDU_LENGTH		(125)
#define MCR20A_GET_SEQ_STATE_RETRIES	(3)

/* Values for the clock output (CLK_OUT) configuration */
#ifdef CONFIG_MCR20A_CLK_OUT_DISABLED
#define MCR20A_CLK_OUT_CONFIG	(MCR20A_CLK_OUT_HIZ)

#elif CONFIG_MCR20A_CLK_OUT_32MHZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(0) | MCR20A_CLK_OUT_DS |\
				 MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_16MHZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(1) | MCR20A_CLK_OUT_DS |\
				 MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_8MHZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(2) | MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_4MHZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(3) | MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_1MHZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(4) | MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_250KHZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(5) | MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_62500HZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(6) | MCR20A_CLK_OUT_EN)

#elif CONFIG_MCR20A_CLK_OUT_32768HZ
#define MCR20A_CLK_OUT_CONFIG	(set_bits_clk_out_div(7) | MCR20A_CLK_OUT_EN)

#endif

#ifdef CONFIG_MCR20A_IS_PART_OF_KW2XD_SIP
#define PART_OF_KW2XD_SIP	1
#else
#define PART_OF_KW2XD_SIP	0
#endif

/* Values for the power mode (PM) configuration */
#define MCR20A_PM_HIBERNATE	0
#define MCR20A_PM_DOZE		MCR20A_PWR_MODES_XTALEN
#define MCR20A_PM_IDLE		(MCR20A_PWR_MODES_XTALEN |\
				 MCR20A_PWR_MODES_PMC_MODE)
#define MCR20A_PM_AUTODOZE	(MCR20A_PWR_MODES_XTALEN |\
				 MCR20A_PWR_MODES_AUTODOZE)

/* Default settings for the device initialization */
#define MCR20A_DEFAULT_TX_POWER	(0)
#define MCR20A_DEFAULT_CHANNEL	(26)

/* RF TX power max/min values (dBm) */
#define MCR20A_OUTPUT_POWER_MAX	(8)
#define MCR20A_OUTPUT_POWER_MIN	(-35)

/* Lookup table for the Power Control register */
static const u8_t pow_lt[44] = {
	3, 4, 5, 6,
	6, 7, 7, 8,
	8, 9, 9, 10,
	11, 11, 12, 13,
	13, 14, 14, 15,
	16, 16, 17, 18,
	18, 19, 20, 20,
	21, 21, 22, 23,
	23, 24, 25, 25,
	26, 27, 27, 28,
	28, 29, 30, 31
};

/* PLL integer and fractional lookup tables
 *
 * Fc = 2405 + 5(k - 11) , k = 11,12,...,26
 *
 * Equation for PLL frequency, MKW2xD Reference Manual, p.255 :
 * F = ((PLL_INT0 + 64) + (PLL_FRAC0/65536))32MHz
 *
 */
static const u8_t pll_int_lt[16] = {
	11, 11, 11, 11,
	11, 11, 12, 12,
	12, 12, 12, 12,
	13, 13, 13, 13
};

static const u16_t pll_frac_lt[16] = {
	10240, 20480, 30720, 40960,
	51200, 61440, 6144, 16384,
	26624, 36864, 47104, 57344,
	2048, 12288, 22528, 32768
};

#define _usleep(usec) k_busy_wait(usec)

/* Read direct (dreg is true) or indirect register (dreg is false) */
u8_t _mcr20a_read_reg(struct mcr20a_spi *spi, bool dreg, u8_t addr)
{
	u8_t len = dreg ? 2 : 3;

	k_sem_take(&spi->spi_sem, K_FOREVER);

	spi->cmd_buf[0] = dreg ? (MCR20A_REG_READ | addr) :
				 (MCR20A_IAR_INDEX | MCR20A_REG_WRITE);
	spi->cmd_buf[1] = dreg ? 0 : (addr | MCR20A_REG_READ);
	spi->cmd_buf[2] = 0;

	spi_slave_select(spi->dev, spi->slave);

	if (spi_transceive(spi->dev, spi->cmd_buf, len,
			   spi->cmd_buf, len) == 0) {
		k_sem_give(&spi->spi_sem);
		return spi->cmd_buf[len - 1];
	}

	k_sem_give(&spi->spi_sem);

	return 0;
}

/* Write direct (dreg is true) or indirect register (dreg is false) */
bool _mcr20a_write_reg(struct mcr20a_spi *spi, bool dreg, u8_t addr,
		       u8_t value)
{
	u8_t len = dreg ? 2 : 3;
	bool retval;

	k_sem_take(&spi->spi_sem, K_FOREVER);

	spi->cmd_buf[0] = dreg ? (MCR20A_REG_WRITE | addr) :
				 (MCR20A_IAR_INDEX | MCR20A_REG_WRITE);
	spi->cmd_buf[1] = dreg ? value : (addr | MCR20A_REG_WRITE);
	spi->cmd_buf[2] = dreg ? 0 : value;

	spi_slave_select(spi->dev, spi->slave);
	retval = (spi_write(spi->dev, spi->cmd_buf, len) == 0);

	k_sem_give(&spi->spi_sem);

	return retval;
}

/* Write multiple bytes to direct or indirect register */
bool _mcr20a_write_burst(struct mcr20a_spi *spi, bool dreg, u16_t addr,
			 u8_t *data_buf, u8_t len)
{
	bool retval;

	k_sem_take(&spi->spi_sem, K_FOREVER);

	if ((len + 2) > sizeof(spi->cmd_buf)) {
		SYS_LOG_ERR("Buffer length too large");
	}

	if (dreg) {
		spi->cmd_buf[0] = MCR20A_REG_WRITE | addr;
		memcpy(&spi->cmd_buf[1], data_buf, len);
		len += 1;
	} else {
		spi->cmd_buf[0] = MCR20A_IAR_INDEX | MCR20A_REG_WRITE;
		spi->cmd_buf[1] = addr | MCR20A_REG_WRITE;
		memcpy(&spi->cmd_buf[2], data_buf, len);
		len += 2;
	}

	spi_slave_select(spi->dev, spi->slave);
	retval = (spi_write(spi->dev, spi->cmd_buf, len) == 0);

	k_sem_give(&spi->spi_sem);

	return retval;
}

/* Read multiple bytes from direct or indirect register */
bool _mcr20a_read_burst(struct mcr20a_spi *spi, bool dreg, u16_t addr,
			u8_t *data_buf, u8_t len)
{
	k_sem_take(&spi->spi_sem, K_FOREVER);

	if ((len + 2) > sizeof(spi->cmd_buf)) {
		SYS_LOG_ERR("Buffer length too large");
	}

	if (dreg) {
		spi->cmd_buf[0] = MCR20A_REG_READ | addr;
		len += 1;
	} else {
		spi->cmd_buf[0] = MCR20A_IAR_INDEX | MCR20A_REG_WRITE;
		spi->cmd_buf[1] = addr | MCR20A_REG_READ;
		len += 2;
	}

	spi_slave_select(spi->dev, spi->slave);

	if (spi_transceive(spi->dev, spi->cmd_buf, len,
			   spi->cmd_buf, len) != 0) {
		k_sem_give(&spi->spi_sem);
		return 0;
	}

	if (dreg) {
		memcpy(data_buf, &spi->cmd_buf[1], len - 1);
	} else {
		memcpy(data_buf, &spi->cmd_buf[2], len - 2);
	}

	k_sem_give(&spi->spi_sem);

	return 1;
}

/* Mask (msk is true) or unmask all interrupts from asserting IRQ_B */
static bool mcr20a_mask_irqb(struct mcr20a_context *dev, bool msk)
{
	u8_t ctrl4 = read_reg_phy_ctrl4(&dev->spi);

	if (msk) {
		ctrl4 |= MCR20A_PHY_CTRL4_TRCV_MSK;
	} else {
		ctrl4 &= ~MCR20A_PHY_CTRL4_TRCV_MSK;
	}

	return write_reg_phy_ctrl4(&dev->spi, ctrl4);
}

/** Set an timeout value for the given compare register */
static int mcr20a_timer_set(struct mcr20a_context *mcr20a,
			    u8_t cmp_reg,
			    u32_t timeout)
{
	u32_t now = 0;
	u32_t next;
	bool retval;

	if (!read_burst_event_timer(&mcr20a->spi, (u8_t *)&now)) {
		goto error;
	}

	now = sys_le32_to_cpu(now);
	next = now + timeout;
	SYS_LOG_DBG("now: 0x%x set 0x%x", now, next);
	next = sys_cpu_to_le32(next);

	switch (cmp_reg) {
	case 1:
		retval = write_burst_t1cmp(&mcr20a->spi, (u8_t *)&next);
		break;
	case 2:
		retval = write_burst_t2cmp(&mcr20a->spi, (u8_t *)&next);
		break;
	case 3:
		retval = write_burst_t3cmp(&mcr20a->spi, (u8_t *)&next);
		break;
	case 4:
		retval = write_burst_t4cmp(&mcr20a->spi, (u8_t *)&next);
		break;
	default:
		goto error;
	}

	if (!retval) {
		goto error;
	}

	return 0;

error:
	SYS_LOG_ERR("Failed");
	return -EIO;
}

static int mcr20a_timer_init(struct device *dev, u8_t tb)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t buf[3] = {0, 0, 0};
	u8_t ctrl4;

	if (!write_reg_tmr_prescale(&mcr20a->spi,
				    set_bits_tmr_prescale(tb))) {
		goto error;
	}

	if (!write_burst_t1cmp(&mcr20a->spi, buf)) {
		goto error;
	}

	ctrl4 = read_reg_phy_ctrl4(&mcr20a->spi);
	ctrl4 |= MCR20A_PHY_CTRL4_TMRLOAD;
	if (!write_reg_phy_ctrl4(&mcr20a->spi, ctrl4)) {
		goto error;
	}

	SYS_LOG_DBG("done, timebase %d", tb);
	return 0;

error:
	SYS_LOG_ERR("Failed");
	return -EIO;
}

/* Set Timer Comparator 4 */
static int mcr20a_t4cmp_set(struct mcr20a_context *mcr20a,
			    u32_t timeout)
{
	u8_t irqsts3;
	u8_t ctrl3;

	if (mcr20a_timer_set(mcr20a, 4, timeout)) {
		goto error;
	}

	/* enable and clear irq for the timer 4 */
	irqsts3 = read_reg_irqsts3(&mcr20a->spi);
	irqsts3 &= ~MCR20A_IRQSTS3_TMR4MSK;
	irqsts3 |= MCR20A_IRQSTS3_TMR4IRQ;
	if (!write_reg_irqsts3(&mcr20a->spi, irqsts3)) {
		goto error;
	}

	ctrl3 = read_reg_phy_ctrl3(&mcr20a->spi);
	ctrl3 |= MCR20A_PHY_CTRL3_TMR4CMP_EN;
	if (!write_reg_phy_ctrl3(&mcr20a->spi, ctrl3)) {
		goto error;
	}

	return 0;

error:
	SYS_LOG_DBG("Failed");
	return -EIO;
}

/* Clear Timer Comparator 4 */
static int mcr20a_t4cmp_clear(struct mcr20a_context *mcr20a)
{
	u8_t irqsts3;
	u8_t ctrl3;

	ctrl3 = read_reg_phy_ctrl3(&mcr20a->spi);
	ctrl3 &= ~MCR20A_PHY_CTRL3_TMR4CMP_EN;
	if (!write_reg_phy_ctrl3(&mcr20a->spi, ctrl3)) {
		goto error;
	}

	irqsts3 = read_reg_irqsts3(&mcr20a->spi);
	irqsts3 |= MCR20A_IRQSTS3_TMR4IRQ;
	if (!write_reg_irqsts3(&mcr20a->spi, irqsts3)) {
		goto error;
	}

	return 0;

error:
	SYS_LOG_DBG("Failed");
	return -EIO;
}

static inline void _xcvseq_wait_until_idle(struct mcr20a_context *mcr20a)
{
	u8_t state;
	u8_t retries = MCR20A_GET_SEQ_STATE_RETRIES;

	do {
		state = read_reg_seq_state(&mcr20a->spi);
		retries--;
	} while ((state & MCR20A_SEQ_STATE_MASK) && retries);

	if (state & MCR20A_SEQ_STATE_MASK) {
		SYS_LOG_ERR("Timeout");
	}
}

static inline int mcr20a_abort_sequence(struct mcr20a_context *mcr20a,
					bool force)
{
	u8_t ctrl1;

	ctrl1 = read_reg_phy_ctrl1(&mcr20a->spi);
	SYS_LOG_DBG("CTRL1 0x%02x", ctrl1);

	if (((ctrl1 & MCR20A_PHY_CTRL1_XCVSEQ_MASK) == MCR20A_XCVSEQ_TX) ||
	    ((ctrl1 & MCR20A_PHY_CTRL1_XCVSEQ_MASK) == MCR20A_XCVSEQ_TX_RX)) {
		if (!force) {
			return -1;
		}
	}

	/* Abort ongoing sequence */
	ctrl1 &= ~MCR20A_PHY_CTRL1_XCVSEQ_MASK;
	if (!write_reg_phy_ctrl1(&mcr20a->spi, ctrl1)) {
		return -1;
	}

	_xcvseq_wait_until_idle(mcr20a);

	/* Clear relevant interrupt flags */
	if (!write_reg_irqsts1(&mcr20a->spi, MCR20A_IRQSTS1_IRQ_MASK)) {
		return -1;
	}

	return 0;
}

/* Initiate a (new) Transceiver Sequence */
static inline int mcr20a_set_sequence(struct mcr20a_context *mcr20a,
				      u8_t seq)
{
	u8_t ctrl1 = 0;

	seq = set_bits_phy_ctrl1_xcvseq(seq);
	ctrl1 = read_reg_phy_ctrl1(&mcr20a->spi);
	ctrl1 &= ~MCR20A_PHY_CTRL1_XCVSEQ_MASK;

	if ((seq == MCR20A_XCVSEQ_TX_RX) &&
	    (ctrl1 & MCR20A_PHY_CTRL1_RXACKRQD)) {
		/* RXACKRQD enabled, timer should be set. */
		mcr20a_t4cmp_set(mcr20a, _MACACKWAITDURATION +
				 _MAX_PKT_TX_DURATION);
	}

	ctrl1 |= seq;
	if (!write_reg_phy_ctrl1(&mcr20a->spi, ctrl1)) {
		return -EIO;
	}

	return 0;
}

static inline u32_t mcr20a_get_rssi(u32_t lqi)
{
	/* Get rssi (Received Signal Strength Indicator, unit is dBm)
	 * from lqi (Link Quality Indicator) value.
	 * There are two different equations for RSSI:
	 * RF = (LQI – 286.6) / 2.69333 (MKW2xD Reference Manual)
	 * RF = (LQI – 295.4) / 2.84 (MCR20A Reference Manual)
	 * The last appears more to match the graphic (Figure 3-10).
	 * Since RSSI value is always positive and we want to
	 * avoid the floating point computation:
	 * -RF * 65536 = (LQI / 2.84 - 295.4 / 2.84) * 65536
	 * RF * 65536 = (295.4 * 65536 / 2.84) - (LQI * 65536 / 2.84)
	 */
	u32_t a = (u32_t)(295.4 * 65536 / 2.84);
	u32_t b = (u32_t)(65536 / 2.84);

	return (a - (b * lqi)) >> 16;
}

static inline u8_t *get_mac(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u32_t *ptr = (u32_t *)(mcr20a->mac_addr);

	UNALIGNED_PUT(sys_rand32_get(), ptr);
	ptr = (u32_t *)(mcr20a->mac_addr + 4);
	UNALIGNED_PUT(sys_rand32_get(), ptr);

	mcr20a->mac_addr[0] = (mcr20a->mac_addr[0] & ~0x01) | 0x02;

	return mcr20a->mac_addr;
}

static inline bool read_rxfifo_content(struct mcr20a_spi *spi,
				       struct net_buf *buf, u8_t len)
{
	u8_t data[1 + MCR20A_PSDU_LENGTH];

	if (len  > MCR20A_PSDU_LENGTH) {
		SYS_LOG_ERR("Packet length too large");
		return false;
	}

	k_sem_take(&spi->spi_sem, K_FOREVER);

	data[0] = MCR20A_BUF_READ;
	spi_slave_select(spi->dev, spi->slave);

	if (spi_transceive(spi->dev, data, len+1, data, len+1) != 0) {
		k_sem_give(&spi->spi_sem);
		return false;
	}

	memcpy(buf->data, &data[1], len);
	net_buf_add(buf, len);

	k_sem_give(&spi->spi_sem);

	return true;
}

static inline void mcr20a_rx(struct mcr20a_context *mcr20a, u8_t len)
{
	struct net_pkt *pkt = NULL;
	struct net_buf *frag;
	u8_t pkt_len;

	pkt_len = len - MCR20A_FCS_LENGTH;

	pkt = net_pkt_get_reserve_rx(0, K_NO_WAIT);
	if (!pkt) {
		SYS_LOG_ERR("No buf available");
		goto out;
	}

#if defined(CONFIG_IEEE802154_MCR20A_RAW)
	/* TODO: Test raw mode */
	/**
	 * Reserve 1 byte for length
	 */
	net_pkt_set_ll_reserve(pkt, 1);
#endif
	frag = net_pkt_get_frag(pkt, K_NO_WAIT);
	if (!frag) {
		SYS_LOG_ERR("No frag available");
		goto out;
	}

	net_pkt_frag_insert(pkt, frag);

	if (!read_rxfifo_content(&mcr20a->spi, frag, pkt_len)) {
		SYS_LOG_ERR("No content read");
		goto out;
	}

	if (ieee802154_radio_handle_ack(mcr20a->iface, pkt) == NET_OK) {
		SYS_LOG_DBG("ACK packet handled");
		goto out;
	}

	net_pkt_set_ieee802154_lqi(pkt, read_reg_lqi_value(&mcr20a->spi));
	net_pkt_set_ieee802154_rssi(pkt, mcr20a_get_rssi(
					    net_pkt_ieee802154_lqi(pkt)));

	SYS_LOG_DBG("Caught a packet (%u) (LQI: %u, RSSI: %u)",
		    pkt_len, net_pkt_ieee802154_lqi(pkt),
		    net_pkt_ieee802154_rssi(pkt));

#if defined(CONFIG_IEEE802154_MCR20A_RAW)
	net_buf_add_u8(frag, mcr20a->lqi);
#endif

	if (net_recv_data(mcr20a->iface, pkt) < 0) {
		SYS_LOG_DBG("Packet dropped by NET stack");
		goto out;
	}

	net_analyze_stack("MCR20A Rx Fiber stack",
			  K_THREAD_STACK_BUFFER(mcr20a->mcr20a_rx_stack),
			  K_THREAD_STACK_SIZEOF(mcr20a->mcr20a_rx_stack));
	return;
out:
	if (pkt) {
		net_pkt_unref(pkt);
	}
}

/*
 * The function checks how the XCV sequence has been completed
 * and sets the variable seq_retval accordingly. It returns true
 * if a new sequence is to be set. This function is only to be called
 * when a sequence has been completed.
 */
static inline bool _irqsts1_event(struct mcr20a_context *mcr20a,
				  u8_t *dregs)
{
	u8_t seq = dregs[MCR20A_PHY_CTRL1] & MCR20A_PHY_CTRL1_XCVSEQ_MASK;
	u8_t new_seq = MCR20A_XCVSEQ_RECEIVE;
	bool retval = false;

	switch (seq) {
	case MCR20A_XCVSEQ_RECEIVE:
		if ((dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_RXIRQ)) {
			if ((dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_TXIRQ)) {
				SYS_LOG_DBG("Finished RxSeq + TxAck");
			} else {
				SYS_LOG_DBG("Finished RxSeq");
			}

			mcr20a_rx(mcr20a, dregs[MCR20A_RX_FRM_LEN]);
			retval = true;
		}
		break;
	case MCR20A_XCVSEQ_TX:
	case MCR20A_XCVSEQ_TX_RX:
		if (dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_CCAIRQ) {
			if (dregs[MCR20A_IRQSTS2] & MCR20A_IRQSTS2_CCA) {
				SYS_LOG_DBG("Finished CCA, CH busy");
				atomic_set(&mcr20a->seq_retval, -EBUSY);
				retval = true;
				break;
			}
		}

		if (dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_TXIRQ) {
			atomic_set(&mcr20a->seq_retval, 0);

			if ((dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_RXIRQ)) {
				SYS_LOG_DBG("Finished TxSeq + RxAck");
				/* Got Ack, timer should be disabled. */
				mcr20a_t4cmp_clear(mcr20a);
			} else {
				SYS_LOG_DBG("Finished TxSeq");
			}

			retval = true;
		}
		break;
	case MCR20A_XCVSEQ_CONTINUOUS_CCA:
	case MCR20A_XCVSEQ_CCA:
		if ((dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_CCAIRQ)) {

			/* If CCCA, then timer should be disabled. */
			/* mcr20a_t4cmp_clear(mcr20a); */

			if (dregs[MCR20A_IRQSTS2] & MCR20A_IRQSTS2_CCA) {
				SYS_LOG_DBG("Finished CCA, CH busy");
				atomic_set(&mcr20a->seq_retval, -EBUSY);
			} else {
				/**
				 * Assume that after the CCA,
				 * a transmit sequence follows and
				 * set here the sequence manager to Idle.
				 */
				SYS_LOG_DBG("Finished CCA, CH idle");
				new_seq = MCR20A_XCVSEQ_IDLE;
				atomic_set(&mcr20a->seq_retval, 0);
			}

			retval = true;
		}
		break;
	case MCR20A_XCVSEQ_IDLE:
	default:
		SYS_LOG_ERR("SEQ triggered, but XCVSEQ is in the Idle state");
		SYS_LOG_ERR("IRQSTS: 0x%02x", dregs[MCR20A_IRQSTS1]);
		break;
	}

	dregs[MCR20A_PHY_CTRL1] &= ~MCR20A_PHY_CTRL1_XCVSEQ_MASK;
	dregs[MCR20A_PHY_CTRL1] |= new_seq;

	return retval;
}

/*
 * Check the Timer Comparator IRQ register IRQSTS3.
 * Currently we use only T4CMP to cancel the running sequence,
 * usually the TR.
 */
static inline bool _irqsts3_event(struct mcr20a_context *mcr20a,
				  u8_t *dregs)
{
	bool retval = false;

	if (dregs[MCR20A_IRQSTS3] & MCR20A_IRQSTS3_TMR4IRQ) {
		SYS_LOG_DBG("Sequence timeout, IRQSTSs 0x%02x 0x%02x 0x%02x",
			    dregs[MCR20A_IRQSTS1],
			    dregs[MCR20A_IRQSTS2],
			    dregs[MCR20A_IRQSTS3]);

		atomic_set(&mcr20a->seq_retval, -EBUSY);
		mcr20a_t4cmp_clear(mcr20a);
		dregs[MCR20A_PHY_CTRL1] &= ~MCR20A_PHY_CTRL1_XCVSEQ_MASK;
		dregs[MCR20A_PHY_CTRL1] |= MCR20A_XCVSEQ_RECEIVE;

		/* Clear all interrupts */
		dregs[MCR20A_IRQSTS1] = MCR20A_IRQSTS1_IRQ_MASK;
		retval = true;
	} else {
		SYS_LOG_ERR("IRQSTS3 contains untreated IRQs: 0x%02x",
			    dregs[MCR20A_IRQSTS3]);
	}

	return retval;
}

static void mcr20a_thread_main(void *arg)
{
	struct device *dev = (struct device *)arg;
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t dregs[MCR20A_PHY_CTRL4 + 1];
	bool set_new_seq;
	u8_t ctrl1 = 0;

	while (true) {
		k_sem_take(&mcr20a->isr_sem, K_FOREVER);

		k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);
		set_new_seq = false;

		if (!mcr20a_mask_irqb(mcr20a, true)) {
			SYS_LOG_ERR("Failed to mask IRQ_B");
			goto unmask_irqb;
		}

		/* Read the register from IRQSTS1 until CTRL4 */
		if (!read_burst_irqsts1_ctrl4(&mcr20a->spi, dregs)) {
			SYS_LOG_ERR("Failed to read register");
			goto unmask_irqb;
		}
		/* make backup from PHY_CTRL1 register */
		ctrl1 = dregs[MCR20A_PHY_CTRL1];

		if (dregs[MCR20A_IRQSTS3] & MCR20A_IRQSTS3_IRQ_MASK) {
			set_new_seq = _irqsts3_event(mcr20a, dregs);
		} else if (dregs[MCR20A_IRQSTS1] & MCR20A_IRQSTS1_SEQIRQ) {
			set_new_seq = _irqsts1_event(mcr20a, dregs);
		}

		if (dregs[MCR20A_IRQSTS2] & MCR20A_IRQSTS2_IRQ_MASK) {
			SYS_LOG_ERR("IRQSTS2 contains untreated IRQs: 0x%02x",
				    dregs[MCR20A_IRQSTS2]);
		}

		SYS_LOG_DBG("WB: 0x%02x | 0x%02x | 0x%02x",
			     dregs[MCR20A_IRQSTS1],
			     dregs[MCR20A_IRQSTS2],
			     dregs[MCR20A_IRQSTS3]);

		/* Write back register, clear IRQs and set new sequence */
		if (set_new_seq) {
			/* Reset sequence manager */
			ctrl1 &= ~MCR20A_PHY_CTRL1_XCVSEQ_MASK;
			if (!write_reg_phy_ctrl1(&mcr20a->spi, ctrl1)) {
				SYS_LOG_ERR("Failed to reset SEQ manager");
			}

			_xcvseq_wait_until_idle(mcr20a);

			if (!write_burst_irqsts1_ctrl1(&mcr20a->spi, dregs)) {
				SYS_LOG_ERR("Failed to write CTRL1");
			}
		} else {
			if (!write_burst_irqsts1_irqsts3(&mcr20a->spi, dregs)) {
				SYS_LOG_ERR("Failed to write IRQSTS3");
			}
		}

unmask_irqb:
		if (!mcr20a_mask_irqb(mcr20a, false)) {
			SYS_LOG_ERR("Failed to unmask IRQ_B");
		}

		k_mutex_unlock(&mcr20a->phy_mutex);

		if (set_new_seq) {
			k_sem_give(&mcr20a->seq_sync);
		}
	}
}

static inline void irqb_int_handler(struct device *port,
				    struct gpio_callback *cb, u32_t pins)
{
	struct mcr20a_context *mcr20a = CONTAINER_OF(cb,
						     struct mcr20a_context,
						     irqb_cb);
	k_sem_give(&mcr20a->isr_sem);
}

static inline void set_reset(struct device *dev, u32_t value)
{
	struct mcr20a_context *mcr20a = dev->driver_data;

	gpio_pin_write(mcr20a->reset_gpio,
		       CONFIG_MCR20A_GPIO_RESET_PIN, value);
}

static void enable_irqb_interrupt(struct mcr20a_context *mcr20a,
				 bool enable)
{
	if (enable) {
		gpio_pin_enable_callback(mcr20a->irq_gpio,
					 CONFIG_MCR20A_GPIO_IRQ_B_PIN);
	} else {
		gpio_pin_disable_callback(mcr20a->irq_gpio,
					  CONFIG_MCR20A_GPIO_IRQ_B_PIN);
	}
}

static inline void setup_gpio_callbacks(struct mcr20a_context *mcr20a)
{
	gpio_init_callback(&mcr20a->irqb_cb,
			   irqb_int_handler,
			   BIT(CONFIG_MCR20A_GPIO_IRQ_B_PIN));
	gpio_add_callback(mcr20a->irq_gpio, &mcr20a->irqb_cb);
}

static int mcr20a_set_cca_mode(struct device *dev, u8_t mode)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t ctrl4;

	ctrl4 = read_reg_phy_ctrl4(&mcr20a->spi);
	ctrl4 &= ~MCR20A_PHY_CTRL4_CCATYPE_MASK;
	ctrl4 |= set_bits_phy_ctrl4_ccatype(mode);

	if (!write_reg_phy_ctrl4(&mcr20a->spi, ctrl4)) {
		SYS_LOG_ERR("Failed");
		return -EIO;
	}

	return 0;
}

static enum ieee802154_hw_caps mcr20a_get_capabilities(struct device *dev)
{
	return IEEE802154_HW_FCS |
		IEEE802154_HW_2_4_GHZ |
		IEEE802154_HW_FILTER;
}

/* Note: CCA before TX is enabled by default */
static int mcr20a_cca(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	int retval;

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	if (!mcr20a_mask_irqb(mcr20a, true)) {
		SYS_LOG_ERR("Failed to mask IRQ_B");
		goto error;
	}

	k_sem_init(&mcr20a->seq_sync, 0, 1);

	if (mcr20a_abort_sequence(mcr20a, false)) {
		SYS_LOG_ERR("Failed to reset XCV sequence");
		goto error;
	}

	SYS_LOG_DBG("start CCA sequence");

	if (mcr20a_set_sequence(mcr20a, MCR20A_XCVSEQ_CCA)) {
		SYS_LOG_ERR("Failed to reset XCV sequence");
		goto error;
	}

	if (!mcr20a_mask_irqb(mcr20a, false)) {
		SYS_LOG_ERR("Failed to unmask IRQ_B");
		goto error;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	retval = k_sem_take(&mcr20a->seq_sync, MCR20A_SEQ_SYNC_TIMEOUT);
	if (retval) {
		SYS_LOG_ERR("Timeout occurred, %d", retval);
		return retval;
	}

	SYS_LOG_DBG("done");

	return mcr20a->seq_retval;

error:
	k_mutex_unlock(&mcr20a->phy_mutex);
	return -EIO;
}

static int mcr20a_set_channel(struct device *dev, u16_t channel)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t buf[3];
	u8_t ctrl1;
	int retval = -EIO;

	if (channel < 11 || channel > 26) {
		SYS_LOG_ERR("Unsupported channel %u", channel);
		return -EINVAL;
	}

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	if (!mcr20a_mask_irqb(mcr20a, true)) {
		SYS_LOG_ERR("Failed to mask IRQ_B");
		goto out;
	}

	ctrl1 = read_reg_phy_ctrl1(&mcr20a->spi);

	if (mcr20a_abort_sequence(mcr20a, false)) {
		SYS_LOG_ERR("Failed to reset XCV sequence");
		goto out;
	}

	SYS_LOG_DBG("%u", channel);
	channel -= 11;
	buf[0] = set_bits_pll_int0_val(pll_int_lt[channel]);
	buf[1] = (u8_t)pll_frac_lt[channel];
	buf[2] = (u8_t)(pll_frac_lt[channel] >> 8);

	if (!write_burst_pll_int0(&mcr20a->spi, buf)) {
		SYS_LOG_ERR("Failed to set PLL");
		goto out;
	}

	if (mcr20a_set_sequence(mcr20a, ctrl1)) {
		SYS_LOG_ERR("Failed to restore XCV sequence");
		goto out;
	}

	retval = 0;

out:
	if (!mcr20a_mask_irqb(mcr20a, false)) {
		SYS_LOG_ERR("Failed to unmask IRQ_B");
		retval = -EIO;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);

	return retval;
}

static int mcr20a_set_pan_id(struct device *dev, u16_t pan_id)
{
	struct mcr20a_context *mcr20a = dev->driver_data;

	pan_id = sys_le16_to_cpu(pan_id);
	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	if (!write_burst_pan_id(&mcr20a->spi, (u8_t *) &pan_id)) {
		SYS_LOG_ERR("FAILED");
		return -EIO;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	SYS_LOG_DBG("0x%x", pan_id);

	return 0;
}

static int mcr20a_set_short_addr(struct device *dev, u16_t short_addr)
{
	struct mcr20a_context *mcr20a = dev->driver_data;

	short_addr = sys_le16_to_cpu(short_addr);
	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	if (!write_burst_short_addr(&mcr20a->spi, (u8_t *) &short_addr)) {
		SYS_LOG_ERR("FAILED");
		return -EIO;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	SYS_LOG_DBG("0x%x", short_addr);

	return 0;
}

static int mcr20a_set_ieee_addr(struct device *dev, const u8_t *ieee_addr)
{
	struct mcr20a_context *mcr20a = dev->driver_data;

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	if (!write_burst_ext_addr(&mcr20a->spi, (void *)ieee_addr)) {
		SYS_LOG_ERR("Failed");
		return -EIO;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	SYS_LOG_DBG("IEEE address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
		    ieee_addr[7], ieee_addr[6], ieee_addr[5], ieee_addr[4],
		    ieee_addr[3], ieee_addr[2], ieee_addr[1], ieee_addr[0]);

	return 0;
}

static int mcr20a_set_filter(struct device *dev,
			     enum ieee802154_filter_type type,
			     const struct ieee802154_filter *filter)
{
	SYS_LOG_DBG("Applying filter %u", type);

	if (type == IEEE802154_FILTER_TYPE_IEEE_ADDR) {
		return mcr20a_set_ieee_addr(dev, filter->ieee_addr);
	} else if (type == IEEE802154_FILTER_TYPE_SHORT_ADDR) {
		return mcr20a_set_short_addr(dev, filter->short_addr);
	} else if (type == IEEE802154_FILTER_TYPE_PAN_ID) {
		return mcr20a_set_pan_id(dev, filter->pan_id);
	}

	return -EINVAL;
}

static int mcr20a_set_txpower(struct device *dev, s16_t dbm)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t pwr;

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);
	SYS_LOG_DBG("%d", dbm);

	if ((dbm > MCR20A_OUTPUT_POWER_MAX) ||
	    (dbm < MCR20A_OUTPUT_POWER_MIN)) {
		goto error;
	}

	pwr = pow_lt[dbm - MCR20A_OUTPUT_POWER_MIN];
	if (!write_reg_pa_pwr(&mcr20a->spi, set_bits_pa_pwr_val(pwr))) {
		goto error;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	return 0;

error:
	k_mutex_unlock(&mcr20a->phy_mutex);
	SYS_LOG_DBG("Failed");
	return -EIO;
}

static inline bool write_txfifo_content(struct mcr20a_spi *spi,
					struct net_pkt *pkt,
					struct net_buf *frag)
{
	u8_t cmd[2 + MCR20A_PSDU_LENGTH];
	u8_t payload_len = net_pkt_ll_reserve(pkt) + frag->len;
	u8_t *payload = frag->data - net_pkt_ll_reserve(pkt);
	bool retval;

	k_sem_take(&spi->spi_sem, K_FOREVER);

	cmd[0] = MCR20A_BUF_WRITE;
	/**
	 * The length of the packet (PSDU + FSC),
	 * is stored at index 0, followed by the PSDU.
	 * Note: maximum FRAME_LEN is 125 + MCR20A_FCS_LENGTH
	 */
	cmd[1] = payload_len + MCR20A_FCS_LENGTH;

	if (payload_len > MCR20A_PSDU_LENGTH) {
		SYS_LOG_ERR("Payload too long");
		return 0;
	}
	memcpy(&cmd[2], payload, payload_len);

	spi_slave_select(spi->dev, spi->slave);

	retval = (spi_transceive(spi->dev,
		  cmd, (2 + payload_len),
		  cmd, (2 + payload_len)) == 0);

	k_sem_give(&spi->spi_sem);

	return retval;
}

static int mcr20a_tx(struct device *dev,
		     struct net_pkt *pkt,
		     struct net_buf *frag)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t seq = MCR20A_AUTOACK_ENABLED ? MCR20A_XCVSEQ_TX_RX :
					       MCR20A_XCVSEQ_TX;
	int retval;

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	SYS_LOG_DBG("%p (%u)",
		    frag, net_pkt_ll_reserve(pkt) + frag->len);

	if (!mcr20a_mask_irqb(mcr20a, true)) {
		SYS_LOG_ERR("Failed to mask IRQ_B");
		goto error;
	}

	if (mcr20a_abort_sequence(mcr20a, false)) {
		SYS_LOG_ERR("Failed to reset XCV sequence");
		goto error;
	}

	if (!write_txfifo_content(&mcr20a->spi, pkt, frag)) {
		SYS_LOG_ERR("Did not write properly into TX FIFO");
		goto error;
	}

	k_sem_init(&mcr20a->seq_sync, 0, 1);

	if (mcr20a_set_sequence(mcr20a, seq)) {
		SYS_LOG_ERR("Cannot start transmission");
		goto error;
	}

	if (!mcr20a_mask_irqb(mcr20a, false)) {
		SYS_LOG_ERR("Failed to unmask IRQ_B");
		goto error;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	retval = k_sem_take(&mcr20a->seq_sync, MCR20A_SEQ_SYNC_TIMEOUT);
	if (retval) {
		SYS_LOG_ERR("Timeout occurred, %d", retval);
		return retval;
	}

	SYS_LOG_DBG("done");

	return mcr20a->seq_retval;

error:
	k_mutex_unlock(&mcr20a->phy_mutex);
	return -EIO;
}

static int mcr20a_start(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t timeout = 6;
	u8_t status;

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);
	enable_irqb_interrupt(mcr20a, false);

	if (!write_reg_pwr_modes(&mcr20a->spi, MCR20A_PM_AUTODOZE)) {
		SYS_LOG_ERR("Error starting MCR20A");
		goto error;
	}

	do {
		_usleep(50);
		timeout--;
		status = read_reg_pwr_modes(&mcr20a->spi);
	} while (!(status & MCR20A_PWR_MODES_XTAL_READY) && timeout);

	if (!(status & MCR20A_PWR_MODES_XTAL_READY)) {
		SYS_LOG_ERR("Timeout, failed to wake up");
		goto error;
	}

	/* Clear all interrupt flags */
	write_reg_irqsts1(&mcr20a->spi, MCR20A_IRQSTS1_IRQ_MASK);
	write_reg_irqsts2(&mcr20a->spi, MCR20A_IRQSTS2_IRQ_MASK);
	write_reg_irqsts3(&mcr20a->spi, MCR20A_IRQSTS3_IRQ_MASK |
					MCR20A_IRQSTS3_TMR_MASK);

	if (mcr20a_abort_sequence(mcr20a, true)) {
		SYS_LOG_ERR("Failed to reset XCV sequence");
		goto error;
	}

	if (mcr20a_set_sequence(mcr20a, MCR20A_XCVSEQ_RECEIVE)) {
		SYS_LOG_ERR("Failed to set XCV sequence");
		goto error;
	}

	enable_irqb_interrupt(mcr20a, true);

	if (!mcr20a_mask_irqb(mcr20a, false)) {
		SYS_LOG_ERR("Failed to unmask IRQ_B");
		goto error;
	}

	k_mutex_unlock(&mcr20a->phy_mutex);
	SYS_LOG_DBG("started");

	return 0;

error:
	k_mutex_unlock(&mcr20a->phy_mutex);
	return -EIO;
}

static int mcr20a_stop(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t power_mode;

	k_mutex_lock(&mcr20a->phy_mutex, K_FOREVER);

	if (!mcr20a_mask_irqb(mcr20a, true)) {
		SYS_LOG_ERR("Failed to mask IRQ_B");
		goto error;
	}

	if (mcr20a_abort_sequence(mcr20a, true)) {
		SYS_LOG_ERR("Failed to reset XCV sequence");
		goto error;
	}

	enable_irqb_interrupt(mcr20a, false);

	if (PART_OF_KW2XD_SIP) {
		power_mode = MCR20A_PM_DOZE;
	} else {
		power_mode = MCR20A_PM_HIBERNATE;
	}

	if (!write_reg_pwr_modes(&mcr20a->spi, power_mode)) {
		goto error;
	}

	SYS_LOG_DBG("stopped");
	k_mutex_unlock(&mcr20a->phy_mutex);

	return 0;

error:
	k_mutex_unlock(&mcr20a->phy_mutex);
	SYS_LOG_ERR("Error stopping MCR20A");
	return -EIO;
}

static int mcr20a_update_overwrites(struct mcr20a_context *dev)
{
	struct mcr20a_spi *spi = &dev->spi;

	if (!write_reg_overwrite_ver(spi, overwrites_direct[0].data)) {
		goto error;
	}

	k_sem_take(&spi->spi_sem, K_FOREVER);

	for (u8_t i = 0;
	     i < sizeof(overwrites_indirect) / sizeof(overwrites_t);
	     i++) {

		spi->cmd_buf[0] = MCR20A_IAR_INDEX | MCR20A_REG_WRITE;
		spi->cmd_buf[1] = overwrites_indirect[i].address;
		spi->cmd_buf[2] = overwrites_indirect[i].data;

		spi_slave_select(spi->dev, spi->slave);

		if (spi_write(spi->dev, spi->cmd_buf, 3)) {
			k_sem_give(&spi->spi_sem);
			goto error;
		}
	}

	k_sem_give(&spi->spi_sem);

	return 0;

error:
	SYS_LOG_ERR("Error update overwrites");
	return -EIO;
}

static int power_on_and_setup(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t timeout = 6;
	u32_t status;
	u8_t tmp = 0;

	if (!PART_OF_KW2XD_SIP) {
		set_reset(dev, 0);
		_usleep(150);
		set_reset(dev, 1);

		do {
			_usleep(50);
			timeout--;
			gpio_pin_read(mcr20a->irq_gpio,
				      CONFIG_MCR20A_GPIO_IRQ_B_PIN, &status);
		} while (status && timeout);

		if (status) {
			SYS_LOG_ERR("Timeout, failed to get WAKE IRQ");
			return -EIO;
		}

	}

	tmp = MCR20A_CLK_OUT_CONFIG | MCR20A_CLK_OUT_EXTEND;
	write_reg_clk_out_ctrl(&mcr20a->spi, tmp);

	if (read_reg_clk_out_ctrl(&mcr20a->spi) != tmp) {
		SYS_LOG_ERR("Failed to get device up");
		return -EIO;
	}

	/* Clear all interrupt flags */
	write_reg_irqsts1(&mcr20a->spi, MCR20A_IRQSTS1_IRQ_MASK);
	write_reg_irqsts2(&mcr20a->spi, MCR20A_IRQSTS2_IRQ_MASK);
	write_reg_irqsts3(&mcr20a->spi, MCR20A_IRQSTS3_IRQ_MASK |
					MCR20A_IRQSTS3_TMR_MASK);

	mcr20a_update_overwrites(mcr20a);
	mcr20a_timer_init(dev, MCR20A_TIMEBASE_62500HZ);

	mcr20a_set_txpower(dev, MCR20A_DEFAULT_TX_POWER);
	mcr20a_set_channel(dev, MCR20A_DEFAULT_CHANNEL);
	mcr20a_set_cca_mode(dev, 1);
	write_reg_rx_wtr_mark(&mcr20a->spi, 8);

	/* Configure PHY behaviour */
	tmp = MCR20A_PHY_CTRL1_CCABFRTX;
	if (MCR20A_AUTOACK_ENABLED) {
		tmp |= MCR20A_PHY_CTRL1_AUTOACK |
		       MCR20A_PHY_CTRL1_RXACKRQD;
	}
	write_reg_phy_ctrl1(&mcr20a->spi, tmp);

	/* Enable Sequence-end interrupt */
	tmp = MCR20A_PHY_CTRL2_SEQMSK;
	write_reg_phy_ctrl2(&mcr20a->spi, ~tmp);

	setup_gpio_callbacks(mcr20a);

	return 0;
}


static inline int configure_gpios(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;

	/* setup gpio for the modem interrupt */
	mcr20a->irq_gpio = device_get_binding(CONFIG_MCR20A_GPIO_IRQ_B_NAME);
	if (mcr20a->irq_gpio == NULL) {
		SYS_LOG_ERR("Failed to get pointer to %s device",
			    CONFIG_MCR20A_GPIO_IRQ_B_NAME);
		return -EINVAL;
	}

	gpio_pin_configure(mcr20a->irq_gpio,
			   CONFIG_MCR20A_GPIO_IRQ_B_PIN,
			   GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
			   GPIO_PUD_PULL_UP |
			   GPIO_INT_ACTIVE_LOW);

	/* setup gpio for the modems reset */
	mcr20a->reset_gpio = device_get_binding(CONFIG_MCR20A_GPIO_RESET_NAME);
	if (mcr20a->reset_gpio == NULL) {
		SYS_LOG_ERR("Failed to get pointer to %s device",
			    CONFIG_MCR20A_GPIO_RESET_NAME);
		return -EINVAL;
	}

	gpio_pin_configure(mcr20a->reset_gpio, CONFIG_MCR20A_GPIO_RESET_PIN,
			   GPIO_DIR_OUT);
	set_reset(dev, 1);

	return 0;
}

static inline int configure_spi(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;
	struct spi_config spi_conf = {
		.config = SPI_WORD(8),
		.max_sys_freq = CONFIG_IEEE802154_MCR20A_SPI_FREQ,
	};

	mcr20a->spi.dev = device_get_binding(
			CONFIG_IEEE802154_MCR20A_SPI_DRV_NAME);
	if (!mcr20a->spi.dev) {
		SYS_LOG_ERR("Unable to get SPI device");
		return -ENODEV;
	}

	mcr20a->spi.slave = CONFIG_IEEE802154_MCR20A_SPI_SLAVE;

	if (spi_configure(mcr20a->spi.dev, &spi_conf) != 0 ||
	    spi_slave_select(mcr20a->spi.dev,
			     mcr20a->spi.slave) != 0) {
		mcr20a->spi.dev = NULL;
		return -EIO;
	}

	SYS_LOG_DBG("SPI configured %s, %d",
				CONFIG_IEEE802154_MCR20A_SPI_DRV_NAME,
				CONFIG_IEEE802154_MCR20A_SPI_SLAVE);

	return 0;
}

static int mcr20a_init(struct device *dev)
{
	struct mcr20a_context *mcr20a = dev->driver_data;

	k_sem_init(&mcr20a->spi.spi_sem, 1, UINT_MAX);

	k_mutex_init(&mcr20a->phy_mutex);
	k_sem_init(&mcr20a->isr_sem, 0, 1);

	SYS_LOG_DBG("\nInitialize MCR20A Transceiver\n");

	if (configure_gpios(dev) != 0) {
		SYS_LOG_ERR("Configuring GPIOS failed");
		return -EIO;
	}

	if (configure_spi(dev) != 0) {
		SYS_LOG_ERR("Configuring SPI failed");
		return -EIO;
	}

	SYS_LOG_DBG("GPIO and SPI configured");

	if (power_on_and_setup(dev) != 0) {
		SYS_LOG_ERR("Configuring MCR20A failed");
		return -EIO;
	}

	k_thread_create(&mcr20a->mcr20a_rx_thread, mcr20a->mcr20a_rx_stack,
			CONFIG_IEEE802154_MCR20A_RX_STACK_SIZE,
			(k_thread_entry_t)mcr20a_thread_main,
			dev, NULL, NULL, K_PRIO_COOP(2), 0, 0);

	return 0;
}

static void mcr20a_iface_init(struct net_if *iface)
{
	struct device *dev = net_if_get_device(iface);
	struct mcr20a_context *mcr20a = dev->driver_data;
	u8_t *mac = get_mac(dev);

	net_if_set_link_addr(iface, mac, 8, NET_LINK_IEEE802154);

	mcr20a->iface = iface;

	ieee802154_init(iface);

	SYS_LOG_DBG("done");
}

static struct mcr20a_context mcr20a_context_data;

static struct ieee802154_radio_api mcr20a_radio_api = {
	.iface_api.init	= mcr20a_iface_init,
	.iface_api.send	= ieee802154_radio_send,

	.get_capabilities	= mcr20a_get_capabilities,
	.cca			= mcr20a_cca,
	.set_channel		= mcr20a_set_channel,
	.set_filter		= mcr20a_set_filter,
	.set_txpower		= mcr20a_set_txpower,
	.start			= mcr20a_start,
	.stop			= mcr20a_stop,
	.tx			= mcr20a_tx,
};

#if defined(CONFIG_IEEE802154_MCR20A_RAW)
DEVICE_AND_API_INIT(mcr20a, CONFIG_IEEE802154_MCR20A_DRV_NAME,
		    mcr20a_init, &mcr20a_context_data, NULL,
		    POST_KERNEL, CONFIG_IEEE802154_MCR20A_INIT_PRIO,
		    &mcr20a_radio_api);
#else
NET_DEVICE_INIT(mcr20a, CONFIG_IEEE802154_MCR20A_DRV_NAME,
		mcr20a_init, &mcr20a_context_data, NULL,
		CONFIG_IEEE802154_MCR20A_INIT_PRIO,
		&mcr20a_radio_api, IEEE802154_L2,
		NET_L2_GET_CTX_TYPE(IEEE802154_L2),
		MCR20A_PSDU_LENGTH);
#endif
