2016-12-20 16:16:47

by Geoff Lansberry

[permalink] [raw]
Subject: [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock

From: Geoff Lansberry <[email protected]>

The TRF7970A has configuration options to support hardware designs
which use a 27.12MHz clock. This commit adds a device tree option
'clock-frequency' to support configuring the this chip for default
13.56MHz clock or the optional 27.12MHz clock.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++
drivers/nfc/trf7970a.c | 50 +++++++++++++++++-----
2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index 32b35a0..e262ac1 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,6 +21,8 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
+

Example (for ARM-based BeagleBone with TRF7970A on SPI1):

@@ -43,6 +45,8 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
+ vdd_io_1v8;
+ clock-frequency = <27120000>;
status = "okay";
};
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 26c9dbb..4e051e9 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -124,6 +124,9 @@
NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)

#define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */
+#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000
+#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000
+

#define TRF7970A_RX_SKB_ALLOC_SIZE 256

@@ -1056,12 +1059,11 @@ static int trf7970a_init(struct trf7970a *trf)

trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;

- ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
+ ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
+ trf->modulator_sys_clk_ctrl);
if (ret)
goto err_out;

- trf->modulator_sys_clk_ctrl = 0;
-
ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
@@ -1181,27 +1183,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
switch (tech) {
case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
break;
case NFC_DIGITAL_RF_TECH_106B:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_ISO15693:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_15693;
break;
default:
@@ -1571,17 +1583,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE |
TRF7970A_ISO_CTRL_NFC_CE_14443A;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
@@ -1987,6 +2005,7 @@ static int trf7970a_probe(struct spi_device *spi)
struct device_node *np = spi->dev.of_node;
struct trf7970a *trf;
int uvolts, autosuspend_delay, ret;
+ u32 clk_freq = 13560000;

if (!np) {
dev_err(&spi->dev, "No Device Tree entry\n");
@@ -2043,6 +2062,15 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}

+ of_property_read_u32(np, "clock-frequency", &clk_freq);
+ if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
+ (clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
+ dev_err(trf->dev,
+ "clock-frequency (%u Hz) unsupported\n",
+ clk_freq);
+ return -EINVAL;
+ }
+
if (of_property_read_bool(np, "en2-rf-quirk"))
trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;

--
Signed-off-by: Geoff Lansberry <[email protected]>


2016-12-20 16:16:50

by Geoff Lansberry

[permalink] [raw]
Subject: [PATCH 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage

From: Geoff Lansberry <[email protected]>

The TRF7970A has configuration options for supporting hardware designs
with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
using a fixed regulator binding, for setting the io voltage to match
the hardware configuration. If no option is supplied it defaults to
3.3 volt configuration.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++--
drivers/nfc/trf7970a.c | 28 +++++++++++++++++++++-
2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index e262ac1..b5777d8 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,9 +21,9 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- vdd-io-supply: Regulator specifying voltage for vdd-io
- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz

-
Example (for ARM-based BeagleBone with TRF7970A on SPI1):

&spi1 {
@@ -41,11 +41,11 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
+ vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
- vdd_io_1v8;
clock-frequency = <27120000>;
status = "okay";
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 4e051e9..8a88195 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -444,6 +444,7 @@ struct trf7970a {
u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1;
+ u8 io_ctrl;
unsigned int guard_time;
int technology;
int framing;
@@ -1051,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret)
goto err_out;

+ ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
+ if (ret)
+ goto err_out;
+
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
if (ret)
goto err_out;
@@ -1767,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
goto out_err;

ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
- TRF7970A_REG_IO_CTRL_VRS(0x1));
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
if (ret)
goto out_err;

@@ -2062,6 +2068,7 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}

+
of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
(clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
@@ -2105,6 +2112,25 @@ static int trf7970a_probe(struct spi_device *spi)
if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;

+ trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
+ if (IS_ERR(trf->regulator)) {
+ ret = PTR_ERR(trf->regulator);
+ dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+ ret = regulator_enable(trf->regulator);
+ if (ret) {
+ dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+
+ if (regulator_get_voltage(trf->regulator) == 1800000) {
+ trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
+ dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
+ }
+
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC |
--
Signed-off-by: Geoff Lansberry <[email protected]>

2016-12-20 16:17:38

by Geoff Lansberry

[permalink] [raw]
Subject: [PATCH 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel

From: Jaret Cantu <[email protected]>

Repeated polling attempts cause a NULL dereference error to occur.
This is because the state of the trf7970a is currently reading but
another request has been made to send a command before it has finished.

The solution is to properly kill the waiting reading (workqueue)
before failing on the send.
---
drivers/nfc/trf7970a.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 8a88195..5916737 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -1496,6 +1496,10 @@ static int trf7970a_send_cmd(struct nfc_digital_dev *ddev,
(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
trf->state);
+ if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA ||
+ trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
+ trf->ignore_timeout =
+ !cancel_delayed_work(&trf->timeout_work);
ret = -EIO;
goto out_err;
}
--
Signed-off-by: Geoff Lansberry <[email protected]>

2016-12-20 17:59:12

by Jones Desougi

[permalink] [raw]
Subject: Re: [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock

On 2016-12-20 17:16, Geoff Lansberry wrote:
> From: Geoff Lansberry <[email protected]>
>
> The TRF7970A has configuration options to support hardware designs
> which use a 27.12MHz clock. This commit adds a device tree option
> 'clock-frequency' to support configuring the this chip for default
> 13.56MHz clock or the optional 27.12MHz clock.
> ---
> .../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++
> drivers/nfc/trf7970a.c | 50 +++++++++++++++++-----
> 2 files changed, 43 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
> index 32b35a0..e262ac1 100644
> --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
> +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
> @@ -21,6 +21,8 @@ Optional SoC Specific Properties:
> - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
> where an extra byte is returned by Read Multiple Block commands issued
> to Type 5 tags.
> +- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
> +
You're adding an empty line here that is removed in the next patch.

>
> Example (for ARM-based BeagleBone with TRF7970A on SPI1):
>
> @@ -43,6 +45,8 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
> irq-status-read-quirk;
> en2-rf-quirk;
> t5t-rmb-extra-byte-quirk;
> + vdd_io_1v8;
This does not belong here, and so no need to remove in the next patch.

> + clock-frequency = <27120000>;
> status = "okay";
> };
> };
> diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
> index 26c9dbb..4e051e9 100644
> --- a/drivers/nfc/trf7970a.c
> +++ b/drivers/nfc/trf7970a.c
> @@ -124,6 +124,9 @@
> NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
>
> #define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */
> +#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000
> +#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000
> +
>
> #define TRF7970A_RX_SKB_ALLOC_SIZE 256
>
> @@ -1056,12 +1059,11 @@ static int trf7970a_init(struct trf7970a *trf)
>
> trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
>
> - ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
> + ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
> + trf->modulator_sys_clk_ctrl);
> if (ret)
> goto err_out;
>
> - trf->modulator_sys_clk_ctrl = 0;
> -
> ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
> TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
> TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
> @@ -1181,27 +1183,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
> switch (tech) {
> case NFC_DIGITAL_RF_TECH_106A:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_OOK;
> trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
> break;
> case NFC_DIGITAL_RF_TECH_106B:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_ASK10;
> trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
> break;
> case NFC_DIGITAL_RF_TECH_212F:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_ASK10;
> trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
> break;
> case NFC_DIGITAL_RF_TECH_424F:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_ASK10;
> trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
> break;
> case NFC_DIGITAL_RF_TECH_ISO15693:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_OOK;
> trf->guard_time = TRF7970A_GUARD_TIME_15693;
> break;
> default:
> @@ -1571,17 +1583,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
> TRF7970A_ISO_CTRL_NFC_CE |
> TRF7970A_ISO_CTRL_NFC_CE_14443A;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_OOK;
> break;
> case NFC_DIGITAL_RF_TECH_212F:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
> TRF7970A_ISO_CTRL_NFC_NFCF_212;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_ASK10;
> break;
> case NFC_DIGITAL_RF_TECH_424F:
> trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
> TRF7970A_ISO_CTRL_NFC_NFCF_424;
> - trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
> + trf->modulator_sys_clk_ctrl =
> + (trf->modulator_sys_clk_ctrl & 0xF8) |
> + TRF7970A_MODULATOR_DEPTH_ASK10;
> break;
> default:
> dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
> @@ -1987,6 +2005,7 @@ static int trf7970a_probe(struct spi_device *spi)
> struct device_node *np = spi->dev.of_node;
> struct trf7970a *trf;
> int uvolts, autosuspend_delay, ret;
> + u32 clk_freq = 13560000;
Use TRF7970A_13MHZ_CLOCK_FREQUENCY here?

>
> if (!np) {
> dev_err(&spi->dev, "No Device Tree entry\n");
> @@ -2043,6 +2062,15 @@ static int trf7970a_probe(struct spi_device *spi)
> return ret;
> }
>
> + of_property_read_u32(np, "clock-frequency", &clk_freq);
> + if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
> + (clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
Two comparisons with 27MHz, missing 13MHz.

> + dev_err(trf->dev,
> + "clock-frequency (%u Hz) unsupported\n",
> + clk_freq);
> + return -EINVAL;
> + }
> +
> if (of_property_read_bool(np, "en2-rf-quirk"))
> trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
>
>

2016-12-20 18:12:07

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock

Hi Geoff.

Please put the version in your subjects when submitting anything but the
initial version of a patch (e.g., [PATCH v2 1/3]).

Which series do you want reviewed?

Mark
--

2016-12-20 18:35:24

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock

On Tue, Dec 20, 2016 at 01:29:13PM -0500, Geoff Lansberry wrote:
> On Tue, Dec 20, 2016 at 1:11 PM, Mark Greer <[email protected]> wrote:
> > Hi Geoff.
> >
> > Please put the version in your subjects when submitting anything but the
> > initial version of a patch (e.g., [PATCH v2 1/3]).
> >
> > Which series do you want reviewed?
> >
> > Mark
> > --
> Sorry about the double posting, I had forgotten to erase the patches I
> generated while rebasing and checking, and I'll have to figure out how
> to add that v2 line to the automatically generated subject line if I
> end up submitting another round.

Hint: -v <n> option of 'git format-patch'

> Please review the three most recent patches, which have the send time
> of 17:16.

Okay, thank.

Mark
--

2016-12-20 18:38:03

by Geoff Lansberry

[permalink] [raw]
Subject: Re: [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock

On Tue, Dec 20, 2016 at 1:11 PM, Mark Greer <[email protected]> wrote:
> Hi Geoff.
>
> Please put the version in your subjects when submitting anything but the
> initial version of a patch (e.g., [PATCH v2 1/3]).
>
> Which series do you want reviewed?
>
> Mark
> --
Sorry about the double posting, I had forgotten to erase the patches I
generated while rebasing and checking, and I'll have to figure out how
to add that v2 line to the automatically generated subject line if I
end up submitting another round.

Please review the three most recent patches, which have the send time
of 17:16.

Best Regards,
Geoff

2016-12-20 19:00:12

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel

On Tue, Dec 20, 2016 at 11:16:32AM -0500, Geoff Lansberry wrote:
> From: Jaret Cantu <[email protected]>
>
> Repeated polling attempts cause a NULL dereference error to occur.
> This is because the state of the trf7970a is currently reading but
> another request has been made to send a command before it has finished.

How is this happening? Was trf7970a_abort_cmd() called and it didn't
work right? Was it not called at all and there is a bug in the digital
layer? More details please.

> The solution is to properly kill the waiting reading (workqueue)
> before failing on the send.

If the bug is in the calling code, then that is what should get fixed.
This seems to be a hack to work-around a digital layer bug.

Mark
--

2016-12-20 19:14:20

by Justin Bronder

[permalink] [raw]
Subject: Re: nfc: trf7970a: Prevent repeated polling from crashing the kernel

On 20/12/16 11:59 -0700, Mark Greer wrote:
> On Tue, Dec 20, 2016 at 11:16:32AM -0500, Geoff Lansberry wrote:
> > From: Jaret Cantu <[email protected]>
> >
> > Repeated polling attempts cause a NULL dereference error to occur.
> > This is because the state of the trf7970a is currently reading but
> > another request has been made to send a command before it has finished.
>
> How is this happening? Was trf7970a_abort_cmd() called and it didn't
> work right? Was it not called at all and there is a bug in the digital
> layer? More details please.
>
> > The solution is to properly kill the waiting reading (workqueue)
> > before failing on the send.
>
> If the bug is in the calling code, then that is what should get fixed.
> This seems to be a hack to work-around a digital layer bug.

One of our uses of NFC is to begin polling to read a tag and then stop polling
(in order to save power) until we know via user interaction that we need to poll
again. This is typically many minutes later so the power saving is pretty
significant. However, it's possible that a user will remove the tag before
reading has completed. We also detect this case and stop polling. I can go
more into this if necessary but that is what exposed a panic.

You can reproduce using neard and python, in our testing it was very likely to
occur in 10-100 iterations of the following.:

#!/usr/bin/python
import time

import dbus

bus = dbus.SystemBus()
nfc0 = bus.get_object('org.neard', '/org/neard/nfc0')
props = dbus.Interface(nfc0, 'org.freedesktop.DBus.Properties')

try:
props.Set('org.neard.Adapter', 'Powered', dbus.Boolean(1))
except:
pass

adapter = dbus.Interface(nfc0, 'org.neard.Adapter')

for i in range(1000):
adapter.StartPollLoop('Initiator')
time.sleep(0.1)
adapter.StopPollLoop()
print(i)

I believe the last time we tested this was around the 4.1 release.

--
Justin Bronder

2016-12-20 19:56:39

by Mark Greer

[permalink] [raw]
Subject: Re: nfc: trf7970a: Prevent repeated polling from crashing the kernel

On Tue, Dec 20, 2016 at 02:13:52PM -0500, Justin Bronder wrote:
> On 20/12/16 11:59 -0700, Mark Greer wrote:
> > On Tue, Dec 20, 2016 at 11:16:32AM -0500, Geoff Lansberry wrote:
> > > From: Jaret Cantu <[email protected]>
> > >
> > > Repeated polling attempts cause a NULL dereference error to occur.
> > > This is because the state of the trf7970a is currently reading but
> > > another request has been made to send a command before it has finished.
> >
> > How is this happening? Was trf7970a_abort_cmd() called and it didn't
> > work right? Was it not called at all and there is a bug in the digital
> > layer? More details please.
> >
> > > The solution is to properly kill the waiting reading (workqueue)
> > > before failing on the send.
> >
> > If the bug is in the calling code, then that is what should get fixed.
> > This seems to be a hack to work-around a digital layer bug.
>
> One of our uses of NFC is to begin polling to read a tag and then stop polling
> (in order to save power) until we know via user interaction that we need to poll
> again. This is typically many minutes later so the power saving is pretty
> significant. However, it's possible that a user will remove the tag before
> reading has completed. We also detect this case and stop polling. I can go
> more into this if necessary but that is what exposed a panic.
>
> You can reproduce using neard and python, in our testing it was very likely to
> occur in 10-100 iterations of the following.:
>
> #!/usr/bin/python
> import time
>
> import dbus
>
> bus = dbus.SystemBus()
> nfc0 = bus.get_object('org.neard', '/org/neard/nfc0')
> props = dbus.Interface(nfc0, 'org.freedesktop.DBus.Properties')
>
> try:
> props.Set('org.neard.Adapter', 'Powered', dbus.Boolean(1))
> except:
> pass
>
> adapter = dbus.Interface(nfc0, 'org.neard.Adapter')
>
> for i in range(1000):
> adapter.StartPollLoop('Initiator')
> time.sleep(0.1)
> adapter.StopPollLoop()
> print(i)
>
> I believe the last time we tested this was around the 4.1 release.

Thanks for the info, Justin, but I was also seeking more information
at the kernel NFC subsystem and trf7970a driver level. This patch
adds code inside an 'if' in the driver whose condition should never
be evaluate to true but apparently it did. How?

Thanks,

Mark
--

2016-12-21 02:23:51

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage

On Tue, Dec 20, 2016 at 11:16:31AM -0500, Geoff Lansberry wrote:
> From: Geoff Lansberry <[email protected]>
>
> The TRF7970A has configuration options for supporting hardware designs
> with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
> using a fixed regulator binding, for setting the io voltage to match
> the hardware configuration. If no option is supplied it defaults to
> 3.3 volt configuration.

Sign-off ?? Same comment for you other patches.

<time passes>

Okay I see you have it at the end of the patch. It should be here.
'git commit -s' is your friend.

> ---
> .../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++--
> drivers/nfc/trf7970a.c | 28 +++++++++++++++++++++-
> 2 files changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
> index e262ac1..b5777d8 100644
> --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
> +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
> @@ -21,9 +21,9 @@ Optional SoC Specific Properties:
> - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
> where an extra byte is returned by Read Multiple Block commands issued
> to Type 5 tags.
> +- vdd-io-supply: Regulator specifying voltage for vdd-io
> - clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
>
> -
> Example (for ARM-based BeagleBone with TRF7970A on SPI1):
>
> &spi1 {
> @@ -41,11 +41,11 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
> <&gpio2 5 GPIO_ACTIVE_LOW>;
> vin-supply = <&ldo3_reg>;
> vin-voltage-override = <5000000>;
> + vdd-io-supply = <&ldo2_reg>;
> autosuspend-delay = <30000>;
> irq-status-read-quirk;
> en2-rf-quirk;
> t5t-rmb-extra-byte-quirk;
> - vdd_io_1v8;

It was already mentioned but this shouldn't have been added in the
previous patch so it shouldn't be here now.

> clock-frequency = <27120000>;
> status = "okay";
> };
> diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
> index 4e051e9..8a88195 100644
> --- a/drivers/nfc/trf7970a.c
> +++ b/drivers/nfc/trf7970a.c

> @@ -2062,6 +2068,7 @@ static int trf7970a_probe(struct spi_device *spi)
> return ret;
> }
>
> +

Please don't add an extra blank line.

> of_property_read_u32(np, "clock-frequency", &clk_freq);
> if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
> (clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
> @@ -2105,6 +2112,25 @@ static int trf7970a_probe(struct spi_device *spi)
> if (uvolts > 4000000)
> trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
>
> + trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
> + if (IS_ERR(trf->regulator)) {
> + ret = PTR_ERR(trf->regulator);
> + dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
> + goto err_destroy_lock;
> + }
> +
> + ret = regulator_enable(trf->regulator);
> + if (ret) {
> + dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
> + goto err_destroy_lock;
> + }
> +
> +

Please don't add an extra blank line.

> + if (regulator_get_voltage(trf->regulator) == 1800000) {
> + trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
> + dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
> + }
> +
> trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
> TRF7970A_SUPPORTED_PROTOCOLS,
> NFC_DIGITAL_DRV_CAPS_IN_CRC |
> --
> Signed-off-by: Geoff Lansberry <[email protected]>

Your 'Signed-off-by:' goes at the end of the commit description not here.

Overall, I think you did the right thing (unless someone disagrees).
Just some minor issues.

Mark
--

2016-12-21 11:47:43

by Geoff Lansberry

[permalink] [raw]
Subject: Re: [PATCH 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage

Thanks Mark. Should I resubmit patches with the requested edits today, or wait a bit for more comments? What is the desired etiquette?

> On Dec 20, 2016, at 9:23 PM, Mark Greer <[email protected]> wrote:
>
>> On Tue, Dec 20, 2016 at 11:16:31AM -0500, Geoff Lansberry wrote:
>> From: Geoff Lansberry <[email protected]>
>>
>> The TRF7970A has configuration options for supporting hardware designs
>> with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
>> using a fixed regulator binding, for setting the io voltage to match
>> the hardware configuration. If no option is supplied it defaults to
>> 3.3 volt configuration.
>
> Sign-off ?? Same comment for you other patches.
>
> <time passes>
>
> Okay I see you have it at the end of the patch. It should be here.
> 'git commit -s' is your friend.
>
>> ---
>> .../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++--
>> drivers/nfc/trf7970a.c | 28 +++++++++++++++++++++-
>> 2 files changed, 29 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
>> index e262ac1..b5777d8 100644
>> --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
>> +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
>> @@ -21,9 +21,9 @@ Optional SoC Specific Properties:
>> - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
>> where an extra byte is returned by Read Multiple Block commands issued
>> to Type 5 tags.
>> +- vdd-io-supply: Regulator specifying voltage for vdd-io
>> - clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
>>
>> -
>> Example (for ARM-based BeagleBone with TRF7970A on SPI1):
>>
>> &spi1 {
>> @@ -41,11 +41,11 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
>> <&gpio2 5 GPIO_ACTIVE_LOW>;
>> vin-supply = <&ldo3_reg>;
>> vin-voltage-override = <5000000>;
>> + vdd-io-supply = <&ldo2_reg>;
>> autosuspend-delay = <30000>;
>> irq-status-read-quirk;
>> en2-rf-quirk;
>> t5t-rmb-extra-byte-quirk;
>> - vdd_io_1v8;
>
> It was already mentioned but this shouldn't have been added in the
> previous patch so it shouldn't be here now.
>
>> clock-frequency = <27120000>;
>> status = "okay";
>> };
>> diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
>> index 4e051e9..8a88195 100644
>> --- a/drivers/nfc/trf7970a.c
>> +++ b/drivers/nfc/trf7970a.c
>
>> @@ -2062,6 +2068,7 @@ static int trf7970a_probe(struct spi_device *spi)
>> return ret;
>> }
>>
>> +
>
> Please don't add an extra blank line.
>
>> of_property_read_u32(np, "clock-frequency", &clk_freq);
>> if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
>> (clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
>> @@ -2105,6 +2112,25 @@ static int trf7970a_probe(struct spi_device *spi)
>> if (uvolts > 4000000)
>> trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
>>
>> + trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
>> + if (IS_ERR(trf->regulator)) {
>> + ret = PTR_ERR(trf->regulator);
>> + dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
>> + goto err_destroy_lock;
>> + }
>> +
>> + ret = regulator_enable(trf->regulator);
>> + if (ret) {
>> + dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
>> + goto err_destroy_lock;
>> + }
>> +
>> +
>
> Please don't add an extra blank line.
>
>> + if (regulator_get_voltage(trf->regulator) == 1800000) {
>> + trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
>> + dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
>> + }
>> +
>> trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
>> TRF7970A_SUPPORTED_PROTOCOLS,
>> NFC_DIGITAL_DRV_CAPS_IN_CRC |
>> --
>> Signed-off-by: Geoff Lansberry <[email protected]>
>
> Your 'Signed-off-by:' goes at the end of the commit description not here.
>
> Overall, I think you did the right thing (unless someone disagrees).
> Just some minor issues.
>
> Mark
> --

2016-12-21 16:21:15

by Mark Greer

[permalink] [raw]
Subject: Re: [PATCH 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage

On Wed, Dec 21, 2016 at 06:47:36AM -0500, Geoff Lansberry wrote:
> Thanks Mark. Should I resubmit patches with the requested edits today, or wait a bit for more comments? What is the desired etiquette?

Its up to you. I don't think there are any hard & fast rules on this.

If it were me, I would likely spin a new version today because there are
several responses already and it lets people review them at their leisure
over the holidays.

Just a thought - you may want to consider separating the third patch from
the other two. The problems the first two solve are well understood and
have reasonable solutions (I believe). The third one - for me, at least -
tries to fix a problem that is not well understood yet.

Mark
--