/*
* userspace interface for pi433 radio module
*
* Pi433 is a 433MHz radio module for the Raspberry Pi.
* It is based on the HopeRf Module RFM69CW. Therefore inside of this
* driver, you'll find an abstraction of the rf69 chip.
*
* If needed, this driver could be extended, to also support other
* devices, basing on HopeRfs rf69.
*
* The driver can also be extended, to support other modules of
* HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ...
*
* Copyright (C) 2016 Wolf-Entwicklungen
* Marcus Wolf <linux@wolf-entwicklungen.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#undef DEBUG
#include <linux/init.h>
#include <linux/module.h>
#include <linux/idr.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/err.h>
#include <linux/kfifo.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio/consumer.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/spi/spi.h>
#ifdef CONFIG_COMPAT
#include <asm/compat.h>
#endif
#include "pi433_if.h"
#include "rf69.h"
#define N_PI433_MINORS (1U << MINORBITS) /*32*/ /* ... up to 256 */
#define MAX_MSG_SIZE 900 /* min: FIFO_SIZE! */
#define MSG_FIFO_SIZE 65536 /* 65536 = 2^16 */
#define NUM_DIO 2
static dev_t pi433_dev;
static DEFINE_IDR(pi433_idr);
static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */
static struct class *pi433_class; /* mainly for udev to create /dev/pi433 */
/* tx config is instance specific
* so with each open a new tx config struct is needed
*/
/* rx config is device specific
* so we have just one rx config, ebedded in device struct
*/
struct pi433_device {
/* device handling related values */
dev_t devt;
int minor;
struct device *dev;
struct cdev *cdev;
struct spi_device *spi;
unsigned users;
/* irq related values */
struct gpio_desc *gpiod[NUM_DIO];
int irq_num[NUM_DIO];
u8 irq_state[NUM_DIO];
/* tx related values */
STRUCT_KFIFO_REC_1(MSG_FIFO_SIZE) tx_fifo;
struct mutex tx_fifo_lock; // TODO: check, whether necessary or obsolete
struct task_struct *tx_task_struct;
wait_queue_head_t tx_wait_queue;
u8 free_in_fifo;
char buffer[MAX_MSG_SIZE];
/* rx related values */
struct pi433_rx_cfg rx_cfg;