cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rf69.c (21104B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * abstraction of the spi interface of HopeRf rf69 radio module
      4 *
      5 * Copyright (C) 2016 Wolf-Entwicklungen
      6 *	Marcus Wolf <linux@wolf-entwicklungen.de>
      7 */
      8
      9#include <linux/types.h>
     10#include <linux/spi/spi.h>
     11
     12#include "rf69.h"
     13#include "rf69_registers.h"
     14
     15#define F_OSC	  32000000 /* in Hz */
     16#define FIFO_SIZE 66	   /* in byte */
     17
     18/*-------------------------------------------------------------------------*/
     19
     20u8 rf69_read_reg(struct spi_device *spi, u8 addr)
     21{
     22	return spi_w8r8(spi, addr);
     23}
     24
     25static int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value)
     26{
     27	char buffer[2];
     28
     29	buffer[0] = addr | WRITE_BIT;
     30	buffer[1] = value;
     31
     32	return spi_write(spi, &buffer, ARRAY_SIZE(buffer));
     33}
     34
     35/*-------------------------------------------------------------------------*/
     36
     37static int rf69_set_bit(struct spi_device *spi, u8 reg, u8 mask)
     38{
     39	u8 tmp;
     40
     41	tmp = rf69_read_reg(spi, reg);
     42	tmp = tmp | mask;
     43	return rf69_write_reg(spi, reg, tmp);
     44}
     45
     46static int rf69_clear_bit(struct spi_device *spi, u8 reg, u8 mask)
     47{
     48	u8 tmp;
     49
     50	tmp = rf69_read_reg(spi, reg);
     51	tmp = tmp & ~mask;
     52	return rf69_write_reg(spi, reg, tmp);
     53}
     54
     55static inline int rf69_read_mod_write(struct spi_device *spi, u8 reg,
     56				      u8 mask, u8 value)
     57{
     58	u8 tmp;
     59
     60	tmp = rf69_read_reg(spi, reg);
     61	tmp = (tmp & ~mask) | value;
     62	return rf69_write_reg(spi, reg, tmp);
     63}
     64
     65/*-------------------------------------------------------------------------*/
     66
     67int rf69_get_version(struct spi_device *spi)
     68{
     69	return rf69_read_reg(spi, REG_VERSION);
     70}
     71
     72int rf69_set_mode(struct spi_device *spi, enum mode mode)
     73{
     74	static const u8 mode_map[] = {
     75		[transmit] = OPMODE_MODE_TRANSMIT,
     76		[receive] = OPMODE_MODE_RECEIVE,
     77		[synthesizer] = OPMODE_MODE_SYNTHESIZER,
     78		[standby] = OPMODE_MODE_STANDBY,
     79		[mode_sleep] = OPMODE_MODE_SLEEP,
     80	};
     81
     82	if (unlikely(mode >= ARRAY_SIZE(mode_map))) {
     83		dev_dbg(&spi->dev, "set: illegal mode %u\n", mode);
     84		return -EINVAL;
     85	}
     86
     87	return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE,
     88				   mode_map[mode]);
     89
     90	/*
     91	 * we are using packet mode, so this check is not really needed
     92	 * but waiting for mode ready is necessary when going from sleep
     93	 * because the FIFO may not be immediately available from previous mode
     94	 * while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) &
     95		  RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady
     96	 */
     97}
     98
     99int rf69_set_data_mode(struct spi_device *spi, u8 data_mode)
    100{
    101	return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODE,
    102				   data_mode);
    103}
    104
    105int rf69_set_modulation(struct spi_device *spi, enum modulation modulation)
    106{
    107	static const u8 modulation_map[] = {
    108		[OOK] = DATAMODUL_MODULATION_TYPE_OOK,
    109		[FSK] = DATAMODUL_MODULATION_TYPE_FSK,
    110	};
    111
    112	if (unlikely(modulation >= ARRAY_SIZE(modulation_map))) {
    113		dev_dbg(&spi->dev, "set: illegal modulation %u\n", modulation);
    114		return -EINVAL;
    115	}
    116
    117	return rf69_read_mod_write(spi, REG_DATAMODUL,
    118				   MASK_DATAMODUL_MODULATION_TYPE,
    119				   modulation_map[modulation]);
    120}
    121
    122static enum modulation rf69_get_modulation(struct spi_device *spi)
    123{
    124	u8 modulation_reg;
    125
    126	modulation_reg = rf69_read_reg(spi, REG_DATAMODUL);
    127
    128	switch (modulation_reg & MASK_DATAMODUL_MODULATION_TYPE) {
    129	case DATAMODUL_MODULATION_TYPE_OOK:
    130		return OOK;
    131	case DATAMODUL_MODULATION_TYPE_FSK:
    132		return FSK;
    133	default:
    134		return UNDEF;
    135	}
    136}
    137
    138int rf69_set_modulation_shaping(struct spi_device *spi,
    139				enum mod_shaping mod_shaping)
    140{
    141	switch (rf69_get_modulation(spi)) {
    142	case FSK:
    143		switch (mod_shaping) {
    144		case SHAPING_OFF:
    145			return rf69_read_mod_write(spi, REG_DATAMODUL,
    146						   MASK_DATAMODUL_MODULATION_SHAPE,
    147						   DATAMODUL_MODULATION_SHAPE_NONE);
    148		case SHAPING_1_0:
    149			return rf69_read_mod_write(spi, REG_DATAMODUL,
    150						   MASK_DATAMODUL_MODULATION_SHAPE,
    151						   DATAMODUL_MODULATION_SHAPE_1_0);
    152		case SHAPING_0_5:
    153			return rf69_read_mod_write(spi, REG_DATAMODUL,
    154						   MASK_DATAMODUL_MODULATION_SHAPE,
    155						   DATAMODUL_MODULATION_SHAPE_0_5);
    156		case SHAPING_0_3:
    157			return rf69_read_mod_write(spi, REG_DATAMODUL,
    158						   MASK_DATAMODUL_MODULATION_SHAPE,
    159						   DATAMODUL_MODULATION_SHAPE_0_3);
    160		default:
    161			dev_dbg(&spi->dev, "set: illegal mod shaping for FSK %u\n", mod_shaping);
    162			return -EINVAL;
    163		}
    164	case OOK:
    165		switch (mod_shaping) {
    166		case SHAPING_OFF:
    167			return rf69_read_mod_write(spi, REG_DATAMODUL,
    168						   MASK_DATAMODUL_MODULATION_SHAPE,
    169						   DATAMODUL_MODULATION_SHAPE_NONE);
    170		case SHAPING_BR:
    171			return rf69_read_mod_write(spi, REG_DATAMODUL,
    172						   MASK_DATAMODUL_MODULATION_SHAPE,
    173						   DATAMODUL_MODULATION_SHAPE_BR);
    174		case SHAPING_2BR:
    175			return rf69_read_mod_write(spi, REG_DATAMODUL,
    176						   MASK_DATAMODUL_MODULATION_SHAPE,
    177						   DATAMODUL_MODULATION_SHAPE_2BR);
    178		default:
    179			dev_dbg(&spi->dev, "set: illegal mod shaping for OOK %u\n", mod_shaping);
    180			return -EINVAL;
    181		}
    182	default:
    183		dev_dbg(&spi->dev, "set: modulation undefined\n");
    184		return -EINVAL;
    185	}
    186}
    187
    188int rf69_set_bit_rate(struct spi_device *spi, u16 bit_rate)
    189{
    190	int retval;
    191	u32 bit_rate_reg;
    192	u8 msb;
    193	u8 lsb;
    194	enum modulation mod;
    195
    196	// check if modulation is configured
    197	mod = rf69_get_modulation(spi);
    198	if (mod == UNDEF) {
    199		dev_dbg(&spi->dev, "setBitRate: modulation is undefined\n");
    200		return -EINVAL;
    201	}
    202
    203	// check input value
    204	if (bit_rate < 1200 || (mod == OOK && bit_rate > 32768)) {
    205		dev_dbg(&spi->dev, "setBitRate: illegal input param\n");
    206		return -EINVAL;
    207	}
    208
    209	// calculate reg settings
    210	bit_rate_reg = (F_OSC / bit_rate);
    211
    212	msb = (bit_rate_reg & 0xff00) >> 8;
    213	lsb = (bit_rate_reg & 0xff);
    214
    215	// transmit to RF 69
    216	retval = rf69_write_reg(spi, REG_BITRATE_MSB, msb);
    217	if (retval)
    218		return retval;
    219	retval = rf69_write_reg(spi, REG_BITRATE_LSB, lsb);
    220	if (retval)
    221		return retval;
    222
    223	return 0;
    224}
    225
    226int rf69_set_deviation(struct spi_device *spi, u32 deviation)
    227{
    228	int retval;
    229	u64 f_reg;
    230	u64 f_step;
    231	u32 bit_rate_reg;
    232	u32 bit_rate;
    233	u8 msb;
    234	u8 lsb;
    235	u64 factor = 1000000; // to improve precision of calculation
    236
    237	// calculate bit rate
    238	bit_rate_reg = rf69_read_reg(spi, REG_BITRATE_MSB) << 8;
    239	bit_rate_reg |= rf69_read_reg(spi, REG_BITRATE_LSB);
    240	bit_rate = F_OSC / bit_rate_reg;
    241
    242	/*
    243	 * frequency deviation must exceed 600 Hz but not exceed
    244	 * 500kHz when taking bitrate dependency into consideration
    245	 * to ensure proper modulation
    246	 */
    247	if (deviation < 600 || (deviation + (bit_rate / 2)) > 500000) {
    248		dev_dbg(&spi->dev,
    249			"set_deviation: illegal input param: %u\n", deviation);
    250		return -EINVAL;
    251	}
    252
    253	// calculat f step
    254	f_step = F_OSC * factor;
    255	do_div(f_step, 524288); //  524288 = 2^19
    256
    257	// calculate register settings
    258	f_reg = deviation * factor;
    259	do_div(f_reg, f_step);
    260
    261	msb = (f_reg & 0xff00) >> 8;
    262	lsb = (f_reg & 0xff);
    263
    264	// check msb
    265	if (msb & ~FDEVMASB_MASK) {
    266		dev_dbg(&spi->dev, "set_deviation: err in calc of msb\n");
    267		return -EINVAL;
    268	}
    269
    270	// write to chip
    271	retval = rf69_write_reg(spi, REG_FDEV_MSB, msb);
    272	if (retval)
    273		return retval;
    274	retval = rf69_write_reg(spi, REG_FDEV_LSB, lsb);
    275	if (retval)
    276		return retval;
    277
    278	return 0;
    279}
    280
    281int rf69_set_frequency(struct spi_device *spi, u32 frequency)
    282{
    283	int retval;
    284	u32 f_max;
    285	u64 f_reg;
    286	u64 f_step;
    287	u8 msb;
    288	u8 mid;
    289	u8 lsb;
    290	u64 factor = 1000000; // to improve precision of calculation
    291
    292	// calculat f step
    293	f_step = F_OSC * factor;
    294	do_div(f_step, 524288); //  524288 = 2^19
    295
    296	// check input value
    297	f_max = div_u64(f_step * 8388608, factor);
    298	if (frequency > f_max) {
    299		dev_dbg(&spi->dev, "setFrequency: illegal input param\n");
    300		return -EINVAL;
    301	}
    302
    303	// calculate reg settings
    304	f_reg = frequency * factor;
    305	do_div(f_reg, f_step);
    306
    307	msb = (f_reg & 0xff0000) >> 16;
    308	mid = (f_reg & 0xff00)   >>  8;
    309	lsb = (f_reg & 0xff);
    310
    311	// write to chip
    312	retval = rf69_write_reg(spi, REG_FRF_MSB, msb);
    313	if (retval)
    314		return retval;
    315	retval = rf69_write_reg(spi, REG_FRF_MID, mid);
    316	if (retval)
    317		return retval;
    318	retval = rf69_write_reg(spi, REG_FRF_LSB, lsb);
    319	if (retval)
    320		return retval;
    321
    322	return 0;
    323}
    324
    325int rf69_enable_amplifier(struct spi_device *spi, u8 amplifier_mask)
    326{
    327	return rf69_set_bit(spi, REG_PALEVEL, amplifier_mask);
    328}
    329
    330int rf69_disable_amplifier(struct spi_device *spi, u8 amplifier_mask)
    331{
    332	return rf69_clear_bit(spi, REG_PALEVEL, amplifier_mask);
    333}
    334
    335int rf69_set_output_power_level(struct spi_device *spi, u8 power_level)
    336{
    337	u8 pa_level, ocp, test_pa1, test_pa2;
    338	bool pa0, pa1, pa2, high_power;
    339	u8 min_power_level;
    340
    341	// check register pa_level
    342	pa_level = rf69_read_reg(spi, REG_PALEVEL);
    343	pa0 = pa_level & MASK_PALEVEL_PA0;
    344	pa1 = pa_level & MASK_PALEVEL_PA1;
    345	pa2 = pa_level & MASK_PALEVEL_PA2;
    346
    347	// check high power mode
    348	ocp = rf69_read_reg(spi, REG_OCP);
    349	test_pa1 = rf69_read_reg(spi, REG_TESTPA1);
    350	test_pa2 = rf69_read_reg(spi, REG_TESTPA2);
    351	high_power = (ocp == 0x0f) && (test_pa1 == 0x5d) && (test_pa2 == 0x7c);
    352
    353	if (pa0 && !pa1 && !pa2) {
    354		power_level += 18;
    355		min_power_level = 0;
    356	} else if (!pa0 && pa1 && !pa2) {
    357		power_level += 18;
    358		min_power_level = 16;
    359	} else if (!pa0 && pa1 && pa2) {
    360		if (high_power)
    361			power_level += 11;
    362		else
    363			power_level += 14;
    364		min_power_level = 16;
    365	} else {
    366		goto failed;
    367	}
    368
    369	// check input value
    370	if (power_level > 0x1f)
    371		goto failed;
    372
    373	if (power_level < min_power_level)
    374		goto failed;
    375
    376	// write value
    377	return rf69_read_mod_write(spi, REG_PALEVEL, MASK_PALEVEL_OUTPUT_POWER,
    378				   power_level);
    379failed:
    380	dev_dbg(&spi->dev, "set: illegal power level %u\n", power_level);
    381	return -EINVAL;
    382}
    383
    384int rf69_set_pa_ramp(struct spi_device *spi, enum pa_ramp pa_ramp)
    385{
    386	static const u8 pa_ramp_map[] = {
    387		[ramp3400] = PARAMP_3400,
    388		[ramp2000] = PARAMP_2000,
    389		[ramp1000] = PARAMP_1000,
    390		[ramp500] = PARAMP_500,
    391		[ramp250] = PARAMP_250,
    392		[ramp125] = PARAMP_125,
    393		[ramp100] = PARAMP_100,
    394		[ramp62] = PARAMP_62,
    395		[ramp50] = PARAMP_50,
    396		[ramp40] = PARAMP_40,
    397		[ramp31] = PARAMP_31,
    398		[ramp25] = PARAMP_25,
    399		[ramp20] = PARAMP_20,
    400		[ramp15] = PARAMP_15,
    401		[ramp10] = PARAMP_10,
    402	};
    403
    404	if (unlikely(pa_ramp >= ARRAY_SIZE(pa_ramp_map))) {
    405		dev_dbg(&spi->dev, "set: illegal pa_ramp %u\n", pa_ramp);
    406		return -EINVAL;
    407	}
    408
    409	return rf69_write_reg(spi, REG_PARAMP, pa_ramp_map[pa_ramp]);
    410}
    411
    412int rf69_set_antenna_impedance(struct spi_device *spi,
    413			       enum antenna_impedance antenna_impedance)
    414{
    415	switch (antenna_impedance) {
    416	case fifty_ohm:
    417		return rf69_clear_bit(spi, REG_LNA, MASK_LNA_ZIN);
    418	case two_hundred_ohm:
    419		return rf69_set_bit(spi, REG_LNA, MASK_LNA_ZIN);
    420	default:
    421		dev_dbg(&spi->dev, "set: illegal antenna impedance %u\n", antenna_impedance);
    422		return -EINVAL;
    423	}
    424}
    425
    426int rf69_set_lna_gain(struct spi_device *spi, enum lna_gain lna_gain)
    427{
    428	static const u8 lna_gain_map[] = {
    429		[automatic] = LNA_GAIN_AUTO,
    430		[max] = LNA_GAIN_MAX,
    431		[max_minus_6] = LNA_GAIN_MAX_MINUS_6,
    432		[max_minus_12] = LNA_GAIN_MAX_MINUS_12,
    433		[max_minus_24] = LNA_GAIN_MAX_MINUS_24,
    434		[max_minus_36] = LNA_GAIN_MAX_MINUS_36,
    435		[max_minus_48] = LNA_GAIN_MAX_MINUS_48,
    436	};
    437
    438	if (unlikely(lna_gain >= ARRAY_SIZE(lna_gain_map))) {
    439		dev_dbg(&spi->dev, "set: illegal lna gain %u\n", lna_gain);
    440		return -EINVAL;
    441	}
    442
    443	return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN,
    444				   lna_gain_map[lna_gain]);
    445}
    446
    447static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg,
    448				     enum mantisse mantisse, u8 exponent)
    449{
    450	u8 bandwidth;
    451
    452	// check value for mantisse and exponent
    453	if (exponent > 7) {
    454		dev_dbg(&spi->dev, "set: illegal bandwidth exponent %u\n", exponent);
    455		return -EINVAL;
    456	}
    457
    458	if (mantisse != mantisse16 &&
    459	    mantisse != mantisse20 &&
    460	    mantisse != mantisse24) {
    461		dev_dbg(&spi->dev, "set: illegal bandwidth mantisse %u\n", mantisse);
    462		return -EINVAL;
    463	}
    464
    465	// read old value
    466	bandwidth = rf69_read_reg(spi, reg);
    467
    468	// "delete" mantisse and exponent = just keep the DCC setting
    469	bandwidth = bandwidth & MASK_BW_DCC_FREQ;
    470
    471	// add new mantisse
    472	switch (mantisse) {
    473	case mantisse16:
    474		bandwidth = bandwidth | BW_MANT_16;
    475		break;
    476	case mantisse20:
    477		bandwidth = bandwidth | BW_MANT_20;
    478		break;
    479	case mantisse24:
    480		bandwidth = bandwidth | BW_MANT_24;
    481		break;
    482	}
    483
    484	// add new exponent
    485	bandwidth = bandwidth | exponent;
    486
    487	// write back
    488	return rf69_write_reg(spi, reg, bandwidth);
    489}
    490
    491int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse,
    492		       u8 exponent)
    493{
    494	return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent);
    495}
    496
    497int rf69_set_bandwidth_during_afc(struct spi_device *spi,
    498				  enum mantisse mantisse,
    499				  u8 exponent)
    500{
    501	return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent);
    502}
    503
    504int rf69_set_ook_threshold_dec(struct spi_device *spi,
    505			       enum threshold_decrement threshold_decrement)
    506{
    507	static const u8 td_map[] = {
    508		[dec_every8th] = OOKPEAK_THRESHDEC_EVERY_8TH,
    509		[dec_every4th] = OOKPEAK_THRESHDEC_EVERY_4TH,
    510		[dec_every2nd] = OOKPEAK_THRESHDEC_EVERY_2ND,
    511		[dec_once] = OOKPEAK_THRESHDEC_ONCE,
    512		[dec_twice] = OOKPEAK_THRESHDEC_TWICE,
    513		[dec_4times] = OOKPEAK_THRESHDEC_4_TIMES,
    514		[dec_8times] = OOKPEAK_THRESHDEC_8_TIMES,
    515		[dec_16times] = OOKPEAK_THRESHDEC_16_TIMES,
    516	};
    517
    518	if (unlikely(threshold_decrement >= ARRAY_SIZE(td_map))) {
    519		dev_dbg(&spi->dev, "set: illegal OOK threshold decrement %u\n",
    520			threshold_decrement);
    521		return -EINVAL;
    522	}
    523
    524	return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC,
    525				   td_map[threshold_decrement]);
    526}
    527
    528int rf69_set_dio_mapping(struct spi_device *spi, u8 dio_number, u8 value)
    529{
    530	u8 mask;
    531	u8 shift;
    532	u8 dio_addr;
    533	u8 dio_value;
    534
    535	switch (dio_number) {
    536	case 0:
    537		mask = MASK_DIO0;
    538		shift = SHIFT_DIO0;
    539		dio_addr = REG_DIOMAPPING1;
    540		break;
    541	case 1:
    542		mask = MASK_DIO1;
    543		shift = SHIFT_DIO1;
    544		dio_addr = REG_DIOMAPPING1;
    545		break;
    546	case 2:
    547		mask = MASK_DIO2;
    548		shift = SHIFT_DIO2;
    549		dio_addr = REG_DIOMAPPING1;
    550		break;
    551	case 3:
    552		mask = MASK_DIO3;
    553		shift = SHIFT_DIO3;
    554		dio_addr = REG_DIOMAPPING1;
    555		break;
    556	case 4:
    557		mask = MASK_DIO4;
    558		shift = SHIFT_DIO4;
    559		dio_addr = REG_DIOMAPPING2;
    560		break;
    561	case 5:
    562		mask = MASK_DIO5;
    563		shift = SHIFT_DIO5;
    564		dio_addr = REG_DIOMAPPING2;
    565		break;
    566	default:
    567		dev_dbg(&spi->dev, "set: illegal dio number %u\n", dio_number);
    568		return -EINVAL;
    569	}
    570
    571	// read reg
    572	dio_value = rf69_read_reg(spi, dio_addr);
    573	// delete old value
    574	dio_value = dio_value & ~mask;
    575	// add new value
    576	dio_value = dio_value | value << shift;
    577	// write back
    578	return rf69_write_reg(spi, dio_addr, dio_value);
    579}
    580
    581int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold)
    582{
    583	/* no value check needed - u8 exactly matches register size */
    584
    585	return rf69_write_reg(spi, REG_RSSITHRESH, threshold);
    586}
    587
    588int rf69_set_preamble_length(struct spi_device *spi, u16 preamble_length)
    589{
    590	int retval;
    591	u8 msb, lsb;
    592
    593	/* no value check needed - u16 exactly matches register size */
    594
    595	/* calculate reg settings */
    596	msb = (preamble_length & 0xff00) >> 8;
    597	lsb = (preamble_length & 0xff);
    598
    599	/* transmit to chip */
    600	retval = rf69_write_reg(spi, REG_PREAMBLE_MSB, msb);
    601	if (retval)
    602		return retval;
    603	return rf69_write_reg(spi, REG_PREAMBLE_LSB, lsb);
    604}
    605
    606int rf69_enable_sync(struct spi_device *spi)
    607{
    608	return rf69_set_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON);
    609}
    610
    611int rf69_disable_sync(struct spi_device *spi)
    612{
    613	return rf69_clear_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON);
    614}
    615
    616int rf69_set_fifo_fill_condition(struct spi_device *spi,
    617				 enum fifo_fill_condition fifo_fill_condition)
    618{
    619	switch (fifo_fill_condition) {
    620	case always:
    621		return rf69_set_bit(spi, REG_SYNC_CONFIG,
    622				    MASK_SYNC_CONFIG_FIFO_FILL_CONDITION);
    623	case after_sync_interrupt:
    624		return rf69_clear_bit(spi, REG_SYNC_CONFIG,
    625				      MASK_SYNC_CONFIG_FIFO_FILL_CONDITION);
    626	default:
    627		dev_dbg(&spi->dev, "set: illegal fifo fill condition %u\n", fifo_fill_condition);
    628		return -EINVAL;
    629	}
    630}
    631
    632int rf69_set_sync_size(struct spi_device *spi, u8 sync_size)
    633{
    634	// check input value
    635	if (sync_size > 0x07) {
    636		dev_dbg(&spi->dev, "set: illegal sync size %u\n", sync_size);
    637		return -EINVAL;
    638	}
    639
    640	// write value
    641	return rf69_read_mod_write(spi, REG_SYNC_CONFIG,
    642				   MASK_SYNC_CONFIG_SYNC_SIZE,
    643				   (sync_size << 3));
    644}
    645
    646int rf69_set_sync_values(struct spi_device *spi, u8 sync_values[8])
    647{
    648	int retval = 0;
    649
    650	retval += rf69_write_reg(spi, REG_SYNCVALUE1, sync_values[0]);
    651	retval += rf69_write_reg(spi, REG_SYNCVALUE2, sync_values[1]);
    652	retval += rf69_write_reg(spi, REG_SYNCVALUE3, sync_values[2]);
    653	retval += rf69_write_reg(spi, REG_SYNCVALUE4, sync_values[3]);
    654	retval += rf69_write_reg(spi, REG_SYNCVALUE5, sync_values[4]);
    655	retval += rf69_write_reg(spi, REG_SYNCVALUE6, sync_values[5]);
    656	retval += rf69_write_reg(spi, REG_SYNCVALUE7, sync_values[6]);
    657	retval += rf69_write_reg(spi, REG_SYNCVALUE8, sync_values[7]);
    658
    659	return retval;
    660}
    661
    662int rf69_set_packet_format(struct spi_device *spi,
    663			   enum packet_format packet_format)
    664{
    665	switch (packet_format) {
    666	case packet_length_var:
    667		return rf69_set_bit(spi, REG_PACKETCONFIG1,
    668				    MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE);
    669	case packet_length_fix:
    670		return rf69_clear_bit(spi, REG_PACKETCONFIG1,
    671				      MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE);
    672	default:
    673		dev_dbg(&spi->dev, "set: illegal packet format %u\n", packet_format);
    674		return -EINVAL;
    675	}
    676}
    677
    678int rf69_enable_crc(struct spi_device *spi)
    679{
    680	return rf69_set_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON);
    681}
    682
    683int rf69_disable_crc(struct spi_device *spi)
    684{
    685	return rf69_clear_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON);
    686}
    687
    688int rf69_set_address_filtering(struct spi_device *spi,
    689			       enum address_filtering address_filtering)
    690{
    691	static const u8 af_map[] = {
    692		[filtering_off] = PACKETCONFIG1_ADDRESSFILTERING_OFF,
    693		[node_address] = PACKETCONFIG1_ADDRESSFILTERING_NODE,
    694		[node_or_broadcast_address] =
    695			PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST,
    696	};
    697
    698	if (unlikely(address_filtering >= ARRAY_SIZE(af_map))) {
    699		dev_dbg(&spi->dev, "set: illegal address filtering %u\n", address_filtering);
    700		return -EINVAL;
    701	}
    702
    703	return rf69_read_mod_write(spi, REG_PACKETCONFIG1,
    704				   MASK_PACKETCONFIG1_ADDRESSFILTERING,
    705				   af_map[address_filtering]);
    706}
    707
    708int rf69_set_payload_length(struct spi_device *spi, u8 payload_length)
    709{
    710	return rf69_write_reg(spi, REG_PAYLOAD_LENGTH, payload_length);
    711}
    712
    713int rf69_set_node_address(struct spi_device *spi, u8 node_address)
    714{
    715	return rf69_write_reg(spi, REG_NODEADRS, node_address);
    716}
    717
    718int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcast_address)
    719{
    720	return rf69_write_reg(spi, REG_BROADCASTADRS, broadcast_address);
    721}
    722
    723int rf69_set_tx_start_condition(struct spi_device *spi,
    724				enum tx_start_condition tx_start_condition)
    725{
    726	switch (tx_start_condition) {
    727	case fifo_level:
    728		return rf69_clear_bit(spi, REG_FIFO_THRESH,
    729				      MASK_FIFO_THRESH_TXSTART);
    730	case fifo_not_empty:
    731		return rf69_set_bit(spi, REG_FIFO_THRESH,
    732				    MASK_FIFO_THRESH_TXSTART);
    733	default:
    734		dev_dbg(&spi->dev, "set: illegal tx start condition %u\n", tx_start_condition);
    735		return -EINVAL;
    736	}
    737}
    738
    739int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold)
    740{
    741	int retval;
    742
    743	/* check input value */
    744	if (threshold & ~MASK_FIFO_THRESH_VALUE) {
    745		dev_dbg(&spi->dev, "set: illegal fifo threshold %u\n", threshold);
    746		return -EINVAL;
    747	}
    748
    749	/* write value */
    750	retval = rf69_read_mod_write(spi, REG_FIFO_THRESH,
    751				     MASK_FIFO_THRESH_VALUE,
    752				     threshold);
    753	if (retval)
    754		return retval;
    755
    756	/*
    757	 * access the fifo to activate new threshold
    758	 * retval (mis-) used as buffer here
    759	 */
    760	return rf69_read_fifo(spi, (u8 *)&retval, 1);
    761}
    762
    763int rf69_set_dagc(struct spi_device *spi, enum dagc dagc)
    764{
    765	static const u8 dagc_map[] = {
    766		[normal_mode] = DAGC_NORMAL,
    767		[improve] = DAGC_IMPROVED_LOWBETA0,
    768		[improve_for_low_modulation_index] = DAGC_IMPROVED_LOWBETA1,
    769	};
    770
    771	if (unlikely(dagc >= ARRAY_SIZE(dagc_map))) {
    772		dev_dbg(&spi->dev, "set: illegal dagc %u\n", dagc);
    773		return -EINVAL;
    774	}
    775
    776	return rf69_write_reg(spi, REG_TESTDAGC, dagc_map[dagc]);
    777}
    778
    779/*-------------------------------------------------------------------------*/
    780
    781int rf69_read_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
    782{
    783	int i;
    784	struct spi_transfer transfer;
    785	u8 local_buffer[FIFO_SIZE + 1] = {};
    786	int retval;
    787
    788	if (size > FIFO_SIZE) {
    789		dev_dbg(&spi->dev,
    790			"read fifo: passed in buffer bigger then internal buffer\n");
    791		return -EMSGSIZE;
    792	}
    793
    794	/* prepare a bidirectional transfer */
    795	local_buffer[0] = REG_FIFO;
    796	memset(&transfer, 0, sizeof(transfer));
    797	transfer.tx_buf = local_buffer;
    798	transfer.rx_buf = local_buffer;
    799	transfer.len	= size + 1;
    800
    801	retval = spi_sync_transfer(spi, &transfer, 1);
    802
    803	/* print content read from fifo for debugging purposes */
    804	for (i = 0; i < size; i++)
    805		dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i + 1]);
    806
    807	memcpy(buffer, &local_buffer[1], size);
    808
    809	return retval;
    810}
    811
    812int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size)
    813{
    814	int i;
    815	u8 local_buffer[FIFO_SIZE + 1];
    816
    817	if (size > FIFO_SIZE) {
    818		dev_dbg(&spi->dev,
    819			"read fifo: passed in buffer bigger then internal buffer\n");
    820		return -EMSGSIZE;
    821	}
    822
    823	local_buffer[0] = REG_FIFO | WRITE_BIT;
    824	memcpy(&local_buffer[1], buffer, size);
    825
    826	/* print content written from fifo for debugging purposes */
    827	for (i = 0; i < size; i++)
    828		dev_dbg(&spi->dev, "%d - 0x%x\n", i, buffer[i]);
    829
    830	return spi_write(spi, local_buffer, size + 1);
    831}
    832