aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/nfc/port100.c366
1 files changed, 363 insertions, 3 deletions
diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c
index 251a2c112299..99a6dd79393d 100644
--- a/drivers/nfc/port100.c
+++ b/drivers/nfc/port100.c
@@ -71,6 +71,12 @@ static u8 ack_frame[PORT100_FRAME_ACK_SIZE] = {
71#define PORT100_CMD_GET_COMMAND_TYPE 0x28 71#define PORT100_CMD_GET_COMMAND_TYPE 0x28
72#define PORT100_CMD_SET_COMMAND_TYPE 0x2A 72#define PORT100_CMD_SET_COMMAND_TYPE 0x2A
73 73
74#define PORT100_CMD_IN_SET_RF 0x00
75#define PORT100_CMD_IN_SET_PROTOCOL 0x02
76#define PORT100_CMD_IN_COMM_RF 0x04
77
78#define PORT100_CMD_SWITCH_RF 0x06
79
74#define PORT100_CMD_RESPONSE(cmd) (cmd + 1) 80#define PORT100_CMD_RESPONSE(cmd) (cmd + 1)
75 81
76#define PORT100_CMD_TYPE_IS_SUPPORTED(mask, cmd_type) \ 82#define PORT100_CMD_TYPE_IS_SUPPORTED(mask, cmd_type) \
@@ -78,11 +84,204 @@ static u8 ack_frame[PORT100_FRAME_ACK_SIZE] = {
78#define PORT100_CMD_TYPE_0 0 84#define PORT100_CMD_TYPE_0 0
79#define PORT100_CMD_TYPE_1 1 85#define PORT100_CMD_TYPE_1 1
80 86
87#define PORT100_CMD_STATUS_OK 0x00
88#define PORT100_CMD_STATUS_TIMEOUT 0x80
89
81struct port100; 90struct port100;
82 91
83typedef void (*port100_send_async_complete_t)(struct port100 *dev, void *arg, 92typedef void (*port100_send_async_complete_t)(struct port100 *dev, void *arg,
84 struct sk_buff *resp); 93 struct sk_buff *resp);
85 94
95/**
96 * Setting sets structure for in_set_rf command
97 *
98 * @in_*_set_number: Represent the entry indexes in the port-100 RF Base Table.
99 * This table contains multiple RF setting sets required for RF
100 * communication.
101 *
102 * @in_*_comm_type: Theses fields set the communication type to be used.
103 */
104struct port100_in_rf_setting {
105 u8 in_send_set_number;
106 u8 in_send_comm_type;
107 u8 in_recv_set_number;
108 u8 in_recv_comm_type;
109} __packed;
110
111#define PORT100_COMM_TYPE_IN_212F 0x01
112#define PORT100_COMM_TYPE_IN_424F 0x02
113#define PORT100_COMM_TYPE_IN_106A 0x03
114
115static const struct port100_in_rf_setting in_rf_settings[] = {
116 [NFC_DIGITAL_RF_TECH_212F] = {
117 .in_send_set_number = 1,
118 .in_send_comm_type = PORT100_COMM_TYPE_IN_212F,
119 .in_recv_set_number = 15,
120 .in_recv_comm_type = PORT100_COMM_TYPE_IN_212F,
121 },
122 [NFC_DIGITAL_RF_TECH_424F] = {
123 .in_send_set_number = 1,
124 .in_send_comm_type = PORT100_COMM_TYPE_IN_424F,
125 .in_recv_set_number = 15,
126 .in_recv_comm_type = PORT100_COMM_TYPE_IN_424F,
127 },
128 [NFC_DIGITAL_RF_TECH_106A] = {
129 .in_send_set_number = 2,
130 .in_send_comm_type = PORT100_COMM_TYPE_IN_106A,
131 .in_recv_set_number = 15,
132 .in_recv_comm_type = PORT100_COMM_TYPE_IN_106A,
133 },
134};
135
136#define PORT100_IN_PROT_INITIAL_GUARD_TIME 0x00
137#define PORT100_IN_PROT_ADD_CRC 0x01
138#define PORT100_IN_PROT_CHECK_CRC 0x02
139#define PORT100_IN_PROT_MULTI_CARD 0x03
140#define PORT100_IN_PROT_ADD_PARITY 0x04
141#define PORT100_IN_PROT_CHECK_PARITY 0x05
142#define PORT100_IN_PROT_BITWISE_AC_RECV_MODE 0x06
143#define PORT100_IN_PROT_VALID_BIT_NUMBER 0x07
144#define PORT100_IN_PROT_CRYPTO1 0x08
145#define PORT100_IN_PROT_ADD_SOF 0x09
146#define PORT100_IN_PROT_CHECK_SOF 0x0A
147#define PORT100_IN_PROT_ADD_EOF 0x0B
148#define PORT100_IN_PROT_CHECK_EOF 0x0C
149#define PORT100_IN_PROT_DEAF_TIME 0x0E
150#define PORT100_IN_PROT_CRM 0x0F
151#define PORT100_IN_PROT_CRM_MIN_LEN 0x10
152#define PORT100_IN_PROT_T1_TAG_FRAME 0x11
153#define PORT100_IN_PROT_RFCA 0x12
154#define PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR 0x13
155#define PORT100_IN_PROT_END 0x14
156
157#define PORT100_IN_MAX_NUM_PROTOCOLS 19
158
159struct port100_protocol {
160 u8 number;
161 u8 value;
162} __packed;
163
164static struct port100_protocol
165in_protocols[][PORT100_IN_MAX_NUM_PROTOCOLS + 1] = {
166 [NFC_DIGITAL_FRAMING_NFCA_SHORT] = {
167 { PORT100_IN_PROT_INITIAL_GUARD_TIME, 6 },
168 { PORT100_IN_PROT_ADD_CRC, 0 },
169 { PORT100_IN_PROT_CHECK_CRC, 0 },
170 { PORT100_IN_PROT_MULTI_CARD, 0 },
171 { PORT100_IN_PROT_ADD_PARITY, 0 },
172 { PORT100_IN_PROT_CHECK_PARITY, 1 },
173 { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
174 { PORT100_IN_PROT_VALID_BIT_NUMBER, 7 },
175 { PORT100_IN_PROT_CRYPTO1, 0 },
176 { PORT100_IN_PROT_ADD_SOF, 0 },
177 { PORT100_IN_PROT_CHECK_SOF, 0 },
178 { PORT100_IN_PROT_ADD_EOF, 0 },
179 { PORT100_IN_PROT_CHECK_EOF, 0 },
180 { PORT100_IN_PROT_DEAF_TIME, 4 },
181 { PORT100_IN_PROT_CRM, 0 },
182 { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
183 { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
184 { PORT100_IN_PROT_RFCA, 0 },
185 { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
186 { PORT100_IN_PROT_END, 0 },
187 },
188 [NFC_DIGITAL_FRAMING_NFCA_STANDARD] = {
189 { PORT100_IN_PROT_INITIAL_GUARD_TIME, 6 },
190 { PORT100_IN_PROT_ADD_CRC, 0 },
191 { PORT100_IN_PROT_CHECK_CRC, 0 },
192 { PORT100_IN_PROT_MULTI_CARD, 0 },
193 { PORT100_IN_PROT_ADD_PARITY, 1 },
194 { PORT100_IN_PROT_CHECK_PARITY, 1 },
195 { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
196 { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
197 { PORT100_IN_PROT_CRYPTO1, 0 },
198 { PORT100_IN_PROT_ADD_SOF, 0 },
199 { PORT100_IN_PROT_CHECK_SOF, 0 },
200 { PORT100_IN_PROT_ADD_EOF, 0 },
201 { PORT100_IN_PROT_CHECK_EOF, 0 },
202 { PORT100_IN_PROT_DEAF_TIME, 4 },
203 { PORT100_IN_PROT_CRM, 0 },
204 { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
205 { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
206 { PORT100_IN_PROT_RFCA, 0 },
207 { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
208 { PORT100_IN_PROT_END, 0 },
209 },
210 [NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A] = {
211 { PORT100_IN_PROT_INITIAL_GUARD_TIME, 6 },
212 { PORT100_IN_PROT_ADD_CRC, 1 },
213 { PORT100_IN_PROT_CHECK_CRC, 1 },
214 { PORT100_IN_PROT_MULTI_CARD, 0 },
215 { PORT100_IN_PROT_ADD_PARITY, 1 },
216 { PORT100_IN_PROT_CHECK_PARITY, 1 },
217 { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
218 { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
219 { PORT100_IN_PROT_CRYPTO1, 0 },
220 { PORT100_IN_PROT_ADD_SOF, 0 },
221 { PORT100_IN_PROT_CHECK_SOF, 0 },
222 { PORT100_IN_PROT_ADD_EOF, 0 },
223 { PORT100_IN_PROT_CHECK_EOF, 0 },
224 { PORT100_IN_PROT_DEAF_TIME, 4 },
225 { PORT100_IN_PROT_CRM, 0 },
226 { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
227 { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
228 { PORT100_IN_PROT_RFCA, 0 },
229 { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
230 { PORT100_IN_PROT_END, 0 },
231 },
232 [NFC_DIGITAL_FRAMING_NFCA_T1T] = {
233 /* nfc_digital_framing_nfca_short */
234 { PORT100_IN_PROT_ADD_CRC, 2 },
235 { PORT100_IN_PROT_CHECK_CRC, 2 },
236 { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
237 { PORT100_IN_PROT_T1_TAG_FRAME, 2 },
238 { PORT100_IN_PROT_END, 0 },
239 },
240 [NFC_DIGITAL_FRAMING_NFCA_T2T] = {
241 /* nfc_digital_framing_nfca_standard */
242 { PORT100_IN_PROT_ADD_CRC, 1 },
243 { PORT100_IN_PROT_CHECK_CRC, 0 },
244 { PORT100_IN_PROT_END, 0 },
245 },
246 [NFC_DIGITAL_FRAMING_NFCA_NFC_DEP] = {
247 /* nfc_digital_framing_nfca_standard */
248 { PORT100_IN_PROT_END, 0 },
249 },
250 [NFC_DIGITAL_FRAMING_NFCF] = {
251 { PORT100_IN_PROT_INITIAL_GUARD_TIME, 18 },
252 { PORT100_IN_PROT_ADD_CRC, 1 },
253 { PORT100_IN_PROT_CHECK_CRC, 1 },
254 { PORT100_IN_PROT_MULTI_CARD, 0 },
255 { PORT100_IN_PROT_ADD_PARITY, 0 },
256 { PORT100_IN_PROT_CHECK_PARITY, 0 },
257 { PORT100_IN_PROT_BITWISE_AC_RECV_MODE, 0 },
258 { PORT100_IN_PROT_VALID_BIT_NUMBER, 8 },
259 { PORT100_IN_PROT_CRYPTO1, 0 },
260 { PORT100_IN_PROT_ADD_SOF, 0 },
261 { PORT100_IN_PROT_CHECK_SOF, 0 },
262 { PORT100_IN_PROT_ADD_EOF, 0 },
263 { PORT100_IN_PROT_CHECK_EOF, 0 },
264 { PORT100_IN_PROT_DEAF_TIME, 4 },
265 { PORT100_IN_PROT_CRM, 0 },
266 { PORT100_IN_PROT_CRM_MIN_LEN, 0 },
267 { PORT100_IN_PROT_T1_TAG_FRAME, 0 },
268 { PORT100_IN_PROT_RFCA, 0 },
269 { PORT100_IN_PROT_GUARD_TIME_AT_INITIATOR, 6 },
270 { PORT100_IN_PROT_END, 0 },
271 },
272 [NFC_DIGITAL_FRAMING_NFCF_T3T] = {
273 /* nfc_digital_framing_nfcf */
274 { PORT100_IN_PROT_END, 0 },
275 },
276 [NFC_DIGITAL_FRAMING_NFCF_NFC_DEP] = {
277 /* nfc_digital_framing_nfcf */
278 { PORT100_IN_PROT_END, 0 },
279 },
280 [NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED] = {
281 { PORT100_IN_PROT_END, 0 },
282 },
283};
284
86struct port100 { 285struct port100 {
87 struct nfc_digital_dev *nfc_digital_dev; 286 struct nfc_digital_dev *nfc_digital_dev;
88 287
@@ -626,20 +825,181 @@ static u16 port100_get_firmware_version(struct port100 *dev)
626 825
627static int port100_switch_rf(struct nfc_digital_dev *ddev, bool on) 826static int port100_switch_rf(struct nfc_digital_dev *ddev, bool on)
628{ 827{
629 return -EOPNOTSUPP; 828 struct port100 *dev = nfc_digital_get_drvdata(ddev);
829 struct sk_buff *skb, *resp;
830
831 skb = port100_alloc_skb(dev, 1);
832 if (!skb)
833 return -ENOMEM;
834
835 *skb_put(skb, 1) = on ? 1 : 0;
836
837 resp = port100_send_cmd_sync(dev, PORT100_CMD_SWITCH_RF, skb);
838
839 if (IS_ERR(resp))
840 return PTR_ERR(resp);
841
842 dev_kfree_skb(resp);
843
844 return 0;
845}
846
847static int port100_in_set_rf(struct nfc_digital_dev *ddev, u8 rf)
848{
849 struct port100 *dev = nfc_digital_get_drvdata(ddev);
850 struct sk_buff *skb;
851 struct sk_buff *resp;
852 int rc;
853
854 if (rf >= NFC_DIGITAL_RF_TECH_LAST)
855 return -EINVAL;
856
857 skb = port100_alloc_skb(dev, sizeof(struct port100_in_rf_setting));
858 if (!skb)
859 return -ENOMEM;
860
861 memcpy(skb_put(skb, sizeof(struct port100_in_rf_setting)),
862 &in_rf_settings[rf],
863 sizeof(struct port100_in_rf_setting));
864
865 resp = port100_send_cmd_sync(dev, PORT100_CMD_IN_SET_RF, skb);
866
867 if (IS_ERR(resp))
868 return PTR_ERR(resp);
869
870 rc = resp->data[0];
871
872 dev_kfree_skb(resp);
873
874 return rc;
875}
876
877static int port100_in_set_framing(struct nfc_digital_dev *ddev, int param)
878{
879 struct port100 *dev = nfc_digital_get_drvdata(ddev);
880 struct port100_protocol *protocols;
881 struct sk_buff *skb;
882 struct sk_buff *resp;
883 int num_protocols;
884 size_t size;
885 int rc;
886
887 if (param >= NFC_DIGITAL_FRAMING_LAST)
888 return -EINVAL;
889
890 protocols = in_protocols[param];
891
892 num_protocols = 0;
893 while (protocols[num_protocols].number != PORT100_IN_PROT_END)
894 num_protocols++;
895
896 if (!num_protocols)
897 return 0;
898
899 size = sizeof(struct port100_protocol) * num_protocols;
900
901 skb = port100_alloc_skb(dev, size);
902 if (!skb)
903 return -ENOMEM;
904
905 memcpy(skb_put(skb, size), protocols, size);
906
907 resp = port100_send_cmd_sync(dev, PORT100_CMD_IN_SET_PROTOCOL, skb);
908
909 if (IS_ERR(resp))
910 return PTR_ERR(resp);
911
912 rc = resp->data[0];
913
914 dev_kfree_skb(resp);
915
916 return rc;
630} 917}
631 918
632static int port100_in_configure_hw(struct nfc_digital_dev *ddev, int type, 919static int port100_in_configure_hw(struct nfc_digital_dev *ddev, int type,
633 int param) 920 int param)
634{ 921{
635 return -EOPNOTSUPP; 922 if (type == NFC_DIGITAL_CONFIG_RF_TECH)
923 return port100_in_set_rf(ddev, param);
924
925 if (type == NFC_DIGITAL_CONFIG_FRAMING)
926 return port100_in_set_framing(ddev, param);
927
928 return -EINVAL;
929}
930
931static void port100_in_comm_rf_complete(struct port100 *dev, void *arg,
932 struct sk_buff *resp)
933{
934 struct port100_cb_arg *cb_arg = arg;
935 nfc_digital_cmd_complete_t cb = cb_arg->complete_cb;
936 u32 status;
937 int rc;
938
939 if (IS_ERR(resp)) {
940 rc = PTR_ERR(resp);
941 goto exit;
942 }
943
944 if (resp->len < 4) {
945 nfc_err(&dev->interface->dev,
946 "Invalid packet length received.\n");
947 rc = -EIO;
948 goto error;
949 }
950
951 status = le32_to_cpu(*(__le32 *)resp->data);
952
953 skb_pull(resp, sizeof(u32));
954
955 if (status == PORT100_CMD_STATUS_TIMEOUT) {
956 rc = -ETIMEDOUT;
957 goto error;
958 }
959
960 if (status != PORT100_CMD_STATUS_OK) {
961 nfc_err(&dev->interface->dev,
962 "in_comm_rf failed with status 0x%08x\n", status);
963 rc = -EIO;
964 goto error;
965 }
966
967 /* Remove collision bits byte */
968 skb_pull(resp, 1);
969
970 goto exit;
971
972error:
973 kfree_skb(resp);
974 resp = ERR_PTR(rc);
975
976exit:
977 cb(dev->nfc_digital_dev, cb_arg->complete_arg, resp);
978
979 kfree(cb_arg);
636} 980}
637 981
638static int port100_in_send_cmd(struct nfc_digital_dev *ddev, 982static int port100_in_send_cmd(struct nfc_digital_dev *ddev,
639 struct sk_buff *skb, u16 _timeout, 983 struct sk_buff *skb, u16 _timeout,
640 nfc_digital_cmd_complete_t cb, void *arg) 984 nfc_digital_cmd_complete_t cb, void *arg)
641{ 985{
642 return -EOPNOTSUPP; 986 struct port100 *dev = nfc_digital_get_drvdata(ddev);
987 struct port100_cb_arg *cb_arg;
988 __le16 timeout;
989
990 cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL);
991 if (!cb_arg)
992 return -ENOMEM;
993
994 cb_arg->complete_cb = cb;
995 cb_arg->complete_arg = arg;
996
997 timeout = cpu_to_le16(_timeout * 10);
998
999 memcpy(skb_push(skb, sizeof(__le16)), &timeout, sizeof(__le16));
1000
1001 return port100_send_cmd_async(dev, PORT100_CMD_IN_COMM_RF, skb,
1002 port100_in_comm_rf_complete, cb_arg);
643} 1003}
644 1004
645static int port100_tg_configure_hw(struct nfc_digital_dev *ddev, int type, 1005static int port100_tg_configure_hw(struct nfc_digital_dev *ddev, int type,