Commit dfa8070d authored by Christophe Ricard's avatar Christophe Ricard Committed by Samuel Ortiz

nfc: st21nfca: Add support for acpi probing for i2c device.

Add support for acpi probing.
SMO2100 is used for st21nfca

It has been tested with the following acpi node on Minnowboard Max:
Note: Remove uicc-present or ese-present Package if one them is not
supported.

Device (NFC1)
{
	Name (_ADR, Zero)  // _ADR: Address
	Name (_HID, "SMO2100")  // _HID: Hardware ID
	Name (_CID, "SMO2100")  // _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 (0x0001, 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: default avatarChristophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 60cd6d89
...@@ -21,8 +21,10 @@ ...@@ -21,8 +21,10 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/acpi.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -205,7 +207,6 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb) ...@@ -205,7 +207,6 @@ static int st21nfca_hci_i2c_write(void *phy_id, struct sk_buff *skb)
I2C_DUMP_SKB("st21nfca_hci_i2c_write", skb); I2C_DUMP_SKB("st21nfca_hci_i2c_write", skb);
if (phy->hard_fault != 0) if (phy->hard_fault != 0)
return phy->hard_fault; return phy->hard_fault;
...@@ -504,6 +505,41 @@ static struct nfc_phy_ops i2c_phy_ops = { ...@@ -504,6 +505,41 @@ static struct nfc_phy_ops i2c_phy_ops = {
.disable = st21nfca_hci_i2c_disable, .disable = st21nfca_hci_i2c_disable,
}; };
static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client)
{
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
const struct acpi_device_id *id;
struct gpio_desc *gpiod_ena;
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 EN GPIO from ACPI */
gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1,
GPIOD_OUT_LOW);
if (!IS_ERR(gpiod_ena))
phy->gpio_ena = desc_to_gpio(gpiod_ena);
phy->gpio_ena = desc_to_gpio(gpiod_ena);
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 st21nfca_hci_i2c_of_request_resources(struct i2c_client *client) static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
{ {
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
...@@ -617,6 +653,12 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -617,6 +653,12 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
nfc_err(&client->dev, "Cannot get platform resources\n"); nfc_err(&client->dev, "Cannot get platform resources\n");
return r; return r;
} }
} else if (ACPI_HANDLE(&client->dev)) {
r = st21nfca_hci_i2c_acpi_request_resources(client);
if (r) {
nfc_err(&client->dev, "Cannot get ACPI data\n");
return r;
}
} else { } else {
nfc_err(&client->dev, "st21nfca platform resources not available\n"); nfc_err(&client->dev, "st21nfca platform resources not available\n");
return -ENODEV; return -ENODEV;
...@@ -665,6 +707,12 @@ static struct i2c_device_id st21nfca_hci_i2c_id_table[] = { ...@@ -665,6 +707,12 @@ static struct i2c_device_id st21nfca_hci_i2c_id_table[] = {
}; };
MODULE_DEVICE_TABLE(i2c, st21nfca_hci_i2c_id_table); MODULE_DEVICE_TABLE(i2c, st21nfca_hci_i2c_id_table);
static const struct acpi_device_id st21nfca_hci_i2c_acpi_match[] = {
{"SMO2100", 0},
{}
};
MODULE_DEVICE_TABLE(acpi, st21nfca_hci_i2c_acpi_match);
static const struct of_device_id of_st21nfca_i2c_match[] = { static const struct of_device_id of_st21nfca_i2c_match[] = {
{ .compatible = "st,st21nfca-i2c", }, { .compatible = "st,st21nfca-i2c", },
{ .compatible = "st,st21nfca_i2c", }, { .compatible = "st,st21nfca_i2c", },
...@@ -677,6 +725,7 @@ static struct i2c_driver st21nfca_hci_i2c_driver = { ...@@ -677,6 +725,7 @@ static struct i2c_driver st21nfca_hci_i2c_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = ST21NFCA_HCI_I2C_DRIVER_NAME, .name = ST21NFCA_HCI_I2C_DRIVER_NAME,
.of_match_table = of_match_ptr(of_st21nfca_i2c_match), .of_match_table = of_match_ptr(of_st21nfca_i2c_match),
.acpi_match_table = ACPI_PTR(st21nfca_hci_i2c_acpi_match),
}, },
.probe = st21nfca_hci_i2c_probe, .probe = st21nfca_hci_i2c_probe,
.id_table = st21nfca_hci_i2c_id_table, .id_table = st21nfca_hci_i2c_id_table,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment