[RFC PATCH v3 0/5] platform/chrome: Introduce DT hardware prober

From: Chen-Yu Tsai
Date: Tue Nov 28 2023 - 03:45:14 EST


Hi everyone,

This is v3 of my "of: Introduce hardware prober driver" [1] series.
v2 continued Doug's "of: device: Support 2nd sources of probeable but
undiscoverable devices" [2] series, but follows the scheme suggested by Rob, marking all second
source component device nodes as "fail-needs-probe", and having a
hardware prober driver enable the one of them. I tried to include
everyone from the original Cc: list. Please let me know if you would
like to be dropped from future submissions.

Changes since v2:
- Added of_changeset_update_prop_string()
- Moved generic I2C code to the I2C core
- Moved remaining platform specific code to platform/chrome/
- Switched to of_node_is_available() to check if node is enabled.
- Switched to OF changeset API to update status property
- I2C probe helper function now accepts "struct device *dev" instead to
reduce line length and dereferences
- Moved "ret = 0" to just before for_each_child_of_node(i2c_node, node)
- Depend on rather than select CONFIG_I2C
- Copied machine check to driver init function
- Explicitly mentioned "device tree" or OF in driver name, description
and Kconfig symbol
- Dropped filename from inside the file
- Made loop variable size_t (instead of unsigned int as Andy asked)
- Switched to PLATFORM_DEVID_NONE instead of raw -1
- Switched to standard goto error path pattern in hw_prober_driver_init()
- Dropped device class from status property

Patches removed from v3 and saved for later:
- of: base: Add of_device_is_fail
- of: hw_prober: Support Chromebook SKU ID based component selection
- dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane
- arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees

For the I2C component (touchscreens and trackpads) case from the
original series, the hardware prober driver finds the particular
class of device in the device tree, gets its parent I2C adapter,
and tries to initiate a simple I2C read for each device under that
I2C bus. When it finds one that responds, it considers that one
present, marks it as "okay", and returns, letting the driver core
actually probe the device.

This works fine in most cases since these components are connected
via ribbon cable and always have the same resources. The driver as
implemented currently doesn't deal with regulators or GPIO pins,
since in the existing device trees they are either always on for
regulators, or have GPIO hogs or pinmux and pinconfig directly
tied to the pin controller.

The other case, selecting a display panel to use based on the SKU ID
from the firmware, hit a bit of an issue with fixing the OF graph.
I've left it out of v3 for now.

Patch 1 adds of_changeset_update_prop_string(), as requested by Rob.

Patch 2 implements probing the I2C bus for presence of components as
a helper function in the I2C core.

Patch 3 adds a ChromeOS specific DT hardware prober. This initial
version targets the Hana Chromebooks, probing its I2C trackpads and
touchscreens.

Patch 4 modifies the Hana device tree and marks the touchscreens
and trackpads as "fail-needs-probe", ready for the driver to probe.

Patch 5 adds a missing touchscreen variant to Hana. This patch
conflicts with another one in flight [3] that is almost the same.


Assuming this is acceptable to folks, because there are compile
time dependencies, I think it would be easier for the code bits
(patches 1 through 4) to go through either the OF tree or I2C
tree. Patches 5 and 6 can go through the soc tree via the mediatek
tree.


Thanks
ChenYu


Background as given in Doug's cover letter:

Support for multiple "equivalent" sources for components (also known
as second sourcing components) is a standard practice that helps keep
cost down and also makes sure that if one component is unavailable due
to a shortage that we don't need to stop production for the whole
product.

Some components are very easy to second source. eMMC, for instance, is
fully discoverable and probable so you can stuff a wide variety of
similar eMMC chips on your board and things will work without a hitch.

Some components are more difficult to second source, specifically
because it's difficult for software to probe what component is present
on any given board. In cases like this software is provided
supplementary information to help it, like a GPIO strap or a SKU ID
programmed into an EEPROM. This helpful information can allow the
bootloader to select a different device tree. The various different
"SKUs" of different Chromebooks are examples of this.

Some components are somewhere in between. These in-between components
are the subject of this patch. Specifically, these components are
easily "probeable" but not easily "discoverable".

A good example of a probeable but undiscoverable device is an
i2c-connected touchscreen or trackpad. Two separate components may be
electrically compatible with each other and may have compatible power
sequencing requirements but may require different software. If
software is told about the different possible components (because it
can't discover them), it can safely probe them to figure out which
ones are present.

On systems using device tree, if we want to tell the OS about all of
the different components we need to list them all in the device
tree. This leads to a problem. The multiple sources for components
likely use the same resources (GPIOs, interrupts, regulators). If the
OS tries to probe all of these components at the same time then it
will detect a resource conflict and that's a fatal error.

The fact that Linux can't handle these probeable but undiscoverable
devices well has had a few consequences:
1. In some cases, we've abandoned the idea of second sourcing
components for a given board, which increases cost / generates
manufacturing headaches.
2. In some cases, we've been forced to add some sort of strapping /
EEPROM to indicate which component is present. This adds difficulty
to manufacturing / refurb processes.
3. In some cases, we've managed to make things work by the skin of our
teeth through slightly hacky solutions. Specifically, if we remove
the "pinctrl" entry from the various options then it won't
conflict. Regulators inherently can have more than one consumer, so
as long as there are no GPIOs involved in power sequencing and
probing devices then things can work. This is how
"sc8280xp-lenovo-thinkpad-x13s" works and also how
"mt8173-elm-hana" works.

End of background from Doug's cover letter.

[1] https://lore.kernel.org/linux-arm-kernel/20231109100606.1245545-1-wenst@xxxxxxxxxxxx/
[2] https://lore.kernel.org/all/20230921102420.RFC.1.I9dddd99ccdca175e3ceb1b9fa1827df0928c5101@changeid/
[3] https://lore.kernel.org/linux-mediatek/20231115043511.2670477-1-treapking@xxxxxxxxxxxx/

Chen-Yu Tsai (5):
of: dynamic: Add of_changeset_update_prop_string
i2c: of: Introduce component probe function
platform/chrome: Introduce device tree hardware prober
arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads
as fail
arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen

.../boot/dts/mediatek/mt8173-elm-hana.dtsi | 20 ++++
drivers/i2c/i2c-core-of.c | 110 ++++++++++++++++++
drivers/of/dynamic.c | 47 ++++++++
drivers/platform/chrome/Kconfig | 11 ++
drivers/platform/chrome/Makefile | 1 +
.../platform/chrome/chromeos_of_hw_prober.c | 89 ++++++++++++++
include/linux/i2c.h | 4 +
include/linux/of.h | 3 +
8 files changed, 285 insertions(+)
create mode 100644 drivers/platform/chrome/chromeos_of_hw_prober.c

--
2.43.0.rc1.413.gea7ed67945-goog