1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * -------------------------------------------------------------------- |
4 | * Driver for ST NFC Transceiver ST95HF |
5 | * -------------------------------------------------------------------- |
6 | * Copyright (C) 2015 STMicroelectronics Pvt. Ltd. All rights reserved. |
7 | */ |
8 | |
9 | #include <linux/err.h> |
10 | #include <linux/gpio.h> |
11 | #include <linux/init.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/irq.h> |
14 | #include <linux/module.h> |
15 | #include <linux/netdevice.h> |
16 | #include <linux/nfc.h> |
17 | #include <linux/of_gpio.h> |
18 | #include <linux/of.h> |
19 | #include <linux/property.h> |
20 | #include <linux/regulator/consumer.h> |
21 | #include <linux/wait.h> |
22 | #include <net/nfc/digital.h> |
23 | #include <net/nfc/nfc.h> |
24 | |
25 | #include "spi.h" |
26 | |
27 | /* supported protocols */ |
28 | #define ST95HF_SUPPORTED_PROT (NFC_PROTO_ISO14443_MASK | \ |
29 | NFC_PROTO_ISO14443_B_MASK | \ |
30 | NFC_PROTO_ISO15693_MASK) |
31 | /* driver capabilities */ |
32 | #define ST95HF_CAPABILITIES NFC_DIGITAL_DRV_CAPS_IN_CRC |
33 | |
34 | /* Command Send Interface */ |
35 | /* ST95HF_COMMAND_SEND CMD Ids */ |
36 | #define ECHO_CMD 0x55 |
37 | #define WRITE_REGISTER_CMD 0x9 |
38 | #define PROTOCOL_SELECT_CMD 0x2 |
39 | #define SEND_RECEIVE_CMD 0x4 |
40 | |
41 | /* Select protocol codes */ |
42 | #define ISO15693_PROTOCOL_CODE 0x1 |
43 | #define ISO14443A_PROTOCOL_CODE 0x2 |
44 | #define ISO14443B_PROTOCOL_CODE 0x3 |
45 | |
46 | /* |
47 | * head room len is 3 |
48 | * 1 byte for control byte |
49 | * 1 byte for cmd |
50 | * 1 byte for size |
51 | */ |
52 | #define ST95HF_HEADROOM_LEN 3 |
53 | |
54 | /* |
55 | * tailroom is 1 for ISO14443A |
56 | * and 0 for ISO14443B/ISO15693, |
57 | * hence the max value 1 should be |
58 | * taken. |
59 | */ |
60 | #define ST95HF_TAILROOM_LEN 1 |
61 | |
62 | /* Command Response interface */ |
63 | #define MAX_RESPONSE_BUFFER_SIZE 280 |
64 | #define ECHORESPONSE 0x55 |
65 | #define ST95HF_ERR_MASK 0xF |
66 | #define ST95HF_TIMEOUT_ERROR 0x87 |
67 | #define ST95HF_NFCA_CRC_ERR_MASK 0x20 |
68 | #define ST95HF_NFCB_CRC_ERR_MASK 0x01 |
69 | |
70 | /* ST95HF transmission flag values */ |
71 | #define TRFLAG_NFCA_SHORT_FRAME 0x07 |
72 | #define TRFLAG_NFCA_STD_FRAME 0x08 |
73 | #define TRFLAG_NFCA_STD_FRAME_CRC 0x28 |
74 | |
75 | /* Misc defs */ |
76 | #define HIGH 1 |
77 | #define LOW 0 |
78 | #define ISO14443A_RATS_REQ 0xE0 |
79 | #define RATS_TB1_PRESENT_MASK 0x20 |
80 | #define RATS_TA1_PRESENT_MASK 0x10 |
81 | #define TB1_FWI_MASK 0xF0 |
82 | #define WTX_REQ_FROM_TAG 0xF2 |
83 | |
84 | #define MAX_CMD_LEN 0x7 |
85 | |
86 | #define MAX_CMD_PARAMS 4 |
87 | struct cmd { |
88 | int cmd_len; |
89 | unsigned char cmd_id; |
90 | unsigned char no_cmd_params; |
91 | unsigned char cmd_params[MAX_CMD_PARAMS]; |
92 | enum req_type req; |
93 | }; |
94 | |
95 | struct param_list { |
96 | int param_offset; |
97 | int new_param_val; |
98 | }; |
99 | |
100 | /* |
101 | * List of top-level cmds to be used internally by the driver. |
102 | * All these commands are build on top of ST95HF basic commands |
103 | * such as SEND_RECEIVE_CMD, PROTOCOL_SELECT_CMD, etc. |
104 | * These top level cmds are used internally while implementing various ops of |
105 | * digital layer/driver probe or extending the digital framework layer for |
106 | * features that are not yet implemented there, for example, WTX cmd handling. |
107 | */ |
108 | enum st95hf_cmd_list { |
109 | CMD_ECHO, |
110 | CMD_ISO14443A_CONFIG, |
111 | CMD_ISO14443A_DEMOGAIN, |
112 | CMD_ISO14443B_DEMOGAIN, |
113 | CMD_ISO14443A_PROTOCOL_SELECT, |
114 | CMD_ISO14443B_PROTOCOL_SELECT, |
115 | CMD_WTX_RESPONSE, |
116 | CMD_FIELD_OFF, |
117 | CMD_ISO15693_PROTOCOL_SELECT, |
118 | }; |
119 | |
120 | static const struct cmd cmd_array[] = { |
121 | [CMD_ECHO] = { |
122 | .cmd_len = 0x2, |
123 | .cmd_id = ECHO_CMD, |
124 | .no_cmd_params = 0, |
125 | .req = SYNC, |
126 | }, |
127 | [CMD_ISO14443A_CONFIG] = { |
128 | .cmd_len = 0x7, |
129 | .cmd_id = WRITE_REGISTER_CMD, |
130 | .no_cmd_params = 0x4, |
131 | .cmd_params = {0x3A, 0x00, 0x5A, 0x04}, |
132 | .req = SYNC, |
133 | }, |
134 | [CMD_ISO14443A_DEMOGAIN] = { |
135 | .cmd_len = 0x7, |
136 | .cmd_id = WRITE_REGISTER_CMD, |
137 | .no_cmd_params = 0x4, |
138 | .cmd_params = {0x68, 0x01, 0x01, 0xDF}, |
139 | .req = SYNC, |
140 | }, |
141 | [CMD_ISO14443B_DEMOGAIN] = { |
142 | .cmd_len = 0x7, |
143 | .cmd_id = WRITE_REGISTER_CMD, |
144 | .no_cmd_params = 0x4, |
145 | .cmd_params = {0x68, 0x01, 0x01, 0x51}, |
146 | .req = SYNC, |
147 | }, |
148 | [CMD_ISO14443A_PROTOCOL_SELECT] = { |
149 | .cmd_len = 0x7, |
150 | .cmd_id = PROTOCOL_SELECT_CMD, |
151 | .no_cmd_params = 0x4, |
152 | .cmd_params = {ISO14443A_PROTOCOL_CODE, 0x00, 0x01, 0xA0}, |
153 | .req = SYNC, |
154 | }, |
155 | [CMD_ISO14443B_PROTOCOL_SELECT] = { |
156 | .cmd_len = 0x7, |
157 | .cmd_id = PROTOCOL_SELECT_CMD, |
158 | .no_cmd_params = 0x4, |
159 | .cmd_params = {ISO14443B_PROTOCOL_CODE, 0x01, 0x03, 0xFF}, |
160 | .req = SYNC, |
161 | }, |
162 | [CMD_WTX_RESPONSE] = { |
163 | .cmd_len = 0x6, |
164 | .cmd_id = SEND_RECEIVE_CMD, |
165 | .no_cmd_params = 0x3, |
166 | .cmd_params = {0xF2, 0x00, TRFLAG_NFCA_STD_FRAME_CRC}, |
167 | .req = ASYNC, |
168 | }, |
169 | [CMD_FIELD_OFF] = { |
170 | .cmd_len = 0x5, |
171 | .cmd_id = PROTOCOL_SELECT_CMD, |
172 | .no_cmd_params = 0x2, |
173 | .cmd_params = {0x0, 0x0}, |
174 | .req = SYNC, |
175 | }, |
176 | [CMD_ISO15693_PROTOCOL_SELECT] = { |
177 | .cmd_len = 0x5, |
178 | .cmd_id = PROTOCOL_SELECT_CMD, |
179 | .no_cmd_params = 0x2, |
180 | .cmd_params = {ISO15693_PROTOCOL_CODE, 0x0D}, |
181 | .req = SYNC, |
182 | }, |
183 | }; |
184 | |
185 | /* st95_digital_cmd_complete_arg stores client context */ |
186 | struct st95_digital_cmd_complete_arg { |
187 | struct sk_buff *skb_resp; |
188 | nfc_digital_cmd_complete_t complete_cb; |
189 | void *cb_usrarg; |
190 | bool rats; |
191 | }; |
192 | |
193 | /* |
194 | * structure containing ST95HF driver specific data. |
195 | * @spicontext: structure containing information required |
196 | * for spi communication between st95hf and host. |
197 | * @ddev: nfc digital device object. |
198 | * @nfcdev: nfc device object. |
199 | * @enable_gpio: gpio used to enable st95hf transceiver. |
200 | * @complete_cb_arg: structure to store various context information |
201 | * that is passed from nfc requesting thread to the threaded ISR. |
202 | * @st95hf_supply: regulator "consumer" for NFC device. |
203 | * @sendrcv_trflag: last byte of frame send by sendrecv command |
204 | * of st95hf. This byte contains transmission flag info. |
205 | * @exchange_lock: semaphore used for signaling the st95hf_remove |
206 | * function that the last outstanding async nfc request is finished. |
207 | * @rm_lock: mutex for ensuring safe access of nfc digital object |
208 | * from threaded ISR. Usage of this mutex avoids any race between |
209 | * deletion of the object from st95hf_remove() and its access from |
210 | * the threaded ISR. |
211 | * @nfcdev_free: flag to have the state of nfc device object. |
212 | * [alive | died] |
213 | * @current_protocol: current nfc protocol. |
214 | * @current_rf_tech: current rf technology. |
215 | * @fwi: frame waiting index, received in reply of RATS according to |
216 | * digital protocol. |
217 | */ |
218 | struct st95hf_context { |
219 | struct st95hf_spi_context spicontext; |
220 | struct nfc_digital_dev *ddev; |
221 | struct nfc_dev *nfcdev; |
222 | unsigned int enable_gpio; |
223 | struct st95_digital_cmd_complete_arg complete_cb_arg; |
224 | struct regulator *st95hf_supply; |
225 | unsigned char sendrcv_trflag; |
226 | struct semaphore exchange_lock; |
227 | struct mutex rm_lock; |
228 | bool nfcdev_free; |
229 | u8 current_protocol; |
230 | u8 current_rf_tech; |
231 | int fwi; |
232 | }; |
233 | |
234 | /* |
235 | * st95hf_send_recv_cmd() is for sending commands to ST95HF |
236 | * that are described in the cmd_array[]. It can optionally |
237 | * receive the response if the cmd request is of type |
238 | * SYNC. For that to happen caller must pass true to recv_res. |
239 | * For ASYNC request, recv_res is ignored and the |
240 | * function will never try to receive the response on behalf |
241 | * of the caller. |
242 | */ |
243 | static int st95hf_send_recv_cmd(struct st95hf_context *st95context, |
244 | enum st95hf_cmd_list cmd, |
245 | int no_modif, |
246 | struct param_list *list_array, |
247 | bool recv_res) |
248 | { |
249 | unsigned char spi_cmd_buffer[MAX_CMD_LEN]; |
250 | int i, ret; |
251 | struct device *dev = &st95context->spicontext.spidev->dev; |
252 | |
253 | if (cmd_array[cmd].cmd_len > MAX_CMD_LEN) |
254 | return -EINVAL; |
255 | if (cmd_array[cmd].no_cmd_params < no_modif) |
256 | return -EINVAL; |
257 | if (no_modif && !list_array) |
258 | return -EINVAL; |
259 | |
260 | spi_cmd_buffer[0] = ST95HF_COMMAND_SEND; |
261 | spi_cmd_buffer[1] = cmd_array[cmd].cmd_id; |
262 | spi_cmd_buffer[2] = cmd_array[cmd].no_cmd_params; |
263 | |
264 | memcpy(&spi_cmd_buffer[3], cmd_array[cmd].cmd_params, |
265 | spi_cmd_buffer[2]); |
266 | |
267 | for (i = 0; i < no_modif; i++) { |
268 | if (list_array[i].param_offset >= cmd_array[cmd].no_cmd_params) |
269 | return -EINVAL; |
270 | spi_cmd_buffer[3 + list_array[i].param_offset] = |
271 | list_array[i].new_param_val; |
272 | } |
273 | |
274 | ret = st95hf_spi_send(spicontext: &st95context->spicontext, |
275 | buffertx: spi_cmd_buffer, |
276 | datalen: cmd_array[cmd].cmd_len, |
277 | reqtype: cmd_array[cmd].req); |
278 | if (ret) { |
279 | dev_err(dev, "st95hf_spi_send failed with error %d\n" , ret); |
280 | return ret; |
281 | } |
282 | |
283 | if (cmd_array[cmd].req == SYNC && recv_res) { |
284 | unsigned char st95hf_response_arr[2]; |
285 | |
286 | ret = st95hf_spi_recv_response(spicontext: &st95context->spicontext, |
287 | receivebuff: st95hf_response_arr); |
288 | if (ret < 0) { |
289 | dev_err(dev, "spi error from st95hf_spi_recv_response(), err = 0x%x\n" , |
290 | ret); |
291 | return ret; |
292 | } |
293 | |
294 | if (st95hf_response_arr[0]) { |
295 | dev_err(dev, "st95hf error from st95hf_spi_recv_response(), err = 0x%x\n" , |
296 | st95hf_response_arr[0]); |
297 | return -EIO; |
298 | } |
299 | } |
300 | |
301 | return 0; |
302 | } |
303 | |
304 | static int st95hf_echo_command(struct st95hf_context *st95context) |
305 | { |
306 | int result = 0; |
307 | unsigned char echo_response; |
308 | |
309 | result = st95hf_send_recv_cmd(st95context, cmd: CMD_ECHO, no_modif: 0, NULL, recv_res: false); |
310 | if (result) |
311 | return result; |
312 | |
313 | /* If control reached here, response can be taken */ |
314 | result = st95hf_spi_recv_echo_res(spicontext: &st95context->spicontext, |
315 | receivebuff: &echo_response); |
316 | if (result) { |
317 | dev_err(&st95context->spicontext.spidev->dev, |
318 | "err: echo response receive error = 0x%x\n" , result); |
319 | return result; |
320 | } |
321 | |
322 | if (echo_response == ECHORESPONSE) |
323 | return 0; |
324 | |
325 | dev_err(&st95context->spicontext.spidev->dev, "err: echo res is 0x%x\n" , |
326 | echo_response); |
327 | |
328 | return -EIO; |
329 | } |
330 | |
331 | static int secondary_configuration_type4a(struct st95hf_context *stcontext) |
332 | { |
333 | int result = 0; |
334 | struct device *dev = &stcontext->nfcdev->dev; |
335 | |
336 | /* 14443A config setting after select protocol */ |
337 | result = st95hf_send_recv_cmd(st95context: stcontext, |
338 | cmd: CMD_ISO14443A_CONFIG, |
339 | no_modif: 0, |
340 | NULL, |
341 | recv_res: true); |
342 | if (result) { |
343 | dev_err(dev, "type a config cmd, err = 0x%x\n" , result); |
344 | return result; |
345 | } |
346 | |
347 | /* 14443A demo gain setting */ |
348 | result = st95hf_send_recv_cmd(st95context: stcontext, |
349 | cmd: CMD_ISO14443A_DEMOGAIN, |
350 | no_modif: 0, |
351 | NULL, |
352 | recv_res: true); |
353 | if (result) |
354 | dev_err(dev, "type a demogain cmd, err = 0x%x\n" , result); |
355 | |
356 | return result; |
357 | } |
358 | |
359 | static int secondary_configuration_type4b(struct st95hf_context *stcontext) |
360 | { |
361 | int result = 0; |
362 | struct device *dev = &stcontext->nfcdev->dev; |
363 | |
364 | result = st95hf_send_recv_cmd(st95context: stcontext, |
365 | cmd: CMD_ISO14443B_DEMOGAIN, |
366 | no_modif: 0, |
367 | NULL, |
368 | recv_res: true); |
369 | if (result) |
370 | dev_err(dev, "type b demogain cmd, err = 0x%x\n" , result); |
371 | |
372 | return result; |
373 | } |
374 | |
375 | static int st95hf_select_protocol(struct st95hf_context *stcontext, int type) |
376 | { |
377 | int result = 0; |
378 | struct device *dev; |
379 | |
380 | dev = &stcontext->nfcdev->dev; |
381 | |
382 | switch (type) { |
383 | case NFC_DIGITAL_RF_TECH_106A: |
384 | stcontext->current_rf_tech = NFC_DIGITAL_RF_TECH_106A; |
385 | result = st95hf_send_recv_cmd(st95context: stcontext, |
386 | cmd: CMD_ISO14443A_PROTOCOL_SELECT, |
387 | no_modif: 0, |
388 | NULL, |
389 | recv_res: true); |
390 | if (result) { |
391 | dev_err(dev, "protocol sel, err = 0x%x\n" , |
392 | result); |
393 | return result; |
394 | } |
395 | |
396 | /* secondary config. for 14443Type 4A after protocol select */ |
397 | result = secondary_configuration_type4a(stcontext); |
398 | if (result) { |
399 | dev_err(dev, "type a secondary config, err = 0x%x\n" , |
400 | result); |
401 | return result; |
402 | } |
403 | break; |
404 | case NFC_DIGITAL_RF_TECH_106B: |
405 | stcontext->current_rf_tech = NFC_DIGITAL_RF_TECH_106B; |
406 | result = st95hf_send_recv_cmd(st95context: stcontext, |
407 | cmd: CMD_ISO14443B_PROTOCOL_SELECT, |
408 | no_modif: 0, |
409 | NULL, |
410 | recv_res: true); |
411 | if (result) { |
412 | dev_err(dev, "protocol sel send, err = 0x%x\n" , |
413 | result); |
414 | return result; |
415 | } |
416 | |
417 | /* |
418 | * delay of 5-6 ms is required after select protocol |
419 | * command in case of ISO14443 Type B |
420 | */ |
421 | usleep_range(min: 50000, max: 60000); |
422 | |
423 | /* secondary config. for 14443Type 4B after protocol select */ |
424 | result = secondary_configuration_type4b(stcontext); |
425 | if (result) { |
426 | dev_err(dev, "type b secondary config, err = 0x%x\n" , |
427 | result); |
428 | return result; |
429 | } |
430 | break; |
431 | case NFC_DIGITAL_RF_TECH_ISO15693: |
432 | stcontext->current_rf_tech = NFC_DIGITAL_RF_TECH_ISO15693; |
433 | result = st95hf_send_recv_cmd(st95context: stcontext, |
434 | cmd: CMD_ISO15693_PROTOCOL_SELECT, |
435 | no_modif: 0, |
436 | NULL, |
437 | recv_res: true); |
438 | if (result) { |
439 | dev_err(dev, "protocol sel send, err = 0x%x\n" , |
440 | result); |
441 | return result; |
442 | } |
443 | break; |
444 | default: |
445 | return -EINVAL; |
446 | } |
447 | |
448 | return 0; |
449 | } |
450 | |
451 | static void st95hf_send_st95enable_negativepulse(struct st95hf_context *st95con) |
452 | { |
453 | /* First make irq_in pin high */ |
454 | gpio_set_value(gpio: st95con->enable_gpio, HIGH); |
455 | |
456 | /* wait for 1 milisecond */ |
457 | usleep_range(min: 1000, max: 2000); |
458 | |
459 | /* Make irq_in pin low */ |
460 | gpio_set_value(gpio: st95con->enable_gpio, LOW); |
461 | |
462 | /* wait for minimum interrupt pulse to make st95 active */ |
463 | usleep_range(min: 1000, max: 2000); |
464 | |
465 | /* At end make it high */ |
466 | gpio_set_value(gpio: st95con->enable_gpio, HIGH); |
467 | } |
468 | |
469 | /* |
470 | * Send a reset sequence over SPI bus (Reset command + wait 3ms + |
471 | * negative pulse on st95hf enable gpio |
472 | */ |
473 | static int st95hf_send_spi_reset_sequence(struct st95hf_context *st95context) |
474 | { |
475 | int result = 0; |
476 | unsigned char reset_cmd = ST95HF_COMMAND_RESET; |
477 | |
478 | result = st95hf_spi_send(spicontext: &st95context->spicontext, |
479 | buffertx: &reset_cmd, |
480 | ST95HF_RESET_CMD_LEN, |
481 | reqtype: ASYNC); |
482 | if (result) { |
483 | dev_err(&st95context->spicontext.spidev->dev, |
484 | "spi reset sequence cmd error = %d" , result); |
485 | return result; |
486 | } |
487 | |
488 | /* wait for 3 milisecond to complete the controller reset process */ |
489 | usleep_range(min: 3000, max: 4000); |
490 | |
491 | /* send negative pulse to make st95hf active */ |
492 | st95hf_send_st95enable_negativepulse(st95con: st95context); |
493 | |
494 | /* wait for 10 milisecond : HFO setup time */ |
495 | usleep_range(min: 10000, max: 20000); |
496 | |
497 | return result; |
498 | } |
499 | |
500 | static int st95hf_por_sequence(struct st95hf_context *st95context) |
501 | { |
502 | int nth_attempt = 1; |
503 | int result; |
504 | |
505 | st95hf_send_st95enable_negativepulse(st95con: st95context); |
506 | |
507 | usleep_range(min: 5000, max: 6000); |
508 | do { |
509 | /* send an ECHO command and checks ST95HF response */ |
510 | result = st95hf_echo_command(st95context); |
511 | |
512 | dev_dbg(&st95context->spicontext.spidev->dev, |
513 | "response from echo function = 0x%x, attempt = %d\n" , |
514 | result, nth_attempt); |
515 | |
516 | if (!result) |
517 | return 0; |
518 | |
519 | /* send an pulse on IRQ in case of the chip is on sleep state */ |
520 | if (nth_attempt == 2) |
521 | st95hf_send_st95enable_negativepulse(st95con: st95context); |
522 | else |
523 | st95hf_send_spi_reset_sequence(st95context); |
524 | |
525 | /* delay of 50 milisecond */ |
526 | usleep_range(min: 50000, max: 51000); |
527 | } while (nth_attempt++ < 3); |
528 | |
529 | return -ETIMEDOUT; |
530 | } |
531 | |
532 | static int iso14443_config_fdt(struct st95hf_context *st95context, int wtxm) |
533 | { |
534 | int result = 0; |
535 | struct device *dev = &st95context->spicontext.spidev->dev; |
536 | struct nfc_digital_dev *nfcddev = st95context->ddev; |
537 | unsigned char pp_typeb; |
538 | struct param_list new_params[2]; |
539 | |
540 | pp_typeb = cmd_array[CMD_ISO14443B_PROTOCOL_SELECT].cmd_params[2]; |
541 | |
542 | if (nfcddev->curr_protocol == NFC_PROTO_ISO14443 && |
543 | st95context->fwi < 4) |
544 | st95context->fwi = 4; |
545 | |
546 | new_params[0].param_offset = 2; |
547 | if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) |
548 | new_params[0].new_param_val = st95context->fwi; |
549 | else if (nfcddev->curr_protocol == NFC_PROTO_ISO14443_B) |
550 | new_params[0].new_param_val = pp_typeb; |
551 | |
552 | new_params[1].param_offset = 3; |
553 | new_params[1].new_param_val = wtxm; |
554 | |
555 | switch (nfcddev->curr_protocol) { |
556 | case NFC_PROTO_ISO14443: |
557 | result = st95hf_send_recv_cmd(st95context, |
558 | cmd: CMD_ISO14443A_PROTOCOL_SELECT, |
559 | no_modif: 2, |
560 | list_array: new_params, |
561 | recv_res: true); |
562 | if (result) { |
563 | dev_err(dev, "WTX type a sel proto, err = 0x%x\n" , |
564 | result); |
565 | return result; |
566 | } |
567 | |
568 | /* secondary config. for 14443Type 4A after protocol select */ |
569 | result = secondary_configuration_type4a(stcontext: st95context); |
570 | if (result) { |
571 | dev_err(dev, "WTX type a second. config, err = 0x%x\n" , |
572 | result); |
573 | return result; |
574 | } |
575 | break; |
576 | case NFC_PROTO_ISO14443_B: |
577 | result = st95hf_send_recv_cmd(st95context, |
578 | cmd: CMD_ISO14443B_PROTOCOL_SELECT, |
579 | no_modif: 2, |
580 | list_array: new_params, |
581 | recv_res: true); |
582 | if (result) { |
583 | dev_err(dev, "WTX type b sel proto, err = 0x%x\n" , |
584 | result); |
585 | return result; |
586 | } |
587 | |
588 | /* secondary config. for 14443Type 4B after protocol select */ |
589 | result = secondary_configuration_type4b(stcontext: st95context); |
590 | if (result) { |
591 | dev_err(dev, "WTX type b second. config, err = 0x%x\n" , |
592 | result); |
593 | return result; |
594 | } |
595 | break; |
596 | default: |
597 | return -EINVAL; |
598 | } |
599 | |
600 | return 0; |
601 | } |
602 | |
603 | static int st95hf_handle_wtx(struct st95hf_context *stcontext, |
604 | bool new_wtx, |
605 | int wtx_val) |
606 | { |
607 | int result = 0; |
608 | unsigned char val_mm = 0; |
609 | struct param_list new_params[1]; |
610 | struct nfc_digital_dev *nfcddev = stcontext->ddev; |
611 | struct device *dev = &stcontext->nfcdev->dev; |
612 | |
613 | if (new_wtx) { |
614 | result = iso14443_config_fdt(st95context: stcontext, wtxm: wtx_val & 0x3f); |
615 | if (result) { |
616 | dev_err(dev, "Config. setting error on WTX req, err = 0x%x\n" , |
617 | result); |
618 | return result; |
619 | } |
620 | |
621 | /* Send response of wtx with ASYNC as no response expected */ |
622 | new_params[0].param_offset = 1; |
623 | new_params[0].new_param_val = wtx_val; |
624 | |
625 | result = st95hf_send_recv_cmd(st95context: stcontext, |
626 | cmd: CMD_WTX_RESPONSE, |
627 | no_modif: 1, |
628 | list_array: new_params, |
629 | recv_res: false); |
630 | if (result) |
631 | dev_err(dev, "WTX response send, err = 0x%x\n" , result); |
632 | return result; |
633 | } |
634 | |
635 | /* if no new wtx, cofigure with default values */ |
636 | if (nfcddev->curr_protocol == NFC_PROTO_ISO14443) |
637 | val_mm = cmd_array[CMD_ISO14443A_PROTOCOL_SELECT].cmd_params[3]; |
638 | else if (nfcddev->curr_protocol == NFC_PROTO_ISO14443_B) |
639 | val_mm = cmd_array[CMD_ISO14443B_PROTOCOL_SELECT].cmd_params[3]; |
640 | |
641 | result = iso14443_config_fdt(st95context: stcontext, wtxm: val_mm); |
642 | if (result) |
643 | dev_err(dev, "Default config. setting error after WTX processing, err = 0x%x\n" , |
644 | result); |
645 | |
646 | return result; |
647 | } |
648 | |
649 | static int st95hf_error_handling(struct st95hf_context *stcontext, |
650 | struct sk_buff *skb_resp, |
651 | int res_len) |
652 | { |
653 | int result = 0; |
654 | unsigned char error_byte; |
655 | struct device *dev = &stcontext->nfcdev->dev; |
656 | |
657 | /* First check ST95HF specific error */ |
658 | if (skb_resp->data[0] & ST95HF_ERR_MASK) { |
659 | if (skb_resp->data[0] == ST95HF_TIMEOUT_ERROR) |
660 | result = -ETIMEDOUT; |
661 | else |
662 | result = -EIO; |
663 | return result; |
664 | } |
665 | |
666 | /* Check for CRC err only if CRC is present in the tag response */ |
667 | switch (stcontext->current_rf_tech) { |
668 | case NFC_DIGITAL_RF_TECH_106A: |
669 | if (stcontext->sendrcv_trflag == TRFLAG_NFCA_STD_FRAME_CRC) { |
670 | error_byte = skb_resp->data[res_len - 3]; |
671 | if (error_byte & ST95HF_NFCA_CRC_ERR_MASK) { |
672 | /* CRC error occurred */ |
673 | dev_err(dev, "CRC error, byte received = 0x%x\n" , |
674 | error_byte); |
675 | result = -EIO; |
676 | } |
677 | } |
678 | break; |
679 | case NFC_DIGITAL_RF_TECH_106B: |
680 | case NFC_DIGITAL_RF_TECH_ISO15693: |
681 | error_byte = skb_resp->data[res_len - 1]; |
682 | if (error_byte & ST95HF_NFCB_CRC_ERR_MASK) { |
683 | /* CRC error occurred */ |
684 | dev_err(dev, "CRC error, byte received = 0x%x\n" , |
685 | error_byte); |
686 | result = -EIO; |
687 | } |
688 | break; |
689 | } |
690 | |
691 | return result; |
692 | } |
693 | |
694 | static int st95hf_response_handler(struct st95hf_context *stcontext, |
695 | struct sk_buff *skb_resp, |
696 | int res_len) |
697 | { |
698 | int result = 0; |
699 | int skb_len; |
700 | unsigned char val_mm; |
701 | struct nfc_digital_dev *nfcddev = stcontext->ddev; |
702 | struct device *dev = &stcontext->nfcdev->dev; |
703 | struct st95_digital_cmd_complete_arg *cb_arg; |
704 | |
705 | cb_arg = &stcontext->complete_cb_arg; |
706 | |
707 | /* Process the response */ |
708 | skb_put(skb: skb_resp, len: res_len); |
709 | |
710 | /* Remove st95 header */ |
711 | skb_pull(skb: skb_resp, len: 2); |
712 | |
713 | skb_len = skb_resp->len; |
714 | |
715 | /* check if it is case of RATS request reply & FWI is present */ |
716 | if (nfcddev->curr_protocol == NFC_PROTO_ISO14443 && cb_arg->rats && |
717 | (skb_resp->data[1] & RATS_TB1_PRESENT_MASK)) { |
718 | if (skb_resp->data[1] & RATS_TA1_PRESENT_MASK) |
719 | stcontext->fwi = |
720 | (skb_resp->data[3] & TB1_FWI_MASK) >> 4; |
721 | else |
722 | stcontext->fwi = |
723 | (skb_resp->data[2] & TB1_FWI_MASK) >> 4; |
724 | |
725 | val_mm = cmd_array[CMD_ISO14443A_PROTOCOL_SELECT].cmd_params[3]; |
726 | |
727 | result = iso14443_config_fdt(st95context: stcontext, wtxm: val_mm); |
728 | if (result) { |
729 | dev_err(dev, "error in config_fdt to handle fwi of ATS, error=%d\n" , |
730 | result); |
731 | return result; |
732 | } |
733 | } |
734 | cb_arg->rats = false; |
735 | |
736 | /* Remove CRC bytes only if received frames data has an eod (CRC) */ |
737 | switch (stcontext->current_rf_tech) { |
738 | case NFC_DIGITAL_RF_TECH_106A: |
739 | if (stcontext->sendrcv_trflag == TRFLAG_NFCA_STD_FRAME_CRC) |
740 | skb_trim(skb: skb_resp, len: (skb_len - 5)); |
741 | else |
742 | skb_trim(skb: skb_resp, len: (skb_len - 3)); |
743 | break; |
744 | case NFC_DIGITAL_RF_TECH_106B: |
745 | case NFC_DIGITAL_RF_TECH_ISO15693: |
746 | skb_trim(skb: skb_resp, len: (skb_len - 3)); |
747 | break; |
748 | } |
749 | |
750 | return result; |
751 | } |
752 | |
753 | static irqreturn_t st95hf_irq_handler(int irq, void *st95hfcontext) |
754 | { |
755 | struct st95hf_context *stcontext = |
756 | (struct st95hf_context *)st95hfcontext; |
757 | |
758 | if (stcontext->spicontext.req_issync) { |
759 | complete(&stcontext->spicontext.done); |
760 | stcontext->spicontext.req_issync = false; |
761 | return IRQ_HANDLED; |
762 | } |
763 | |
764 | return IRQ_WAKE_THREAD; |
765 | } |
766 | |
767 | static irqreturn_t st95hf_irq_thread_handler(int irq, void *st95hfcontext) |
768 | { |
769 | int result = 0; |
770 | int res_len; |
771 | static bool wtx; |
772 | struct device *spidevice; |
773 | struct sk_buff *skb_resp; |
774 | struct st95hf_context *stcontext = |
775 | (struct st95hf_context *)st95hfcontext; |
776 | struct st95_digital_cmd_complete_arg *cb_arg; |
777 | |
778 | spidevice = &stcontext->spicontext.spidev->dev; |
779 | |
780 | /* |
781 | * check semaphore, if not down() already, then we don't |
782 | * know in which context the ISR is called and surely it |
783 | * will be a bug. Note that down() of the semaphore is done |
784 | * in the corresponding st95hf_in_send_cmd() and then |
785 | * only this ISR should be called. ISR will up() the |
786 | * semaphore before leaving. Hence when the ISR is called |
787 | * the correct behaviour is down_trylock() should always |
788 | * return 1 (indicating semaphore cant be taken and hence no |
789 | * change in semaphore count). |
790 | * If not, then we up() the semaphore and crash on |
791 | * a BUG() ! |
792 | */ |
793 | if (!down_trylock(sem: &stcontext->exchange_lock)) { |
794 | up(sem: &stcontext->exchange_lock); |
795 | WARN(1, "unknown context in ST95HF ISR" ); |
796 | return IRQ_NONE; |
797 | } |
798 | |
799 | cb_arg = &stcontext->complete_cb_arg; |
800 | skb_resp = cb_arg->skb_resp; |
801 | |
802 | mutex_lock(&stcontext->rm_lock); |
803 | res_len = st95hf_spi_recv_response(spicontext: &stcontext->spicontext, |
804 | receivebuff: skb_resp->data); |
805 | if (res_len < 0) { |
806 | dev_err(spidevice, "TISR spi response err = 0x%x\n" , res_len); |
807 | result = res_len; |
808 | goto end; |
809 | } |
810 | |
811 | /* if stcontext->nfcdev_free is true, it means remove already ran */ |
812 | if (stcontext->nfcdev_free) { |
813 | result = -ENODEV; |
814 | goto end; |
815 | } |
816 | |
817 | if (skb_resp->data[2] == WTX_REQ_FROM_TAG) { |
818 | /* Request for new FWT from tag */ |
819 | result = st95hf_handle_wtx(stcontext, new_wtx: true, wtx_val: skb_resp->data[3]); |
820 | if (result) |
821 | goto end; |
822 | |
823 | wtx = true; |
824 | mutex_unlock(lock: &stcontext->rm_lock); |
825 | return IRQ_HANDLED; |
826 | } |
827 | |
828 | result = st95hf_error_handling(stcontext, skb_resp, res_len); |
829 | if (result) |
830 | goto end; |
831 | |
832 | result = st95hf_response_handler(stcontext, skb_resp, res_len); |
833 | if (result) |
834 | goto end; |
835 | |
836 | /* |
837 | * If select protocol is done on wtx req. do select protocol |
838 | * again with default values |
839 | */ |
840 | if (wtx) { |
841 | wtx = false; |
842 | result = st95hf_handle_wtx(stcontext, new_wtx: false, wtx_val: 0); |
843 | if (result) |
844 | goto end; |
845 | } |
846 | |
847 | /* call digital layer callback */ |
848 | cb_arg->complete_cb(stcontext->ddev, cb_arg->cb_usrarg, skb_resp); |
849 | |
850 | /* up the semaphore before returning */ |
851 | up(sem: &stcontext->exchange_lock); |
852 | mutex_unlock(lock: &stcontext->rm_lock); |
853 | |
854 | return IRQ_HANDLED; |
855 | |
856 | end: |
857 | kfree_skb(skb: skb_resp); |
858 | wtx = false; |
859 | cb_arg->rats = false; |
860 | skb_resp = ERR_PTR(error: result); |
861 | /* call of callback with error */ |
862 | cb_arg->complete_cb(stcontext->ddev, cb_arg->cb_usrarg, skb_resp); |
863 | /* up the semaphore before returning */ |
864 | up(sem: &stcontext->exchange_lock); |
865 | mutex_unlock(lock: &stcontext->rm_lock); |
866 | return IRQ_HANDLED; |
867 | } |
868 | |
869 | /* NFC ops functions definition */ |
870 | static int st95hf_in_configure_hw(struct nfc_digital_dev *ddev, |
871 | int type, |
872 | int param) |
873 | { |
874 | struct st95hf_context *stcontext = nfc_digital_get_drvdata(dev: ddev); |
875 | |
876 | if (type == NFC_DIGITAL_CONFIG_RF_TECH) |
877 | return st95hf_select_protocol(stcontext, type: param); |
878 | |
879 | if (type == NFC_DIGITAL_CONFIG_FRAMING) { |
880 | switch (param) { |
881 | case NFC_DIGITAL_FRAMING_NFCA_SHORT: |
882 | stcontext->sendrcv_trflag = TRFLAG_NFCA_SHORT_FRAME; |
883 | break; |
884 | case NFC_DIGITAL_FRAMING_NFCA_STANDARD: |
885 | stcontext->sendrcv_trflag = TRFLAG_NFCA_STD_FRAME; |
886 | break; |
887 | case NFC_DIGITAL_FRAMING_NFCA_T4T: |
888 | case NFC_DIGITAL_FRAMING_NFCA_NFC_DEP: |
889 | case NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A: |
890 | stcontext->sendrcv_trflag = TRFLAG_NFCA_STD_FRAME_CRC; |
891 | break; |
892 | case NFC_DIGITAL_FRAMING_NFCB: |
893 | case NFC_DIGITAL_FRAMING_ISO15693_INVENTORY: |
894 | case NFC_DIGITAL_FRAMING_ISO15693_T5T: |
895 | break; |
896 | } |
897 | } |
898 | |
899 | return 0; |
900 | } |
901 | |
902 | static int rf_off(struct st95hf_context *stcontext) |
903 | { |
904 | int rc; |
905 | struct device *dev; |
906 | |
907 | dev = &stcontext->nfcdev->dev; |
908 | |
909 | rc = st95hf_send_recv_cmd(st95context: stcontext, cmd: CMD_FIELD_OFF, no_modif: 0, NULL, recv_res: true); |
910 | if (rc) |
911 | dev_err(dev, "protocol sel send field off, err = 0x%x\n" , rc); |
912 | |
913 | return rc; |
914 | } |
915 | |
916 | static int st95hf_in_send_cmd(struct nfc_digital_dev *ddev, |
917 | struct sk_buff *skb, |
918 | u16 timeout, |
919 | nfc_digital_cmd_complete_t cb, |
920 | void *arg) |
921 | { |
922 | struct st95hf_context *stcontext = nfc_digital_get_drvdata(dev: ddev); |
923 | int rc; |
924 | struct sk_buff *skb_resp; |
925 | int len_data_to_tag = 0; |
926 | |
927 | skb_resp = nfc_alloc_recv_skb(MAX_RESPONSE_BUFFER_SIZE, GFP_KERNEL); |
928 | if (!skb_resp) |
929 | return -ENOMEM; |
930 | |
931 | switch (stcontext->current_rf_tech) { |
932 | case NFC_DIGITAL_RF_TECH_106A: |
933 | len_data_to_tag = skb->len + 1; |
934 | skb_put_u8(skb, val: stcontext->sendrcv_trflag); |
935 | break; |
936 | case NFC_DIGITAL_RF_TECH_106B: |
937 | case NFC_DIGITAL_RF_TECH_ISO15693: |
938 | len_data_to_tag = skb->len; |
939 | break; |
940 | default: |
941 | rc = -EINVAL; |
942 | goto free_skb_resp; |
943 | } |
944 | |
945 | skb_push(skb, len: 3); |
946 | skb->data[0] = ST95HF_COMMAND_SEND; |
947 | skb->data[1] = SEND_RECEIVE_CMD; |
948 | skb->data[2] = len_data_to_tag; |
949 | |
950 | stcontext->complete_cb_arg.skb_resp = skb_resp; |
951 | stcontext->complete_cb_arg.cb_usrarg = arg; |
952 | stcontext->complete_cb_arg.complete_cb = cb; |
953 | |
954 | if ((skb->data[3] == ISO14443A_RATS_REQ) && |
955 | ddev->curr_protocol == NFC_PROTO_ISO14443) |
956 | stcontext->complete_cb_arg.rats = true; |
957 | |
958 | /* |
959 | * down the semaphore to indicate to remove func that an |
960 | * ISR is pending, note that it will not block here in any case. |
961 | * If found blocked, it is a BUG! |
962 | */ |
963 | rc = down_killable(sem: &stcontext->exchange_lock); |
964 | if (rc) { |
965 | WARN(1, "Semaphore is not found up in st95hf_in_send_cmd\n" ); |
966 | goto free_skb_resp; |
967 | } |
968 | |
969 | rc = st95hf_spi_send(spicontext: &stcontext->spicontext, buffertx: skb->data, |
970 | datalen: skb->len, |
971 | reqtype: ASYNC); |
972 | if (rc) { |
973 | dev_err(&stcontext->nfcdev->dev, |
974 | "Error %d trying to perform data_exchange" , rc); |
975 | /* up the semaphore since ISR will never come in this case */ |
976 | up(sem: &stcontext->exchange_lock); |
977 | goto free_skb_resp; |
978 | } |
979 | |
980 | kfree_skb(skb); |
981 | |
982 | return rc; |
983 | |
984 | free_skb_resp: |
985 | kfree_skb(skb: skb_resp); |
986 | return rc; |
987 | } |
988 | |
989 | /* p2p will be supported in a later release ! */ |
990 | static int st95hf_tg_configure_hw(struct nfc_digital_dev *ddev, |
991 | int type, |
992 | int param) |
993 | { |
994 | return 0; |
995 | } |
996 | |
997 | static int st95hf_tg_send_cmd(struct nfc_digital_dev *ddev, |
998 | struct sk_buff *skb, |
999 | u16 timeout, |
1000 | nfc_digital_cmd_complete_t cb, |
1001 | void *arg) |
1002 | { |
1003 | return 0; |
1004 | } |
1005 | |
1006 | static int st95hf_tg_listen(struct nfc_digital_dev *ddev, |
1007 | u16 timeout, |
1008 | nfc_digital_cmd_complete_t cb, |
1009 | void *arg) |
1010 | { |
1011 | return 0; |
1012 | } |
1013 | |
1014 | static int st95hf_tg_get_rf_tech(struct nfc_digital_dev *ddev, u8 *rf_tech) |
1015 | { |
1016 | return 0; |
1017 | } |
1018 | |
1019 | static int st95hf_switch_rf(struct nfc_digital_dev *ddev, bool on) |
1020 | { |
1021 | u8 rf_tech; |
1022 | struct st95hf_context *stcontext = nfc_digital_get_drvdata(dev: ddev); |
1023 | |
1024 | rf_tech = ddev->curr_rf_tech; |
1025 | |
1026 | if (on) |
1027 | /* switch on RF field */ |
1028 | return st95hf_select_protocol(stcontext, type: rf_tech); |
1029 | |
1030 | /* switch OFF RF field */ |
1031 | return rf_off(stcontext); |
1032 | } |
1033 | |
1034 | /* TODO st95hf_abort_cmd */ |
1035 | static void st95hf_abort_cmd(struct nfc_digital_dev *ddev) |
1036 | { |
1037 | } |
1038 | |
1039 | static const struct nfc_digital_ops st95hf_nfc_digital_ops = { |
1040 | .in_configure_hw = st95hf_in_configure_hw, |
1041 | .in_send_cmd = st95hf_in_send_cmd, |
1042 | |
1043 | .tg_listen = st95hf_tg_listen, |
1044 | .tg_configure_hw = st95hf_tg_configure_hw, |
1045 | .tg_send_cmd = st95hf_tg_send_cmd, |
1046 | .tg_get_rf_tech = st95hf_tg_get_rf_tech, |
1047 | |
1048 | .switch_rf = st95hf_switch_rf, |
1049 | .abort_cmd = st95hf_abort_cmd, |
1050 | }; |
1051 | |
1052 | static const struct spi_device_id st95hf_id[] = { |
1053 | { "st95hf" , 0 }, |
1054 | {} |
1055 | }; |
1056 | MODULE_DEVICE_TABLE(spi, st95hf_id); |
1057 | |
1058 | static const struct of_device_id st95hf_spi_of_match[] __maybe_unused = { |
1059 | { .compatible = "st,st95hf" }, |
1060 | {}, |
1061 | }; |
1062 | MODULE_DEVICE_TABLE(of, st95hf_spi_of_match); |
1063 | |
1064 | static int st95hf_probe(struct spi_device *nfc_spi_dev) |
1065 | { |
1066 | int ret; |
1067 | |
1068 | struct st95hf_context *st95context; |
1069 | struct st95hf_spi_context *spicontext; |
1070 | |
1071 | nfc_info(&nfc_spi_dev->dev, "ST95HF driver probe called.\n" ); |
1072 | |
1073 | st95context = devm_kzalloc(dev: &nfc_spi_dev->dev, |
1074 | size: sizeof(struct st95hf_context), |
1075 | GFP_KERNEL); |
1076 | if (!st95context) |
1077 | return -ENOMEM; |
1078 | |
1079 | spicontext = &st95context->spicontext; |
1080 | |
1081 | spicontext->spidev = nfc_spi_dev; |
1082 | |
1083 | st95context->fwi = |
1084 | cmd_array[CMD_ISO14443A_PROTOCOL_SELECT].cmd_params[2]; |
1085 | |
1086 | if (device_property_present(dev: &nfc_spi_dev->dev, propname: "st95hfvin" )) { |
1087 | st95context->st95hf_supply = |
1088 | devm_regulator_get(dev: &nfc_spi_dev->dev, |
1089 | id: "st95hfvin" ); |
1090 | if (IS_ERR(ptr: st95context->st95hf_supply)) { |
1091 | dev_err(&nfc_spi_dev->dev, "failed to acquire regulator\n" ); |
1092 | return PTR_ERR(ptr: st95context->st95hf_supply); |
1093 | } |
1094 | |
1095 | ret = regulator_enable(regulator: st95context->st95hf_supply); |
1096 | if (ret) { |
1097 | dev_err(&nfc_spi_dev->dev, "failed to enable regulator\n" ); |
1098 | return ret; |
1099 | } |
1100 | } |
1101 | |
1102 | init_completion(x: &spicontext->done); |
1103 | mutex_init(&spicontext->spi_lock); |
1104 | |
1105 | /* |
1106 | * Store spicontext in spi device object for using it in |
1107 | * remove function |
1108 | */ |
1109 | dev_set_drvdata(dev: &nfc_spi_dev->dev, data: spicontext); |
1110 | |
1111 | st95context->enable_gpio = |
1112 | of_get_named_gpio(np: nfc_spi_dev->dev.of_node, |
1113 | list_name: "enable-gpio" , |
1114 | index: 0); |
1115 | if (!gpio_is_valid(number: st95context->enable_gpio)) { |
1116 | dev_err(&nfc_spi_dev->dev, "No valid enable gpio\n" ); |
1117 | ret = st95context->enable_gpio; |
1118 | goto err_disable_regulator; |
1119 | } |
1120 | |
1121 | ret = devm_gpio_request_one(dev: &nfc_spi_dev->dev, gpio: st95context->enable_gpio, |
1122 | GPIOF_DIR_OUT | GPIOF_INIT_HIGH, |
1123 | label: "enable_gpio" ); |
1124 | if (ret) |
1125 | goto err_disable_regulator; |
1126 | |
1127 | if (nfc_spi_dev->irq > 0) { |
1128 | if (devm_request_threaded_irq(dev: &nfc_spi_dev->dev, |
1129 | irq: nfc_spi_dev->irq, |
1130 | handler: st95hf_irq_handler, |
1131 | thread_fn: st95hf_irq_thread_handler, |
1132 | IRQF_TRIGGER_FALLING, |
1133 | devname: "st95hf" , |
1134 | dev_id: (void *)st95context) < 0) { |
1135 | dev_err(&nfc_spi_dev->dev, "err: irq request for st95hf is failed\n" ); |
1136 | ret = -EINVAL; |
1137 | goto err_disable_regulator; |
1138 | } |
1139 | } else { |
1140 | dev_err(&nfc_spi_dev->dev, "not a valid IRQ associated with ST95HF\n" ); |
1141 | ret = -EINVAL; |
1142 | goto err_disable_regulator; |
1143 | } |
1144 | |
1145 | /* |
1146 | * First reset SPI to handle warm reset of the system. |
1147 | * It will put the ST95HF device in Power ON state |
1148 | * which make the state of device identical to state |
1149 | * at the time of cold reset of the system. |
1150 | */ |
1151 | ret = st95hf_send_spi_reset_sequence(st95context); |
1152 | if (ret) { |
1153 | dev_err(&nfc_spi_dev->dev, "err: spi_reset_sequence failed\n" ); |
1154 | goto err_disable_regulator; |
1155 | } |
1156 | |
1157 | /* call PowerOnReset sequence of ST95hf to activate it */ |
1158 | ret = st95hf_por_sequence(st95context); |
1159 | if (ret) { |
1160 | dev_err(&nfc_spi_dev->dev, "err: por seq failed for st95hf\n" ); |
1161 | goto err_disable_regulator; |
1162 | } |
1163 | |
1164 | /* create NFC dev object and register with NFC Subsystem */ |
1165 | st95context->ddev = nfc_digital_allocate_device(ops: &st95hf_nfc_digital_ops, |
1166 | ST95HF_SUPPORTED_PROT, |
1167 | ST95HF_CAPABILITIES, |
1168 | ST95HF_HEADROOM_LEN, |
1169 | ST95HF_TAILROOM_LEN); |
1170 | if (!st95context->ddev) { |
1171 | ret = -ENOMEM; |
1172 | goto err_disable_regulator; |
1173 | } |
1174 | |
1175 | st95context->nfcdev = st95context->ddev->nfc_dev; |
1176 | nfc_digital_set_parent_dev(ndev: st95context->ddev, dev: &nfc_spi_dev->dev); |
1177 | |
1178 | ret = nfc_digital_register_device(ndev: st95context->ddev); |
1179 | if (ret) { |
1180 | dev_err(&st95context->nfcdev->dev, "st95hf registration failed\n" ); |
1181 | goto err_free_digital_device; |
1182 | } |
1183 | |
1184 | /* store st95context in nfc device object */ |
1185 | nfc_digital_set_drvdata(dev: st95context->ddev, data: st95context); |
1186 | |
1187 | sema_init(sem: &st95context->exchange_lock, val: 1); |
1188 | mutex_init(&st95context->rm_lock); |
1189 | |
1190 | return ret; |
1191 | |
1192 | err_free_digital_device: |
1193 | nfc_digital_free_device(ndev: st95context->ddev); |
1194 | err_disable_regulator: |
1195 | if (st95context->st95hf_supply) |
1196 | regulator_disable(regulator: st95context->st95hf_supply); |
1197 | |
1198 | return ret; |
1199 | } |
1200 | |
1201 | static void st95hf_remove(struct spi_device *nfc_spi_dev) |
1202 | { |
1203 | int result = 0; |
1204 | unsigned char reset_cmd = ST95HF_COMMAND_RESET; |
1205 | struct st95hf_spi_context *spictx = dev_get_drvdata(dev: &nfc_spi_dev->dev); |
1206 | |
1207 | struct st95hf_context *stcontext = container_of(spictx, |
1208 | struct st95hf_context, |
1209 | spicontext); |
1210 | |
1211 | mutex_lock(&stcontext->rm_lock); |
1212 | |
1213 | nfc_digital_unregister_device(ndev: stcontext->ddev); |
1214 | nfc_digital_free_device(ndev: stcontext->ddev); |
1215 | stcontext->nfcdev_free = true; |
1216 | |
1217 | mutex_unlock(lock: &stcontext->rm_lock); |
1218 | |
1219 | /* if last in_send_cmd's ISR is pending, wait for it to finish */ |
1220 | result = down_killable(sem: &stcontext->exchange_lock); |
1221 | if (result == -EINTR) |
1222 | dev_err(&spictx->spidev->dev, "sleep for semaphore interrupted by signal\n" ); |
1223 | |
1224 | /* next reset the ST95HF controller */ |
1225 | result = st95hf_spi_send(spicontext: &stcontext->spicontext, |
1226 | buffertx: &reset_cmd, |
1227 | ST95HF_RESET_CMD_LEN, |
1228 | reqtype: ASYNC); |
1229 | if (result) |
1230 | dev_err(&spictx->spidev->dev, |
1231 | "ST95HF reset failed in remove() err = %d\n" , result); |
1232 | |
1233 | /* wait for 3 ms to complete the controller reset process */ |
1234 | usleep_range(min: 3000, max: 4000); |
1235 | |
1236 | /* disable regulator */ |
1237 | if (stcontext->st95hf_supply) |
1238 | regulator_disable(regulator: stcontext->st95hf_supply); |
1239 | } |
1240 | |
1241 | /* Register as SPI protocol driver */ |
1242 | static struct spi_driver st95hf_driver = { |
1243 | .driver = { |
1244 | .name = "st95hf" , |
1245 | .owner = THIS_MODULE, |
1246 | .of_match_table = of_match_ptr(st95hf_spi_of_match), |
1247 | }, |
1248 | .id_table = st95hf_id, |
1249 | .probe = st95hf_probe, |
1250 | .remove = st95hf_remove, |
1251 | }; |
1252 | |
1253 | module_spi_driver(st95hf_driver); |
1254 | |
1255 | MODULE_AUTHOR("Shikha Singh <shikha.singh@st.com>" ); |
1256 | MODULE_DESCRIPTION("ST NFC Transceiver ST95HF driver" ); |
1257 | MODULE_LICENSE("GPL v2" ); |
1258 | |