diff options
Diffstat (limited to 'drivers/nfc/st21nfca/i2c.c')
-rw-r--r-- | drivers/nfc/st21nfca/i2c.c | 106 |
1 files changed, 87 insertions, 19 deletions
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c index 2337737c6cd4..3f954ed86d98 100644 --- a/drivers/nfc/st21nfca/i2c.c +++ b/drivers/nfc/st21nfca/i2c.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/of_irq.h> | ||
25 | #include <linux/of_gpio.h> | ||
24 | #include <linux/miscdevice.h> | 26 | #include <linux/miscdevice.h> |
25 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
26 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
@@ -502,11 +504,65 @@ static struct nfc_phy_ops i2c_phy_ops = { | |||
502 | .disable = st21nfca_hci_i2c_disable, | 504 | .disable = st21nfca_hci_i2c_disable, |
503 | }; | 505 | }; |
504 | 506 | ||
507 | #ifdef CONFIG_OF | ||
508 | static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) | ||
509 | { | ||
510 | struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); | ||
511 | struct device_node *pp; | ||
512 | int gpio; | ||
513 | int r; | ||
514 | |||
515 | pp = client->dev.of_node; | ||
516 | if (!pp) | ||
517 | return -ENODEV; | ||
518 | |||
519 | /* Get GPIO from device tree */ | ||
520 | gpio = of_get_named_gpio(pp, "enable-gpios", 0); | ||
521 | if (gpio < 0) { | ||
522 | nfc_err(&client->dev, "Failed to retrieve enable-gpios from device tree\n"); | ||
523 | return gpio; | ||
524 | } | ||
525 | |||
526 | /* GPIO request and configuration */ | ||
527 | r = devm_gpio_request(&client->dev, gpio, "clf_enable"); | ||
528 | if (r) { | ||
529 | nfc_err(&client->dev, "Failed to request enable pin\n"); | ||
530 | return -ENODEV; | ||
531 | } | ||
532 | |||
533 | r = gpio_direction_output(gpio, 1); | ||
534 | if (r) { | ||
535 | nfc_err(&client->dev, "Failed to set enable pin direction as output\n"); | ||
536 | return -ENODEV; | ||
537 | } | ||
538 | phy->gpio_ena = gpio; | ||
539 | |||
540 | /* IRQ */ | ||
541 | r = irq_of_parse_and_map(pp, 0); | ||
542 | if (r < 0) { | ||
543 | nfc_err(&client->dev, | ||
544 | "Unable to get irq, error: %d\n", r); | ||
545 | return r; | ||
546 | } | ||
547 | |||
548 | phy->irq_polarity = irq_get_trigger_type(r); | ||
549 | client->irq = r; | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | #else | ||
554 | static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) | ||
555 | { | ||
556 | return -ENODEV; | ||
557 | } | ||
558 | #endif | ||
559 | |||
505 | static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) | 560 | static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) |
506 | { | 561 | { |
507 | struct st21nfca_nfc_platform_data *pdata; | 562 | struct st21nfca_nfc_platform_data *pdata; |
508 | struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); | 563 | struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); |
509 | int r; | 564 | int r; |
565 | int irq; | ||
510 | 566 | ||
511 | pdata = client->dev.platform_data; | 567 | pdata = client->dev.platform_data; |
512 | if (pdata == NULL) { | 568 | if (pdata == NULL) { |
@@ -547,6 +603,16 @@ static int st21nfca_hci_i2c_request_resources(struct i2c_client *client) | |||
547 | } | 603 | } |
548 | } | 604 | } |
549 | 605 | ||
606 | /* IRQ */ | ||
607 | irq = gpio_to_irq(phy->gpio_irq); | ||
608 | if (irq < 0) { | ||
609 | nfc_err(&client->dev, | ||
610 | "Unable to get irq number for GPIO %d error %d\n", | ||
611 | phy->gpio_irq, r); | ||
612 | return -ENODEV; | ||
613 | } | ||
614 | client->irq = irq; | ||
615 | |||
550 | return 0; | 616 | return 0; |
551 | } | 617 | } |
552 | 618 | ||
@@ -556,7 +622,6 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, | |||
556 | struct st21nfca_i2c_phy *phy; | 622 | struct st21nfca_i2c_phy *phy; |
557 | struct st21nfca_nfc_platform_data *pdata; | 623 | struct st21nfca_nfc_platform_data *pdata; |
558 | int r; | 624 | int r; |
559 | int irq; | ||
560 | 625 | ||
561 | dev_dbg(&client->dev, "%s\n", __func__); | 626 | dev_dbg(&client->dev, "%s\n", __func__); |
562 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); | 627 | dev_dbg(&client->dev, "IRQ: %d\n", client->irq); |
@@ -585,26 +650,22 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, | |||
585 | i2c_set_clientdata(client, phy); | 650 | i2c_set_clientdata(client, phy); |
586 | 651 | ||
587 | pdata = client->dev.platform_data; | 652 | pdata = client->dev.platform_data; |
588 | if (!pdata) { | 653 | if (!pdata && client->dev.of_node) { |
589 | nfc_err(&client->dev, "No platform data\n"); | 654 | r = st21nfca_hci_i2c_of_request_resources(client); |
590 | return -EINVAL; | 655 | if (r) { |
591 | } | 656 | nfc_err(&client->dev, "No platform data\n"); |
592 | 657 | return r; | |
593 | r = st21nfca_hci_i2c_request_resources(client); | 658 | } |
594 | if (r) { | 659 | } else if (pdata) { |
595 | nfc_err(&client->dev, "Cannot get platform resources\n"); | 660 | r = st21nfca_hci_i2c_request_resources(client); |
596 | return r; | 661 | if (r) { |
597 | } | 662 | nfc_err(&client->dev, "Cannot get platform resources\n"); |
598 | 663 | return r; | |
599 | /* IRQ */ | 664 | } |
600 | irq = gpio_to_irq(phy->gpio_irq); | 665 | } else { |
601 | if (irq < 0) { | 666 | nfc_err(&client->dev, "st21nfca platform resources not available\n"); |
602 | nfc_err(&client->dev, | ||
603 | "Unable to get irq number for GPIO %d error %d\n", | ||
604 | phy->gpio_irq, r); | ||
605 | return -ENODEV; | 667 | return -ENODEV; |
606 | } | 668 | } |
607 | client->irq = irq; | ||
608 | 669 | ||
609 | r = st21nfca_hci_platform_init(phy); | 670 | r = st21nfca_hci_platform_init(phy); |
610 | if (r < 0) { | 671 | if (r < 0) { |
@@ -640,10 +701,17 @@ static int st21nfca_hci_i2c_remove(struct i2c_client *client) | |||
640 | return 0; | 701 | return 0; |
641 | } | 702 | } |
642 | 703 | ||
704 | static const struct of_device_id of_st21nfca_i2c_match[] = { | ||
705 | { .compatible = "st,st21nfca_i2c", }, | ||
706 | {} | ||
707 | }; | ||
708 | |||
643 | static struct i2c_driver st21nfca_hci_i2c_driver = { | 709 | static struct i2c_driver st21nfca_hci_i2c_driver = { |
644 | .driver = { | 710 | .driver = { |
645 | .owner = THIS_MODULE, | 711 | .owner = THIS_MODULE, |
646 | .name = ST21NFCA_HCI_I2C_DRIVER_NAME, | 712 | .name = ST21NFCA_HCI_I2C_DRIVER_NAME, |
713 | .owner = THIS_MODULE, | ||
714 | .of_match_table = of_match_ptr(of_st21nfca_i2c_match), | ||
647 | }, | 715 | }, |
648 | .probe = st21nfca_hci_i2c_probe, | 716 | .probe = st21nfca_hci_i2c_probe, |
649 | .id_table = st21nfca_hci_i2c_id_table, | 717 | .id_table = st21nfca_hci_i2c_id_table, |