|
272 | 272 | #define TRF7970A_MODULATOR_EN_OOK BIT(6) |
273 | 273 | #define TRF7970A_MODULATOR_27MHZ BIT(7) |
274 | 274 |
|
| 275 | +#define TRF7970A_RX_GAIN_REDUCTION_MAX_DB 15 |
| 276 | +#define TRF7970A_RX_GAIN_REDUCTION_DB_PER_LSB 5 |
275 | 277 | #define TRF7970A_RX_SPECIAL_SETTINGS_NO_LIM BIT(0) |
276 | 278 | #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) |
281 | 287 | #define TRF7970A_RX_SPECIAL_SETTINGS_HBT BIT(4) |
282 | 288 | #define TRF7970A_RX_SPECIAL_SETTINGS_M848 BIT(5) |
283 | 289 | #define TRF7970A_RX_SPECIAL_SETTINGS_C424 BIT(6) |
@@ -452,6 +458,8 @@ struct trf7970a { |
452 | 458 | unsigned int timeout; |
453 | 459 | bool ignore_timeout; |
454 | 460 | struct delayed_work timeout_work; |
| 461 | + u8 rx_gain_reduction; |
| 462 | + bool custom_rx_gain_reduction; |
455 | 463 | }; |
456 | 464 |
|
457 | 465 | static int trf7970a_cmd(struct trf7970a *trf, u8 opcode) |
@@ -551,6 +559,41 @@ static int trf7970a_read_irqstatus(struct trf7970a *trf, u8 *status) |
551 | 559 | return ret; |
552 | 560 | } |
553 | 561 |
|
| 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, ®); |
| 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 | + |
554 | 597 | static int trf7970a_read_target_proto(struct trf7970a *trf, u8 *target_proto) |
555 | 598 | { |
556 | 599 | int ret; |
@@ -930,8 +973,7 @@ static irqreturn_t trf7970a_irq(int irq, void *dev_id) |
930 | 973 | } |
931 | 974 |
|
932 | 975 | 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); |
935 | 977 | if (ret) |
936 | 978 | goto err_unlock_exit; |
937 | 979 |
|
@@ -1035,6 +1077,11 @@ static int trf7970a_init(struct trf7970a *trf) |
1035 | 1077 | if (ret) |
1036 | 1078 | goto err_out; |
1037 | 1079 |
|
| 1080 | + /* Set the gain reduction after soft init */ |
| 1081 | + ret = trf7970a_update_rx_gain_reduction(trf); |
| 1082 | + if (ret) |
| 1083 | + goto err_out; |
| 1084 | + |
1038 | 1085 | ret = trf7970a_cmd(trf, TRF7970A_CMD_IDLE); |
1039 | 1086 | if (ret) |
1040 | 1087 | goto err_out; |
@@ -1309,7 +1356,7 @@ static int trf7970a_in_config_framing(struct trf7970a *trf, int framing) |
1309 | 1356 | } |
1310 | 1357 |
|
1311 | 1358 | 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); |
1313 | 1360 | if (ret) |
1314 | 1361 | return ret; |
1315 | 1362 |
|
@@ -1441,7 +1488,7 @@ static int trf7970a_per_cmd_config(struct trf7970a *trf, |
1441 | 1488 | } |
1442 | 1489 |
|
1443 | 1490 | 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); |
1445 | 1492 | if (ret) |
1446 | 1493 | return ret; |
1447 | 1494 |
|
@@ -1605,8 +1652,7 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech) |
1605 | 1652 | */ |
1606 | 1653 | if ((trf->framing == NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED) && |
1607 | 1654 | (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); |
1610 | 1656 |
|
1611 | 1657 | trf->iso_ctrl = trf->iso_ctrl_tech; |
1612 | 1658 | } |
@@ -1654,7 +1700,7 @@ static int trf7970a_tg_config_framing(struct trf7970a *trf, int framing) |
1654 | 1700 | trf->framing = framing; |
1655 | 1701 |
|
1656 | 1702 | 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); |
1658 | 1704 | if (ret) |
1659 | 1705 | return ret; |
1660 | 1706 |
|
@@ -1755,6 +1801,10 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout, |
1755 | 1801 | if (ret) |
1756 | 1802 | goto out_err; |
1757 | 1803 |
|
| 1804 | + ret = trf7970a_update_rx_gain_reduction(trf); |
| 1805 | + if (ret) |
| 1806 | + goto out_err; |
| 1807 | + |
1758 | 1808 | ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL, |
1759 | 1809 | trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1)); |
1760 | 1810 | if (ret) |
@@ -1945,6 +1995,10 @@ static int trf7970a_startup(struct trf7970a *trf) |
1945 | 1995 | if (ret) |
1946 | 1996 | return ret; |
1947 | 1997 |
|
| 1998 | + ret = trf7970a_update_rx_gain_reduction(trf); |
| 1999 | + if (ret) |
| 2000 | + return ret; |
| 2001 | + |
1948 | 2002 | pm_runtime_set_active(trf->dev); |
1949 | 2003 | pm_runtime_enable(trf->dev); |
1950 | 2004 | pm_runtime_mark_last_busy(trf->dev); |
@@ -1993,6 +2047,7 @@ static int trf7970a_probe(struct spi_device *spi) |
1993 | 2047 | struct trf7970a *trf; |
1994 | 2048 | int uvolts, autosuspend_delay, ret; |
1995 | 2049 | u32 clk_freq = TRF7970A_13MHZ_CLOCK_FREQUENCY; |
| 2050 | + u32 rx_gain_reduction_db; |
1996 | 2051 |
|
1997 | 2052 | if (!np) { |
1998 | 2053 | dev_err(&spi->dev, "No Device Tree entry\n"); |
@@ -2054,6 +2109,20 @@ static int trf7970a_probe(struct spi_device *spi) |
2054 | 2109 | trf->modulator_sys_clk_ctrl = 0; |
2055 | 2110 | } |
2056 | 2111 |
|
| 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 | + |
2057 | 2126 | ret = devm_request_threaded_irq(trf->dev, spi->irq, NULL, |
2058 | 2127 | trf7970a_irq, |
2059 | 2128 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
|
0 commit comments