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>
This commit is contained in:
Christophe Ricard 2015-12-23 23:45:09 +01:00 committed by Samuel Ortiz
parent 04e99b71fe
commit ed6a2f3fb7
1 changed files with 53 additions and 0 deletions

View File

@ -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,