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