diff options
Diffstat (limited to 'drivers/nfc/st-nci/spi.c')
-rw-r--r-- | drivers/nfc/st-nci/spi.c | 162 |
1 files changed, 25 insertions, 137 deletions
diff --git a/drivers/nfc/st-nci/spi.c b/drivers/nfc/st-nci/spi.c index 89e341eba3eb..14705591b0fb 100644 --- a/drivers/nfc/st-nci/spi.c +++ b/drivers/nfc/st-nci/spi.c @@ -19,16 +19,13 @@ #include <linux/module.h> #include <linux/spi/spi.h> -#include <linux/gpio.h> #include <linux/gpio/consumer.h> -#include <linux/of_irq.h> -#include <linux/of_gpio.h> #include <linux/acpi.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/nfc.h> +#include <linux/of.h> #include <net/nfc/nci.h> -#include <linux/platform_data/st-nci.h> #include "st-nci.h" @@ -41,18 +38,16 @@ #define ST_NCI_SPI_MIN_SIZE 4 /* PCB(1) + NCI Packet header(3) */ #define ST_NCI_SPI_MAX_SIZE 250 /* req 4.2.1 */ +#define ST_NCI_DRIVER_NAME "st_nci" #define ST_NCI_SPI_DRIVER_NAME "st_nci_spi" -#define ST_NCI_GPIO_NAME_RESET "reset" - struct st_nci_spi_phy { struct spi_device *spi_dev; struct llt_ndlc *ndlc; bool irq_active; - unsigned int gpio_reset; - unsigned int irq_polarity; + struct gpio_desc *gpiod_reset; struct st_nci_se_status se_status; }; @@ -61,9 +56,9 @@ static int st_nci_spi_enable(void *phy_id) { struct st_nci_spi_phy *phy = phy_id; - gpio_set_value(phy->gpio_reset, 0); + gpiod_set_value(phy->gpiod_reset, 0); usleep_range(10000, 15000); - gpio_set_value(phy->gpio_reset, 1); + gpiod_set_value(phy->gpiod_reset, 1); usleep_range(80000, 85000); if (phy->ndlc->powered == 0 && phy->irq_active == 0) { @@ -223,113 +218,16 @@ static struct nfc_phy_ops spi_phy_ops = { .disable = st_nci_spi_disable, }; -static int st_nci_spi_acpi_request_resources(struct spi_device *spi_dev) -{ - struct st_nci_spi_phy *phy = spi_get_drvdata(spi_dev); - struct gpio_desc *gpiod_reset; - struct device *dev = &spi_dev->dev; - u8 tmp; - - /* Get RESET GPIO from ACPI */ - gpiod_reset = devm_gpiod_get_index(dev, ST_NCI_GPIO_NAME_RESET, 1, - GPIOD_OUT_HIGH); - if (IS_ERR(gpiod_reset)) { - nfc_err(dev, "Unable to get RESET GPIO\n"); - return -ENODEV; - } - - phy->gpio_reset = desc_to_gpio(gpiod_reset); - - phy->irq_polarity = irq_get_trigger_type(spi_dev->irq); - - phy->se_status.is_ese_present = false; - phy->se_status.is_uicc_present = false; - - if (device_property_present(dev, "ese-present")) { - device_property_read_u8(dev, "ese-present", &tmp); - tmp = phy->se_status.is_ese_present; - } - - if (device_property_present(dev, "uicc-present")) { - device_property_read_u8(dev, "uicc-present", &tmp); - tmp = phy->se_status.is_uicc_present; - } - - return 0; -} - -static int st_nci_spi_of_request_resources(struct spi_device *dev) -{ - struct st_nci_spi_phy *phy = spi_get_drvdata(dev); - struct device_node *pp; - int gpio; - int r; - - pp = dev->dev.of_node; - if (!pp) - return -ENODEV; - - /* Get GPIO from device tree */ - gpio = of_get_named_gpio(pp, "reset-gpios", 0); - if (gpio < 0) { - nfc_err(&dev->dev, - "Failed to retrieve reset-gpios from device tree\n"); - return gpio; - } - - /* GPIO request and configuration */ - r = devm_gpio_request_one(&dev->dev, gpio, - GPIOF_OUT_INIT_HIGH, ST_NCI_GPIO_NAME_RESET); - if (r) { - nfc_err(&dev->dev, "Failed to request reset pin\n"); - return r; - } - phy->gpio_reset = gpio; - - phy->irq_polarity = irq_get_trigger_type(dev->irq); +static const struct acpi_gpio_params reset_gpios = { 1, 0, false }; - phy->se_status.is_ese_present = - of_property_read_bool(pp, "ese-present"); - phy->se_status.is_uicc_present = - of_property_read_bool(pp, "uicc-present"); - - return 0; -} - -static int st_nci_spi_request_resources(struct spi_device *dev) -{ - struct st_nci_nfc_platform_data *pdata; - struct st_nci_spi_phy *phy = spi_get_drvdata(dev); - int r; - - pdata = dev->dev.platform_data; - if (pdata == NULL) { - nfc_err(&dev->dev, "No platform data\n"); - return -EINVAL; - } - - /* store for later use */ - phy->gpio_reset = pdata->gpio_reset; - phy->irq_polarity = pdata->irq_polarity; - - r = devm_gpio_request_one(&dev->dev, - phy->gpio_reset, GPIOF_OUT_INIT_HIGH, - ST_NCI_GPIO_NAME_RESET); - if (r) { - pr_err("%s : reset gpio_request failed\n", __FILE__); - return r; - } - - phy->se_status.is_ese_present = pdata->is_ese_present; - phy->se_status.is_uicc_present = pdata->is_uicc_present; - - return 0; -} +static const struct acpi_gpio_mapping acpi_st_nci_gpios[] = { + { "reset-gpios", &reset_gpios, 1 }, + {}, +}; static int st_nci_spi_probe(struct spi_device *dev) { struct st_nci_spi_phy *phy; - struct st_nci_nfc_platform_data *pdata; int r; dev_dbg(&dev->dev, "%s\n", __func__); @@ -351,32 +249,22 @@ static int st_nci_spi_probe(struct spi_device *dev) spi_set_drvdata(dev, phy); - pdata = dev->dev.platform_data; - if (!pdata && dev->dev.of_node) { - r = st_nci_spi_of_request_resources(dev); - if (r) { - nfc_err(&dev->dev, "No platform data\n"); - return r; - } - } else if (pdata) { - r = st_nci_spi_request_resources(dev); - if (r) { - nfc_err(&dev->dev, - "Cannot get platform resources\n"); - return r; - } - } else if (ACPI_HANDLE(&dev->dev)) { - r = st_nci_spi_acpi_request_resources(dev); - if (r) { - nfc_err(&dev->dev, "Cannot get ACPI data\n"); - return r; - } - } else { - nfc_err(&dev->dev, - "st_nci platform resources not available\n"); - return -ENODEV; + r = devm_acpi_dev_add_driver_gpios(&dev->dev, acpi_st_nci_gpios); + if (r) + dev_dbg(&dev->dev, "Unable to add GPIO mapping table\n"); + + /* Get RESET GPIO */ + phy->gpiod_reset = devm_gpiod_get(&dev->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(phy->gpiod_reset)) { + nfc_err(&dev->dev, "Unable to get RESET GPIO\n"); + return PTR_ERR(phy->gpiod_reset); } + phy->se_status.is_ese_present = + device_property_read_bool(&dev->dev, "ese-present"); + phy->se_status.is_uicc_present = + device_property_read_bool(&dev->dev, "uicc-present"); + r = ndlc_probe(phy, &spi_phy_ops, &dev->dev, ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, &phy->ndlc, &phy->se_status); @@ -388,7 +276,7 @@ static int st_nci_spi_probe(struct spi_device *dev) phy->irq_active = true; r = devm_request_threaded_irq(&dev->dev, dev->irq, NULL, st_nci_irq_thread_fn, - phy->irq_polarity | IRQF_ONESHOT, + IRQF_ONESHOT, ST_NCI_SPI_DRIVER_NAME, phy); if (r < 0) nfc_err(&dev->dev, "Unable to register IRQ handler\n"); |