/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Semtech LR11xx private driver header.
 * Defines SPI opcodes, register constants, and internal types.
 */

#ifndef LR11XX_H
#define LR11XX_H

#include <stdint.h>
#include <stddef.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>

/* ── SPI opcode definitions ──────────────────────────────────────────────── */

/* System commands */
#define LR11XX_CMD_RESET_STATS            0x0200u
#define LR11XX_CMD_GET_STATUS             0x0100u
#define LR11XX_CMD_SET_STANDBY            0x011Bu  /* Note: opcode varies by fw */
#define LR11XX_CMD_SET_PACKET_TYPE        0x010Au
#define LR11XX_CMD_SET_RF_FREQUENCY       0x010Eu
#define LR11XX_CMD_SET_MODULATION_PARAMS  0x0115u
#define LR11XX_CMD_SET_PACKET_PARAMS      0x0116u
#define LR11XX_CMD_SET_TX_PARAMS          0x0110u
#define LR11XX_CMD_SET_DIO_IRQ_PARAMS     0x0113u
#define LR11XX_CMD_CLEAR_IRQ_STATUS       0x0114u
#define LR11XX_CMD_GET_IRQ_STATUS         0x0112u
#define LR11XX_CMD_SET_RX                 0x0107u
#define LR11XX_CMD_SET_TX                 0x0108u
#define LR11XX_CMD_GET_RX_BUFFER_STATUS   0x011Cu
#define LR11XX_CMD_READ_BUFFER            0x011Eu
#define LR11XX_CMD_GET_PACKET_STATUS      0x011Du
#define LR11XX_CMD_SET_BUFFER_BASE_ADDR   0x010Fu

/* Packet type: LoRa = 0x01 */
#define LR11XX_PKT_TYPE_LORA              0x01u

/* Standby mode: RC oscillator = 0x00, XOSC = 0x01 */
#define LR11XX_STANDBY_RC                 0x00u
#define LR11XX_STANDBY_XOSC              0x01u

/* IRQ bitmasks */
#define LR11XX_IRQ_TX_DONE                BIT(2)
#define LR11XX_IRQ_RX_DONE                BIT(3)
#define LR11XX_IRQ_TIMEOUT                BIT(8)
#define LR11XX_IRQ_CRC_ERROR              BIT(10)
#define LR11XX_IRQ_ALL                    0xFFFFFFFFu

/* DIO mask for routing IRQs to EVENT/DIO9 */
#define LR11XX_DIO9_MASK   (LR11XX_IRQ_TX_DONE | LR11XX_IRQ_RX_DONE | \
			    LR11XX_IRQ_TIMEOUT | LR11XX_IRQ_CRC_ERROR)

/* LoRa spreading factor codes */
#define LR11XX_LORA_SF5   0x05u
#define LR11XX_LORA_SF6   0x06u
#define LR11XX_LORA_SF7   0x07u
#define LR11XX_LORA_SF8   0x08u
#define LR11XX_LORA_SF9   0x09u
#define LR11XX_LORA_SF10  0x0Au
#define LR11XX_LORA_SF11  0x0Bu
#define LR11XX_LORA_SF12  0x0Cu

/* LoRa bandwidth codes */
#define LR11XX_LORA_BW_125  0x04u
#define LR11XX_LORA_BW_250  0x05u
#define LR11XX_LORA_BW_500  0x06u

/* LoRa coding rate codes */
#define LR11XX_LORA_CR_4_5  0x01u
#define LR11XX_LORA_CR_4_6  0x02u
#define LR11XX_LORA_CR_4_7  0x03u
#define LR11XX_LORA_CR_4_8  0x04u

/* RX timeout: 0 = continuous, 0xFFFFFF = single (timeout on preamble) */
#define LR11XX_RX_CONTINUOUS  0x000000u

/* ── Driver config/data structures ───────────────────────────────────────── */

struct lr11xx_config {
	struct spi_dt_spec spi;
	struct gpio_dt_spec reset;
	struct gpio_dt_spec busy;
	struct gpio_dt_spec event;
};

struct lr11xx_data {
	struct gpio_callback event_cb;
	struct k_sem         event_sem;
	uint32_t             last_irq;
};

/* ── HAL function prototypes (implemented in lr11xx_hal.c) ───────────────── */

int  lr11xx_hal_reset(const struct device *dev);
int  lr11xx_hal_wait_busy(const struct device *dev, k_timeout_t timeout);
int  lr11xx_hal_write_cmd(const struct device *dev,
			  uint16_t opcode,
			  const uint8_t *params, size_t params_len);
int  lr11xx_hal_read_resp(const struct device *dev,
			  uint8_t *buf, size_t len);
void lr11xx_hal_event_handler(const struct device *port,
			      struct gpio_callback *cb, uint32_t pins);

#endif /* LR11XX_H */
