]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/staging/pi433/rf69.c
Merge remote-tracking branch 'asoc/topic/pcm512x' into asoc-next
[mirror_ubuntu-focal-kernel.git] / drivers / staging / pi433 / rf69.c
CommitLineData
874bcba6
MW
1/*
2 * abstraction of the spi interface of HopeRf rf69 radio module
3 *
4 * Copyright (C) 2016 Wolf-Entwicklungen
5 * Marcus Wolf <linux@wolf-entwicklungen.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18/* enable prosa debug info */
19#undef DEBUG
20/* enable print of values on reg access */
21#undef DEBUG_VALUES
22/* enable print of values on fifo access */
23#undef DEBUG_FIFO_ACCESS
24
25#include <linux/types.h>
26#include <linux/spi/spi.h>
27
28#include "rf69.h"
29#include "rf69_registers.h"
30
31#define F_OSC 32000000 /* in Hz */
32#define FIFO_SIZE 66 /* in byte */
33
34/*-------------------------------------------------------------------------*/
35
36#define READ_REG(x) rf69_read_reg (spi, x)
329822a0 37#define WRITE_REG(x, y) rf69_write_reg(spi, x, y)
874bcba6
MW
38
39/*-------------------------------------------------------------------------*/
40
41int rf69_set_mode(struct spi_device *spi, enum mode mode)
42{
43 #ifdef DEBUG
44 dev_dbg(&spi->dev, "set: mode");
45 #endif
46
b4bac77f 47 switch (mode) {
874bcba6
MW
48 case transmit: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_TRANSMIT);
49 case receive: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_RECEIVE);
50 case synthesizer: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SYNTHESIZER);
51 case standby: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_STANDBY);
52 case mode_sleep: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SLEEP);
e221b2b1
MC
53 default:
54 dev_dbg(&spi->dev, "set: illegal input param");
55 return -EINVAL;
874bcba6
MW
56 }
57
58 // we are using packet mode, so this check is not really needed
59 // but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode
60 //while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady
61
62}
63
64int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode)
65{
66 #ifdef DEBUG
67 dev_dbg(&spi->dev, "set: data mode");
68 #endif
69
70 switch (dataMode) {
71 case packet: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_PACKET);
72 case continuous: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS);
73 case continuousNoSync: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS_NOSYNC);
e221b2b1
MC
74 default:
75 dev_dbg(&spi->dev, "set: illegal input param");
76 return -EINVAL;
874bcba6
MW
77 }
78}
79
80int rf69_set_modulation(struct spi_device *spi, enum modulation modulation)
81{
82 #ifdef DEBUG
83 dev_dbg(&spi->dev, "set: modulation");
84 #endif
85
86 switch (modulation) {
87 case OOK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_OOK);
88 case FSK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_FSK);
e221b2b1
MC
89 default:
90 dev_dbg(&spi->dev, "set: illegal input param");
91 return -EINVAL;
874bcba6
MW
92 }
93}
94
95enum modulation rf69_get_modulation(struct spi_device *spi)
96{
97 u8 currentValue;
98
99 #ifdef DEBUG
100 dev_dbg(&spi->dev, "get: mode");
101 #endif
102
103 currentValue = READ_REG(REG_DATAMODUL);
104
202fc673 105 switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE) {
874bcba6
MW
106 case DATAMODUL_MODULATION_TYPE_OOK: return OOK;
107 case DATAMODUL_MODULATION_TYPE_FSK: return FSK;
108 default: return undefined;
109 }
110}
111
112int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping)
113{
114 #ifdef DEBUG
115 dev_dbg(&spi->dev, "set: mod shaping");
116 #endif
117
9391cb31 118 if (rf69_get_modulation(spi) == FSK) {
874bcba6
MW
119 switch (modShaping) {
120 case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE);
121 case shaping1_0: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_1_0);
122 case shaping0_5: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_3);
123 case shaping0_3: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_5);
e221b2b1
MC
124 default:
125 dev_dbg(&spi->dev, "set: illegal input param");
126 return -EINVAL;
874bcba6 127 }
46659ed7 128 } else {
874bcba6
MW
129 switch (modShaping) {
130 case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE);
131 case shapingBR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_BR);
132 case shaping2BR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_2BR);
e221b2b1
MC
133 default:
134 dev_dbg(&spi->dev, "set: illegal input param");
135 return -EINVAL;
874bcba6
MW
136 }
137 }
138}
139
140int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate)
141{
142 int retval;
143 u32 bitRate_min;
144 u32 bitRate_reg;
145 u8 msb;
146 u8 lsb;
147
148 #ifdef DEBUG
149 dev_dbg(&spi->dev, "set: bit rate");
150 #endif
151
152 // check input value
153 bitRate_min = F_OSC / 8388608; // 8388608 = 2^23;
9391cb31 154 if (bitRate < bitRate_min) {
874bcba6 155 dev_dbg(&spi->dev, "setBitRate: illegal input param");
e221b2b1 156 return -EINVAL;
874bcba6
MW
157 }
158
159 // calculate reg settings
160 bitRate_reg = (F_OSC / bitRate);
161
162 msb = (bitRate_reg&0xff00) >> 8;
163 lsb = (bitRate_reg&0xff);
164
165 // transmit to RF 69
166 retval = WRITE_REG(REG_BITRATE_MSB, msb);
4a74749a
MC
167 if (retval)
168 return retval;
169
874bcba6 170 retval = WRITE_REG(REG_BITRATE_LSB, lsb);
4a74749a
MC
171 if (retval)
172 return retval;
874bcba6
MW
173
174 return 0;
175}
176
177int rf69_set_deviation(struct spi_device *spi, u32 deviation)
178{
179 int retval;
180