• Home
  • Raw
  • Download

Lines Matching +full:fw +full:- +full:gpios

21 #include <linux/crc-ccitt.h>
145 #define PN544_FW_I2C_WRITE_DATA_MAX_LEN MIN((PN544_FW_I2C_MAX_PAYLOAD -\
149 #define PN544_FW_SECURE_CHUNK_WRITE_DATA_MAX_LEN (PN544_FW_I2C_MAX_PAYLOAD -\
174 const struct firmware *fw; member
196 16, 1, (skb)->data, (skb)->len, 0); \
205 nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n"); in pn544_hci_i2c_platform_init()
207 /* Disable fw download */ in pn544_hci_i2c_platform_init()
208 gpiod_set_value_cansleep(phy->gpiod_fw, 0); in pn544_hci_i2c_platform_init()
211 phy->en_polarity = polarity; in pn544_hci_i2c_platform_init()
213 while (retry--) { in pn544_hci_i2c_platform_init()
215 gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); in pn544_hci_i2c_platform_init()
219 gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity); in pn544_hci_i2c_platform_init()
223 dev_dbg(&phy->i2c_dev->dev, "Sending reset cmd\n"); in pn544_hci_i2c_platform_init()
224 ret = i2c_master_send(phy->i2c_dev, rset_cmd, count); in pn544_hci_i2c_platform_init()
226 nfc_info(&phy->i2c_dev->dev, in pn544_hci_i2c_platform_init()
234 nfc_err(&phy->i2c_dev->dev, in pn544_hci_i2c_platform_init()
238 gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); in pn544_hci_i2c_platform_init()
244 gpiod_set_value_cansleep(phy->gpiod_fw, run_mode == PN544_FW_MODE ? 1 : 0); in pn544_hci_i2c_enable_mode()
245 gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity); in pn544_hci_i2c_enable_mode()
248 phy->run_mode = run_mode; in pn544_hci_i2c_enable_mode()
259 phy->powered = 1; in pn544_hci_i2c_enable()
268 gpiod_set_value_cansleep(phy->gpiod_fw, 0); in pn544_hci_i2c_disable()
269 gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); in pn544_hci_i2c_disable()
272 gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity); in pn544_hci_i2c_disable()
275 gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); in pn544_hci_i2c_disable()
278 phy->powered = 0; in pn544_hci_i2c_disable()
286 len = skb->len + 2; in pn544_hci_i2c_add_len_crc()
289 crc = crc_ccitt(0xffff, skb->data, skb->len); in pn544_hci_i2c_add_len_crc()
310 struct i2c_client *client = phy->i2c_dev; in pn544_hci_i2c_write()
312 if (phy->hard_fault != 0) in pn544_hci_i2c_write()
313 return phy->hard_fault; in pn544_hci_i2c_write()
321 r = i2c_master_send(client, skb->data, skb->len); in pn544_hci_i2c_write()
323 if (r == -EREMOTEIO) { /* Retry, chip was in standby */ in pn544_hci_i2c_write()
325 r = i2c_master_send(client, skb->data, skb->len); in pn544_hci_i2c_write()
329 if (r != skb->len) in pn544_hci_i2c_write()
330 r = -EREMOTEIO; in pn544_hci_i2c_write()
346 crc = crc_ccitt(0xffff, buf, len - 2); in check_crc()
349 if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { in check_crc()
351 crc, buf[len - 1], buf[len - 2]); in check_crc()
355 return -EPERM; in check_crc()
365 * -EREMOTEIO : i2c read error (fatal)
366 * -EBADMSG : frame was incorrect and discarded
367 * -ENOMEM : cannot allocate skb, frame dropped
373 u8 tmp[PN544_HCI_I2C_LLC_MAX_SIZE - 1]; in pn544_hci_i2c_read()
374 struct i2c_client *client = phy->i2c_dev; in pn544_hci_i2c_read()
378 nfc_err(&client->dev, "cannot read len byte\n"); in pn544_hci_i2c_read()
379 return -EREMOTEIO; in pn544_hci_i2c_read()
382 if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) || in pn544_hci_i2c_read()
383 (len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) { in pn544_hci_i2c_read()
384 nfc_err(&client->dev, "invalid len byte\n"); in pn544_hci_i2c_read()
385 r = -EBADMSG; in pn544_hci_i2c_read()
391 r = -ENOMEM; in pn544_hci_i2c_read()
400 return -EREMOTEIO; in pn544_hci_i2c_read()
405 r = check_crc((*skb)->data, (*skb)->len); in pn544_hci_i2c_read()
408 r = -EBADMSG; in pn544_hci_i2c_read()
413 skb_trim(*skb, (*skb)->len - 2); in pn544_hci_i2c_read()
421 r = -EREMOTEIO; in pn544_hci_i2c_read()
432 struct i2c_client *client = phy->i2c_dev; in pn544_hci_i2c_fw_read_status()
436 nfc_err(&client->dev, "cannot read fw status\n"); in pn544_hci_i2c_fw_read_status()
437 return -EIO; in pn544_hci_i2c_fw_read_status()
448 return -ETIMEDOUT; in pn544_hci_i2c_fw_read_status()
450 return -ENODATA; in pn544_hci_i2c_fw_read_status()
452 return -EACCES; in pn544_hci_i2c_fw_read_status()
454 return -EPROTO; in pn544_hci_i2c_fw_read_status()
456 return -EINVAL; in pn544_hci_i2c_fw_read_status()
458 return -ENOTSUPP; in pn544_hci_i2c_fw_read_status()
460 return -EBADMSG; in pn544_hci_i2c_fw_read_status()
462 return -ENOKEY; in pn544_hci_i2c_fw_read_status()
464 return -EINVAL; in pn544_hci_i2c_fw_read_status()
466 return -ENOMEM; in pn544_hci_i2c_fw_read_status()
468 return -EACCES; in pn544_hci_i2c_fw_read_status()
471 return -EIO; in pn544_hci_i2c_fw_read_status()
473 return -EIO; in pn544_hci_i2c_fw_read_status()
480 * The frame format is len-data-crc, and corruption can occur anywhere while
485 * - the chip will always present only one single complete frame on the bus
487 * - the chip will not present a new frame until we have completely read
500 if (!phy || irq != phy->i2c_dev->irq) { in pn544_hci_i2c_irq_thread_fn()
505 client = phy->i2c_dev; in pn544_hci_i2c_irq_thread_fn()
506 dev_dbg(&client->dev, "IRQ\n"); in pn544_hci_i2c_irq_thread_fn()
508 if (phy->hard_fault != 0) in pn544_hci_i2c_irq_thread_fn()
511 if (phy->run_mode == PN544_FW_MODE) { in pn544_hci_i2c_irq_thread_fn()
512 phy->fw_cmd_result = pn544_hci_i2c_fw_read_status(phy); in pn544_hci_i2c_irq_thread_fn()
513 schedule_work(&phy->fw_work); in pn544_hci_i2c_irq_thread_fn()
516 if (r == -EREMOTEIO) { in pn544_hci_i2c_irq_thread_fn()
517 phy->hard_fault = r; in pn544_hci_i2c_irq_thread_fn()
519 nfc_hci_recv_frame(phy->hdev, NULL); in pn544_hci_i2c_irq_thread_fn()
522 } else if ((r == -ENOMEM) || (r == -EBADMSG)) { in pn544_hci_i2c_irq_thread_fn()
526 nfc_hci_recv_frame(phy->hdev, skb); in pn544_hci_i2c_irq_thread_fn()
544 strcpy(phy->firmware_name, firmware_name); in pn544_hci_i2c_fw_download()
546 phy->hw_variant = hw_variant; in pn544_hci_i2c_fw_download()
547 phy->fw_work_state = FW_WORK_STATE_START; in pn544_hci_i2c_fw_download()
549 schedule_work(&phy->fw_work); in pn544_hci_i2c_fw_download()
561 phy->fw_work_state = FW_WORK_STATE_IDLE; in pn544_hci_i2c_fw_work_complete()
563 if (phy->fw) { in pn544_hci_i2c_fw_work_complete()
564 release_firmware(phy->fw); in pn544_hci_i2c_fw_work_complete()
565 phy->fw = NULL; in pn544_hci_i2c_fw_work_complete()
568 nfc_fw_download_done(phy->hdev->ndev, phy->firmware_name, (u32) -result); in pn544_hci_i2c_fw_work_complete()
585 params_len = sizeof(framep->be_dest_addr) + in pn544_hci_i2c_fw_write_cmd()
586 sizeof(framep->be_datalen) + datalen; in pn544_hci_i2c_fw_write_cmd()
587 framelen = params_len + sizeof(framep->cmd) + in pn544_hci_i2c_fw_write_cmd()
588 sizeof(framep->be_length); in pn544_hci_i2c_fw_write_cmd()
590 framep->cmd = PN544_FW_CMD_WRITE; in pn544_hci_i2c_fw_write_cmd()
592 put_unaligned_be16(params_len, &framep->be_length); in pn544_hci_i2c_fw_write_cmd()
594 framep->be_dest_addr[0] = (dest_addr & 0xff0000) >> 16; in pn544_hci_i2c_fw_write_cmd()
595 framep->be_dest_addr[1] = (dest_addr & 0xff00) >> 8; in pn544_hci_i2c_fw_write_cmd()
596 framep->be_dest_addr[2] = dest_addr & 0xff; in pn544_hci_i2c_fw_write_cmd()
598 put_unaligned_be16(datalen, &framep->be_datalen); in pn544_hci_i2c_fw_write_cmd()
600 memcpy(framep->data, data, datalen); in pn544_hci_i2c_fw_write_cmd()
609 return -EIO; in pn544_hci_i2c_fw_write_cmd()
648 return -EIO; in pn544_hci_i2c_fw_check_cmd()
655 r = pn544_hci_i2c_fw_write_cmd(phy->i2c_dev, in pn544_hci_i2c_fw_write_chunk()
656 phy->fw_blob_dest_addr + phy->fw_written, in pn544_hci_i2c_fw_write_chunk()
657 phy->fw_blob_data + phy->fw_written, in pn544_hci_i2c_fw_write_chunk()
658 phy->fw_blob_size - phy->fw_written); in pn544_hci_i2c_fw_write_chunk()
662 phy->fw_written += r; in pn544_hci_i2c_fw_write_chunk()
663 phy->fw_work_state = FW_WORK_STATE_WAIT_WRITE_ANSWER; in pn544_hci_i2c_fw_write_chunk()
681 chunk->cmd = PN544_FW_CMD_SECURE_CHUNK_WRITE; in pn544_hci_i2c_fw_secure_write_frame_cmd()
683 put_unaligned_be16(datalen, &chunk->be_datalen); in pn544_hci_i2c_fw_secure_write_frame_cmd()
685 memcpy(chunk->data, data, datalen); in pn544_hci_i2c_fw_secure_write_frame_cmd()
687 chunklen = sizeof(chunk->cmd) + sizeof(chunk->be_datalen) + datalen; in pn544_hci_i2c_fw_secure_write_frame_cmd()
689 r = i2c_master_send(phy->i2c_dev, buf, chunklen); in pn544_hci_i2c_fw_secure_write_frame_cmd()
696 return -EIO; in pn544_hci_i2c_fw_secure_write_frame_cmd()
705 framep = (struct pn544_i2c_fw_secure_frame *) phy->fw_blob_data; in pn544_hci_i2c_fw_secure_write_frame()
706 if (phy->fw_written == 0) in pn544_hci_i2c_fw_secure_write_frame()
707 phy->fw_blob_size = get_unaligned_be16(&framep->be_datalen) in pn544_hci_i2c_fw_secure_write_frame()
711 if (phy->fw_blob_size > PN544_FW_I2C_MAX_PAYLOAD && in pn544_hci_i2c_fw_secure_write_frame()
712 framep->cmd != PN544_FW_CMD_SECURE_WRITE) in pn544_hci_i2c_fw_secure_write_frame()
713 return -EINVAL; in pn544_hci_i2c_fw_secure_write_frame()
716 if (phy->fw_blob_size < PN544_FW_I2C_MAX_PAYLOAD) { in pn544_hci_i2c_fw_secure_write_frame()
717 r = i2c_master_send(phy->i2c_dev, in pn544_hci_i2c_fw_secure_write_frame()
718 (const char *) phy->fw_blob_data, phy->fw_blob_size); in pn544_hci_i2c_fw_secure_write_frame()
720 if (r == phy->fw_blob_size) in pn544_hci_i2c_fw_secure_write_frame()
725 return -EIO; in pn544_hci_i2c_fw_secure_write_frame()
729 phy->fw_blob_data + phy->fw_written, in pn544_hci_i2c_fw_secure_write_frame()
730 phy->fw_blob_size - phy->fw_written); in pn544_hci_i2c_fw_secure_write_frame()
735 phy->fw_written += r; in pn544_hci_i2c_fw_secure_write_frame()
736 phy->fw_work_state = FW_WORK_STATE_WAIT_SECURE_WRITE_ANSWER; in pn544_hci_i2c_fw_secure_write_frame()
739 if (framep->cmd == PN544_FW_CMD_RESET) { in pn544_hci_i2c_fw_secure_write_frame()
741 phy->fw_cmd_result = 0; in pn544_hci_i2c_fw_secure_write_frame()
742 schedule_work(&phy->fw_work); in pn544_hci_i2c_fw_secure_write_frame()
756 switch (phy->fw_work_state) { in pn544_hci_i2c_fw_work()
760 r = request_firmware(&phy->fw, phy->firmware_name, in pn544_hci_i2c_fw_work()
761 &phy->i2c_dev->dev); in pn544_hci_i2c_fw_work()
765 phy->fw_written = 0; in pn544_hci_i2c_fw_work()
767 switch (phy->hw_variant) { in pn544_hci_i2c_fw_work()
769 blob = (struct pn544_i2c_fw_blob *) phy->fw->data; in pn544_hci_i2c_fw_work()
770 phy->fw_blob_size = get_unaligned_be32(&blob->be_size); in pn544_hci_i2c_fw_work()
771 phy->fw_blob_dest_addr = get_unaligned_be32( in pn544_hci_i2c_fw_work()
772 &blob->be_destaddr); in pn544_hci_i2c_fw_work()
773 phy->fw_blob_data = blob->data; in pn544_hci_i2c_fw_work()
779 phy->fw->data; in pn544_hci_i2c_fw_work()
780 phy->fw_blob_data = secure_blob->data; in pn544_hci_i2c_fw_work()
781 phy->fw_size = phy->fw->size; in pn544_hci_i2c_fw_work()
785 r = -ENOTSUPP; in pn544_hci_i2c_fw_work()
795 r = phy->fw_cmd_result; in pn544_hci_i2c_fw_work()
799 if (phy->fw_written == phy->fw_blob_size) { in pn544_hci_i2c_fw_work()
800 r = pn544_hci_i2c_fw_check_cmd(phy->i2c_dev, in pn544_hci_i2c_fw_work()
801 phy->fw_blob_dest_addr, in pn544_hci_i2c_fw_work()
802 phy->fw_blob_data, in pn544_hci_i2c_fw_work()
803 phy->fw_blob_size); in pn544_hci_i2c_fw_work()
806 phy->fw_work_state = FW_WORK_STATE_WAIT_CHECK_ANSWER; in pn544_hci_i2c_fw_work()
818 r = phy->fw_cmd_result; in pn544_hci_i2c_fw_work()
822 blob = (struct pn544_i2c_fw_blob *) (phy->fw_blob_data + in pn544_hci_i2c_fw_work()
823 phy->fw_blob_size); in pn544_hci_i2c_fw_work()
824 phy->fw_blob_size = get_unaligned_be32(&blob->be_size); in pn544_hci_i2c_fw_work()
825 if (phy->fw_blob_size != 0) { in pn544_hci_i2c_fw_work()
826 phy->fw_blob_dest_addr = in pn544_hci_i2c_fw_work()
827 get_unaligned_be32(&blob->be_destaddr); in pn544_hci_i2c_fw_work()
828 phy->fw_blob_data = blob->data; in pn544_hci_i2c_fw_work()
830 phy->fw_written = 0; in pn544_hci_i2c_fw_work()
835 if (r < 0 || phy->fw_blob_size == 0) in pn544_hci_i2c_fw_work()
840 r = phy->fw_cmd_result; in pn544_hci_i2c_fw_work()
849 if (phy->fw_written == phy->fw_blob_size) { in pn544_hci_i2c_fw_work()
851 (phy->fw_blob_data + phy->fw_blob_size); in pn544_hci_i2c_fw_work()
852 phy->fw_size -= phy->fw_blob_size + in pn544_hci_i2c_fw_work()
854 if (phy->fw_size >= PN544_FW_SECURE_BLOB_HEADER_LEN in pn544_hci_i2c_fw_work()
856 phy->fw_blob_data = secure_blob->data; in pn544_hci_i2c_fw_work()
858 phy->fw_written = 0; in pn544_hci_i2c_fw_work()
864 if (r < 0 || phy->fw_size == 0) in pn544_hci_i2c_fw_work()
877 { "enable-gpios", &enable_gpios, 1 },
878 { "firmware-gpios", &firmware_gpios, 1 },
885 struct device *dev = &client->dev; in pn544_hci_i2c_probe()
889 dev_dbg(&client->dev, "%s\n", __func__); in pn544_hci_i2c_probe()
890 dev_dbg(&client->dev, "IRQ: %d\n", client->irq); in pn544_hci_i2c_probe()
892 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { in pn544_hci_i2c_probe()
893 nfc_err(&client->dev, "Need I2C_FUNC_I2C\n"); in pn544_hci_i2c_probe()
894 return -ENODEV; in pn544_hci_i2c_probe()
897 phy = devm_kzalloc(&client->dev, sizeof(struct pn544_i2c_phy), in pn544_hci_i2c_probe()
900 return -ENOMEM; in pn544_hci_i2c_probe()
902 INIT_WORK(&phy->fw_work, pn544_hci_i2c_fw_work); in pn544_hci_i2c_probe()
903 phy->fw_work_state = FW_WORK_STATE_IDLE; in pn544_hci_i2c_probe()
905 phy->i2c_dev = client; in pn544_hci_i2c_probe()
913 phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); in pn544_hci_i2c_probe()
914 if (IS_ERR(phy->gpiod_en)) { in pn544_hci_i2c_probe()
916 return PTR_ERR(phy->gpiod_en); in pn544_hci_i2c_probe()
919 /* Get FW GPIO */ in pn544_hci_i2c_probe()
920 phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW); in pn544_hci_i2c_probe()
921 if (IS_ERR(phy->gpiod_fw)) { in pn544_hci_i2c_probe()
922 nfc_err(dev, "Unable to get FW GPIO\n"); in pn544_hci_i2c_probe()
923 return PTR_ERR(phy->gpiod_fw); in pn544_hci_i2c_probe()
928 r = devm_request_threaded_irq(&client->dev, client->irq, NULL, in pn544_hci_i2c_probe()
933 nfc_err(&client->dev, "Unable to register IRQ handler\n"); in pn544_hci_i2c_probe()
940 pn544_hci_i2c_fw_download, &phy->hdev); in pn544_hci_i2c_probe()
951 dev_dbg(&client->dev, "%s\n", __func__); in pn544_hci_i2c_remove()
953 cancel_work_sync(&phy->fw_work); in pn544_hci_i2c_remove()
954 if (phy->fw_work_state != FW_WORK_STATE_IDLE) in pn544_hci_i2c_remove()
955 pn544_hci_i2c_fw_work_complete(phy, -ENODEV); in pn544_hci_i2c_remove()
957 pn544_hci_remove(phy->hdev); in pn544_hci_i2c_remove()
959 if (phy->powered) in pn544_hci_i2c_remove()
966 { .compatible = "nxp,pn544-i2c", },