1 /*
2  * Copyright (c) 2019 Manivannan Sadhasivam
3  * Copyright (c) 2020 Grinn
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/drivers/gpio.h>
9 #include <zephyr/drivers/lora.h>
10 #include <zephyr/drivers/spi.h>
11 #include <zephyr/kernel.h>
12 
13 #include "sx12xx_common.h"
14 
15 #include <zephyr/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 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_startup_delay_ms)
101 #define TCXO_POWER_STARTUP_DELAY_MS			\
102 	DT_INST_PROP(0, tcxo_power_startup_delay_ms)
103 #else
104 #define TCXO_POWER_STARTUP_DELAY_MS		0
105 #endif
106 
107 /*
108  * Those macros must be in sync with 'power-amplifier-output' dts property.
109  */
110 #define SX127X_PA_RFO				0
111 #define SX127X_PA_BOOST				1
112 
113 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios) &&	\
114 	DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
115 #define SX127X_PA_OUTPUT(power)				\
116 	((power) > 14 ? SX127X_PA_BOOST : SX127X_PA_RFO)
117 #elif DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
118 #define SX127X_PA_OUTPUT(power)		SX127X_PA_RFO
119 #elif DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
120 #define SX127X_PA_OUTPUT(power)		SX127X_PA_BOOST
121 #elif DT_INST_NODE_HAS_PROP(0, power_amplifier_output)
122 #define SX127X_PA_OUTPUT(power)				\
123 	DT_INST_ENUM_IDX(0, power_amplifier_output)
124 #else
125 BUILD_ASSERT(0, "None of rfo-enable-gpios, pa-boost-enable-gpios and "
126 	     "power-amplifier-output has been specified. "
127 	     "Look at semtech,sx127x-base.yaml to fix that.");
128 #endif
129 
130 #define SX127X_PADAC_20DBM_ON (RF_PADAC_20DBM_ON)
131 #define SX127X_PADAC_20DBM_OFF (RF_PADAC_20DBM_OFF)
132 #define SX127X_PADAC_20DBM_MASK (~RF_PADAC_20DBM_MASK)
133 
134 #define SX127X_PACONFIG_PASELECT_PABOOST (RF_PACONFIG_PASELECT_PABOOST)
135 #define SX127X_PACONFIG_OUTPUTPOWER_MASK (~RF_PACONFIG_OUTPUTPOWER_MASK)
136 
137 #ifdef RF_PACONFIG_MAX_POWER_MASK
138 #define SX127X_PACONFIG_MAX_POWER_SHIFT 4
139 #endif
140 
141 extern DioIrqHandler *DioIrq[];
142 
143 /* Helper macro that UTIL_LISTIFY can use and produces an element with comma */
144 #define SX127X_DIO_GPIO_LEN(inst) \
145 	DT_INST_PROP_LEN(inst, dio_gpios)
146 
147 #define SX127X_DIO_GPIO_ELEM(idx, inst) \
148 	GPIO_DT_SPEC_INST_GET_BY_IDX(inst, dio_gpios, idx)
149 
150 #define SX127X_DIO_GPIO_INIT(n) \
151 	LISTIFY(SX127X_DIO_GPIO_LEN(n), SX127X_DIO_GPIO_ELEM, (,), n)
152 
153 static const struct gpio_dt_spec sx127x_dios[] = { SX127X_DIO_GPIO_INIT(0) };
154 
155 #define SX127X_MAX_DIO ARRAY_SIZE(sx127x_dios)
156 
157 struct sx127x_config {
158 	struct spi_dt_spec bus;
159 	struct gpio_dt_spec reset;
160 #if DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
161 	struct gpio_dt_spec antenna_enable;
162 #endif
163 #if DT_INST_NODE_HAS_PROP(0, rfi_enable_gpios)
164 	struct gpio_dt_spec rfi_enable;
165 #endif
166 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
167 	struct gpio_dt_spec rfo_enable;
168 #endif
169 #if DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
170 	struct gpio_dt_spec pa_boost_enable;
171 #endif
172 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_gpios)
173 	struct gpio_dt_spec tcxo_power;
174 #endif
175 };
176 
177 static const struct sx127x_config dev_config = {
178 	.bus = SPI_DT_SPEC_INST_GET(0, SPI_WORD_SET(8) | SPI_TRANSFER_MSB, 0),
179 	.reset = GPIO_DT_SPEC_INST_GET(0, reset_gpios),
180 #if DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
181 	.antenna_enable = GPIO_DT_SPEC_INST_GET(0, antenna_enable_gpios),
182 #endif
183 #if DT_INST_NODE_HAS_PROP(0, rfi_enable_gpios)
184 	.rfi_enable = GPIO_DT_SPEC_INST_GET(0, rfi_enable_gpios),
185 #endif
186 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
187 	.rfo_enable = GPIO_DT_SPEC_INST_GET(0, rfo_enable_gpios),
188 #endif
189 #if DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
190 	.pa_boost_enable = GPIO_DT_SPEC_INST_GET(0, pa_boost_enable_gpios),
191 #endif
192 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_gpios)
193 	.tcxo_power = GPIO_DT_SPEC_INST_GET(0, tcxo_power_gpios),
194 #endif
195 };
196 
197 static struct sx127x_data {
198 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios) &&	\
199 	DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
200 	uint8_t tx_power;
201 #endif
202 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_gpios)
203 	bool tcxo_power_enabled;
204 #endif
205 	struct k_work dio_work[SX127X_MAX_DIO];
206 } dev_data;
207 
clamp_int8(int8_t x,int8_t min,int8_t max)208 static int8_t clamp_int8(int8_t x, int8_t min, int8_t max)
209 {
210 	if (x < min) {
211 		return min;
212 	} else if (x > max) {
213 		return max;
214 	} else {
215 		return x;
216 	}
217 }
218 
SX127xCheckRfFrequency(uint32_t frequency)219 bool SX127xCheckRfFrequency(uint32_t frequency)
220 {
221 	/* TODO */
222 	return true;
223 }
224 
SX127xGetBoardTcxoWakeupTime(void)225 uint32_t SX127xGetBoardTcxoWakeupTime(void)
226 {
227 	return TCXO_POWER_STARTUP_DELAY_MS;
228 }
229 
sx127x_antenna_enable(int val)230 static inline void sx127x_antenna_enable(int val)
231 {
232 #if DT_INST_NODE_HAS_PROP(0, antenna_enable_gpios)
233 	gpio_pin_set_dt(&dev_config.antenna_enable, val);
234 #endif
235 }
236 
sx127x_rfi_enable(int val)237 static inline void sx127x_rfi_enable(int val)
238 {
239 #if DT_INST_NODE_HAS_PROP(0, rfi_enable_gpios)
240 	gpio_pin_set_dt(&dev_config.rfi_enable, val);
241 #endif
242 }
243 
sx127x_rfo_enable(int val)244 static inline void sx127x_rfo_enable(int val)
245 {
246 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios)
247 	gpio_pin_set_dt(&dev_config.rfo_enable, val);
248 #endif
249 }
250 
sx127x_pa_boost_enable(int val)251 static inline void sx127x_pa_boost_enable(int val)
252 {
253 #if DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
254 	gpio_pin_set_dt(&dev_config.pa_boost_enable, val);
255 #endif
256 }
257 
SX127xSetAntSwLowPower(bool low_power)258 void SX127xSetAntSwLowPower(bool low_power)
259 {
260 	if (low_power) {
261 		/* force inactive (low power) state of all antenna paths */
262 		sx127x_rfi_enable(0);
263 		sx127x_rfo_enable(0);
264 		sx127x_pa_boost_enable(0);
265 
266 		sx127x_antenna_enable(0);
267 	} else {
268 		sx127x_antenna_enable(1);
269 
270 		/* rely on SX127xSetAntSw() to configure proper antenna path */
271 	}
272 }
273 
SX127xSetBoardTcxo(uint8_t state)274 void SX127xSetBoardTcxo(uint8_t state)
275 {
276 #if DT_INST_NODE_HAS_PROP(0, tcxo_power_gpios)
277 	bool enable = state;
278 
279 	if (enable == dev_data.tcxo_power_enabled) {
280 		return;
281 	}
282 
283 	if (enable) {
284 		gpio_pin_set_dt(&dev_config.tcxo_power, 1);
285 
286 		if (TCXO_POWER_STARTUP_DELAY_MS > 0) {
287 			k_sleep(K_MSEC(TCXO_POWER_STARTUP_DELAY_MS));
288 		}
289 	} else {
290 		gpio_pin_set_dt(&dev_config.tcxo_power, 0);
291 	}
292 
293 	dev_data.tcxo_power_enabled = enable;
294 #endif
295 }
296 
SX127xSetAntSw(uint8_t opMode)297 void SX127xSetAntSw(uint8_t opMode)
298 {
299 	switch (opMode) {
300 	case RFLR_OPMODE_TRANSMITTER:
301 		sx127x_rfi_enable(0);
302 
303 		if (SX127X_PA_OUTPUT(dev_data.tx_power) == SX127X_PA_BOOST) {
304 			sx127x_rfo_enable(0);
305 			sx127x_pa_boost_enable(1);
306 		} else {
307 			sx127x_pa_boost_enable(0);
308 			sx127x_rfo_enable(1);
309 		}
310 		break;
311 	default:
312 		sx127x_rfo_enable(0);
313 		sx127x_pa_boost_enable(0);
314 		sx127x_rfi_enable(1);
315 		break;
316 	}
317 }
318 
SX127xReset(void)319 void SX127xReset(void)
320 {
321 	SX127xSetBoardTcxo(true);
322 
323 	gpio_pin_set_dt(&dev_config.reset, 1);
324 
325 	k_sleep(K_MSEC(1));
326 
327 	gpio_pin_set_dt(&dev_config.reset, 0);
328 
329 	k_sleep(K_MSEC(6));
330 }
331 
sx127x_dio_work_handle(struct k_work * work)332 static void sx127x_dio_work_handle(struct k_work *work)
333 {
334 	int dio = work - dev_data.dio_work;
335 
336 	(*DioIrq[dio])(NULL);
337 }
338 
sx127x_irq_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)339 static void sx127x_irq_callback(const struct device *dev,
340 				struct gpio_callback *cb, uint32_t pins)
341 {
342 	unsigned int i, pin;
343 
344 	pin = find_lsb_set(pins) - 1;
345 
346 	for (i = 0; i < SX127X_MAX_DIO; i++) {
347 		if (dev == sx127x_dios[i].port &&
348 		    pin == sx127x_dios[i].pin) {
349 			k_work_submit(&dev_data.dio_work[i]);
350 		}
351 	}
352 }
353 
SX127xIoIrqInit(DioIrqHandler ** irqHandlers)354 void SX127xIoIrqInit(DioIrqHandler **irqHandlers)
355 {
356 	unsigned int i;
357 	static struct gpio_callback callbacks[SX127X_MAX_DIO];
358 
359 	/* Setup DIO gpios */
360 	for (i = 0; i < SX127X_MAX_DIO; i++) {
361 		if (!irqHandlers[i]) {
362 			continue;
363 		}
364 
365 		if (!gpio_is_ready_dt(&sx127x_dios[i])) {
366 			LOG_ERR("GPIO port %s not ready",
367 				sx127x_dios[i].port->name);
368 			return;
369 		}
370 
371 		k_work_init(&dev_data.dio_work[i], sx127x_dio_work_handle);
372 
373 		gpio_pin_configure_dt(&sx127x_dios[i], GPIO_INPUT);
374 
375 		gpio_init_callback(&callbacks[i],
376 				   sx127x_irq_callback,
377 				   BIT(sx127x_dios[i].pin));
378 
379 		if (gpio_add_callback(sx127x_dios[i].port, &callbacks[i]) < 0) {
380 			LOG_ERR("Could not set gpio callback.");
381 			return;
382 		}
383 		gpio_pin_interrupt_configure_dt(&sx127x_dios[i],
384 						GPIO_INT_EDGE_TO_ACTIVE);
385 	}
386 
387 }
388 
sx127x_transceive(uint8_t reg,bool write,void * data,size_t length)389 static int sx127x_transceive(uint8_t reg, bool write, void *data, size_t length)
390 {
391 	const struct spi_buf buf[2] = {
392 		{
393 			.buf = &reg,
394 			.len = sizeof(reg)
395 		},
396 		{
397 			.buf = data,
398 			.len = length
399 		}
400 	};
401 
402 	struct spi_buf_set tx = {
403 		.buffers = buf,
404 		.count = ARRAY_SIZE(buf),
405 	};
406 
407 	if (!write) {
408 		const struct spi_buf_set rx = {
409 			.buffers = buf,
410 			.count = ARRAY_SIZE(buf)
411 		};
412 
413 		return spi_transceive_dt(&dev_config.bus, &tx, &rx);
414 	}
415 
416 	return spi_write_dt(&dev_config.bus, &tx);
417 }
418 
sx127x_read(uint8_t reg_addr,uint8_t * data,uint8_t len)419 int sx127x_read(uint8_t reg_addr, uint8_t *data, uint8_t len)
420 {
421 	return sx127x_transceive(reg_addr, false, data, len);
422 }
423 
sx127x_write(uint8_t reg_addr,uint8_t * data,uint8_t len)424 int sx127x_write(uint8_t reg_addr, uint8_t *data, uint8_t len)
425 {
426 	return sx127x_transceive(reg_addr | BIT(7), true, data, len);
427 }
428 
SX127xWriteBuffer(uint32_t addr,uint8_t * buffer,uint8_t size)429 void SX127xWriteBuffer(uint32_t addr, uint8_t *buffer, uint8_t size)
430 {
431 	int ret;
432 
433 	ret = sx127x_write(addr, buffer, size);
434 	if (ret < 0) {
435 		LOG_ERR("Unable to write address: 0x%x", addr);
436 	}
437 }
438 
SX127xReadBuffer(uint32_t addr,uint8_t * buffer,uint8_t size)439 void SX127xReadBuffer(uint32_t addr, uint8_t *buffer, uint8_t size)
440 {
441 	int ret;
442 
443 	ret = sx127x_read(addr, buffer, size);
444 	if (ret < 0) {
445 		LOG_ERR("Unable to read address: 0x%x", addr);
446 	}
447 }
448 
SX127xSetRfTxPower(int8_t power)449 void SX127xSetRfTxPower(int8_t power)
450 {
451 	int ret;
452 	uint8_t pa_config = 0;
453 	uint8_t pa_dac = 0;
454 
455 	ret = sx127x_read(REG_PADAC, &pa_dac, 1);
456 	if (ret < 0) {
457 		LOG_ERR("Unable to read PA dac");
458 		return;
459 	}
460 
461 	pa_dac &= ~SX127X_PADAC_20DBM_MASK;
462 
463 	if (SX127X_PA_OUTPUT(power) == SX127X_PA_BOOST) {
464 		power = clamp_int8(power, 2, 20);
465 
466 		pa_config |= SX127X_PACONFIG_PASELECT_PABOOST;
467 		if (power > 17) {
468 			pa_dac |= SX127X_PADAC_20DBM_ON;
469 			pa_config |= (power - 5) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
470 		} else {
471 			pa_dac |= SX127X_PADAC_20DBM_OFF;
472 			pa_config |= (power - 2) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
473 		}
474 	} else {
475 #ifdef SX127X_PACONFIG_MAX_POWER_SHIFT
476 		power = clamp_int8(power, -4, 15);
477 
478 		pa_dac |= SX127X_PADAC_20DBM_OFF;
479 		if (power > 0) {
480 			/* Set the power range to 0 -- 10.8+0.6*7 dBm */
481 			pa_config |= 7 << SX127X_PACONFIG_MAX_POWER_SHIFT;
482 			pa_config |= power & SX127X_PACONFIG_OUTPUTPOWER_MASK;
483 		} else {
484 			/* Set the power range to -4.2 -- 10.8+0.6*0 dBm */
485 			pa_config |= (power + 4) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
486 		}
487 #else
488 		power = clamp_int8(power, -1, 14);
489 
490 		pa_dac |= SX127X_PADAC_20DBM_OFF;
491 		pa_config |= (power + 1) & SX127X_PACONFIG_OUTPUTPOWER_MASK;
492 #endif
493 	}
494 
495 #if DT_INST_NODE_HAS_PROP(0, rfo_enable_gpios) &&	\
496 	DT_INST_NODE_HAS_PROP(0, pa_boost_enable_gpios)
497 	dev_data.tx_power = power;
498 #endif
499 
500 	ret = sx127x_write(REG_PACONFIG, &pa_config, 1);
501 	if (ret < 0) {
502 		LOG_ERR("Unable to write PA config");
503 		return;
504 	}
505 
506 	ret = sx127x_write(REG_PADAC, &pa_dac, 1);
507 	if (ret < 0) {
508 		LOG_ERR("Unable to write PA dac");
509 		return;
510 	}
511 }
512 
SX127xGetDio1PinState(void)513 uint32_t SX127xGetDio1PinState(void)
514 {
515 #if SX127X_DIO_GPIO_LEN(0) >= 2
516 	if (gpio_pin_get_dt(&sx127x_dios[1]) > 0) {
517 		return 1U;
518 	}
519 #endif
520 
521 	return 0U;
522 }
523 
524 /* Initialize Radio driver callbacks */
525 const struct Radio_s Radio = {
526 	.Init = SX127xInit,
527 	.GetStatus = SX127xGetStatus,
528 	.SetModem = SX127xSetModem,
529 	.SetChannel = SX127xSetChannel,
530 	.IsChannelFree = SX127xIsChannelFree,
531 	.Random = SX127xRandom,
532 	.SetRxConfig = SX127xSetRxConfig,
533 	.SetTxConfig = SX127xSetTxConfig,
534 	.CheckRfFrequency = SX127xCheckRfFrequency,
535 	.TimeOnAir = SX127xGetTimeOnAir,
536 	.Send = SX127xSend,
537 	.Sleep = SX127xSetSleep,
538 	.Standby = SX127xSetStby,
539 	.Rx = SX127xSetRx,
540 	.Write = SX127xWrite,
541 	.Read = SX127xRead,
542 	.WriteBuffer = SX127xWriteBuffer,
543 	.ReadBuffer = SX127xReadBuffer,
544 	.SetMaxPayloadLength = SX127xSetMaxPayloadLength,
545 	.SetPublicNetwork = SX127xSetPublicNetwork,
546 	.GetWakeupTime = SX127xGetWakeupTime,
547 	.IrqProcess = NULL,
548 	.RxBoosted = NULL,
549 	.SetRxDutyCycle = NULL,
550 	.SetTxContinuousWave = SX127xSetTxContinuousWave,
551 };
552 
sx127x_antenna_configure(void)553 static int sx127x_antenna_configure(void)
554 {
555 	int ret;
556 
557 	ret = sx12xx_configure_pin(antenna_enable, GPIO_OUTPUT_INACTIVE);
558 	if (ret) {
559 		return ret;
560 	}
561 
562 	ret = sx12xx_configure_pin(rfi_enable, GPIO_OUTPUT_INACTIVE);
563 	if (ret) {
564 		return ret;
565 	}
566 
567 	ret = sx12xx_configure_pin(rfo_enable, GPIO_OUTPUT_INACTIVE);
568 	if (ret) {
569 		return ret;
570 	}
571 
572 	ret = sx12xx_configure_pin(pa_boost_enable, GPIO_OUTPUT_INACTIVE);
573 	if (ret) {
574 		return ret;
575 	}
576 
577 	return 0;
578 }
579 
sx127x_lora_init(const struct device * dev)580 static int sx127x_lora_init(const struct device *dev)
581 {
582 	int ret;
583 	uint8_t regval;
584 
585 	if (!spi_is_ready_dt(&dev_config.bus)) {
586 		LOG_ERR("SPI device not ready");
587 		return -ENODEV;
588 	}
589 
590 	ret = sx12xx_configure_pin(tcxo_power, GPIO_OUTPUT_INACTIVE);
591 	if (ret) {
592 		return ret;
593 	}
594 
595 	/* Setup Reset gpio and perform soft reset */
596 	ret = sx12xx_configure_pin(reset, GPIO_OUTPUT_ACTIVE);
597 	if (ret) {
598 		return ret;
599 	}
600 
601 	k_sleep(K_MSEC(100));
602 	gpio_pin_set_dt(&dev_config.reset, 0);
603 	k_sleep(K_MSEC(100));
604 
605 	ret = sx127x_read(REG_VERSION, &regval, 1);
606 	if (ret < 0) {
607 		LOG_ERR("Unable to read version info");
608 		return -EIO;
609 	}
610 
611 	LOG_INF("SX127x version 0x%02x found", regval);
612 
613 	ret = sx127x_antenna_configure();
614 	if (ret < 0) {
615 		LOG_ERR("Unable to configure antenna");
616 		return -EIO;
617 	}
618 
619 	ret = sx12xx_init(dev);
620 	if (ret < 0) {
621 		LOG_ERR("Failed to initialize SX12xx common");
622 		return ret;
623 	}
624 
625 	return 0;
626 }
627 
628 static const struct lora_driver_api sx127x_lora_api = {
629 	.config = sx12xx_lora_config,
630 	.send = sx12xx_lora_send,
631 	.send_async = sx12xx_lora_send_async,
632 	.recv = sx12xx_lora_recv,
633 	.recv_async = sx12xx_lora_recv_async,
634 	.test_cw = sx12xx_lora_test_cw,
635 };
636 
637 DEVICE_DT_INST_DEFINE(0, &sx127x_lora_init, NULL, NULL,
638 		      NULL, POST_KERNEL, CONFIG_LORA_INIT_PRIORITY,
639 		      &sx127x_lora_api);
640