1 /*
2  * Copyright (c) 2019 Manivannan Sadhasivam
3  * Copyright (c) 2020 Grinn
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <drivers/gpio.h>
9 #include <drivers/lora.h>
10 #include <drivers/spi.h>
11 #include <zephyr.h>
12 
13 #include "sx12xx_common.h"
14 
15 #include <logging/log.h>
16 LOG_MODULE_REGISTER(sx127x, CONFIG_LORA_LOG_LEVEL);
17 
18 #if DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1272)
19 
20 #include <sx1272/sx1272.h>
21 
22 #define DT_DRV_COMPAT semtech_sx1272
23 
24 #define SX127xCheckRfFrequency SX1272CheckRfFrequency
25 #define SX127xGetBoardTcxoWakeupTime SX1272GetBoardTcxoWakeupTime
26 #define SX127xSetAntSwLowPower SX1272SetAntSwLowPower
27 #define SX127xSetBoardTcxo SX1272SetBoardTcxo
28 #define SX127xSetAntSw SX1272SetAntSw
29 #define SX127xReset SX1272Reset
30 #define SX127xIoIrqInit SX1272IoIrqInit
31 #define SX127xWriteBuffer SX1272WriteBuffer
32 #define SX127xReadBuffer SX1272ReadBuffer
33 #define SX127xSetRfTxPower SX1272SetRfTxPower
34 #define SX127xGetDio1PinState SX1272GetDio1PinState
35 #define SX127xInit SX1272Init
36 #define SX127xGetStatus SX1272GetStatus
37 #define SX127xSetModem SX1272SetModem
38 #define SX127xSetChannel SX1272SetChannel
39 #define SX127xIsChannelFree SX1272IsChannelFree
40 #define SX127xRandom SX1272Random
41 #define SX127xSetRxConfig SX1272SetRxConfig
42 #define SX127xSetTxConfig SX1272SetTxConfig
43 #define SX127xGetTimeOnAir SX1272GetTimeOnAir
44 #define SX127xSend SX1272Send
45 #define SX127xSetSleep SX1272SetSleep
46 #define SX127xSetStby SX1272SetStby
47 #define SX127xSetRx SX1272SetRx
48 #define SX127xWrite SX1272Write
49 #define SX127xRead SX1272Read
50 #define SX127xSetMaxPayloadLength SX1272SetMaxPayloadLength
51 #define SX127xSetPublicNetwork SX1272SetPublicNetwork
52 #define SX127xGetWakeupTime SX1272GetWakeupTime
53 #define SX127xSetTxContinuousWave SX1272SetTxContinuousWave
54 
55 #elif DT_HAS_COMPAT_STATUS_OKAY(semtech_sx1276)
56 
57 #include <sx1276/sx1276.h>
58 
59 #define DT_DRV_COMPAT semtech_sx1276
60 
61 #define SX127xCheckRfFrequency SX1276CheckRfFrequency
62 #define SX127xGetBoardTcxoWakeupTime SX1276GetBoardTcxoWakeupTime
63 #define SX127xSetAntSwLowPower SX1276SetAntSwLowPower
64 #define SX127xSetBoardTcxo SX1276SetBoardTcxo
65 #define SX127xSetAntSw SX1276SetAntSw
66 #define SX127xReset SX1276Reset
67 #define SX127xIoIrqInit SX1276IoIrqInit
68 #define SX127xWriteBuffer SX1276WriteBuffer
69 #define SX127xReadBuffer SX1276ReadBuffer
70 #define SX127xSetRfTxPower SX1276SetRfTxPower
71 #define SX127xGetDio1PinState SX1276GetDio1PinState
72 #define SX127xInit SX1276Init
73 #define SX127xGetStatus SX1276GetStatus
74 #define SX127xSetModem SX1276SetModem
75 #define SX127xSetChannel SX1276SetChannel
76 #define SX127xIsChannelFree SX1276IsChannelFree
77 #define SX127xRandom SX1276Random
78 #define SX127xSetRxConfig SX1276SetRxConfig
79 #define SX127xSetTxConfig SX1276SetTxConfig
80 #define SX127xGetTimeOnAir SX1276GetTimeOnAir
81 #define SX127xSend SX1276Send
82 #define SX127xSetSleep SX1276SetSleep
83 #define SX127xSetStby SX1276SetStby
84 #define SX127xSetRx SX1276SetRx
85 #define SX127xWrite SX1276Write
86 #define SX127xRead SX1276Read
87 #define SX127xSetMaxPayloadLength SX1276SetMaxPayloadLength
88 #define SX127xSetPublicNetwork SX1276SetPublicNetwork
89 #define SX127xGetWakeupTime SX1276GetWakeupTime
90 #define SX127xSetTxContinuousWave SX1276SetTxContinuousWave
91 
92 #else
93 #error No SX127x instance in device tree.
94 #endif
95 
96 BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(semtech_sx1272) +
97 	     DT_NUM_INST_STATUS_OKAY(semtech_sx1276) <= 1,
98 	     "Multiple SX127x instances in DT");
99 
100 #define GPIO_RESET_PIN		DT_INST_GPIO_PIN(0, reset_gpios)
101 #define GPIO_CS_PIN		DT_INST_SPI_DEV_CS_GPIOS_PIN(0)
102 #define GPIO_CS_FLAGS		DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0)
103 
104 #define GPIO_ANTENNA_ENABLE_PIN				\
105 	DT_INST_GPIO_PIN(0, antenna_enable_gpios)
106 #define GPIO_RFI_ENABLE_PIN			\
107 	DT_INST_GPIO_PIN(0, rfi_enable_gpios)
108 #define GPIO_RFO_ENABLE_PIN			\
109 	DT_INST_GPIO_PIN(0, rfo_enable_gpios)
110 #define GPIO_PA_BOOST_ENABLE_PIN			\
111 	DT_INST_GPIO_PIN(0, pa_boost_enable_gpios)
112 
113 #define GPIO_TCXO_POWER_PIN	DT_INST_GPIO_PIN(0, tcxo_power_gpios)
114 
115 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_startup_delay_ms)
116 #define TCXO_POWER_STARTUP_DELAY_MS			\
117 	DT_INST_PROP(0, tcxo_power_startup_delay_ms)
118 #else
119 #define TCXO_POWER_STARTUP_DELAY_MS		0
120 #endif
121 
122 /*
123  * Those macros must be in sync with 'power-amplifier-output' dts property.
124  */
125 #define SX127X_PA_RFO				0
126 #define SX127X_PA_BOOST				1
127 
128 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios) &&	\
129 	DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
130 #define SX127X_PA_OUTPUT(power)				\
131 	((power) > 14 ? SX127X_PA_BOOST : SX127X_PA_RFO)
132 #elif DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
133 #define SX127X_PA_OUTPUT(power)		SX127X_PA_RFO
134 #elif DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
135 #define SX127X_PA_OUTPUT(power)		SX127X_PA_BOOST
136 #elif DT_INST_NODE_HAS_PROP(0, power_amplifier_output)
137 #define SX127X_PA_OUTPUT(power)				\
138 	DT_ENUM_IDX(DT_DRV_INST(0), power_amplifier_output)
139 #else
140 BUILD_ASSERT(0, "None of rfo-enable-gpios, pa-boost-enable-gpios and "
141 	     "power-amplifier-output has been specified. "
142 	     "Look at semtech,sx127x-base.yaml to fix that.");
143 #endif
144 
145 #define SX127X_PADAC_20DBM_ON (RF_PADAC_20DBM_ON)
146 #define SX127X_PADAC_20DBM_OFF (RF_PADAC_20DBM_OFF)
147 #define SX127X_PADAC_20DBM_MASK (~RF_PADAC_20DBM_MASK)
148 
149 #define SX127X_PACONFIG_PASELECT_PABOOST (RF_PACONFIG_PASELECT_PABOOST)
150 #define SX127X_PACONFIG_OUTPUTPOWER_MASK (~RF_PACONFIG_OUTPUTPOWER_MASK)
151 
152 #ifdef RF_PACONFIG_MAX_POWER_MASK
153 #define SX127X_PACONFIG_MAX_POWER_SHIFT 4
154 #endif
155 
156 extern DioIrqHandler *DioIrq[];
157 
158 struct sx127x_dio {
159 	const char *port;
160 	gpio_pin_t pin;
161 	gpio_dt_flags_t flags;
162 };
163 
164 /* Helper macro that UTIL_LISTIFY can use and produces an element with comma */
165 #define SX127X_DIO_GPIO_LEN(inst) \
166 	DT_INST_PROP_LEN(inst, dio_gpios)
167 
168 #define SX127X_DIO_GPIO_ELEM(idx, inst) \
169 	{ \
170 		DT_INST_GPIO_LABEL_BY_IDX(inst, dio_gpios, idx), \
171 		DT_INST_GPIO_PIN_BY_IDX(inst, dio_gpios, idx), \
172 		DT_INST_GPIO_FLAGS_BY_IDX(inst, dio_gpios, idx), \
173 	},
174 
175 #define SX127X_DIO_GPIO_INIT(n) \
176 	UTIL_LISTIFY(SX127X_DIO_GPIO_LEN(n), SX127X_DIO_GPIO_ELEM, n)
177 
178 static const struct sx127x_dio sx127x_dios[] = { SX127X_DIO_GPIO_INIT(0) };
179 
180 #define SX127X_MAX_DIO ARRAY_SIZE(sx127x_dios)
181 
182 static struct sx127x_data {
183 	const struct device *reset;
184 #if DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
185 	const struct device *antenna_enable;
186 #endif
187 #if DT_INST_NODE_HAS_PROP(0, rfi_enable_gpios)
188 	const struct device *rfi_enable;
189 #endif
190 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
191 	const struct device *rfo_enable;
192 #endif
193 #if DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
194 	const struct device *pa_boost_enable;
195 #endif
196 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios) &&	\
197 	DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
198 	uint8_t tx_power;
199 #endif
200 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_gpios)
201 	const struct device *tcxo_power;
202 	bool tcxo_power_enabled;
203 #endif
204 	const struct device *spi;
205 	struct spi_config spi_cfg;
206 	const struct device *dio_dev[SX127X_MAX_DIO];
207 	struct k_work dio_work[SX127X_MAX_DIO];
208 } dev_data;
209 
clamp_int8(int8_t x,int8_t min,int8_t max)210 static int8_t clamp_int8(int8_t x, int8_t min, int8_t max)
211 {
212 	if (x < min) {
213 		return min;
214 	} else if (x > max) {
215 		return max;
216 	} else {
217 		return x;
218 	}
219 }
220 
SX127xCheckRfFrequency(uint32_t frequency)221 bool SX127xCheckRfFrequency(uint32_t frequency)
222 {
223 	/* TODO */
224 	return true;
225 }
226 
SX127xGetBoardTcxoWakeupTime(void)227 uint32_t SX127xGetBoardTcxoWakeupTime(void)
228 {
229 	return TCXO_POWER_STARTUP_DELAY_MS;
230 }
231 
sx127x_antenna_enable(int val)232 static inline void sx127x_antenna_enable(int val)
233 {
234 #if DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
235 	gpio_pin_set(dev_data.antenna_enable, GPIO_ANTENNA_ENABLE_PIN, val);
236 #endif
237 }
238 
sx127x_rfi_enable(int val)239 static inline void sx127x_rfi_enable(int val)
240 {
241 #if DT_INST_NODE_HAS_PROP(0, rfi_enable_gpios)
242 	gpio_pin_set(dev_data.rfi_enable, GPIO_RFI_ENABLE_PIN, val);
243 #endif
244 }
245 
sx127x_rfo_enable(int val)246 static inline void sx127x_rfo_enable(int val)
247 {
248 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
249 	gpio_pin_set(dev_data.rfo_enable, GPIO_RFO_ENABLE_PIN, val);
250 #endif
251 }
252 
sx127x_pa_boost_enable(int val)253 static inline void sx127x_pa_boost_enable(int val)
254 {
255 #if DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
256 	gpio_pin_set(dev_data.pa_boost_enable, GPIO_PA_BOOST_ENABLE_PIN, val);
257 #endif
258 }
259 
SX127xSetAntSwLowPower(bool low_power)260 void SX127xSetAntSwLowPower(bool low_power)
261 {
262 	if (low_power) {
263 		/* force inactive (low power) state of all antenna paths */
264 		sx127x_rfi_enable(0);
265 		sx127x_rfo_enable(0);
266 		sx127x_pa_boost_enable(0);
267 
268 		sx127x_antenna_enable(0);
269 	} else {
270 		sx127x_antenna_enable(1);
271 
272 		/* rely on SX127xSetAntSw() to configure proper antenna path */
273 	}
274 }
275 
SX127xSetBoardTcxo(uint8_t state)276 void SX127xSetBoardTcxo(uint8_t state)
277 {
278 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_gpios)
279 	bool enable = state;
280 
281 	if (enable == dev_data.tcxo_power_enabled) {
282 		return;
283 	}
284 
285 	if (enable) {
286 		gpio_pin_set(dev_data.tcxo_power, GPIO_TCXO_POWER_PIN, 1);
287 
288 		if (TCXO_POWER_STARTUP_DELAY_MS > 0) {
289 			k_sleep(K_MSEC(TCXO_POWER_STARTUP_DELAY_MS));
290 		}
291 	} else {
292 		gpio_pin_set(dev_data.tcxo_power, GPIO_TCXO_POWER_PIN, 0);
293 	}
294 
295 	dev_data.tcxo_power_enabled = enable;
296 #endif
297 }
298 
SX127xSetAntSw(uint8_t opMode)299 void SX127xSetAntSw(uint8_t opMode)
300 {
301 	switch (opMode) {
302 	case RFLR_OPMODE_TRANSMITTER:
303 		sx127x_rfi_enable(0);
304 
305 		if (SX127X_PA_OUTPUT(dev_data.tx_power) == SX127X_PA_BOOST) {
306 			sx127x_rfo_enable(0);
307 			sx127x_pa_boost_enable(1);
308 		} else {
309 			sx127x_pa_boost_enable(0);
310 			sx127x_rfo_enable(1);
311 		}
312 		break;
313 	default:
314 		sx127x_rfo_enable(0);
315 		sx127x_pa_boost_enable(0);
316 		sx127x_rfi_enable(1);
317 		break;
318 	}
319 }
320 
SX127xReset(void)321 void SX127xReset(void)
322 {
323 	SX127xSetBoardTcxo(true);
324 
325 	gpio_pin_set(dev_data.reset, GPIO_RESET_PIN, 1);
326 
327 	k_sleep(K_MSEC(1));
328 
329 	gpio_pin_set(dev_data.reset, GPIO_RESET_PIN, 0);
330 
331 	k_sleep(K_MSEC(6));
332 }
333 
sx127x_dio_work_handle(struct k_work * work)334 static void sx127x_dio_work_handle(struct k_work *work)
335 {
336 	int dio = work - dev_data.dio_work;
337 
338 	(*DioIrq[dio])(NULL);
339 }
340 
sx127x_irq_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)341 static void sx127x_irq_callback(const struct device *dev,
342 				struct gpio_callback *cb, uint32_t pins)
343 {
344 	unsigned int i, pin;
345 
346 	pin = find_lsb_set(pins) - 1;
347 
348 	for (i = 0; i < SX127X_MAX_DIO; i++) {
349 		if (dev == dev_data.dio_dev[i] &&
350 		    pin == sx127x_dios[i].pin) {
351 			k_work_submit(&dev_data.dio_work[i]);
352 		}
353 	}
354 }
355 
SX127xIoIrqInit(DioIrqHandler ** irqHandlers)356 void SX127xIoIrqInit(DioIrqHandler **irqHandlers)
357 {
358 	unsigned int i;
359 	static struct gpio_callback callbacks[SX127X_MAX_DIO];
360 
361 	/* Setup DIO gpios */
362 	for (i = 0; i < SX127X_MAX_DIO; i++) {
363 		if (!irqHandlers[i]) {
364 			continue;
365 		}
366 
367 		dev_data.dio_dev[i] = device_get_binding(sx127x_dios[i].port);
368 		if (dev_data.dio_dev[i] == NULL) {
369 			LOG_ERR("Cannot get pointer to %s device",
370 				sx127x_dios[i].port);
371 			return;
372 		}
373 
374 		k_work_init(&dev_data.dio_work[i], sx127x_dio_work_handle);
375 
376 		gpio_pin_configure(dev_data.dio_dev[i], sx127x_dios[i].pin,
377 				   GPIO_INPUT | GPIO_INT_DEBOUNCE
378 				   | sx127x_dios[i].flags);
379 
380 		gpio_init_callback(&callbacks[i],
381 				   sx127x_irq_callback,
382 				   BIT(sx127x_dios[i].pin));
383 
384 		if (gpio_add_callback(dev_data.dio_dev[i], &callbacks[i]) < 0) {
385 			LOG_ERR("Could not set gpio callback.");
386 			return;
387 		}
388 		gpio_pin_interrupt_configure(dev_data.dio_dev[i],
389 					     sx127x_dios[i].pin,
390 					     GPIO_INT_EDGE_TO_ACTIVE);
391 	}
392 
393 }
394 
sx127x_transceive(uint8_t reg,bool write,void * data,size_t length)395 static int sx127x_transceive(uint8_t reg, bool write, void *data, size_t length)
396 {
397 	const struct spi_buf buf[2] = {
398 		{
399 			.buf = &reg,
400 			.len = sizeof(reg)
401 		},
402 		{
403 			.buf = data,
404 			.len = length
405 		}
406 	};
407 
408 	struct spi_buf_set tx = {
409 		.buffers = buf,
410 		.count = ARRAY_SIZE(buf),
411 	};
412 
413 	if (!write) {
414 		const struct spi_buf_set rx = {
415 			.buffers = buf,
416 			.count = ARRAY_SIZE(buf)
417 		};
418 
419 		return spi_transceive(dev_data.spi, &dev_data.spi_cfg, &tx, &rx);
420 	}
421 
422 	return spi_write(dev_data.spi, &dev_data.spi_cfg, &tx);
423 }
424 
sx127x_read(uint8_t reg_addr,uint8_t * data,uint8_t len)425 int sx127x_read(uint8_t reg_addr, uint8_t *data, uint8_t len)
426 {
427 	return sx127x_transceive(reg_addr, false, data, len);
428 }
429 
sx127x_write(uint8_t reg_addr,uint8_t * data,uint8_t len)430 int sx127x_write(uint8_t reg_addr, uint8_t *data, uint8_t len)
431 {
432 	return sx127x_transceive(reg_addr | BIT(7), true, data, len);
433 }
434 
SX127xWriteBuffer(uint32_t addr,uint8_t * buffer,uint8_t size)435 void SX127xWriteBuffer(uint32_t addr, uint8_t *buffer, uint8_t size)
436 {
437 	int ret;
438 
439 	ret = sx127x_write(addr, buffer, size);
440 	if (ret < 0) {
441 		LOG_ERR("Unable to write address: 0x%x", addr);
442 	}
443 }
444 
SX127xReadBuffer(uint32_t addr,uint8_t * buffer,uint8_t size)445 void SX127xReadBuffer(uint32_t addr, uint8_t *buffer, uint8_t size)
446 {
447 	int ret;
448 
449 	ret = sx127x_read(addr, buffer, size);
450 	if (ret < 0) {
451 		LOG_ERR("Unable to read address: 0x%x", addr);
452 	}
453 }
454 
SX127xSetRfTxPower(int8_t power)455 void SX127xSetRfTxPower(int8_t power)
456 {
457 	int ret;
458 	uint8_t pa_config = 0;
459 	uint8_t pa_dac = 0;
460 
461 	ret = sx127x_read(REG_PADAC, &pa_dac, 1);
462 	if (ret < 0) {
463 		LOG_ERR("Unable to read PA dac");
464 		return;
465 	}
466 
467 	pa_dac &= ~SX127X_PADAC_20DBM_MASK;
468 
469 	if (SX127X_PA_OUTPUT(power) == SX127X_PA_BOOST) {
470 		power = clamp_int8(power, 2, 20);
471 
472 		pa_config |= SX127X_PACONFIG_PASELECT_PABOOST;
473 		if (power > 17) {
474 			pa_dac |= SX127X_PADAC_20DBM_ON;
475 			pa_config |= (power - 5) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
476 		} else {
477 			pa_dac |= SX127X_PADAC_20DBM_OFF;
478 			pa_config |= (power - 2) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
479 		}
480 	} else {
481 #ifdef SX127X_PACONFIG_MAX_POWER_SHIFT
482 		power = clamp_int8(power, -4, 15);
483 
484 		pa_dac |= SX127X_PADAC_20DBM_OFF;
485 		if (power > 0) {
486 			/* Set the power range to 0 -- 10.8+0.6*7 dBm */
487 			pa_config |= 7 << SX127X_PACONFIG_MAX_POWER_SHIFT;
488 			pa_config |= power & SX127X_PACONFIG_OUTPUTPOWER_MASK;
489 		} else {
490 			/* Set the power range to -4.2 -- 10.8+0.6*0 dBm */
491 			pa_config |= (power + 4) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
492 		}
493 #else
494 		power = clamp_int8(power, -1, 14);
495 
496 		pa_dac |= SX127X_PADAC_20DBM_OFF;
497 		pa_config |= (power + 1) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
498 #endif
499 	}
500 
501 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios) &&	\
502 	DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
503 	dev_data.tx_power = power;
504 #endif
505 
506 	ret = sx127x_write(REG_PACONFIG, &pa_config, 1);
507 	if (ret < 0) {
508 		LOG_ERR("Unable to write PA config");
509 		return;
510 	}
511 
512 	ret = sx127x_write(REG_PADAC, &pa_dac, 1);
513 	if (ret < 0) {
514 		LOG_ERR("Unable to write PA dac");
515 		return;
516 	}
517 }
518 
SX127xGetDio1PinState(void)519 uint32_t SX127xGetDio1PinState(void)
520 {
521 #if SX127X_DIO_GPIO_LEN(0) >= 2
522 	if (gpio_pin_get(dev_data.dio_dev[1], sx127x_dios[1].pin) > 0) {
523 		return 1U;
524 	}
525 #endif
526 
527 	return 0U;
528 }
529 
530 /* Initialize Radio driver callbacks */
531 const struct Radio_s Radio = {
532 	.Init = SX127xInit,
533 	.GetStatus = SX127xGetStatus,
534 	.SetModem = SX127xSetModem,
535 	.SetChannel = SX127xSetChannel,
536 	.IsChannelFree = SX127xIsChannelFree,
537 	.Random = SX127xRandom,
538 	.SetRxConfig = SX127xSetRxConfig,
539 	.SetTxConfig = SX127xSetTxConfig,
540 	.CheckRfFrequency = SX127xCheckRfFrequency,
541 	.TimeOnAir = SX127xGetTimeOnAir,
542 	.Send = SX127xSend,
543 	.Sleep = SX127xSetSleep,
544 	.Standby = SX127xSetStby,
545 	.Rx = SX127xSetRx,
546 	.Write = SX127xWrite,
547 	.Read = SX127xRead,
548 	.WriteBuffer = SX127xWriteBuffer,
549 	.ReadBuffer = SX127xReadBuffer,
550 	.SetMaxPayloadLength = SX127xSetMaxPayloadLength,
551 	.SetPublicNetwork = SX127xSetPublicNetwork,
552 	.GetWakeupTime = SX127xGetWakeupTime,
553 	.IrqProcess = NULL,
554 	.RxBoosted = NULL,
555 	.SetRxDutyCycle = NULL,
556 	.SetTxContinuousWave = SX127xSetTxContinuousWave,
557 };
558 
sx127x_antenna_configure(void)559 static int sx127x_antenna_configure(void)
560 {
561 	int ret;
562 
563 	ret = sx12xx_configure_pin(antenna_enable, GPIO_OUTPUT_INACTIVE);
564 	if (ret) {
565 		return ret;
566 	}
567 
568 	ret = sx12xx_configure_pin(rfi_enable, GPIO_OUTPUT_INACTIVE);
569 	if (ret) {
570 		return ret;
571 	}
572 
573 	ret = sx12xx_configure_pin(rfo_enable, GPIO_OUTPUT_INACTIVE);
574 	if (ret) {
575 		return ret;
576 	}
577 
578 	ret = sx12xx_configure_pin(pa_boost_enable, GPIO_OUTPUT_INACTIVE);
579 	if (ret) {
580 		return ret;
581 	}
582 
583 	return 0;
584 }
585 
sx127x_lora_init(const struct device * dev)586 static int sx127x_lora_init(const struct device *dev)
587 {
588 #if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
589 	static struct spi_cs_control spi_cs;
590 #endif
591 	int ret;
592 	uint8_t regval;
593 
594 	dev_data.spi = device_get_binding(DT_INST_BUS_LABEL(0));
595 	if (!dev_data.spi) {
596 		LOG_ERR("Cannot get pointer to %s device",
597 			DT_INST_BUS_LABEL(0));
598 		return -EINVAL;
599 	}
600 
601 	dev_data.spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB;
602 	dev_data.spi_cfg.frequency = DT_INST_PROP(0, spi_max_frequency);
603 	dev_data.spi_cfg.slave = DT_INST_REG_ADDR(0);
604 
605 #if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
606 	spi_cs.gpio_dev = device_get_binding(DT_INST_SPI_DEV_CS_GPIOS_LABEL(0));
607 	if (!spi_cs.gpio_dev) {
608 		LOG_ERR("Cannot get pointer to %s device",
609 			DT_INST_SPI_DEV_CS_GPIOS_LABEL(0));
610 		return -EIO;
611 	}
612 
613 	spi_cs.gpio_pin = GPIO_CS_PIN;
614 	spi_cs.gpio_dt_flags = GPIO_CS_FLAGS;
615 	spi_cs.delay = 0U;
616 
617 	dev_data.spi_cfg.cs = &spi_cs;
618 #endif
619 
620 	ret = sx12xx_configure_pin(tcxo_power, GPIO_OUTPUT_INACTIVE);
621 	if (ret) {
622 		return ret;
623 	}
624 
625 	/* Setup Reset gpio and perform soft reset */
626 	ret = sx12xx_configure_pin(reset, GPIO_OUTPUT_ACTIVE);
627 	if (ret) {
628 		return ret;
629 	}
630 
631 	k_sleep(K_MSEC(100));
632 	gpio_pin_set(dev_data.reset, GPIO_RESET_PIN, 0);
633 	k_sleep(K_MSEC(100));
634 
635 	ret = sx127x_read(REG_VERSION, &regval, 1);
636 	if (ret < 0) {
637 		LOG_ERR("Unable to read version info");
638 		return -EIO;
639 	}
640 
641 	LOG_INF("SX127x version 0x%02x found", regval);
642 
643 	ret = sx127x_antenna_configure();
644 	if (ret < 0) {
645 		LOG_ERR("Unable to configure antenna");
646 		return -EIO;
647 	}
648 
649 	ret = sx12xx_init(dev);
650 	if (ret < 0) {
651 		LOG_ERR("Failed to initialize SX12xx common");
652 		return ret;
653 	}
654 
655 	return 0;
656 }
657 
658 static const struct lora_driver_api sx127x_lora_api = {
659 	.config = sx12xx_lora_config,
660 	.send = sx12xx_lora_send,
661 	.send_async = sx12xx_lora_send_async,
662 	.recv = sx12xx_lora_recv,
663 	.test_cw = sx12xx_lora_test_cw,
664 };
665 
666 DEVICE_DT_INST_DEFINE(0, &sx127x_lora_init, NULL, NULL,
667 		      NULL, POST_KERNEL, CONFIG_LORA_INIT_PRIORITY,
668 		      &sx127x_lora_api);
669