Skip to content

Commit cedb355

Browse files
committed
Merge branch 'nfc-trf7970a-add-option-to-reduce-antenna-gain'
Paul Geurts says: ==================== NFC: trf7970a: Add option to reduce antenna gain The TRF7970a device is sensitive to RF disturbances, which can make it hard to pass some EMC immunity tests. By reducing the RX antenna gain, the device becomes less sensitive to EMC disturbances, as a trade-off against antenna performance. ==================== Link: https://patch.msgid.link/20250626141242.3749958-1-paul.geurts@prodrive-technologies.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents cb70b1b + 5d69351 commit cedb355

File tree

2 files changed

+87
-11
lines changed

2 files changed

+87
-11
lines changed

Documentation/devicetree/bindings/net/nfc/ti,trf7970a.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ properties:
5555
description: |
5656
Regulator for supply voltage to VIN pin
5757
58+
ti,rx-gain-reduction-db:
59+
$ref: /schemas/types.yaml#/definitions/uint32
60+
description: |
61+
Specify an RX gain reduction to reduce antenna sensitivity with 5dB per
62+
increment, with a maximum of 15dB. Supported values: [0, 5, 10, 15].
63+
5864
required:
5965
- compatible
6066
- interrupts
@@ -95,5 +101,6 @@ examples:
95101
irq-status-read-quirk;
96102
en2-rf-quirk;
97103
clock-frequency = <27120000>;
104+
ti,rx-gain-reduction-db = <15>;
98105
};
99106
};

drivers/nfc/trf7970a.c

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,18 @@
272272
#define TRF7970A_MODULATOR_EN_OOK BIT(6)
273273
#define TRF7970A_MODULATOR_27MHZ BIT(7)
274274

275+
#define TRF7970A_RX_GAIN_REDUCTION_MAX_DB 15
276+
#define TRF7970A_RX_GAIN_REDUCTION_DB_PER_LSB 5
275277
#define TRF7970A_RX_SPECIAL_SETTINGS_NO_LIM BIT(0)
276278
#define TRF7970A_RX_SPECIAL_SETTINGS_AGCR BIT(1)
277-
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_0DB (0x0 << 2)
278-
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_5DB (0x1 << 2)
279-
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_10DB (0x2 << 2)
280-
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_15DB (0x3 << 2)
279+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT 2
280+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_MAX (0x3)
281+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_MASK (TRF7970A_RX_SPECIAL_SETTINGS_GD_MAX << \
282+
TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT)
283+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_0DB (0x0 << TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT)
284+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_5DB (0x1 << TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT)
285+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_10DB (0x2 << TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT)
286+
#define TRF7970A_RX_SPECIAL_SETTINGS_GD_15DB (0x3 << TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT)
281287
#define TRF7970A_RX_SPECIAL_SETTINGS_HBT BIT(4)
282288
#define TRF7970A_RX_SPECIAL_SETTINGS_M848 BIT(5)
283289
#define TRF7970A_RX_SPECIAL_SETTINGS_C424 BIT(6)
@@ -452,6 +458,8 @@ struct trf7970a {
452458
unsigned int timeout;
453459
bool ignore_timeout;
454460
struct delayed_work timeout_work;
461+
u8 rx_gain_reduction;
462+
bool custom_rx_gain_reduction;
455463
};
456464

457465
static int trf7970a_cmd(struct trf7970a *trf, u8 opcode)
@@ -551,6 +559,41 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status)
551559
return ret;
552560
}
553561

562+
static int trf7970a_update_rx_gain_reduction(struct trf7970a *trf)
563+
{
564+
int ret = 0;
565+
u8 reg;
566+
567+
if (!trf->custom_rx_gain_reduction)
568+
return 0;
569+
570+
ret = trf7970a_read(trf, TRF7970A_RX_SPECIAL_SETTINGS, &reg);
571+
if (ret)
572+
return ret;
573+
reg &= ~(TRF7970A_RX_SPECIAL_SETTINGS_GD_MASK);
574+
reg |= trf->rx_gain_reduction;
575+
576+
ret = trf7970a_write(trf, TRF7970A_RX_SPECIAL_SETTINGS, reg);
577+
578+
return ret;
579+
}
580+
581+
static int trf7970a_update_iso_ctrl_register(struct trf7970a *trf, u8 iso_ctrl)
582+
{
583+
int ret;
584+
585+
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
586+
if (ret)
587+
return ret;
588+
/*
589+
* Every time the ISO_CTRL register is written, the RX special setting register is reset by
590+
* the chip. When a custom gain reguduction is required, it should be rewritten now.
591+
*/
592+
ret = trf7970a_update_rx_gain_reduction(trf);
593+
594+
return ret;
595+
}
596+
554597
static int trf7970a_read_target_proto(struct trf7970a *trf, u8 *target_proto)
555598
{
556599
int ret;
@@ -930,8 +973,7 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id)
930973
}
931974

932975
if (iso_ctrl != trf->iso_ctrl) {
933-
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL,
934-
iso_ctrl);
976+
ret = trf7970a_update_iso_ctrl_register(trf, iso_ctrl);
935977
if (ret)
936978
goto err_unlock_exit;
937979

@@ -1035,6 +1077,11 @@ static int trf7970a_init(struct trf7970a *trf)
10351077
if (ret)
10361078
goto err_out;
10371079

1080+
/* Set the gain reduction after soft init */
1081+
ret = trf7970a_update_rx_gain_reduction(trf);
1082+
if (ret)
1083+
goto err_out;
1084+
10381085
ret = trf7970a_cmd(trf, TRF7970A_CMD_IDLE);
10391086
if (ret)
10401087
goto err_out;
@@ -1309,7 +1356,7 @@ static int trf7970a_in_config_framing(struct trf7970a *trf, int framing)
13091356
}
13101357

13111358
if (iso_ctrl != trf->iso_ctrl) {
1312-
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
1359+
ret = trf7970a_update_iso_ctrl_register(trf, iso_ctrl);
13131360
if (ret)
13141361
return ret;
13151362

@@ -1441,7 +1488,7 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf,
14411488
}
14421489

14431490
if (iso_ctrl != trf->iso_ctrl) {
1444-
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
1491+
ret = trf7970a_update_iso_ctrl_register(trf, iso_ctrl);
14451492
if (ret)
14461493
return ret;
14471494

@@ -1605,8 +1652,7 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
16051652
*/
16061653
if ((trf->framing == NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED) &&
16071654
(trf->iso_ctrl_tech != trf->iso_ctrl)) {
1608-
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL,
1609-
trf->iso_ctrl_tech);
1655+
ret = trf7970a_update_iso_ctrl_register(trf, trf->iso_ctrl_tech);
16101656

16111657
trf->iso_ctrl = trf->iso_ctrl_tech;
16121658
}
@@ -1654,7 +1700,7 @@ static int trf7970a_tg_config_framing(struct trf7970a *trf, int framing)
16541700
trf->framing = framing;
16551701

16561702
if (iso_ctrl != trf->iso_ctrl) {
1657-
ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl);
1703+
ret = trf7970a_update_iso_ctrl_register(trf, iso_ctrl);
16581704
if (ret)
16591705
return ret;
16601706

@@ -1755,6 +1801,10 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
17551801
if (ret)
17561802
goto out_err;
17571803

1804+
ret = trf7970a_update_rx_gain_reduction(trf);
1805+
if (ret)
1806+
goto out_err;
1807+
17581808
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
17591809
trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
17601810
if (ret)
@@ -1945,6 +1995,10 @@ static int trf7970a_startup(struct trf7970a *trf)
19451995
if (ret)
19461996
return ret;
19471997

1998+
ret = trf7970a_update_rx_gain_reduction(trf);
1999+
if (ret)
2000+
return ret;
2001+
19482002
pm_runtime_set_active(trf->dev);
19492003
pm_runtime_enable(trf->dev);
19502004
pm_runtime_mark_last_busy(trf->dev);
@@ -1993,6 +2047,7 @@ static int trf7970a_probe(struct spi_device *spi)
19932047
struct trf7970a *trf;
19942048
int uvolts, autosuspend_delay, ret;
19952049
u32 clk_freq = TRF7970A_13MHZ_CLOCK_FREQUENCY;
2050+
u32 rx_gain_reduction_db;
19962051

19972052
if (!np) {
19982053
dev_err(&spi->dev, "No Device Tree entry\n");
@@ -2054,6 +2109,20 @@ static int trf7970a_probe(struct spi_device *spi)
20542109
trf->modulator_sys_clk_ctrl = 0;
20552110
}
20562111

2112+
if (of_property_read_u32(np, "ti,rx-gain-reduction-db", &rx_gain_reduction_db) == 0) {
2113+
if (rx_gain_reduction_db > TRF7970A_RX_GAIN_REDUCTION_MAX_DB) {
2114+
dev_warn(trf->dev, "RX Gain reduction too high. Ignored\n");
2115+
} else if ((rx_gain_reduction_db % TRF7970A_RX_GAIN_REDUCTION_DB_PER_LSB)) {
2116+
dev_warn(trf->dev, "RX Gain must be set in 5 dB increments. Ignored\n");
2117+
} else {
2118+
dev_dbg(trf->dev, "RX gain set to -%udB\n", rx_gain_reduction_db);
2119+
trf->rx_gain_reduction = ((rx_gain_reduction_db /
2120+
TRF7970A_RX_GAIN_REDUCTION_DB_PER_LSB) <<
2121+
TRF7970A_RX_SPECIAL_SETTINGS_GD_SHIFT);
2122+
trf->custom_rx_gain_reduction = true;
2123+
}
2124+
}
2125+
20572126
ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL,
20582127
trf7970a_irq,
20592128
IRQF_TRIGGER_RISING | IRQF_ONESHOT,

0 commit comments

Comments
 (0)