Commit 874bcba6 authored by Marcus Wolf's avatar Marcus Wolf Committed by Greg Kroah-Hartman

staging: pi433: New driver

Added a driver for the pi433 radio module
(see https://www.pi433.de/en.html for details).
Signed-off-by: default avatarMarcus Wolf <linux@Wolf-Entwicklungen.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 07119e25
......@@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig"
source "drivers/staging/typec/Kconfig"
source "drivers/staging/pi433/Kconfig"
endif # STAGING
......@@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/
obj-$(CONFIG_PI433) += pi433/
// Definitions for Pi433
/dts-v1/;
/plugin/;
/ {
compatible = "bcm,bcm2835", "bcm,bcm2708", "bcm,bcm2709";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
spidev@0{
status = "disabled";
};
spidev@1{
status = "disabled";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
pi433_pins: pi433_pins {
brcm,pins = <7 25 24>;
brcm,function = <0 0 0>; // in in in
};
};
};
fragment@2 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
pi433: pi433@0 {
compatible = "Smarthome-Wolf,pi433";
reg = <0>;
spi-max-frequency = <10000000>;
status = "okay";
pinctrl-0 = <&pi433_pins>;
DIO0-gpio = <&gpio 24 0>;
DIO1-gpio = <&gpio 25 0>;
DIO2-gpio = <&gpio 7 0>;
};
};
};
};
* Smarthome-Wolf Pi433 - a 433MHz radio module/shield for Raspberry Pi (see www.pi433.de)
Required properties:
- compatible: must be "Smarthome-Wolf,pi433"
- reg: chip select of SPI Interface
- DIOx-gpio must be dedicated to the GPIO, connected with DIOx of the RFM69 module
Example:
With the following lines in gpio-section, the gpio pins, connected with pi433 are
reserved/declared.
&gpio{
[...]
pi433_pins: pi433_pins {
brcm,pins = <7 25 24>;
brcm,function = <0 0 0>; // in in in
};
[...]
}
With the following lines in spi section, the device pi433 is declared.
It consists of the three gpio pins and an spi interface (here chip select 0)
&spi0{
[...]
pi433: pi433@0 {
compatible = "Smarthome-Wolf,pi433";
reg = <0>; /* CE 0 */
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <10000000>;
pinctrl-0 = <&pi433_pins>;
DIO0-gpio = <&gpio 24 0>;
DIO1-gpio = <&gpio 25 0>;
DIO2-gpio = <&gpio 7 0>;
};
}
For Raspbian users only
=======================
Since Raspbian supports device tree overlays, you may use and overlay, instead
of editing your boards device tree.
For using the overlay, you need to compile the file pi433-overlay.dts you can
find aside to this documentation.
The file needs to be compiled - either manually or by integration in your kernel
source tree. For a manual compile, you may use a command line like the following:
'linux/scripts/dtc/dtc -@ -I dts -O dtb -o pi433.dtbo pi433-overlay.dts'
For compiling inside of the kernel tree, you need to copy pi433-overlay.dts to
arch/arm/boot/dts/overlays and you need to add the file to the list of files
in the Makefile over there. Execute 'make dtbs' in kernel tree root to make the
kernel make files compile the device tree overlay for you.
This diff is collapsed.
config PI433
tristate "Pi433 - a 433MHz radio module for Raspberry Pi"
default n
---help---
This option allows you to enable support for the radio module Pi433.
Pi433 is a shield that fits onto the GPIO header of a Raspberry Pi
or compatible. It extends the Raspberry Pi with the option, to
send and receive data in the 433MHz ISM band - for example to
communicate between two systems without using ethernet or bluetooth
or for control or read sockets, actors, sensors, widely available
for low price.
For details or the option to buy, please visit https://pi433.de/en.html
If in doubt, say N here, but saying yes most probably won't hurt
obj-$(CONFIG_PI433) += pi433.o
pi433-objs := pi433_if.o rf69.o
* coding style does not fully comply with the kernel style guide.
* still TODOs, annotated in the code
* currently the code introduces new IOCTLs. I'm afraid this is a bad idea.
-> Replace this with another interface, hints are welcome!
* Some missing data (marked with ###) needs to be added in the documentation
This diff is collapsed.
/*
* include/linux/TODO
*
* 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.
*/
#ifndef PI433_H
#define PI433_H
#include <linux/types.h>
#include "rf69_enum.h"
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* IOCTL structs and commands */
/**
* struct pi433_tx_config - describes the configuration of the radio module for sending
* @frequency:
* @bit_rate:
* @modulation:
* @data_mode:
* @preamble_length:
* @sync_pattern:
* @tx_start_condition:
* @payload_length:
* @repetitions:
*
* ATTENTION:
* If the contents of 'pi433_tx_config' ever change
* incompatibly, then the ioctl number (see define below) must change.
*
* NOTE: struct layout is the same in 64bit and 32bit userspace.
*/
#define PI433_TX_CFG_IOCTL_NR 0
struct pi433_tx_cfg
{
__u32 frequency;
__u16 bit_rate;
__u32 dev_frequency;
enum modulation modulation;
enum modShaping modShaping;
enum paRamp pa_ramp;
enum txStartCondition tx_start_condition;
__u16 repetitions;
/* packet format */
enum optionOnOff enable_preamble;
enum optionOnOff enable_sync;
enum optionOnOff enable_length_byte;
enum optionOnOff enable_address_byte;
enum optionOnOff enable_crc;
__u16 preamble_length;
__u8 sync_length;
__u8 fixed_message_length;
__u8 sync_pattern[8];
__u8 address_byte;
};
/**
* struct pi433_rx_config - describes the configuration of the radio module for sending
* @frequency:
* @bit_rate:
* @modulation:
* @data_mode:
* @preamble_length:
* @sync_pattern:
* @tx_start_condition:
* @payload_length:
* @repetitions:
*
* ATTENTION:
* If the contents of 'pi433_rx_config' ever change
* incompatibly, then the ioctl number (see define below) must change
*
* NOTE: struct layout is the same in 64bit and 32bit userspace.
*/
#define PI433_RX_CFG_IOCTL_NR 1
struct pi433_rx_cfg {
__u32 frequency;
__u16 bit_rate;
__u32 dev_frequency;
enum modulation modulation;
__u8 rssi_threshold;
enum thresholdDecrement thresholdDecrement;
enum antennaImpedance antenna_impedance;
enum lnaGain lna_gain;
enum mantisse bw_mantisse; /* normal: 0x50 */
__u8 bw_exponent; /* during AFC: 0x8b */
enum dagc dagc;
/* packet format */
enum optionOnOff enable_sync;
enum optionOnOff enable_length_byte; /* should be used in combination with sync, only */
enum addressFiltering enable_address_filtering; /* operational with sync, only */
enum optionOnOff enable_crc; /* only operational, if sync on and fixed length or length byte is used */
__u8 sync_length;
__u8 fixed_message_length;
__u32 bytes_to_drop;
__u8 sync_pattern[8];
__u8 node_address;
__u8 broadcast_address;
};
#define PI433_IOC_MAGIC 'r'
#define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)])
#define PI433_IOC_WR_TX_CFG _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)])
#define PI433_IOC_RD_RX_CFG _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)])
#define PI433_IOC_WR_RX_CFG _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)])
#endif /* PI433_H */
This diff is collapsed.
/*
* hardware abstraction/register access for HopeRf rf69 radio module
*
* 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.
*/
#ifndef RF69_H
#define RF69_H
#include "rf69_enum.h"
#include "rf69_registers.h"
#define F_OSC 32000000 /* in Hz */
#define FREQUENCY 433920000 /* in Hz, modifying this value impacts CE certification */
#define FIFO_SIZE 66 /* in byte */
#define FIFO_THRESHOLD 15 /* in byte */
int rf69_set_mode(struct spi_device *spi, enum mode mode);
int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode);
int rf69_set_modulation(struct spi_device *spi, enum modulation modulation);
enum modulation rf69_get_modulation(struct spi_device *spi);
int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping);
int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate);
int rf69_set_deviation(struct spi_device *spi, u32 deviation);
int rf69_set_frequency(struct spi_device *spi, u32 frequency);
int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff);
int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff);
int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff);
int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel);
int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp);
int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance);
int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain);
enum lnaGain rf69_get_lna_gain(struct spi_device *spi);
int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi, u8 reg, enum dccPercent dccPercent);
int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent);
int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent);
int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent);
int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent);
int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType);
int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep);
int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement);
int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value);
bool rf69_get_flag(struct spi_device *spi, enum flag flag);
int rf69_reset_flag(struct spi_device *spi, enum flag flag);
int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold);
int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout);
int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout);
int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength);
int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff);
int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition);
int rf69_set_sync_size(struct spi_device *spi, u8 sync_size);
int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance);
int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]);
int rf69_set_packet_format(struct spi_device * spi, enum packetFormat packetFormat);
int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff);
int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering);
int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength);
u8 rf69_get_payload_length(struct spi_device *spi);
int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress);
int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress);
int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition);
int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold);
int rf69_set_dagc(struct spi_device *spi, enum dagc dagc);
int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size);
int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size);
u8 rf69_read_reg (struct spi_device *spi, u8 addr);
int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value);
#endif
/*
* enumerations for HopeRf rf69 radio module
*
* 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.
*/
#ifndef RF69_ENUM_H
#define RF69_ENUM_H
enum optionOnOff
{
optionOff,
optionOn
};
enum mode
{
mode_sleep,
standby,
synthesizer,
transmit,
receive
};
enum dataMode
{
packet,
continuous,
continuousNoSync
};
enum modulation
{
OOK,
FSK
};
enum modShaping
{
shapingOff,
shaping1_0,
shaping0_5,
shaping0_3,
shapingBR,
shaping2BR
};
enum paRamp
{
ramp3400,
ramp2000,
ramp1000,
ramp500,
ramp250,
ramp125,
ramp100,
ramp62,
ramp50,
ramp40,
ramp31,
ramp25,
ramp20,
ramp15,
ramp12,
ramp10
};
enum antennaImpedance
{
fiftyOhm,
twohundretOhm
};
enum lnaGain
{
automatic,
max,
maxMinus6,
maxMinus12,
maxMinus24,
maxMinus36,
maxMinus48,
undefined
};
enum dccPercent
{
dcc16Percent,
dcc8Percent,
dcc4Percent,
dcc2Percent,
dcc1Percent,
dcc0_5Percent,
dcc0_25Percent,
dcc0_125Percent
};
enum mantisse
{
mantisse16,
mantisse20,
mantisse24
};
enum thresholdType
{
fixed,
peak,
average
};
enum thresholdStep
{
step_0_5db,
step_1_0db,
step_1_5db,
step_2_0db,
step_3_0db,
step_4_0db,
step_5_0db,
step_6_0db
};
enum thresholdDecrement
{
dec_every8th,
dec_every4th,
dec_every2nd,
dec_once,
dec_twice,
dec_4times,
dec_8times,
dec_16times
};
enum flag
{
modeSwitchCompleted,
readyToReceive,
readyToSend,
pllLocked,
rssiExceededThreshold,
timeout,
automode,
syncAddressMatch,
fifoFull,
// fifoNotEmpty, collision with next enum; replaced by following enum...
fifoEmpty,
fifoLevelBelowThreshold,
fifoOverrun,
packetSent,
payloadReady,
crcOk,
batteryLow
};
enum fifoFillCondition
{
afterSyncInterrupt,
always
};
enum packetFormat
{
packetLengthFix,
packetLengthVar
};
enum txStartCondition
{
fifoLevel,
fifoNotEmpty
};
enum addressFiltering
{
filteringOff,
nodeAddress,
nodeOrBroadcastAddress
};
enum dagc
{
normalMode,
improve,
improve4LowModulationIndex
};
#endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment