aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nfc/microread
diff options
context:
space:
mode:
authorEric Lapuyade <eric.lapuyade@linux.intel.com>2013-04-15 05:19:20 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-04-15 18:39:31 -0400
commit4912e2fe74811693703e9b4e21bf36c067643a03 (patch)
tree827f23daf7a94f55366357f6ad98bdc86f17a8e1 /drivers/nfc/microread
parentbe055b2f89b5842f41363b5655a33dffb51a8294 (diff)
NFC: mei: Add a common mei bus API for NFC drivers
This isolates the common code that is required to use an mei bus nfc device from an NFC HCI drivers. This prepares for future drivers for NFC chips connected behind an Intel Management Engine controller. The microread_mei HCI driver is also modified to use that common code. Signed-off-by: Eric Lapuyade <eric.lapuyade@intel.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc/microread')
-rw-r--r--drivers/nfc/microread/Kconfig2
-rw-r--r--drivers/nfc/microread/mei.c139
2 files changed, 10 insertions, 131 deletions
diff --git a/drivers/nfc/microread/Kconfig b/drivers/nfc/microread/Kconfig
index 572305be6e37..951d5542f6bc 100644
--- a/drivers/nfc/microread/Kconfig
+++ b/drivers/nfc/microread/Kconfig
@@ -25,7 +25,7 @@ config NFC_MICROREAD_I2C
25 25
26config NFC_MICROREAD_MEI 26config NFC_MICROREAD_MEI
27 tristate "NFC Microread MEI support" 27 tristate "NFC Microread MEI support"
28 depends on NFC_MICROREAD && INTEL_MEI_BUS_NFC 28 depends on NFC_MICROREAD && NFC_MEI_PHY
29 ---help--- 29 ---help---
30 This module adds support for the mei interface of adapters using 30 This module adds support for the mei interface of adapters using
31 Inside microread chipsets. Select this if your microread chipset 31 Inside microread chipsets. Select this if your microread chipset
diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c
index ca33ae193935..1ad044dce7b6 100644
--- a/drivers/nfc/microread/mei.c
+++ b/drivers/nfc/microread/mei.c
@@ -19,151 +19,31 @@
19 */ 19 */
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h> 22#include <linux/mod_devicetable.h>
23#include <linux/interrupt.h>
24#include <linux/gpio.h>
25#include <linux/mei_cl_bus.h>
26
27#include <linux/nfc.h> 23#include <linux/nfc.h>
28#include <net/nfc/hci.h> 24#include <net/nfc/hci.h>
29#include <net/nfc/llc.h> 25#include <net/nfc/llc.h>
30 26
27#include "../mei_phy.h"
31#include "microread.h" 28#include "microread.h"
32 29
33#define MICROREAD_DRIVER_NAME "microread" 30#define MICROREAD_DRIVER_NAME "microread"
34 31
35struct mei_nfc_hdr {
36 u8 cmd;
37 u8 status;
38 u16 req_id;
39 u32 reserved;
40 u16 data_size;
41} __attribute__((packed));
42
43#define MEI_NFC_HEADER_SIZE 10
44#define MEI_NFC_MAX_HCI_PAYLOAD 300
45#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)
46
47struct microread_mei_phy {
48 struct mei_cl_device *device;
49 struct nfc_hci_dev *hdev;
50
51 int powered;
52
53 int hard_fault; /*
54 * < 0 if hardware error occured (e.g. i2c err)
55 * and prevents normal operation.
56 */
57};
58
59#define MEI_DUMP_SKB_IN(info, skb) \
60do { \
61 pr_debug("%s:\n", info); \
62 print_hex_dump(KERN_DEBUG, "mei in : ", DUMP_PREFIX_OFFSET, \
63 16, 1, (skb)->data, (skb)->len, 0); \
64} while (0)
65
66#define MEI_DUMP_SKB_OUT(info, skb) \
67do { \
68 pr_debug("%s:\n", info); \
69 print_hex_dump(KERN_DEBUG, "mei out: ", DUMP_PREFIX_OFFSET, \
70 16, 1, (skb)->data, (skb)->len, 0); \
71} while (0)
72
73static int microread_mei_enable(void *phy_id)
74{
75 struct microread_mei_phy *phy = phy_id;
76
77 pr_info(DRIVER_DESC ": %s\n", __func__);
78
79 phy->powered = 1;
80
81 return 0;
82}
83
84static void microread_mei_disable(void *phy_id)
85{
86 struct microread_mei_phy *phy = phy_id;
87
88 pr_info(DRIVER_DESC ": %s\n", __func__);
89
90 phy->powered = 0;
91}
92
93/*
94 * Writing a frame must not return the number of written bytes.
95 * It must return either zero for success, or <0 for error.
96 * In addition, it must not alter the skb
97 */
98static int microread_mei_write(void *phy_id, struct sk_buff *skb)
99{
100 struct microread_mei_phy *phy = phy_id;
101 int r;
102
103 MEI_DUMP_SKB_OUT("mei frame sent", skb);
104
105 r = mei_cl_send(phy->device, skb->data, skb->len);
106 if (r > 0)
107 r = 0;
108
109 return r;
110}
111
112static void microread_event_cb(struct mei_cl_device *device, u32 events,
113 void *context)
114{
115 struct microread_mei_phy *phy = context;
116
117 if (phy->hard_fault != 0)
118 return;
119
120 if (events & BIT(MEI_CL_EVENT_RX)) {
121 struct sk_buff *skb;
122 int reply_size;
123
124 skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL);
125 if (!skb)
126 return;
127
128 reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ);
129 if (reply_size < MEI_NFC_HEADER_SIZE) {
130 kfree(skb);
131 return;
132 }
133
134 skb_put(skb, reply_size);
135 skb_pull(skb, MEI_NFC_HEADER_SIZE);
136
137 MEI_DUMP_SKB_IN("mei frame read", skb);
138
139 nfc_hci_recv_frame(phy->hdev, skb);
140 }
141}
142
143static struct nfc_phy_ops mei_phy_ops = {
144 .write = microread_mei_write,
145 .enable = microread_mei_enable,
146 .disable = microread_mei_disable,
147};
148
149static int microread_mei_probe(struct mei_cl_device *device, 32static int microread_mei_probe(struct mei_cl_device *device,
150 const struct mei_cl_device_id *id) 33 const struct mei_cl_device_id *id)
151{ 34{
152 struct microread_mei_phy *phy; 35 struct nfc_mei_phy *phy;
153 int r; 36 int r;
154 37
155 pr_info("Probing NFC microread\n"); 38 pr_info("Probing NFC microread\n");
156 39
157 phy = kzalloc(sizeof(struct microread_mei_phy), GFP_KERNEL); 40 phy = nfc_mei_phy_alloc(device);
158 if (!phy) { 41 if (!phy) {
159 pr_err("Cannot allocate memory for microread mei phy.\n"); 42 pr_err("Cannot allocate memory for microread mei phy.\n");
160 return -ENOMEM; 43 return -ENOMEM;
161 } 44 }
162 45
163 phy->device = device; 46 r = mei_cl_register_event_cb(device, nfc_mei_event_cb, phy);
164 mei_cl_set_drvdata(device, phy);
165
166 r = mei_cl_register_event_cb(device, microread_event_cb, phy);
167 if (r) { 47 if (r) {
168 pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); 48 pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n");
169 goto err_out; 49 goto err_out;
@@ -178,23 +58,22 @@ static int microread_mei_probe(struct mei_cl_device *device,
178 return 0; 58 return 0;
179 59
180err_out: 60err_out:
181 kfree(phy); 61 nfc_mei_phy_free(phy);
182 62
183 return r; 63 return r;
184} 64}
185 65
186static int microread_mei_remove(struct mei_cl_device *device) 66static int microread_mei_remove(struct mei_cl_device *device)
187{ 67{
188 struct microread_mei_phy *phy = mei_cl_get_drvdata(device); 68 struct nfc_mei_phy *phy = mei_cl_get_drvdata(device);
189 69
190 pr_info("Removing microread\n"); 70 pr_info("Removing microread\n");
191 71
192 microread_remove(phy->hdev); 72 microread_remove(phy->hdev);
193 73
194 if (phy->powered) 74 nfc_mei_phy_disable(phy);
195 microread_mei_disable(phy);
196 75
197 kfree(phy); 76 nfc_mei_phy_free(phy);
198 77
199 return 0; 78 return 0;
200} 79}