^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * NCI based driver for Samsung S3FWRN5 NFC chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 Samsung Electrnoics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Robert Baldyga <r.baldyga@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #ifndef __LOCAL_S3FWRN5_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define __LOCAL_S3FWRN5_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/nfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <net/nfc/nci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "firmware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) enum s3fwrn5_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) S3FWRN5_MODE_COLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) S3FWRN5_MODE_NCI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) S3FWRN5_MODE_FW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct s3fwrn5_phy_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void (*set_wake)(void *id, bool sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void (*set_mode)(void *id, enum s3fwrn5_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) enum s3fwrn5_mode (*get_mode)(void *id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int (*write)(void *id, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct s3fwrn5_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct nci_dev *ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) void *phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const struct s3fwrn5_phy_ops *phy_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned int max_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct s3fwrn5_fw_info fw_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static inline int s3fwrn5_set_mode(struct s3fwrn5_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) enum s3fwrn5_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (!info->phy_ops->set_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) info->phy_ops->set_mode(info->phy_id, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static inline enum s3fwrn5_mode s3fwrn5_get_mode(struct s3fwrn5_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!info->phy_ops->get_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return info->phy_ops->get_mode(info->phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static inline int s3fwrn5_set_wake(struct s3fwrn5_info *info, bool wake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (!info->phy_ops->set_wake)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) info->phy_ops->set_wake(info->phy_id, wake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline int s3fwrn5_write(struct s3fwrn5_info *info, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!info->phy_ops->write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return info->phy_ops->write(info->phy_id, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int s3fwrn5_probe(struct nci_dev **ndev, void *phy_id, struct device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const struct s3fwrn5_phy_ops *phy_ops, unsigned int max_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void s3fwrn5_remove(struct nci_dev *ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int s3fwrn5_recv_frame(struct nci_dev *ndev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) enum s3fwrn5_mode mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #endif /* __LOCAL_S3FWRN5_H_ */