diff options
Diffstat (limited to 'drivers/staging/pi433/pi433_if.c')
-rw-r--r-- | drivers/staging/pi433/pi433_if.c | 172 |
1 files changed, 121 insertions, 51 deletions
diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c index 29bd37669059..d4e06a3929f3 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" @@ -92,7 +94,7 @@ struct pi433_device { u32 rx_bytes_to_drop; u32 rx_bytes_dropped; unsigned int rx_position; - struct mutex rx_lock; + struct mutex rx_lock; /* protects rx_* variable accesses */ wait_queue_head_t rx_wait_queue; /* fifo wait queue */ @@ -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,64 @@ 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; +} +DEFINE_SHOW_ATTRIBUTE(pi433_debugfs_regs); + /*-------------------------------------------------------------------------*/ 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 +1174,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 +1224,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 +1254,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 +1283,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 +1291,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 +1299,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, &pi433_debugfs_regs_fops); + return 0; del_cdev: @@ -1264,9 +1330,12 @@ RX_failed: return retval; } -static int pi433_remove(struct spi_device *spi) +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); @@ -1284,8 +1353,6 @@ static int pi433_remove(struct spi_device *spi) kfree(device->rx_buffer); kfree(device); - - return 0; } static const struct of_device_id pi433_dt_ids[] = { @@ -1327,7 +1394,7 @@ static int __init pi433_init(void) /* * Claim device numbers. Then register a class - * that will key udev/mdev to add/remove /dev nodes. Last, register + * that will key udev/mdev to add/remove /dev nodes. * Last, register the driver which manages those device numbers. */ status = alloc_chrdev_region(&pi433_dev, 0, N_PI433_MINORS, "pi433"); @@ -1341,6 +1408,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); @@ -1358,6 +1427,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); |