blob: dfac69a341e699fba29b4dfc68c20cfa46e5b125 [file] [log] [blame]
From 5ffe0e63e1ceb6cc6aa6110beeddc6528edb765a Mon Sep 17 00:00:00 2001
From: Furquan Shaikh <furquan@google.com>
Date: Wed, 13 Jun 2018 21:55:26 -0700
Subject: [PATCH] CHROMIUM: i2c: Add device property for probing
Add a new device property to indicate if an I2C device should be
probed before being added. If this property is present and set
then the I2C core layer will use i2c_new_probed_device() instead
of i2c_new_device().
This can be used to provide devices in ACPI or DT that may not be
present on the board. For example, multiple trackpad vendors can
be supported on a single board with a unified firmware image this
way by having their device address be probed before being added.
This property is styled after the PCI Host Bridge probe property
(bindings/pci/host-generic-pci.txt:linuxk,pci-probe-only) and is
a linux specific directive to alter device probing.
BUG=b:110013532
TEST=tested on soraka with 4.14 kernel:
1) add "linux,probed=1" device property to the touchscreen ACPI device
on soraka and ensure that the device is probed before being added.
tested on yorp with 4.14 kernel:
1) I2C devices without the "linux,probed=1" device property are still
functional.
Original-change-Id: I9cf689f7b75ef445c1f0e9f7ec143fa695eb398e
Original-signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Original-reviewed-on: https://chromium-review.googlesource.com/388767
Original-reviewed-by: Benson Leung <bleung@chromium.org>
Change-Id: I54015fe102f2834f6a094d9e650c166a0cc0583b
Signed-off-by: Furquan Shaikh <furquan@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1100544
Commit-Ready: Furquan Shaikh <furquan@chromium.org>
Tested-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Justin TerAvest <teravest@chromium.org>
Conflicts:
drivers/i2c/i2c-core-of.c
[rebase419(groeck): Context conflicts]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
[rebase510(groeck): Context conflicts]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
Change-Id: Id10adae00b381e62813fd6b8ce7c6c50f140c31b
---
Documentation/devicetree/bindings/i2c/i2c.txt | 156 ++++++++++++++++++
drivers/i2c/i2c-core-acpi.c | 12 +-
drivers/i2c/i2c-core-of.c | 10 +-
3 files changed, 176 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c.txt
diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dc08a6c8d2ac765b783b787967e5dffdd56be632
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c.txt
@@ -0,0 +1,156 @@
+Generic device tree bindings for I2C busses
+===========================================
+
+This document describes generic bindings which can be used to describe I2C
+busses and their child devices in a device tree.
+
+Required properties (per bus)
+-----------------------------
+
+- #address-cells - should be <1>. Read more about addresses below.
+- #size-cells - should be <0>.
+- compatible - name of I2C bus controller
+
+For other required properties e.g. to describe register sets,
+clocks, etc. check the binding documentation of the specific driver.
+
+The cells properties above define that an address of children of an I2C bus
+are described by a single value.
+
+Optional properties (per bus)
+-----------------------------
+
+These properties may not be supported by all drivers. However, if a driver
+wants to support one of the below features, it should adapt these bindings.
+
+- clock-frequency
+ frequency of bus clock in Hz.
+
+- i2c-bus
+ For I2C adapters that have child nodes that are a mixture of both I2C
+ devices and non-I2C devices, the 'i2c-bus' subnode can be used for
+ populating I2C devices. If the 'i2c-bus' subnode is present, only
+ subnodes of this will be considered as I2C slaves. The properties,
+ '#address-cells' and '#size-cells' must be defined under this subnode
+ if present.
+
+- i2c-scl-falling-time-ns
+ Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C
+ specification.
+
+- i2c-scl-internal-delay-ns
+ Number of nanoseconds the IP core additionally needs to setup SCL.
+
+- i2c-scl-rising-time-ns
+ Number of nanoseconds the SCL signal takes to rise; t(r) in the I2C
+ specification.
+
+- i2c-sda-falling-time-ns
+ Number of nanoseconds the SDA signal takes to fall; t(f) in the I2C
+ specification.
+
+- i2c-analog-filter
+ Enable analog filter for i2c lines.
+
+- i2c-digital-filter
+ Enable digital filter for i2c lines.
+
+- i2c-digital-filter-width-ns
+ Width of spikes which can be filtered by digital filter
+ (i2c-digital-filter). This width is specified in nanoseconds.
+
+- i2c-analog-filter-cutoff-frequency
+ Frequency that the analog filter (i2c-analog-filter) uses to distinguish
+ which signal to filter. Signal with higher frequency than specified will
+ be filtered out. Only lower frequency will pass (this is applicable to
+ a low-pass analog filter). Typical value should be above the normal
+ i2c bus clock frequency (clock-frequency).
+ Specified in Hz.
+
+- multi-master
+ states that there is another master active on this bus. The OS can use
+ this information to adapt power management to keep the arbitration awake
+ all the time, for example. Can not be combined with 'single-master'.
+
+- pinctrl
+ add extra pinctrl to configure SCL/SDA pins to GPIO function for bus
+ recovery, call it "gpio" or "recovery" (deprecated) state
+
+- scl-gpios
+ specify the gpio related to SCL pin. Used for GPIO bus recovery.
+
+- sda-gpios
+ specify the gpio related to SDA pin. Optional for GPIO bus recovery.
+
+- single-master
+ states that there is no other master active on this bus. The OS can use
+ this information to detect a stalled bus more reliably, for example.
+ Can not be combined with 'multi-master'.
+
+- smbus
+ states that additional SMBus restrictions and features apply to this bus.
+ An example of feature is SMBusHostNotify. Examples of restrictions are
+ more reserved addresses and timeout definitions.
+
+- smbus-alert
+ states that the optional SMBus-Alert feature apply to this bus.
+
+- mctp-controller
+ indicates that the system is accessible via this bus as an endpoint for
+ MCTP over I2C transport.
+
+Required properties (per child device)
+--------------------------------------
+
+- compatible
+ name of I2C slave device
+
+- reg
+ One or many I2C slave addresses. These are usually a 7 bit addresses.
+ However, flags can be attached to an address. I2C_TEN_BIT_ADDRESS is
+ used to mark a 10 bit address. It is needed to avoid the ambiguity
+ between e.g. a 7 bit address of 0x50 and a 10 bit address of 0x050
+ which, in theory, can be on the same bus.
+ Another flag is I2C_OWN_SLAVE_ADDRESS to mark addresses on which we
+ listen to be devices ourselves.
+
+Optional properties (per child device)
+--------------------------------------
+
+These properties may not be supported by all drivers. However, if a driver
+wants to support one of the below features, it should adapt these bindings.
+
+- host-notify
+ device uses SMBus host notify protocol instead of interrupt line.
+
+- interrupts
+ interrupts used by the device.
+
+- interrupt-names
+ "irq", "wakeup" and "smbus_alert" names are recognized by I2C core,
+ other names are left to individual drivers.
+
+- reg-names
+ Names of map programmable addresses.
+ It can contain any map needing another address than default one.
+
+- wakeup-source
+ device can be used as a wakeup source.
+
+- linux,probed
+ If this property is present, then the I2C device will be
+ probed before being added using i2c_new_scanned_device, else
+ linux will instantiate the I2C device normally.
+
+Binding may contain optional "interrupts" property, describing interrupts
+used by the device. I2C core will assign "irq" interrupt (or the very first
+interrupt if not using interrupt names) as primary interrupt for the slave.
+
+Alternatively, devices supporting SMBus Host Notify, and connected to
+adapters that support this feature, may use "host-notify" property. I2C
+core will create a virtual interrupt for Host Notify and assign it as
+primary interrupt for the slave.
+
+Also, if device is marked as a wakeup source, I2C core will set up "wakeup"
+interrupt for the device. If "wakeup" interrupt name is not present in the
+binding, then primary interrupt will be used as wakeup interrupt.
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index d6037a3286690593d57f29cfb8c72467f472c4e3..69c50e8506d32fdc7b0796dda4b9806dd85525aa 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -278,6 +278,8 @@ static void i2c_acpi_register_device(struct i2c_adapter *adapter,
struct acpi_device *adev,
struct i2c_board_info *info)
{
+ struct i2c_client *client;
+
/*
* Skip registration on boards where the ACPI tables are
* known to contain bogus I2C devices.
@@ -288,7 +290,15 @@ static void i2c_acpi_register_device(struct i2c_adapter *adapter,
adev->power.flags.ignore_parent = true;
acpi_device_set_enumerated(adev);
- if (IS_ERR(i2c_new_client_device(adapter, info)))
+ if (!acpi_dev_get_property(adev, "linux,probed", ACPI_TYPE_ANY, NULL)) {
+ unsigned short addrs[] = { info->addr, I2C_CLIENT_END };
+
+ client = i2c_new_scanned_device(adapter, info, addrs, NULL);
+ } else {
+ client = i2c_new_client_device(adapter, info);
+ }
+
+ if (IS_ERR(client))
adev->power.flags.ignore_parent = false;
}
diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c
index a6c407d3680098272a341de84269ef036e302279..16594a0b29253fdd2a67d4002309a91247578f96 100644
--- a/drivers/i2c/i2c-core-of.c
+++ b/drivers/i2c/i2c-core-of.c
@@ -75,7 +75,15 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
if (ret)
return ERR_PTR(ret);
- client = i2c_new_client_device(adap, &info);
+ /* Allow device property to enable probing before init */
+ if (of_get_property(node, "linux,probed", NULL)) {
+ unsigned short addrs[] = { info.addr, I2C_CLIENT_END };
+
+ client = i2c_new_scanned_device(adap, &info, addrs, NULL);
+ } else {
+ client = i2c_new_client_device(adap, &info);
+ }
+
if (IS_ERR(client))
dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
--
2.44.0.478.gd926399ef9-goog