aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@animalcreek.com>2014-09-02 18:12:42 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-09-07 17:13:45 -0400
commit851ee3cbf850501104e76683e439a4061f378a96 (patch)
tree698b971d53ad0a2876e1eb3b1e85bd53f42eafdc
parent7149d6bfecadc255e9d964782a9fdd70f610f1ea (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.c51
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
996static 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
992static int trf7970a_in_config_framing(struct trf7970a *trf, int framing) 1029static 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)