Commit | Line | Data |
---|---|---|
35630df6 | 1 | /* |
ed06aeef CR |
2 | * I2C Link Layer for ST NCI NFC controller familly based Driver |
3 | * Copyright (C) 2014-2015 STMicroelectronics SAS. All rights reserved. | |
35630df6 CR |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
19 | ||
35630df6 CR |
20 | #include <linux/module.h> |
21 | #include <linux/i2c.h> | |
22 | #include <linux/gpio.h> | |
ed6a2f3f | 23 | #include <linux/gpio/consumer.h> |
35630df6 CR |
24 | #include <linux/of_irq.h> |
25 | #include <linux/of_gpio.h> | |
ed6a2f3f | 26 | #include <linux/acpi.h> |
35630df6 CR |
27 | #include <linux/interrupt.h> |
28 | #include <linux/delay.h> | |
29 | #include <linux/nfc.h> | |
76b733d1 | 30 | #include <linux/platform_data/st-nci.h> |
35630df6 | 31 | |
e67e7e59 | 32 | #include "st-nci.h" |
35630df6 | 33 | |
30458aac | 34 | #define DRIVER_DESC "NCI NFC driver for ST_NCI" |
35630df6 CR |
35 | |
36 | /* ndlc header */ | |
064d0047 | 37 | #define ST_NCI_FRAME_HEADROOM 1 |
30458aac | 38 | #define ST_NCI_FRAME_TAILROOM 0 |
35630df6 | 39 | |
ed06aeef CR |
40 | #define ST_NCI_I2C_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */ |
41 | #define ST_NCI_I2C_MAX_SIZE 250 /* req 4.2.1 */ | |
35630df6 | 42 | |
ed06aeef | 43 | #define ST_NCI_I2C_DRIVER_NAME "st_nci_i2c" |
35630df6 | 44 | |
c1fc9136 | 45 | #define ST_NCI_GPIO_NAME_RESET "reset" |
35630df6 | 46 | |
ed06aeef | 47 | struct st_nci_i2c_phy { |
35630df6 CR |
48 | struct i2c_client *i2c_dev; |
49 | struct llt_ndlc *ndlc; | |
50 | ||
bb2496c3 CR |
51 | bool irq_active; |
52 | ||
35630df6 CR |
53 | unsigned int gpio_reset; |
54 | unsigned int irq_polarity; | |
3648dc6d CR |
55 | |
56 | struct st_nci_se_status se_status; | |
35630df6 CR |
57 | }; |
58 | ||
ed06aeef | 59 | static int st_nci_i2c_enable(void *phy_id) |
35630df6 | 60 | { |
ed06aeef | 61 | struct st_nci_i2c_phy *phy = phy_id; |
35630df6 CR |
62 | |
63 | gpio_set_value(phy->gpio_reset, 0); | |
64 | usleep_range(10000, 15000); | |
65 | gpio_set_value(phy->gpio_reset, 1); | |
35630df6 CR |
66 | usleep_range(80000, 85000); |
67 | ||
bb2496c3 | 68 | if (phy->ndlc->powered == 0 && phy->irq_active == 0) { |
05f0939f | 69 | enable_irq(phy->i2c_dev->irq); |
bb2496c3 CR |
70 | phy->irq_active = true; |
71 | } | |
05f0939f | 72 | |
35630df6 CR |
73 | return 0; |
74 | } | |
75 | ||
ed06aeef | 76 | static void st_nci_i2c_disable(void *phy_id) |
35630df6 | 77 | { |
ed06aeef | 78 | struct st_nci_i2c_phy *phy = phy_id; |
35630df6 | 79 | |
05f0939f | 80 | disable_irq_nosync(phy->i2c_dev->irq); |
bb2496c3 | 81 | phy->irq_active = false; |
35630df6 CR |
82 | } |
83 | ||
35630df6 CR |
84 | /* |
85 | * Writing a frame must not return the number of written bytes. | |
86 | * It must return either zero for success, or <0 for error. | |
87 | * In addition, it must not alter the skb | |
88 | */ | |
ed06aeef | 89 | static int st_nci_i2c_write(void *phy_id, struct sk_buff *skb) |
35630df6 CR |
90 | { |
91 | int r = -1; | |
ed06aeef | 92 | struct st_nci_i2c_phy *phy = phy_id; |
35630df6 CR |
93 | struct i2c_client *client = phy->i2c_dev; |
94 | ||
4294e320 CR |
95 | if (phy->ndlc->hard_fault != 0) |
96 | return phy->ndlc->hard_fault; | |
35630df6 CR |
97 | |
98 | r = i2c_master_send(client, skb->data, skb->len); | |
d4a41d10 | 99 | if (r < 0) { /* Retry, chip was in standby */ |
35630df6 CR |
100 | usleep_range(1000, 4000); |
101 | r = i2c_master_send(client, skb->data, skb->len); | |
102 | } | |
103 | ||
104 | if (r >= 0) { | |
105 | if (r != skb->len) | |
106 | r = -EREMOTEIO; | |
107 | else | |
108 | r = 0; | |
109 | } | |
110 | ||
35630df6 CR |
111 | return r; |
112 | } | |
113 | ||
114 | /* | |
115 | * Reads an ndlc frame and returns it in a newly allocated sk_buff. | |
116 | * returns: | |
e7723b33 | 117 | * 0 : if received frame is complete |
35630df6 CR |
118 | * -EREMOTEIO : i2c read error (fatal) |
119 | * -EBADMSG : frame was incorrect and discarded | |
e7723b33 | 120 | * -ENOMEM : cannot allocate skb, frame dropped |
35630df6 | 121 | */ |
ed06aeef | 122 | static int st_nci_i2c_read(struct st_nci_i2c_phy *phy, |
35630df6 CR |
123 | struct sk_buff **skb) |
124 | { | |
125 | int r; | |
126 | u8 len; | |
ed06aeef | 127 | u8 buf[ST_NCI_I2C_MAX_SIZE]; |
35630df6 CR |
128 | struct i2c_client *client = phy->i2c_dev; |
129 | ||
ed06aeef | 130 | r = i2c_master_recv(client, buf, ST_NCI_I2C_MIN_SIZE); |
d4a41d10 | 131 | if (r < 0) { /* Retry, chip was in standby */ |
35630df6 | 132 | usleep_range(1000, 4000); |
ed06aeef | 133 | r = i2c_master_recv(client, buf, ST_NCI_I2C_MIN_SIZE); |
ac633ba6 CR |
134 | } |
135 | ||
ed06aeef | 136 | if (r != ST_NCI_I2C_MIN_SIZE) |
35630df6 | 137 | return -EREMOTEIO; |
35630df6 CR |
138 | |
139 | len = be16_to_cpu(*(__be16 *) (buf + 2)); | |
ed06aeef | 140 | if (len > ST_NCI_I2C_MAX_SIZE) { |
35630df6 CR |
141 | nfc_err(&client->dev, "invalid frame len\n"); |
142 | return -EBADMSG; | |
143 | } | |
144 | ||
ed06aeef | 145 | *skb = alloc_skb(ST_NCI_I2C_MIN_SIZE + len, GFP_KERNEL); |
35630df6 CR |
146 | if (*skb == NULL) |
147 | return -ENOMEM; | |
148 | ||
ed06aeef CR |
149 | skb_reserve(*skb, ST_NCI_I2C_MIN_SIZE); |
150 | skb_put(*skb, ST_NCI_I2C_MIN_SIZE); | |
151 | memcpy((*skb)->data, buf, ST_NCI_I2C_MIN_SIZE); | |
35630df6 CR |
152 | |
153 | if (!len) | |
154 | return 0; | |
155 | ||
156 | r = i2c_master_recv(client, buf, len); | |
157 | if (r != len) { | |
158 | kfree_skb(*skb); | |
159 | return -EREMOTEIO; | |
160 | } | |
161 | ||
162 | skb_put(*skb, len); | |
ed06aeef | 163 | memcpy((*skb)->data + ST_NCI_I2C_MIN_SIZE, buf, len); |
35630df6 | 164 | |
35630df6 CR |
165 | return 0; |
166 | } | |
167 | ||
168 | /* | |
169 | * Reads an ndlc frame from the chip. | |
170 | * | |
30458aac | 171 | * On ST_NCI, IRQ goes in idle state when read starts. |
35630df6 | 172 | */ |
ed06aeef | 173 | static irqreturn_t st_nci_irq_thread_fn(int irq, void *phy_id) |
35630df6 | 174 | { |
ed06aeef | 175 | struct st_nci_i2c_phy *phy = phy_id; |
35630df6 CR |
176 | struct i2c_client *client; |
177 | struct sk_buff *skb = NULL; | |
178 | int r; | |
179 | ||
7274496f | 180 | if (!phy || !phy->ndlc || irq != phy->i2c_dev->irq) { |
35630df6 CR |
181 | WARN_ON_ONCE(1); |
182 | return IRQ_NONE; | |
183 | } | |
184 | ||
185 | client = phy->i2c_dev; | |
186 | dev_dbg(&client->dev, "IRQ\n"); | |
187 | ||
4294e320 | 188 | if (phy->ndlc->hard_fault) |
35630df6 CR |
189 | return IRQ_HANDLED; |
190 | ||
183fe2d0 | 191 | if (!phy->ndlc->powered) { |
ed06aeef | 192 | st_nci_i2c_disable(phy); |
35630df6 CR |
193 | return IRQ_HANDLED; |
194 | } | |
195 | ||
ed06aeef | 196 | r = st_nci_i2c_read(phy, &skb); |
4294e320 | 197 | if (r == -EREMOTEIO || r == -ENOMEM || r == -EBADMSG) |
35630df6 | 198 | return IRQ_HANDLED; |
35630df6 CR |
199 | |
200 | ndlc_recv(phy->ndlc, skb); | |
201 | ||
202 | return IRQ_HANDLED; | |
203 | } | |
204 | ||
205 | static struct nfc_phy_ops i2c_phy_ops = { | |
ed06aeef CR |
206 | .write = st_nci_i2c_write, |
207 | .enable = st_nci_i2c_enable, | |
208 | .disable = st_nci_i2c_disable, | |
35630df6 CR |
209 | }; |
210 | ||
ed6a2f3f CR |
211 | static int st_nci_i2c_acpi_request_resources(struct i2c_client *client) |
212 | { | |
213 | struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); | |
ed6a2f3f | 214 | struct gpio_desc *gpiod_reset; |
4ac52a0f | 215 | struct device *dev = &client->dev; |
27420fec | 216 | u8 tmp; |
ed6a2f3f | 217 | |
ed6a2f3f CR |
218 | /* Get RESET GPIO from ACPI */ |
219 | gpiod_reset = devm_gpiod_get_index(dev, ST_NCI_GPIO_NAME_RESET, 1, | |
220 | GPIOD_OUT_HIGH); | |
221 | if (IS_ERR(gpiod_reset)) { | |
222 | nfc_err(dev, "Unable to get RESET GPIO\n"); | |
223 | return -ENODEV; | |
224 | } | |
225 | ||
226 | phy->gpio_reset = desc_to_gpio(gpiod_reset); | |
227 | ||
228 | phy->irq_polarity = irq_get_trigger_type(client->irq); | |
229 | ||
27420fec CR |
230 | phy->se_status.is_ese_present = false; |
231 | phy->se_status.is_uicc_present = false; | |
232 | ||
233 | if (device_property_present(dev, "ese-present")) { | |
234 | device_property_read_u8(dev, "ese-present", &tmp); | |
235 | phy->se_status.is_ese_present = tmp; | |
236 | } | |
237 | ||
238 | if (device_property_present(dev, "uicc-present")) { | |
239 | device_property_read_u8(dev, "uicc-present", &tmp); | |
240 | phy->se_status.is_uicc_present = tmp; | |
241 | } | |
ed6a2f3f CR |
242 | |
243 | return 0; | |
244 | } | |
245 | ||
ed06aeef | 246 | static int st_nci_i2c_of_request_resources(struct i2c_client *client) |
35630df6 | 247 | { |
ed06aeef | 248 | struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); |
35630df6 CR |
249 | struct device_node *pp; |
250 | int gpio; | |
251 | int r; | |
252 | ||
253 | pp = client->dev.of_node; | |
254 | if (!pp) | |
255 | return -ENODEV; | |
256 | ||
257 | /* Get GPIO from device tree */ | |
258 | gpio = of_get_named_gpio(pp, "reset-gpios", 0); | |
259 | if (gpio < 0) { | |
260 | nfc_err(&client->dev, | |
261 | "Failed to retrieve reset-gpios from device tree\n"); | |
262 | return gpio; | |
263 | } | |
264 | ||
265 | /* GPIO request and configuration */ | |
56ee645e | 266 | r = devm_gpio_request_one(&client->dev, gpio, |
4c62c208 | 267 | GPIOF_OUT_INIT_HIGH, ST_NCI_GPIO_NAME_RESET); |
35630df6 CR |
268 | if (r) { |
269 | nfc_err(&client->dev, "Failed to request reset pin\n"); | |
18159624 | 270 | return r; |
35630df6 | 271 | } |
35630df6 CR |
272 | phy->gpio_reset = gpio; |
273 | ||
a80d0cb6 | 274 | phy->irq_polarity = irq_get_trigger_type(client->irq); |
35630df6 | 275 | |
3648dc6d CR |
276 | phy->se_status.is_ese_present = |
277 | of_property_read_bool(pp, "ese-present"); | |
278 | phy->se_status.is_uicc_present = | |
279 | of_property_read_bool(pp, "uicc-present"); | |
280 | ||
35630df6 CR |
281 | return 0; |
282 | } | |
35630df6 | 283 | |
ed06aeef | 284 | static int st_nci_i2c_request_resources(struct i2c_client *client) |
35630df6 | 285 | { |
ed06aeef CR |
286 | struct st_nci_nfc_platform_data *pdata; |
287 | struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); | |
35630df6 | 288 | int r; |
35630df6 CR |
289 | |
290 | pdata = client->dev.platform_data; | |
291 | if (pdata == NULL) { | |
292 | nfc_err(&client->dev, "No platform data\n"); | |
293 | return -EINVAL; | |
294 | } | |
295 | ||
296 | /* store for later use */ | |
35630df6 CR |
297 | phy->gpio_reset = pdata->gpio_reset; |
298 | phy->irq_polarity = pdata->irq_polarity; | |
299 | ||
56ee645e | 300 | r = devm_gpio_request_one(&client->dev, |
4c62c208 CR |
301 | phy->gpio_reset, GPIOF_OUT_INIT_HIGH, |
302 | ST_NCI_GPIO_NAME_RESET); | |
35630df6 CR |
303 | if (r) { |
304 | pr_err("%s : reset gpio_request failed\n", __FILE__); | |
18159624 | 305 | return r; |
35630df6 CR |
306 | } |
307 | ||
3648dc6d CR |
308 | phy->se_status.is_ese_present = pdata->is_ese_present; |
309 | phy->se_status.is_uicc_present = pdata->is_uicc_present; | |
310 | ||
35630df6 CR |
311 | return 0; |
312 | } | |
313 | ||
ed06aeef | 314 | static int st_nci_i2c_probe(struct i2c_client *client, |
35630df6 CR |
315 | const struct i2c_device_id *id) |
316 | { | |
ed06aeef CR |
317 | struct st_nci_i2c_phy *phy; |
318 | struct st_nci_nfc_platform_data *pdata; | |
35630df6 CR |
319 | int r; |
320 | ||
321 | dev_dbg(&client->dev, "%s\n", __func__); | |
322 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | |
323 | ||
324 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | |
325 | nfc_err(&client->dev, "Need I2C_FUNC_I2C\n"); | |
326 | return -ENODEV; | |
327 | } | |
328 | ||
ed06aeef | 329 | phy = devm_kzalloc(&client->dev, sizeof(struct st_nci_i2c_phy), |
35630df6 | 330 | GFP_KERNEL); |
3590ebc0 | 331 | if (!phy) |
35630df6 | 332 | return -ENOMEM; |
35630df6 CR |
333 | |
334 | phy->i2c_dev = client; | |
335 | ||
336 | i2c_set_clientdata(client, phy); | |
337 | ||
338 | pdata = client->dev.platform_data; | |
339 | if (!pdata && client->dev.of_node) { | |
ed06aeef | 340 | r = st_nci_i2c_of_request_resources(client); |
35630df6 CR |
341 | if (r) { |
342 | nfc_err(&client->dev, "No platform data\n"); | |
343 | return r; | |
344 | } | |
345 | } else if (pdata) { | |
ed06aeef | 346 | r = st_nci_i2c_request_resources(client); |
35630df6 CR |
347 | if (r) { |
348 | nfc_err(&client->dev, | |
349 | "Cannot get platform resources\n"); | |
350 | return r; | |
351 | } | |
ed6a2f3f CR |
352 | } else if (ACPI_HANDLE(&client->dev)) { |
353 | r = st_nci_i2c_acpi_request_resources(client); | |
354 | if (r) { | |
355 | nfc_err(&client->dev, "Cannot get ACPI data\n"); | |
356 | return r; | |
357 | } | |
35630df6 CR |
358 | } else { |
359 | nfc_err(&client->dev, | |
30458aac | 360 | "st_nci platform resources not available\n"); |
35630df6 CR |
361 | return -ENODEV; |
362 | } | |
363 | ||
7274496f | 364 | r = ndlc_probe(phy, &i2c_phy_ops, &client->dev, |
30458aac | 365 | ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, |
3648dc6d | 366 | &phy->ndlc, &phy->se_status); |
7274496f CR |
367 | if (r < 0) { |
368 | nfc_err(&client->dev, "Unable to register ndlc layer\n"); | |
369 | return r; | |
370 | } | |
371 | ||
bb2496c3 | 372 | phy->irq_active = true; |
35630df6 | 373 | r = devm_request_threaded_irq(&client->dev, client->irq, NULL, |
ed06aeef | 374 | st_nci_irq_thread_fn, |
35630df6 | 375 | phy->irq_polarity | IRQF_ONESHOT, |
ed06aeef | 376 | ST_NCI_DRIVER_NAME, phy); |
7274496f | 377 | if (r < 0) |
35630df6 | 378 | nfc_err(&client->dev, "Unable to register IRQ handler\n"); |
35630df6 | 379 | |
7274496f | 380 | return r; |
35630df6 CR |
381 | } |
382 | ||
ed06aeef | 383 | static int st_nci_i2c_remove(struct i2c_client *client) |
35630df6 | 384 | { |
ed06aeef | 385 | struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); |
35630df6 CR |
386 | |
387 | dev_dbg(&client->dev, "%s\n", __func__); | |
388 | ||
389 | ndlc_remove(phy->ndlc); | |
390 | ||
35630df6 CR |
391 | return 0; |
392 | } | |
393 | ||
3252897f CR |
394 | static struct i2c_device_id st_nci_i2c_id_table[] = { |
395 | {ST_NCI_DRIVER_NAME, 0}, | |
396 | {} | |
397 | }; | |
398 | MODULE_DEVICE_TABLE(i2c, st_nci_i2c_id_table); | |
399 | ||
ed6a2f3f CR |
400 | static const struct acpi_device_id st_nci_i2c_acpi_match[] = { |
401 | {"SMO2101"}, | |
402 | {"SMO2102"}, | |
403 | {} | |
404 | }; | |
405 | MODULE_DEVICE_TABLE(acpi, st_nci_i2c_acpi_match); | |
406 | ||
ed06aeef | 407 | static const struct of_device_id of_st_nci_i2c_match[] = { |
1a94cb60 | 408 | { .compatible = "st,st21nfcb-i2c", }, |
35630df6 | 409 | { .compatible = "st,st21nfcb_i2c", }, |
ed06aeef | 410 | { .compatible = "st,st21nfcc-i2c", }, |
35630df6 CR |
411 | {} |
412 | }; | |
ed06aeef | 413 | MODULE_DEVICE_TABLE(of, of_st_nci_i2c_match); |
35630df6 | 414 | |
ed06aeef | 415 | static struct i2c_driver st_nci_i2c_driver = { |
35630df6 | 416 | .driver = { |
ed06aeef CR |
417 | .name = ST_NCI_I2C_DRIVER_NAME, |
418 | .of_match_table = of_match_ptr(of_st_nci_i2c_match), | |
ed6a2f3f | 419 | .acpi_match_table = ACPI_PTR(st_nci_i2c_acpi_match), |
35630df6 | 420 | }, |
ed06aeef CR |
421 | .probe = st_nci_i2c_probe, |
422 | .id_table = st_nci_i2c_id_table, | |
423 | .remove = st_nci_i2c_remove, | |
35630df6 | 424 | }; |
ed06aeef | 425 | module_i2c_driver(st_nci_i2c_driver); |
35630df6 CR |
426 | |
427 | MODULE_LICENSE("GPL"); | |
428 | MODULE_DESCRIPTION(DRIVER_DESC); |