diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2018-06-25 09:57:37 -0400 |
---|---|---|
committer | Stefan Schmidt <stefan@datenfreihafen.org> | 2018-07-09 04:53:12 -0400 |
commit | 58e9683d14752debc6f22daf6b23e031787df31f (patch) | |
tree | 5b8fcaf2129c8dfc6b7cb1f117ae549d9014ea06 | |
parent | 36d26d6b6208399070a9d7993534fef9fc26b1ba (diff) |
net: ieee802154: adf7242: Fix OCL calibration runs
Reissuing RC_RX every 400ms - to adjust for offset drift in
receiver see datasheet page 61, OCL section.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
-rw-r--r-- | drivers/net/ieee802154/adf7242.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/net/ieee802154/adf7242.c b/drivers/net/ieee802154/adf7242.c index c3da43191f70..23a52b9293f3 100644 --- a/drivers/net/ieee802154/adf7242.c +++ b/drivers/net/ieee802154/adf7242.c | |||
@@ -275,6 +275,8 @@ struct adf7242_local { | |||
275 | struct spi_message stat_msg; | 275 | struct spi_message stat_msg; |
276 | struct spi_transfer stat_xfer; | 276 | struct spi_transfer stat_xfer; |
277 | struct dentry *debugfs_root; | 277 | struct dentry *debugfs_root; |
278 | struct delayed_work work; | ||
279 | struct workqueue_struct *wqueue; | ||
278 | unsigned long flags; | 280 | unsigned long flags; |
279 | int tx_stat; | 281 | int tx_stat; |
280 | bool promiscuous; | 282 | bool promiscuous; |
@@ -575,10 +577,26 @@ static int adf7242_cmd_rx(struct adf7242_local *lp) | |||
575 | /* Wait until the ACK is sent */ | 577 | /* Wait until the ACK is sent */ |
576 | adf7242_wait_status(lp, RC_STATUS_PHY_RDY, RC_STATUS_MASK, __LINE__); | 578 | adf7242_wait_status(lp, RC_STATUS_PHY_RDY, RC_STATUS_MASK, __LINE__); |
577 | adf7242_clear_irqstat(lp); | 579 | adf7242_clear_irqstat(lp); |
580 | mod_delayed_work(lp->wqueue, &lp->work, msecs_to_jiffies(400)); | ||
578 | 581 | ||
579 | return adf7242_cmd(lp, CMD_RC_RX); | 582 | return adf7242_cmd(lp, CMD_RC_RX); |
580 | } | 583 | } |
581 | 584 | ||
585 | static void adf7242_rx_cal_work(struct work_struct *work) | ||
586 | { | ||
587 | struct adf7242_local *lp = | ||
588 | container_of(work, struct adf7242_local, work.work); | ||
589 | |||
590 | /* Reissuing RC_RX every 400ms - to adjust for offset | ||
591 | * drift in receiver (datasheet page 61, OCL section) | ||
592 | */ | ||
593 | |||
594 | if (!test_bit(FLAG_XMIT, &lp->flags)) { | ||
595 | adf7242_cmd(lp, CMD_RC_PHY_RDY); | ||
596 | adf7242_cmd_rx(lp); | ||
597 | } | ||
598 | } | ||
599 | |||
582 | static int adf7242_set_txpower(struct ieee802154_hw *hw, int mbm) | 600 | static int adf7242_set_txpower(struct ieee802154_hw *hw, int mbm) |
583 | { | 601 | { |
584 | struct adf7242_local *lp = hw->priv; | 602 | struct adf7242_local *lp = hw->priv; |
@@ -686,7 +704,7 @@ static int adf7242_start(struct ieee802154_hw *hw) | |||
686 | enable_irq(lp->spi->irq); | 704 | enable_irq(lp->spi->irq); |
687 | set_bit(FLAG_START, &lp->flags); | 705 | set_bit(FLAG_START, &lp->flags); |
688 | 706 | ||
689 | return adf7242_cmd(lp, CMD_RC_RX); | 707 | return adf7242_cmd_rx(lp); |
690 | } | 708 | } |
691 | 709 | ||
692 | static void adf7242_stop(struct ieee802154_hw *hw) | 710 | static void adf7242_stop(struct ieee802154_hw *hw) |
@@ -694,6 +712,7 @@ static void adf7242_stop(struct ieee802154_hw *hw) | |||
694 | struct adf7242_local *lp = hw->priv; | 712 | struct adf7242_local *lp = hw->priv; |
695 | 713 | ||
696 | disable_irq(lp->spi->irq); | 714 | disable_irq(lp->spi->irq); |
715 | cancel_delayed_work_sync(&lp->work); | ||
697 | adf7242_cmd(lp, CMD_RC_IDLE); | 716 | adf7242_cmd(lp, CMD_RC_IDLE); |
698 | clear_bit(FLAG_START, &lp->flags); | 717 | clear_bit(FLAG_START, &lp->flags); |
699 | adf7242_clear_irqstat(lp); | 718 | adf7242_clear_irqstat(lp); |
@@ -817,6 +836,7 @@ static int adf7242_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) | |||
817 | /* ensure existing instances of the IRQ handler have completed */ | 836 | /* ensure existing instances of the IRQ handler have completed */ |
818 | disable_irq(lp->spi->irq); | 837 | disable_irq(lp->spi->irq); |
819 | set_bit(FLAG_XMIT, &lp->flags); | 838 | set_bit(FLAG_XMIT, &lp->flags); |
839 | cancel_delayed_work_sync(&lp->work); | ||
820 | reinit_completion(&lp->tx_complete); | 840 | reinit_completion(&lp->tx_complete); |
821 | adf7242_cmd(lp, CMD_RC_PHY_RDY); | 841 | adf7242_cmd(lp, CMD_RC_PHY_RDY); |
822 | adf7242_clear_irqstat(lp); | 842 | adf7242_clear_irqstat(lp); |
@@ -955,6 +975,7 @@ static irqreturn_t adf7242_isr(int irq, void *data) | |||
955 | unsigned int xmit; | 975 | unsigned int xmit; |
956 | u8 irq1; | 976 | u8 irq1; |
957 | 977 | ||
978 | mod_delayed_work(lp->wqueue, &lp->work, msecs_to_jiffies(400)); | ||
958 | adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1); | 979 | adf7242_read_reg(lp, REG_IRQ1_SRC1, &irq1); |
959 | 980 | ||
960 | if (!(irq1 & (IRQ_RX_PKT_RCVD | IRQ_CSMA_CA))) | 981 | if (!(irq1 & (IRQ_RX_PKT_RCVD | IRQ_CSMA_CA))) |
@@ -1244,6 +1265,9 @@ static int adf7242_probe(struct spi_device *spi) | |||
1244 | spi_message_add_tail(&lp->stat_xfer, &lp->stat_msg); | 1265 | spi_message_add_tail(&lp->stat_xfer, &lp->stat_msg); |
1245 | 1266 | ||
1246 | spi_set_drvdata(spi, lp); | 1267 | spi_set_drvdata(spi, lp); |
1268 | INIT_DELAYED_WORK(&lp->work, adf7242_rx_cal_work); | ||
1269 | lp->wqueue = alloc_ordered_workqueue(dev_name(&spi->dev), | ||
1270 | WQ_MEM_RECLAIM); | ||
1247 | 1271 | ||
1248 | ret = adf7242_hw_init(lp); | 1272 | ret = adf7242_hw_init(lp); |
1249 | if (ret) | 1273 | if (ret) |
@@ -1287,6 +1311,9 @@ static int adf7242_remove(struct spi_device *spi) | |||
1287 | if (!IS_ERR_OR_NULL(lp->debugfs_root)) | 1311 | if (!IS_ERR_OR_NULL(lp->debugfs_root)) |
1288 | debugfs_remove_recursive(lp->debugfs_root); | 1312 | debugfs_remove_recursive(lp->debugfs_root); |
1289 | 1313 | ||
1314 | cancel_delayed_work_sync(&lp->work); | ||
1315 | destroy_workqueue(lp->wqueue); | ||
1316 | |||
1290 | ieee802154_unregister_hw(lp->hw); | 1317 | ieee802154_unregister_hw(lp->hw); |
1291 | mutex_destroy(&lp->bmux); | 1318 | mutex_destroy(&lp->bmux); |
1292 | ieee802154_free_hw(lp->hw); | 1319 | ieee802154_free_hw(lp->hw); |