// SPDX-License-Identifier: GPL-2.0+
/*
 * abstraction of the spi interface of HopeRf rf69 radio module
 *
 * Copyright (C) 2016 Wolf-Entwicklungen
 *	Marcus Wolf <linux@wolf-entwicklungen.de>
 */

#include <linux/types.h>
#include <linux/spi/spi.h>

#include "rf69.h"
#include "rf69_registers.h"

#define F_OSC	  32000000 /* in Hz */
#define FIFO_SIZE 66	   /* in byte */

/*-------------------------------------------------------------------------*/

u8 rf69_read_reg(struct spi_device *spi, u8 addr)
{
	return spi_w8r8(spi, addr);
}

static int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value)
{
	char buffer[2];

	buffer[0] = addr | WRITE_BIT;
	buffer[1] = value;

	return spi_write(spi, &buffer, ARRAY_SIZE(buffer));
}

/*-------------------------------------------------------------------------*/

static int rf69_set_bit(struct spi_device *spi, u8 reg, u8 mask)
{
	u8 tmp;

	tmp = rf69_read_reg(spi, reg);
	tmp = tmp | mask;
	return rf69_write_reg(spi, reg, tmp);
}

static int rf69_clear_bit(struct spi_device *spi, u8 reg, u8 mask)
{
	u8 tmp;

	tmp = rf69_read_reg(spi, reg);
	tmp = tmp & ~mask;
	return rf69_write_reg(spi, reg, tmp);
}

static inline int rf69_read_mod_write(struct spi_device *spi, u8 reg,
				      u8 mask, u8 value)
{
	u8 tmp;

	tmp = rf69_read_reg(spi, reg);
	tmp = (tmp & ~mask) | value;
	return rf69_write_reg(spi, reg, tmp);
}

/*-------------------------------------------------------------------------*/

int rf69_get_version(struct spi_device *spi)
{
	return rf69_read_reg(spi, REG_VERSION);
}

int rf69_set_mode(struct spi_device *spi, enum mode mode)
{
	static const u8 mode_map[] = {
		[transmit] = OPMODE_MODE_TRANSMIT,
		[receive] = OPMODE_MODE_RECEIVE,
		[synthesizer] = OPMODE_MODE_SYNTHESIZER,
		[standby] = OPMODE_MODE_STANDBY,
		[mode_sleep] = OPMODE_MODE_SLEEP,
	};

	if (unlikely(mode >= ARRAY_SIZE(mode_map))) {
		dev_dbg(&spi->dev, "set: illegal mode %u\n", mode);
		return -EINVAL;
	}

	return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE,
				   mode_map[mode]);

	/*
	 * we are using packet mode, so this check is not really needed
	 * but waiting for mode ready is necessary when going from sleep
	 * because the FIFO may not be immediately available from previous mode
	 * while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) &
		  RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady
	 */
}

int rf69_set_data_mode(struct spi_device *spi, u8 data_mode)
{
	return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODE,
				   data_mode);
}

int rf69_set_modulation(struct spi_device *spi, enum modulation modulation)
{
	static const u8 modulation_map[] = {
		[OOK] = DATAMODUL_MODULATION_TYPE_OOK,
		[FSK] = DATAMODUL_MODULATION_TYPE_FSK,
	};

	if (unlikely(modulation >= ARRAY_SIZE(modulation_map))) {
		dev_dbg(&spi->dev, "set: illegal modulation %u\n", modulation);
		return -EINVAL;
	}

	return rf69_read_mod_write(spi, REG_DATAMODUL,
				   MASK_DATAMODUL_MODULATION_TYPE,
				   modulation_map[modulation]);
}

static enum modulation rf69_get_modulation(struct spi_device *spi)
{
	u8 modulation_reg;

	modulation_reg = rf69_read_reg(spi, REG_DATAMODUL);

	switch (modulation_reg & MASK_DATAMODUL_MODULATION_TYPE) {
	case DATAMODUL_MODULATION_TYPE_OOK:
		return OOK;
	case DATAMODUL_MODULATION_TYPE_FSK:
		return FSK;
	default:
		return UNDEF;
	}
}

int rf69_set_modulation_shaping(struct spi_device *spi,
				enum mod_shaping mod_shaping)
{
	switch (rf69_get_modulation(spi)) {
	case FSK:
		switch (mod_shaping) {
		case SHAPING_OFF:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_NONE);
		case SHAPING_1_0:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_1_0);
		case SHAPING_0_5:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_0_5);
		case SHAPING_0_3:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_0_3);
		default:
			dev_dbg(&spi->dev, "set: illegal mod shaping for FSK %u\n", mod_shaping);
			return -EINVAL;
		}
	case OOK:
		switch (mod_shaping) {
		case SHAPING_OFF:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_NONE);
		case SHAPING_BR:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_BR);
		case SHAPING_2BR:
			return rf69_read_mod_write(spi, REG_DATAMODUL,
						   MASK_DATAMODUL_MODULATION_SHAPE,
						   DATAMODUL_MODULATION_SHAPE_2BR);
		default:
			dev_dbg(&spi->dev, "set: illegal mod shaping for OOK %u\n", mod_shaping);
			return -EINVAL;
		}
	default:
		dev_dbg(&spi->dev, "set: modulation undefined\n");
		return -EINVAL;
	}
}

int rf69_set_bit_rate(struct spi_device *spi, u16 bit_rate)
{
	int retval;
	u32 bit_rate_reg;
	u8 msb;
	u8 lsb;
	enum modulation mod;

	// check if modulation is configured
	mod = rf69_get_modulation(spi);
	if (mod == UNDEF) {
		dev_dbg(&spi->dev, "setBitRate: modulation is undefined\n");
		return -EINVAL;
	}

	// check input value
	if (bit_rate < 1200 || (mod == OOK && bit_rate > 32768)) {
		dev_dbg(&spi->dev, "setBitRate: illegal input param\n");
		return -EINVAL;
	}

	// calculate reg settings
	bit_rate_reg = (F_OSC / bit_rate);

	msb = (bit_rate_reg & 0xff00) >> 8;
	lsb = (bit_rate_reg & 0xff);

	// transmit to RF 69
	retval = rf69_write_reg(spi, REG_BITRATE_MSB, msb);
	if (retval)
		return retval;
	retval = rf69_write_reg(spi, REG_BITRATE_LSB, lsb);
	if (retval)
		return retval;

	return 0;
}

int rf69_set_deviation(struct spi_device *spi, u32 deviation)
{
	int retval;
	u64 f_reg;
	u64 f_step;
	u32 bit_rate_reg;
	u32 bit_rate;
	u8 msb;
	u8 lsb;
	u64 factor = 1000000; // to improve precision of calculation

	// calculate bit rate
	bit_rate_reg = rf69_read_reg(spi, REG_BITRATE_MSB) << 8;
	bit_rate_reg |= rf69_read_reg(spi, REG_BITRATE_LSB);
	bit_rate = F_OSC / bit_rate_reg;

	/*
	 * frequency deviation must exceed 600 Hz but not exceed
	 * 500kHz when taking bitrate dependency into consideration
	 * to ensure proper modulation
	 */
	if (deviation < 600 || (deviation + (bit_rate / 2)) > 500000) {
		dev_dbg(&spi->dev,
			"set_deviation: illegal input param: %u\n", deviation);
		return -EINVAL;
	}

	// calculat f step
	f_step = F_OSC * factor;
	do_div(f_step, 524288); //  524288 = 2^19

	// calculate register settings
	f_reg = deviation * factor;
	do_div(f_reg, f_step);

	msb = (f_reg & 0xff00) >> 8;
	lsb = (f_reg & 0xff);

	// check msb
	if (msb & ~FDEVMASB_MASK) {
		dev_dbg(&spi->dev, "set_deviation: err in calc of msb\n");
		return -EINVAL;
	}

	// write to chip
	retval = rf69_write_reg(spi, REG_FDEV_MSB, msb);
	if (retval)
		return retval;
	retval = rf69_write_reg(spi, REG_FDEV_LSB, lsb);
	if (retval)
		return retval;

	return 0;
}

int rf69_set_frequency(struct spi_device *spi, u32 frequency)
{
	int retval;
	u32 f_max;
	u64 f_reg;
	u64 f_step;
	u8 msb;
	u8 mid;
	u8 lsb;
	u64 factor = 1000000; // to improve precision of calculation

	// calculat f step
	f_step = F_OSC * factor;
	do_div(f_step, 524288); //  524288 = 2^19

	// check input value
	f_max = div_u64(f_step * 8388608, factor);
	if (frequency > f_max) {
		dev_dbg(&spi->dev, "setFrequency: illegal input param\n");
		return -EINVAL;
	}

	// calculate reg settings
	f_reg = frequency * factor;
	do_div(f_reg, f_step);

	msb = (f_reg & 0xff0000) >> 16;
	mid = (f_reg & 0xff00)   >>  8;
	lsb = (f_reg & 0xff);

	// write to chip
	retval = rf69_write_reg(spi, REG_FRF_MSB, msb);
	if (retval)
		return retval;
	retval = rf69_write_reg(spi, REG_FRF_MID, mid);
	if (retval)
		return retval;
	retval = rf69_write_reg(spi, REG_FRF_LSB, lsb);
	if (retval)
		return retval;

	return 0;
}

int rf69_enable_amplifier(struct spi_device *spi, u8 amplifier_mask)
{
	return rf69_set_bit(spi, REG_PALEVEL, amplifier_mask);
}

int rf69_disable_amplifier(struct spi_device *spi, u8 amplifier_mask)
{
	return rf69_clear_bit(spi, REG_PALEVEL, amplifier_mask);
}

int rf69_set_output_power_level(struct spi_device *spi, u8 power_level)
{
	u8 pa_level, ocp, test_pa1, test_pa2;
	bool pa0, pa1, pa2, high_power;
	u8 min_power_level;

	// check register pa_level
	pa_level = rf69_read_reg(spi, REG_PALEVEL);
	pa0 = pa_level & MASK_PALEVEL_PA0;
	pa1 = pa_level & MASK_PALEVEL_PA1;
	pa2 = pa_level & MASK_PALEVEL_PA2;

	// check high power mode
	ocp = rf69_read_reg(spi, REG_OCP);
	test_pa1 = rf69_read_reg(spi, REG_TESTPA1);
	test_pa2 = rf69_read_reg(spi, REG_TESTPA2);
	high_power = (ocp == 0x0f) && (test_pa1 == 0x5d) && (test_pa2 == 0x7c);

	if (pa0 && !pa1 && !pa2) {
		power_level += 18;
		min_power_level = 0;
	} else if (!pa0 && pa1 && !pa2) {
		power_level += 18;
		min_power_level = 16;
	} else if (!pa0 && pa1 && pa2) {
		if (high_power)
			power_level += 11;
		else
			power_level += 14;
		min_power_level = 16;
	} else {
		goto failed;
	}

	// check input value
	if (power_level > 0x1f)
		goto failed;

	if (power_level < min_power_level)
		goto failed;

	// write value
	return rf69_read_mod_write(spi, REG_PALEVEL, MASK_PALEVEL_OUTPUT_POWER,
				   power_level);
failed:
	dev_dbg(&spi->dev, "set: illegal power level %u\n", power_level);
	return -EINVAL;
}

int rf69_set_pa_ramp(struct spi_device *spi, enum pa_ramp pa_ramp)
{
	static const u8 pa_ramp_map[] = {
		[ramp3400] = PARAMP_3400,
		[ramp2000] = PARAMP_2000,
		[ramp1000] = PARAMP_1000,
		[ramp500] = PARAMP_500,
		[ramp250] = PARAMP_250,
		[ramp125] = PARAMP_125,
		[ramp100] = PARAMP_100,
		[ramp62] = PARAMP_62,
		[ramp50] = PARAMP_50,
		[ramp40] = PARAMP_40,
		[ramp31] = PARAMP_31,
		[ramp25] = PARAMP_25,
		[ramp20] = PARAMP_20,
		[ramp15] = PARAMP_15,
		[ramp10] = PARAMP_10,
	};

	if (unlikely(pa_ramp >= ARRAY_SIZE(pa_ramp_map))) {
		dev_dbg(&spi->dev, "set: illegal pa_ramp %u\n", pa_ramp);
		return -EINVAL;
	}

	return rf69_write_reg(spi, REG_PARAMP, pa_ramp_map[pa_ramp]);
}

int rf69_set_antenna_impedance(struct spi_device *spi,
			       enum antenna_impedance antenna_impedance)
{
	switch (antenna_impedance) {
	case fifty_ohm:
		return rf69_clear_bit(spi, REG_LNA, MASK_LNA_ZIN);
	case two_hundred_ohm:
		return rf69_set_bit(spi, REG_LNA, MASK_LNA_ZIN);
	default:
		dev_dbg(&spi->dev, "set: illegal antenna impedance %u\n", antenna_impedance);
		return -EINVAL;
	}
}

int rf69_set_lna_gain(struct spi_device *spi, enum lna_gain lna_gain)
{
	static const u8 lna_gain_map[] = {
		[automatic] = LNA_GAIN_AUTO,
		[max] = LNA_GAIN_MAX,
		[max_minus_6] = LNA_GAIN_MAX_MINUS_6,
		[max_minus_12] = LNA_GAIN_MAX_MINUS_12,
		[max_minus_24] = LNA_GAIN_MAX_MINUS_24,
		[max_minus_36] = LNA_GAIN_MAX_MINUS_36,
		[max_minus_48] = LNA_GAIN_MAX_MINUS_48,
	};

	if (unlikely(lna_gain >= ARRAY_SIZE(lna_gain_map))) {
		dev_dbg(&spi->dev, "set: illegal lna gain %u\n", lna_gain);
		return -EINVAL;
	}

	return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN,
				   lna_gain_map[lna_gain]);
}

static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg,
				     enum mantisse mantisse, u8 exponent)
{
	u8 bandwidth;

	// check value for mantisse and exponent
	if (exponent > 7) {
		dev_dbg(&spi->dev, "set: illegal bandwidth exponent %u\n", exponent);
		return -EINVAL;
	}

	if (mantisse != mantisse16 &&
	    mantisse != mantisse20 &&
	    mantisse != mantisse24) {
		dev_dbg(&spi->dev, "set: illegal bandwidth mantisse %u\n", mantisse);
		return -EINVAL;
	}

	// read old value
	bandwidth = rf69_read_reg(spi, reg);

	// "delete" mantisse and exponent = just keep the DCC setting
	bandwidth = bandwidth & MASK_BW_DCC_FREQ;

	// add new mantisse
	switch (mantisse) {
	case mantisse16:
		bandwidth = bandwidth | BW_MANT_16;
		break;
	case mantisse20:
		bandwidth = bandwidth | BW_MANT_20;
		break;
	case mantisse24:
		bandwidth = bandwidth | BW_MANT_24;
		break;
	}

	// add new exponent
	bandwidth = bandwidth | exponent;

	// write back
	return rf69_write_reg(spi, reg, bandwidth);
}

int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse,
		       u8 exponent)
{
	return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent);
}

int rf69_set_bandwidth_during_afc(struct spi_device *spi,
				  enum mantisse mantisse,
				  u8 exponent)
{
	return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent);
}

int rf69_set_ook_threshold_dec(struct spi_device *spi,
			       enum threshold_decrement threshold_decrement)
{
	static const u8 td_map[] = {
		[dec_every8th] = OOKPEAK_THRESHDEC_EVERY_8TH,
		[dec_every4th] = OOKPEAK_THRESHDEC_EVERY_4TH,
		[dec_every2nd] = OOKPEAK_THRESHDEC_EVERY_2ND,
		[dec_once] = OOKPEAK_THRESHDEC_ONCE,
		[dec_twice] = OOKPEAK_THRESHDEC_TWICE,
		[dec_4times] = OOKPEAK_THRESHDEC_4_TIMES,
		[dec_8times] = OOKPEAK_THRESHDEC_8_TIMES,
		[dec_16times] = OOKPEAK_THRESHDEC_16_TIMES,
	};

	if (unlikely(threshold_decrement >= ARRAY_SIZE(td_map))) {
		dev_dbg(&spi->dev, "set: illegal OOK threshold decrement %u\n",
			threshold_decrement);
		return -EINVAL;
	}

	return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC,
				   td_map[threshold_decrement]);
}

int rf69_set_dio_mapping(struct spi_device *spi, u8 dio_number, u8 value)
{
	u8 mask;
	u8 shift;
	u8 dio_addr;
	u8 dio_value;

	switch (dio_number) {
	case 0:
		mask = MASK_DIO0;
		shift = SHIFT_DIO0;
		dio_addr = REG_DIOMAPPING1;
		break;
	case 1:
		mask = MASK_DIO1;
		shift = SHIFT_DIO1;
		dio_addr = REG_DIOMAPPING1;
		break;
	case 2:
		mask = MASK_DIO2;
		shift = SHIFT_DIO2;
		dio_addr = REG_DIOMAPPING1;
		break;
	case 3:
		mask = MASK_DIO3;
		shift = SHIFT_DIO3;
		dio_addr = REG_DIOMAPPING1;
		break;
	case 4:
		mask = MASK_DIO4;
		shift = SHIFT_DIO4;
		dio_addr = REG_DIOMAPPING2;
		break;
	case 5:
		mask = MASK_DIO5;
		shift = SHIFT_DIO5;
		dio_addr = REG_DIOMAPPING2;
		break;
	default:
		dev_dbg(&spi->dev, "set: illegal dio number %u\n", dio_number);
		return -EINVAL;
	}

	// read reg
	dio_value = rf69_read_reg(spi, dio_addr);
	// delete old value
	dio_value = dio_value & ~mask;
	// add new value
	dio_value = dio_value | value << shift;
	// write back
	return rf69_write_reg(spi, dio_addr, dio_value);
}

int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold)
{
	/* no value check needed - u8 exactly matches register size */

	return rf69_write_reg(spi, REG_RSSITHRESH, threshold);
}

int rf69_set_preamble_length(struct spi_device *spi, u16 preamble_length)
{
	int retval;
	u8 msb, lsb;

	/* no value check needed - u16 exactly matches register size */

	/* calculate reg settings */
	msb = (preamble_length & 0xff00) >> 8;
	lsb = (preamble_length & 0xff);

	/* transmit to chip */
	retval = rf69_write_reg(spi, REG_PREAMBLE_MSB, msb);
	if (retval)
		return retval;
	return rf69_write_reg(spi, REG_PREAMBLE_LSB, lsb);
}

int rf69_enable_sync(struct spi_device *spi)
{
	return rf69_set_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON);
}

int rf69_disable_sync(struct spi_device *spi)
{
	return rf69_clear_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON);
}

int rf69_set_fifo_fill_condition(struct spi_device *spi,
				 enum fifo_fill_condition fifo_fill_condition)
{
	switch (fifo_fill_condition) {
	case always:
		return rf69_set_bit(spi, REG_SYNC_CONFIG,
				    MASK_SYNC_CONFIG_FIFO_FILL_CONDITION);
	case after_sync_interrupt:
		return rf69_clear_bit(spi, REG_SYNC_CONFIG,
				      MASK_SYNC_CONFIG_FIFO_FILL_CONDITION);
	default:
		dev_dbg(&spi->dev, "set: illegal fifo fill condition %u\n", fifo_fill_condition);
		return -EINVAL;
	}
}

int rf69_set_sync_size(struct spi_device *spi, u8 sync_size)
{
	// check input value
	if (sync_size > 0x07) {
		dev_dbg(&spi->dev, "set: illegal sync size %u\n", sync_size);
		return -EINVAL;
	}

	// write value
	return rf69_read_mod_write(spi, REG_SYNC_CONFIG,
				   MASK_SYNC_CONFIG_SYNC_SIZE,
				   (sync_size << 3));
}

int rf69_set_sync_values(struct spi_device *spi, u8 sync_values[8])
{
	int retval = 0;

	retval += rf69_write_reg(spi, REG_SYNCVALUE1, sync_values[0]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE2, sync_values[1]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE3, sync_values[2]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE4, sync_values[3]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE5, sync_values[4]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE6, sync_values[5]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE7, sync_values[6]);
	retval += rf69_write_reg(spi, REG_SYNCVALUE8, sync_values[7]);

	return retval;
}

int rf69_set_packet_format(struct spi_device *spi,
			   enum packet_format packet_format)
{
	switch (packet_format) {
	case packet_length_var:
		return rf69_set_bit(spi, REG_PACKETCONFIG1,
				    MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE);
	case packet_length_fix:
		return rf69_clear_bit(spi, REG_PACKETCONFIG1,
				      MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE);
	default:
		dev_dbg(&spi->dev, "set: illegal packet format %u\n", packet_format);
		return -EINVAL;
	}
}

int rf69_enable_crc(struct spi_device *spi)
{
	return rf69_set_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON);
}

int rf69_disable_crc(struct spi_device *spi)
{
	return rf69_clear_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON);
}

int rf69_set_address_filtering(struct spi_device *spi,
			       enum address_filtering address_filtering)
{
	static const u8 af_map[] = {
		[filtering_off] = PACKETCONFIG1_ADDRESSFILTERING_OFF,
		[node_address] = PACKETCONFIG1_ADDRESSFILTERING_NODE,
		[node_or_broadcast_address] =
			PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST,
	};

	if (unlikely(address_filtering >= ARRAY_SIZE(af_map))) {
		dev_dbg(&spi->dev, "set: illegal address filtering %u\n", address_filtering);
		return -EINVAL;
	}

	return rf69_read_mod_write(spi, REG_PACKETCONFIG1,
				   MASK_PACKETCONFIG1_ADDRESSFILTERING,
				   af_map[address_filtering]);
}

int rf69_set_payload_length(struct spi_device *spi, u8 payload_length)
{
	return rf69_write_reg(spi, REG_PAYLOAD_LENGTH, payload_length);
}

int rf69_set_node_address(struct spi_device *spi, u8 node_address)
{
	return rf69_write_reg(spi, REG_NODEADRS, node_address);
}

int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcast_address)
{
	return rf69_write_reg(spi, REG_BROADCASTADRS, broadcast_address);
}

int rf69_set_tx_start_condition(struct spi_device *spi,
				enum tx_start_condition tx_start_condition)
{
	switch (tx_start_condition) {
	case fifo_level:
		return rf69_clear_bit(spi, REG_FIFO_THRESH,
				      MASK_FIFO_THRESH_TXSTART);
	case fifo_not_empty:
		return rf69_set_bit(spi, REG_FIFO_THRESH,
				    MASK_FIFO_THRESH_TXSTART);
	default:
		dev_dbg(&spi->dev, "set: illegal tx start condition %u\n", tx_start_condition);
		return -EINVAL;
	}
}

int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold)
{
	int retval;

	/* check input value */
	if (threshold & ~MASK_FIFO_THRESH_VALUE) {
		dev_dbg(&spi->dev, "set: illegal fifo threshold %u\n", threshold);
		return -EINVAL;
	}

	/* write value */
	retval = rf69_read_mod_write(spi, REG_FIFO_THRESH,
				     MASK_FIFO_THRESH_VALUE,
				     threshold);
	if (retval)
		return retval;

	/*
	 * access the fifo to activate new threshold
	 * retval (mis-) used as buffer here
	 */
	return rf69_read_fifo(spi, (u8 *)&retval, 1);
}

int rf69_set_dagc(struct spi_device *spi, enum dagc dagc)
{
	static const u8 dagc_map[] = {
		[normal_mode] = DAGC_NORMAL,
		[improve] = DAGC_IMPROVED_LOWBETA0,
		[improve_for_low_modulation_index] = DAGC_IMPROVED_LOWBETA1,
	};

	if (unlikely(dagc >= ARRAY_SIZE(dagc_map))) {
		dev_dbg(&spi->dev, "set: illegal dagc %u\n", dagc);
		return -EINVAL;
	}

	return rf69_write_reg(spi, REG_TESTDAGC, dagc_map[dagc]);
}

/*-------------------------------------------------------------------------*/

int rf69_read_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
{
	int i;
	struct spi_transfer transfer;
	u8 local_buffer[FIFO_SIZE + 1] = {};
	int retval;

	if (size > FIFO_SIZE) {
		dev_dbg(&spi->dev,
			"read fifo: passed in buffer bigger then internal buffer\n");
		return -EMSGSIZE;
	}

	/* prepare a bidirectional transfer */
	local_buffer[0] = REG_FIFO;
	memset(&transfer, 0, sizeof(transfer));
	transfer.tx_buf = local_buffer;
	transfer.rx_buf = local_buffer;
	transfer.len	= size + 1;

	retval = spi_sync_transfer(spi, &transfer, 1);

	/* print content read from fifo for debugging purposes */
	for (i = 0; i < size; i++)
		dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i + 1]);

	memcpy(buffer, &local_buffer[1], size);

	return retval;
}

int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
{
	int i;
	u8 local_buffer[FIFO_SIZE + 1];

	if (size > FIFO_SIZE) {
		dev_dbg(&spi->dev,
			"read fifo: passed in buffer bigger then internal buffer\n");
		return -EMSGSIZE;
	}

	local_buffer[0] = REG_FIFO | WRITE_BIT;
	memcpy(&local_buffer[1], buffer, size);

	/* print content written from fifo for debugging purposes */
	for (i = 0; i < size; i++)
		dev_dbg(&spi->dev, "%d - 0x%x\n", i, buffer[i]);

	return spi_write(spi, local_buffer, size + 1);
}

