summaryrefslogtreecommitdiff
path: root/drivers/staging/pi433/pi433_if.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-28 22:50:50 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-28 22:50:50 +0300
commitdfdc1de64248b5e1024d8188aeaf0e59ec6cecd5 (patch)
treea1ced75e6a54c6dc0f7e41bbf517012bb0d21af6 /drivers/staging/pi433/pi433_if.c
parent266d17a8c0d857a579813ad185cd1640b0d6ccac (diff)
parent41197a5f11a4b2d11ac19bc62552022153032811 (diff)
downloadlinux-dfdc1de64248b5e1024d8188aeaf0e59ec6cecd5.tar.xz
Merge tag 'staging-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH: "Here is the big set of staging driver updates for 5.18-rc1. Loads of tiny cleanups for almost all staging drivers in here, nothing major at all. Highlights include: - remove the ashmem Android driver. It is long-dead and if there are any legacy userspace applications still using it, the Android kernel images will maintain it, the community shouldn't care about it anymore - wfx wifi driver major cleanups. Should be ready to merge out of staging soon, and will coordinate with the wifi maintainers after -rc1 is out - major cleanups and unwinding of the layers of the r8188eu driver. It's amazing just how many unneeded layers of abstraction is in there, just when we think it's done, another is found... - lots of tiny coding style cleanups in many other staging drivers. All have been in linux-next for a while with no reported problems" * tag 'staging-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (455 commits) staging: r8188eu: remove unnecessary memset in r8188eu staging: greybus: introduce pwm_ops::apply staging: rts5208: Resolve checkpatch.pl issues. staging: sm750fb: fix naming style staging: fbtft: Consider type of init sequence values in fbtft_init_display() staging: fbtft: Constify buf parameter in fbtft_dbg_hex() staging: mmal-vchiq: clear redundant item named bulk_scratch mips: dts: ralink: add MT7621 SoC staging: r8188eu: remove some unused local ieee80211 macros staging: r8188eu: make rtl8188e_process_phy_info static staging: r8188eu: remove unused function prototype staging: r8188eu: remove three unused receive defines staging: r8188eu: remove unnecessary initializations staging: rtl8192e: Fix spelling mistake "RESQUEST" -> "REQUEST" MAINTAINERS: remove the obsolete file entry for staging in ANDROID DRIVERS staging: r8188eu: proper error handling in rtw_init_drv_sw staging: r8188eu: call _cancel_timer_ex from _rtw_free_recv_priv staging: vt6656: Removed unused variable vt3342_vnt_threshold staging: vt6656: Removed unused variable bb_vga_0 staging: remove ashmem ...
Diffstat (limited to 'drivers/staging/pi433/pi433_if.c')
-rw-r--r--drivers/staging/pi433/pi433_if.c176
1 files changed, 130 insertions, 46 deletions
diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c
index 1d31c35875e3..941aaa7eab2e 100644
--- a/drivers/staging/pi433/pi433_if.c
+++ b/drivers/staging/pi433/pi433_if.c
@@ -41,6 +41,8 @@
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
#endif
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include "pi433_if.h"
#include "rf69.h"
@@ -108,6 +110,9 @@ struct pi433_device {
struct pi433_instance {
struct pi433_device *device;
struct pi433_tx_cfg tx_cfg;
+
+ /* control flags */
+ bool tx_cfg_initialized;
};
/*-------------------------------------------------------------------------*/
@@ -164,10 +169,10 @@ rf69_set_rx_cfg(struct pi433_device *dev, struct pi433_rx_cfg *rx_cfg)
ret = rf69_set_frequency(dev->spi, rx_cfg->frequency);
if (ret < 0)
return ret;
- ret = rf69_set_bit_rate(dev->spi, rx_cfg->bit_rate);
+ ret = rf69_set_modulation(dev->spi, rx_cfg->modulation);
if (ret < 0)
return ret;
- ret = rf69_set_modulation(dev->spi, rx_cfg->modulation);
+ ret = rf69_set_bit_rate(dev->spi, rx_cfg->bit_rate);
if (ret < 0)
return ret;
ret = rf69_set_antenna_impedance(dev->spi, rx_cfg->antenna_impedance);
@@ -287,10 +292,10 @@ rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg)
ret = rf69_set_frequency(dev->spi, tx_cfg->frequency);
if (ret < 0)
return ret;
- ret = rf69_set_bit_rate(dev->spi, tx_cfg->bit_rate);
+ ret = rf69_set_modulation(dev->spi, tx_cfg->modulation);
if (ret < 0)
return ret;
- ret = rf69_set_modulation(dev->spi, tx_cfg->modulation);
+ ret = rf69_set_bit_rate(dev->spi, tx_cfg->bit_rate);
if (ret < 0)
return ret;
ret = rf69_set_deviation(dev->spi, tx_cfg->dev_frequency);
@@ -359,8 +364,7 @@ rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg)
/*-------------------------------------------------------------------------*/
-static int
-pi433_start_rx(struct pi433_device *dev)
+static int pi433_start_rx(struct pi433_device *dev)
{
int retval;
@@ -400,8 +404,7 @@ pi433_start_rx(struct pi433_device *dev)
/*-------------------------------------------------------------------------*/
-static int
-pi433_receive(void *data)
+static int pi433_receive(void *data)
{
struct pi433_device *dev = data;
struct spi_device *spi = dev->spi;
@@ -411,7 +414,7 @@ pi433_receive(void *data)
dev->interrupt_rx_allowed = false;
/* wait for any tx to finish */
- dev_dbg(dev->dev, "rx: going to wait for any tx to finish");
+ dev_dbg(dev->dev, "rx: going to wait for any tx to finish\n");
retval = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active);
if (retval) {
/* wait was interrupted */
@@ -431,16 +434,16 @@ pi433_receive(void *data)
return retval;
/* now check RSSI, if low wait for getting high (RSSI interrupt) */
- while (!rf69_get_flag(dev->spi, rssi_exceeded_threshold)) {
+ while (!(rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI)) {
/* allow tx to interrupt us while waiting for high RSSI */
dev->interrupt_rx_allowed = true;
wake_up_interruptible(&dev->tx_wait_queue);
/* wait for RSSI level to become high */
- dev_dbg(dev->dev, "rx: going to wait for high RSSI level");
+ dev_dbg(dev->dev, "rx: going to wait for high RSSI level\n");
retval = wait_event_interruptible(dev->rx_wait_queue,
- rf69_get_flag(dev->spi,
- rssi_exceeded_threshold));
+ rf69_read_reg(spi, REG_IRQFLAGS1) &
+ MASK_IRQFLAGS1_RSSI);
if (retval) /* wait was interrupted */
goto abort;
dev->interrupt_rx_allowed = false;
@@ -464,11 +467,11 @@ pi433_receive(void *data)
goto abort;
}
bytes_total = dev->rx_cfg.fixed_message_length;
- dev_dbg(dev->dev, "rx: msg len set to %d by fixed length",
+ dev_dbg(dev->dev, "rx: msg len set to %d by fixed length\n",
bytes_total);
} else {
bytes_total = dev->rx_buffer_size;
- dev_dbg(dev->dev, "rx: msg len set to %d as requested by read",
+ dev_dbg(dev->dev, "rx: msg len set to %d as requested by read\n",
bytes_total);
}
@@ -485,7 +488,7 @@ pi433_receive(void *data)
goto abort;
}
dev->free_in_fifo++;
- dev_dbg(dev->dev, "rx: msg len reset to %d due to length byte",
+ dev_dbg(dev->dev, "rx: msg len reset to %d due to length byte\n",
bytes_total);
}
@@ -502,12 +505,12 @@ pi433_receive(void *data)
rf69_read_fifo(spi, &dummy, 1);
dev->free_in_fifo++;
- dev_dbg(dev->dev, "rx: address byte stripped off");
+ dev_dbg(dev->dev, "rx: address byte stripped off\n");
}
/* get payload */
while (dev->rx_position < bytes_total) {
- if (!rf69_get_flag(dev->spi, payload_ready)) {
+ if (!(rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY)) {
retval = wait_event_interruptible(dev->fifo_wait_queue,
dev->free_in_fifo < FIFO_SIZE);
if (retval) /* wait was interrupted */
@@ -552,8 +555,7 @@ abort:
return bytes_total;
}
-static int
-pi433_tx_thread(void *data)
+static int pi433_tx_thread(void *data)
{
struct pi433_device *device = data;
struct spi_device *spi = device->spi;
@@ -565,7 +567,7 @@ pi433_tx_thread(void *data)
while (1) {
/* wait for fifo to be populated or for request to terminate*/
- dev_dbg(device->dev, "thread: going to wait for new messages");
+ dev_dbg(device->dev, "thread: going to wait for new messages\n");
wait_event_interruptible(device->tx_wait_queue,
(!kfifo_is_empty(&device->tx_fifo) ||
kthread_should_stop()));
@@ -581,7 +583,7 @@ pi433_tx_thread(void *data)
retval = kfifo_out(&device->tx_fifo, &tx_cfg, sizeof(tx_cfg));
if (retval != sizeof(tx_cfg)) {
dev_dbg(device->dev,
- "reading tx_cfg from fifo failed: got %d byte(s), expected %d",
+ "reading tx_cfg from fifo failed: got %d byte(s), expected %d\n",
retval, (unsigned int)sizeof(tx_cfg));
continue;
}
@@ -589,7 +591,7 @@ pi433_tx_thread(void *data)
retval = kfifo_out(&device->tx_fifo, &size, sizeof(size_t));
if (retval != sizeof(size_t)) {
dev_dbg(device->dev,
- "reading msg size from fifo failed: got %d, expected %d",
+ "reading msg size from fifo failed: got %d, expected %d\n",
retval, (unsigned int)sizeof(size_t));
continue;
}
@@ -626,7 +628,7 @@ pi433_tx_thread(void *data)
retval = kfifo_out(&device->tx_fifo, &device->buffer[position],
sizeof(device->buffer) - position);
dev_dbg(device->dev,
- "read %d message byte(s) from fifo queue.", retval);
+ "read %d message byte(s) from fifo queue.\n", retval);
/*
* if rx is active, we need to interrupt the waiting for
@@ -731,7 +733,7 @@ pi433_tx_thread(void *data)
/* we are done. Wait for packet to get sent */
dev_dbg(device->dev,
- "thread: wait for packet to get sent/fifo to be empty");
+ "thread: wait for packet to get sent/fifo to be empty\n");
wait_event_interruptible(device->fifo_wait_queue,
device->free_in_fifo == FIFO_SIZE ||
kthread_should_stop());
@@ -739,7 +741,7 @@ pi433_tx_thread(void *data)
return 0;
/* STOP_TRANSMISSION */
- dev_dbg(device->dev, "thread: Packet sent. Set mode to stby.");
+ dev_dbg(device->dev, "thread: Packet sent. Set mode to stby.\n");
retval = rf69_set_mode(spi, standby);
if (retval < 0)
goto abort;
@@ -824,6 +826,16 @@ pi433_write(struct file *filp, const char __user *buf,
return -EMSGSIZE;
/*
+ * check if tx_cfg has been initialized otherwise we won't be able to
+ * config the RF trasmitter correctly due to invalid settings
+ */
+ if (!instance->tx_cfg_initialized) {
+ dev_notice_once(device->dev,
+ "write: failed due to unconfigured tx_cfg (see PI433_IOC_WR_TX_CFG)\n");
+ return -EINVAL;
+ }
+
+ /*
* write the following sequence into fifo:
* - tx_cfg
* - size of message
@@ -834,7 +846,7 @@ pi433_write(struct file *filp, const char __user *buf,
required = sizeof(instance->tx_cfg) + sizeof(size_t) + count;
available = kfifo_avail(&device->tx_fifo);
if (required > available) {
- dev_dbg(device->dev, "write to fifo failed: %d bytes required but %d available",
+ dev_dbg(device->dev, "write to fifo failed: %d bytes required but %d available\n",
required, available);
mutex_unlock(&device->tx_fifo_lock);
return -EAGAIN;
@@ -857,19 +869,18 @@ pi433_write(struct file *filp, const char __user *buf,
/* start transfer */
wake_up_interruptible(&device->tx_wait_queue);
- dev_dbg(device->dev, "write: generated new msg with %d bytes.", copied);
+ dev_dbg(device->dev, "write: generated new msg with %d bytes.\n", copied);
return copied;
abort:
dev_warn(device->dev,
- "write to fifo failed, non recoverable: 0x%x", retval);
+ "write to fifo failed, non recoverable: 0x%x\n", retval);
mutex_unlock(&device->tx_fifo_lock);
return -EAGAIN;
}
-static long
-pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+static long pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct pi433_instance *instance;
struct pi433_device *device;
@@ -897,6 +908,7 @@ pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return -EFAULT;
mutex_lock(&device->tx_fifo_lock);
memcpy(&instance->tx_cfg, &tx_cfg, sizeof(struct pi433_tx_cfg));
+ instance->tx_cfg_initialized = true;
mutex_unlock(&device->tx_fifo_lock);
break;
case PI433_IOC_RD_RX_CFG:
@@ -949,8 +961,6 @@ static int pi433_open(struct inode *inode, struct file *filp)
/* setup instance data*/
instance->device = device;
- instance->tx_cfg.bit_rate = 4711;
- // TODO: fill instance->tx_cfg;
/* instance data as context */
filp->private_data = instance;
@@ -990,12 +1000,12 @@ static int setup_gpio(struct pi433_device *device)
if (device->gpiod[i] == ERR_PTR(-ENOENT)) {
dev_dbg(&device->spi->dev,
- "Could not find entry for %s. Ignoring.", name);
+ "Could not find entry for %s. Ignoring.\n", name);
continue;
}
if (device->gpiod[i] == ERR_PTR(-EBUSY))
- dev_dbg(&device->spi->dev, "%s is busy.", name);
+ dev_dbg(&device->spi->dev, "%s is busy.\n", name);
if (IS_ERR(device->gpiod[i])) {
retval = PTR_ERR(device->gpiod[i]);
@@ -1028,7 +1038,7 @@ static int setup_gpio(struct pi433_device *device)
if (retval)
return retval;
- dev_dbg(&device->spi->dev, "%s successfully configured", name);
+ dev_dbg(&device->spi->dev, "%s successfully configured\n", name);
}
return 0;
@@ -1090,12 +1100,76 @@ static const struct file_operations pi433_fops = {
.llseek = no_llseek,
};
+static int pi433_debugfs_regs_show(struct seq_file *m, void *p)
+{
+ struct pi433_device *dev;
+ u8 reg_data[114];
+ int i;
+ char *fmt = "0x%02x, 0x%02x\n";
+ int ret;
+
+ dev = m->private;
+
+ mutex_lock(&dev->tx_fifo_lock);
+ mutex_lock(&dev->rx_lock);
+
+ // wait for on-going operations to finish
+ ret = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active);
+ if (ret)
+ goto out_unlock;
+
+ ret = wait_event_interruptible(dev->tx_wait_queue, !dev->rx_active);
+ if (ret)
+ goto out_unlock;
+
+ // skip FIFO register (0x0) otherwise this can affect some of uC ops
+ for (i = 1; i < 0x50; i++)
+ reg_data[i] = rf69_read_reg(dev->spi, i);
+
+ reg_data[REG_TESTLNA] = rf69_read_reg(dev->spi, REG_TESTLNA);
+ reg_data[REG_TESTPA1] = rf69_read_reg(dev->spi, REG_TESTPA1);
+ reg_data[REG_TESTPA2] = rf69_read_reg(dev->spi, REG_TESTPA2);
+ reg_data[REG_TESTDAGC] = rf69_read_reg(dev->spi, REG_TESTDAGC);
+ reg_data[REG_TESTAFC] = rf69_read_reg(dev->spi, REG_TESTAFC);
+
+ seq_puts(m, "# reg, val\n");
+
+ for (i = 1; i < 0x50; i++)
+ seq_printf(m, fmt, i, reg_data[i]);
+
+ seq_printf(m, fmt, REG_TESTLNA, reg_data[REG_TESTLNA]);
+ seq_printf(m, fmt, REG_TESTPA1, reg_data[REG_TESTPA1]);
+ seq_printf(m, fmt, REG_TESTPA2, reg_data[REG_TESTPA2]);
+ seq_printf(m, fmt, REG_TESTDAGC, reg_data[REG_TESTDAGC]);
+ seq_printf(m, fmt, REG_TESTAFC, reg_data[REG_TESTAFC]);
+
+out_unlock:
+ mutex_unlock(&dev->rx_lock);
+ mutex_unlock(&dev->tx_fifo_lock);
+
+ return ret;
+}
+
+static int pi433_debugfs_regs_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, pi433_debugfs_regs_show, inode->i_private);
+}
+
+static const struct file_operations debugfs_fops = {
+ .llseek = seq_lseek,
+ .open = pi433_debugfs_regs_open,
+ .owner = THIS_MODULE,
+ .read = seq_read,
+ .release = single_release
+};
+
/*-------------------------------------------------------------------------*/
static int pi433_probe(struct spi_device *spi)
{
struct pi433_device *device;
int retval;
+ struct dentry *entry;
/* setup spi parameters */
spi->mode = 0x00;
@@ -1112,20 +1186,20 @@ static int pi433_probe(struct spi_device *spi)
}
dev_dbg(&spi->dev,
- "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed",
+ "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed\n",
spi->mode, spi->bits_per_word, spi->max_speed_hz);
- /* Ping the chip by reading the version register */
- retval = spi_w8r8(spi, 0x10);
+ /* read chip version */
+ retval = rf69_get_version(spi);
if (retval < 0)
return retval;
switch (retval) {
case 0x24:
- dev_dbg(&spi->dev, "found pi433 (ver. 0x%x)", retval);
+ dev_dbg(&spi->dev, "found pi433 (ver. 0x%x)\n", retval);
break;
default:
- dev_dbg(&spi->dev, "unknown chip version: 0x%x", retval);
+ dev_dbg(&spi->dev, "unknown chip version: 0x%x\n", retval);
return -ENODEV;
}
@@ -1162,7 +1236,7 @@ static int pi433_probe(struct spi_device *spi)
/* setup GPIO (including irq_handler) for the different DIOs */
retval = setup_gpio(device);
if (retval) {
- dev_dbg(&spi->dev, "setup of GPIOs failed");
+ dev_dbg(&spi->dev, "setup of GPIOs failed\n");
goto GPIO_failed;
}
@@ -1192,7 +1266,7 @@ static int pi433_probe(struct spi_device *spi)
/* determ minor number */
retval = pi433_get_minor(device);
if (retval) {
- dev_dbg(&spi->dev, "get of minor number failed");
+ dev_dbg(&spi->dev, "get of minor number failed\n");
goto minor_failed;
}
@@ -1221,7 +1295,7 @@ static int pi433_probe(struct spi_device *spi)
"pi433.%d_tx_task",
device->minor);
if (IS_ERR(device->tx_task_struct)) {
- dev_dbg(device->dev, "start of send thread failed");
+ dev_dbg(device->dev, "start of send thread failed\n");
retval = PTR_ERR(device->tx_task_struct);
goto send_thread_failed;
}
@@ -1229,7 +1303,7 @@ static int pi433_probe(struct spi_device *spi)
/* create cdev */
device->cdev = cdev_alloc();
if (!device->cdev) {
- dev_dbg(device->dev, "allocation of cdev failed");
+ dev_dbg(device->dev, "allocation of cdev failed\n");
retval = -ENOMEM;
goto cdev_failed;
}
@@ -1237,13 +1311,17 @@ static int pi433_probe(struct spi_device *spi)
cdev_init(device->cdev, &pi433_fops);
retval = cdev_add(device->cdev, device->devt, 1);
if (retval) {
- dev_dbg(device->dev, "register of cdev failed");
+ dev_dbg(device->dev, "register of cdev failed\n");
goto del_cdev;
}
/* spi setup */
spi_set_drvdata(spi, device);
+ entry = debugfs_create_dir(dev_name(device->dev),
+ debugfs_lookup(KBUILD_MODNAME, NULL));
+ debugfs_create_file("regs", 0400, entry, device, &debugfs_fops);
+
return 0;
del_cdev:
@@ -1267,6 +1345,9 @@ RX_failed:
static void pi433_remove(struct spi_device *spi)
{
struct pi433_device *device = spi_get_drvdata(spi);
+ struct dentry *mod_entry = debugfs_lookup(KBUILD_MODNAME, NULL);
+
+ debugfs_remove(debugfs_lookup(dev_name(device->dev), mod_entry));
/* free GPIOs */
free_gpio(device);
@@ -1339,6 +1420,8 @@ static int __init pi433_init(void)
return PTR_ERR(pi433_class);
}
+ debugfs_create_dir(KBUILD_MODNAME, NULL);
+
status = spi_register_driver(&pi433_spi_driver);
if (status < 0) {
class_destroy(pi433_class);
@@ -1356,6 +1439,7 @@ static void __exit pi433_exit(void)
spi_unregister_driver(&pi433_spi_driver);
class_destroy(pi433_class);
unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name);
+ debugfs_remove_recursive(debugfs_lookup(KBUILD_MODNAME, NULL));
}
module_exit(pi433_exit);