diff options
author | Christophe Ricard <christophe.ricard@gmail.com> | 2015-12-24 01:45:09 +0300 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2015-12-29 21:06:16 +0300 |
commit | ed6a2f3fb770acc18bba8c9bc86f09e95d7fc641 (patch) | |
tree | 672e449e9fce4a0005fa8b71806255a2aafc1db0 /drivers/nfc/st-nci/i2c.c | |
parent | 04e99b71fe6e96476884b0e6d50bfe421dee9960 (diff) | |
download | linux-ed6a2f3fb770acc18bba8c9bc86f09e95d7fc641.tar.xz |
nfc: st-nci: Add support for acpi probing for i2c device.
Add support for acpi probing.
SMO2101 is used for st21nfcb
SMO2102 is used for st21nfcc
It has been tested with the following acpi node on Minnowboard:
Note: Remove uicc-present or ese-present Package if one them is not
supported.
Device (NFC1)
{
Name (_ADR, Zero) // _ADR: Address
Name (_HID, "SMO2101") // _HID: Hardware ID
Name (_CID, "SMO2101") // _CID: Compatible ID
Name (_DDN, "SMO NFC") // _DDN: DOS Device Name
Name (_UID, One) // _UID: Unique ID
Name (_DSD, Package (0x02)
{
/* Device Properties for _DSD */
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package (0x02)
{
Package (0x02) { "uicc-present", 1 },
Package (0x02) { "ese-present", 1 }
}
})
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (SBUF, ResourceTemplate ()
{
I2cSerialBus (0x0008, ControllerInitiated, 400000,
AddressingMode7Bit, "\\_SB.I2C7",
0x00, ResourceConsumer, ,)
GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone, 0x0000,
"\\_SB.GPO2", 0x00, ResourceConsumer, ,)
{ // Pin list
0x0001
}
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly,
"\\_SB.GPO2", 0x00, ResourceConsumer, ,)
{ // Pin list
0x0002,
}
})
Return (SBUF) /* \_SB_.I2C7.NFC1._CRS.SBUF */
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
}
Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc/st-nci/i2c.c')
-rw-r--r-- | drivers/nfc/st-nci/i2c.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/nfc/st-nci/i2c.c b/drivers/nfc/st-nci/i2c.c index 0e6e3b22e24a..3e384159b288 100644 --- a/drivers/nfc/st-nci/i2c.c +++ b/drivers/nfc/st-nci/i2c.c @@ -20,8 +20,10 @@ #include <linux/module.h> #include <linux/i2c.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> @@ -206,6 +208,43 @@ static struct nfc_phy_ops i2c_phy_ops = { .disable = st_nci_i2c_disable, }; +static int st_nci_i2c_acpi_request_resources(struct i2c_client *client) +{ + struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); + const struct acpi_device_id *id; + struct gpio_desc *gpiod_reset; + struct device *dev; + + if (!client) + return -EINVAL; + + dev = &client->dev; + + /* Match the struct device against a given list of ACPI IDs */ + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return -ENODEV; + + /* 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(client->irq); + + phy->se_status.is_ese_present = + device_property_present(dev, "ese-present"); + phy->se_status.is_uicc_present = + device_property_present(dev, "uicc-present"); + + return 0; +} + static int st_nci_i2c_of_request_resources(struct i2c_client *client) { struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); @@ -312,6 +351,12 @@ static int st_nci_i2c_probe(struct i2c_client *client, "Cannot get platform resources\n"); return r; } + } else if (ACPI_HANDLE(&client->dev)) { + r = st_nci_i2c_acpi_request_resources(client); + if (r) { + nfc_err(&client->dev, "Cannot get ACPI data\n"); + return r; + } } else { nfc_err(&client->dev, "st_nci platform resources not available\n"); @@ -354,6 +399,13 @@ static struct i2c_device_id st_nci_i2c_id_table[] = { }; MODULE_DEVICE_TABLE(i2c, st_nci_i2c_id_table); +static const struct acpi_device_id st_nci_i2c_acpi_match[] = { + {"SMO2101"}, + {"SMO2102"}, + {} +}; +MODULE_DEVICE_TABLE(acpi, st_nci_i2c_acpi_match); + static const struct of_device_id of_st_nci_i2c_match[] = { { .compatible = "st,st21nfcb-i2c", }, { .compatible = "st,st21nfcb_i2c", }, @@ -367,6 +419,7 @@ static struct i2c_driver st_nci_i2c_driver = { .owner = THIS_MODULE, .name = ST_NCI_I2C_DRIVER_NAME, .of_match_table = of_match_ptr(of_st_nci_i2c_match), + .acpi_match_table = ACPI_PTR(st_nci_i2c_acpi_match), }, .probe = st_nci_i2c_probe, .id_table = st_nci_i2c_id_table, |