diff options
author | Mark A. Greer <mgreer@animalcreek.com> | 2014-09-02 18:12:42 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2014-09-07 17:13:45 -0400 |
commit | 851ee3cbf850501104e76683e439a4061f378a96 (patch) | |
tree | 698b971d53ad0a2876e1eb3b1e85bd53f42eafdc | |
parent | 7149d6bfecadc255e9d964782a9fdd70f610f1ea (diff) |
NFC: trf7970a: Don't turn on RF if there is already an RF field
Currently, the trf7970a driver blindly turns on its
RF field when configuring its framing. This isn't
a good idea if there is already a device generating
an RF field. Instead, check if there is already an
RF field present before turning on this device's RF
field and, if there is, return EBUSY.
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/nfc/trf7970a.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c index ab6e276be6a6..0f09278ec37a 100644 --- a/drivers/nfc/trf7970a.c +++ b/drivers/nfc/trf7970a.c | |||
@@ -164,8 +164,8 @@ | |||
164 | #define TRF7970A_CMD_CLOSE_SLOT 0x15 | 164 | #define TRF7970A_CMD_CLOSE_SLOT 0x15 |
165 | #define TRF7970A_CMD_BLOCK_RX 0x16 | 165 | #define TRF7970A_CMD_BLOCK_RX 0x16 |
166 | #define TRF7970A_CMD_ENABLE_RX 0x17 | 166 | #define TRF7970A_CMD_ENABLE_RX 0x17 |
167 | #define TRF7970A_CMD_TEST_EXT_RF 0x18 | 167 | #define TRF7970A_CMD_TEST_INT_RF 0x18 |
168 | #define TRF7970A_CMD_TEST_INT_RF 0x19 | 168 | #define TRF7970A_CMD_TEST_EXT_RF 0x19 |
169 | #define TRF7970A_CMD_RX_GAIN_ADJUST 0x1a | 169 | #define TRF7970A_CMD_RX_GAIN_ADJUST 0x1a |
170 | 170 | ||
171 | /* Bits determining whether its a direct command or register R/W, | 171 | /* Bits determining whether its a direct command or register R/W, |
@@ -280,6 +280,10 @@ | |||
280 | TRF7970A_IRQ_STATUS_PARITY_ERROR | \ | 280 | TRF7970A_IRQ_STATUS_PARITY_ERROR | \ |
281 | TRF7970A_IRQ_STATUS_CRC_ERROR) | 281 | TRF7970A_IRQ_STATUS_CRC_ERROR) |
282 | 282 | ||
283 | #define TRF7970A_RSSI_OSC_STATUS_RSSI_MASK (BIT(2) | BIT(1) | BIT(0)) | ||
284 | #define TRF7970A_RSSI_OSC_STATUS_RSSI_X_MASK (BIT(5) | BIT(4) | BIT(3)) | ||
285 | #define TRF7970A_RSSI_OSC_STATUS_RSSI_OSC_OK BIT(6) | ||
286 | |||
283 | #define TRF7970A_SPECIAL_FCN_REG1_COL_7_6 BIT(0) | 287 | #define TRF7970A_SPECIAL_FCN_REG1_COL_7_6 BIT(0) |
284 | #define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL BIT(1) | 288 | #define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL BIT(1) |
285 | #define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX BIT(2) | 289 | #define TRF7970A_SPECIAL_FCN_REG1_4_BIT_RX BIT(2) |
@@ -989,9 +993,43 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech) | |||
989 | return ret; | 993 | return ret; |
990 | } | 994 | } |
991 | 995 | ||
996 | static int trf7970a_is_rf_field(struct trf7970a *trf, bool *is_rf_field) | ||
997 | { | ||
998 | int ret; | ||
999 | u8 rssi; | ||
1000 | |||
1001 | ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, | ||
1002 | trf->chip_status_ctrl | TRF7970A_CHIP_STATUS_REC_ON); | ||
1003 | if (ret) | ||
1004 | return ret; | ||
1005 | |||
1006 | ret = trf7970a_cmd(trf, TRF7970A_CMD_TEST_EXT_RF); | ||
1007 | if (ret) | ||
1008 | return ret; | ||
1009 | |||
1010 | usleep_range(50, 60); | ||
1011 | |||
1012 | ret = trf7970a_read(trf, TRF7970A_RSSI_OSC_STATUS, &rssi); | ||
1013 | if (ret) | ||
1014 | return ret; | ||
1015 | |||
1016 | ret = trf7970a_write(trf, TRF7970A_CHIP_STATUS_CTRL, | ||
1017 | trf->chip_status_ctrl); | ||
1018 | if (ret) | ||
1019 | return ret; | ||
1020 | |||
1021 | if (rssi & TRF7970A_RSSI_OSC_STATUS_RSSI_MASK) | ||
1022 | *is_rf_field = true; | ||
1023 | else | ||
1024 | *is_rf_field = false; | ||
1025 | |||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
992 | static int trf7970a_in_config_framing(struct trf7970a *trf, int framing) | 1029 | static int trf7970a_in_config_framing(struct trf7970a *trf, int framing) |
993 | { | 1030 | { |
994 | u8 iso_ctrl = trf->iso_ctrl_tech; | 1031 | u8 iso_ctrl = trf->iso_ctrl_tech; |
1032 | bool is_rf_field = false; | ||
995 | int ret; | 1033 | int ret; |
996 | 1034 | ||
997 | dev_dbg(trf->dev, "framing: %d\n", framing); | 1035 | dev_dbg(trf->dev, "framing: %d\n", framing); |
@@ -1024,6 +1062,15 @@ static int trf7970a_in_config_framing(struct trf7970a *trf, int framing) | |||
1024 | 1062 | ||
1025 | trf->framing = framing; | 1063 | trf->framing = framing; |
1026 | 1064 | ||
1065 | if (!(trf->chip_status_ctrl & TRF7970A_CHIP_STATUS_RF_ON)) { | ||
1066 | ret = trf7970a_is_rf_field(trf, &is_rf_field); | ||
1067 | if (ret) | ||
1068 | return ret; | ||
1069 | |||
1070 | if (is_rf_field) | ||
1071 | return -EBUSY; | ||
1072 | } | ||
1073 | |||
1027 | if (iso_ctrl != trf->iso_ctrl) { | 1074 | if (iso_ctrl != trf->iso_ctrl) { |
1028 | ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl); | 1075 | ret = trf7970a_write(trf, TRF7970A_ISO_CTRL, iso_ctrl); |
1029 | if (ret) | 1076 | if (ret) |