1*157ce8f3SChen-Yu Tsai // SPDX-License-Identifier: GPL-2.0-or-later 2*157ce8f3SChen-Yu Tsai /* 3*157ce8f3SChen-Yu Tsai * Linux I2C core OF component prober code 4*157ce8f3SChen-Yu Tsai * 5*157ce8f3SChen-Yu Tsai * Copyright (C) 2024 Google LLC 6*157ce8f3SChen-Yu Tsai */ 7*157ce8f3SChen-Yu Tsai 8*157ce8f3SChen-Yu Tsai #include <linux/cleanup.h> 9*157ce8f3SChen-Yu Tsai #include <linux/device.h> 10*157ce8f3SChen-Yu Tsai #include <linux/dev_printk.h> 11*157ce8f3SChen-Yu Tsai #include <linux/err.h> 12*157ce8f3SChen-Yu Tsai #include <linux/i2c.h> 13*157ce8f3SChen-Yu Tsai #include <linux/i2c-of-prober.h> 14*157ce8f3SChen-Yu Tsai #include <linux/module.h> 15*157ce8f3SChen-Yu Tsai #include <linux/of.h> 16*157ce8f3SChen-Yu Tsai #include <linux/slab.h> 17*157ce8f3SChen-Yu Tsai #include <linux/stddef.h> 18*157ce8f3SChen-Yu Tsai 19*157ce8f3SChen-Yu Tsai /* 20*157ce8f3SChen-Yu Tsai * Some devices, such as Google Hana Chromebooks, are produced by multiple 21*157ce8f3SChen-Yu Tsai * vendors each using their preferred components. Such components are all 22*157ce8f3SChen-Yu Tsai * in the device tree. Instead of having all of them enabled and having each 23*157ce8f3SChen-Yu Tsai * driver separately try and probe its device while fighting over shared 24*157ce8f3SChen-Yu Tsai * resources, they can be marked as "fail-needs-probe" and have a prober 25*157ce8f3SChen-Yu Tsai * figure out which one is actually used beforehand. 26*157ce8f3SChen-Yu Tsai * 27*157ce8f3SChen-Yu Tsai * This prober assumes such drop-in parts are on the same I2C bus, have 28*157ce8f3SChen-Yu Tsai * non-conflicting addresses, and can be directly probed by seeing which 29*157ce8f3SChen-Yu Tsai * address responds. 30*157ce8f3SChen-Yu Tsai * 31*157ce8f3SChen-Yu Tsai * TODO: 32*157ce8f3SChen-Yu Tsai * - Support handling common regulators. 33*157ce8f3SChen-Yu Tsai * - Support handling common GPIOs. 34*157ce8f3SChen-Yu Tsai * - Support I2C muxes 35*157ce8f3SChen-Yu Tsai */ 36*157ce8f3SChen-Yu Tsai 37*157ce8f3SChen-Yu Tsai static struct device_node *i2c_of_probe_get_i2c_node(struct device *dev, const char *type) 38*157ce8f3SChen-Yu Tsai { 39*157ce8f3SChen-Yu Tsai struct device_node *node __free(device_node) = of_find_node_by_name(NULL, type); 40*157ce8f3SChen-Yu Tsai if (!node) { 41*157ce8f3SChen-Yu Tsai dev_err(dev, "Could not find %s device node\n", type); 42*157ce8f3SChen-Yu Tsai return NULL; 43*157ce8f3SChen-Yu Tsai } 44*157ce8f3SChen-Yu Tsai 45*157ce8f3SChen-Yu Tsai struct device_node *i2c_node __free(device_node) = of_get_parent(node); 46*157ce8f3SChen-Yu Tsai if (!of_node_name_eq(i2c_node, "i2c")) { 47*157ce8f3SChen-Yu Tsai dev_err(dev, "%s device isn't on I2C bus\n", type); 48*157ce8f3SChen-Yu Tsai return NULL; 49*157ce8f3SChen-Yu Tsai } 50*157ce8f3SChen-Yu Tsai 51*157ce8f3SChen-Yu Tsai if (!of_device_is_available(i2c_node)) { 52*157ce8f3SChen-Yu Tsai dev_err(dev, "I2C controller not available\n"); 53*157ce8f3SChen-Yu Tsai return NULL; 54*157ce8f3SChen-Yu Tsai } 55*157ce8f3SChen-Yu Tsai 56*157ce8f3SChen-Yu Tsai return no_free_ptr(i2c_node); 57*157ce8f3SChen-Yu Tsai } 58*157ce8f3SChen-Yu Tsai 59*157ce8f3SChen-Yu Tsai static int i2c_of_probe_enable_node(struct device *dev, struct device_node *node) 60*157ce8f3SChen-Yu Tsai { 61*157ce8f3SChen-Yu Tsai int ret; 62*157ce8f3SChen-Yu Tsai 63*157ce8f3SChen-Yu Tsai dev_dbg(dev, "Enabling %pOF\n", node); 64*157ce8f3SChen-Yu Tsai 65*157ce8f3SChen-Yu Tsai struct of_changeset *ocs __free(kfree) = kzalloc(sizeof(*ocs), GFP_KERNEL); 66*157ce8f3SChen-Yu Tsai if (!ocs) 67*157ce8f3SChen-Yu Tsai return -ENOMEM; 68*157ce8f3SChen-Yu Tsai 69*157ce8f3SChen-Yu Tsai of_changeset_init(ocs); 70*157ce8f3SChen-Yu Tsai ret = of_changeset_update_prop_string(ocs, node, "status", "okay"); 71*157ce8f3SChen-Yu Tsai if (ret) 72*157ce8f3SChen-Yu Tsai return ret; 73*157ce8f3SChen-Yu Tsai 74*157ce8f3SChen-Yu Tsai ret = of_changeset_apply(ocs); 75*157ce8f3SChen-Yu Tsai if (ret) { 76*157ce8f3SChen-Yu Tsai /* ocs needs to be explicitly cleaned up before being freed. */ 77*157ce8f3SChen-Yu Tsai of_changeset_destroy(ocs); 78*157ce8f3SChen-Yu Tsai } else { 79*157ce8f3SChen-Yu Tsai /* 80*157ce8f3SChen-Yu Tsai * ocs is intentionally kept around as it needs to 81*157ce8f3SChen-Yu Tsai * exist as long as the change is applied. 82*157ce8f3SChen-Yu Tsai */ 83*157ce8f3SChen-Yu Tsai void *ptr __always_unused = no_free_ptr(ocs); 84*157ce8f3SChen-Yu Tsai } 85*157ce8f3SChen-Yu Tsai 86*157ce8f3SChen-Yu Tsai return ret; 87*157ce8f3SChen-Yu Tsai } 88*157ce8f3SChen-Yu Tsai 89*157ce8f3SChen-Yu Tsai static const struct i2c_of_probe_ops i2c_of_probe_dummy_ops; 90*157ce8f3SChen-Yu Tsai 91*157ce8f3SChen-Yu Tsai /** 92*157ce8f3SChen-Yu Tsai * i2c_of_probe_component() - probe for devices of "type" on the same i2c bus 93*157ce8f3SChen-Yu Tsai * @dev: Pointer to the &struct device of the caller, only used for dev_printk() messages. 94*157ce8f3SChen-Yu Tsai * @cfg: Pointer to the &struct i2c_of_probe_cfg containing callbacks and other options 95*157ce8f3SChen-Yu Tsai * for the prober. 96*157ce8f3SChen-Yu Tsai * @ctx: Context data for callbacks. 97*157ce8f3SChen-Yu Tsai * 98*157ce8f3SChen-Yu Tsai * Probe for possible I2C components of the same "type" (&i2c_of_probe_cfg->type) 99*157ce8f3SChen-Yu Tsai * on the same I2C bus that have their status marked as "fail-needs-probe". 100*157ce8f3SChen-Yu Tsai * 101*157ce8f3SChen-Yu Tsai * Assumes that across the entire device tree the only instances of nodes 102*157ce8f3SChen-Yu Tsai * with "type" prefixed node names (not including the address portion) are 103*157ce8f3SChen-Yu Tsai * the ones that need handling for second source components. In other words, 104*157ce8f3SChen-Yu Tsai * if "type" is "touchscreen", then all device nodes named "touchscreen*" 105*157ce8f3SChen-Yu Tsai * are the ones that need probing. There cannot be another "touchscreen*" 106*157ce8f3SChen-Yu Tsai * node that is already enabled. 107*157ce8f3SChen-Yu Tsai * 108*157ce8f3SChen-Yu Tsai * Assumes that for each "type" of component, only one actually exists. In 109*157ce8f3SChen-Yu Tsai * other words, only one matching and existing device will be enabled. 110*157ce8f3SChen-Yu Tsai * 111*157ce8f3SChen-Yu Tsai * Context: Process context only. Does non-atomic I2C transfers. 112*157ce8f3SChen-Yu Tsai * Should only be used from a driver probe function, as the function 113*157ce8f3SChen-Yu Tsai * can return -EPROBE_DEFER if the I2C adapter or other resources 114*157ce8f3SChen-Yu Tsai * are unavailable. 115*157ce8f3SChen-Yu Tsai * Return: 0 on success or no-op, error code otherwise. 116*157ce8f3SChen-Yu Tsai * A no-op can happen when it seems like the device tree already 117*157ce8f3SChen-Yu Tsai * has components of the type to be probed already enabled. This 118*157ce8f3SChen-Yu Tsai * can happen when the device tree had not been updated to mark 119*157ce8f3SChen-Yu Tsai * the status of the to-be-probed components as "fail-needs-probe". 120*157ce8f3SChen-Yu Tsai * Or this function was already run with the same parameters and 121*157ce8f3SChen-Yu Tsai * succeeded in enabling a component. The latter could happen if 122*157ce8f3SChen-Yu Tsai * the user had multiple types of components to probe, and one of 123*157ce8f3SChen-Yu Tsai * them down the list caused a deferred probe. This is expected 124*157ce8f3SChen-Yu Tsai * behavior. 125*157ce8f3SChen-Yu Tsai */ 126*157ce8f3SChen-Yu Tsai int i2c_of_probe_component(struct device *dev, const struct i2c_of_probe_cfg *cfg, void *ctx) 127*157ce8f3SChen-Yu Tsai { 128*157ce8f3SChen-Yu Tsai const struct i2c_of_probe_ops *ops; 129*157ce8f3SChen-Yu Tsai const char *type; 130*157ce8f3SChen-Yu Tsai struct i2c_adapter *i2c; 131*157ce8f3SChen-Yu Tsai int ret; 132*157ce8f3SChen-Yu Tsai 133*157ce8f3SChen-Yu Tsai ops = cfg->ops ?: &i2c_of_probe_dummy_ops; 134*157ce8f3SChen-Yu Tsai type = cfg->type; 135*157ce8f3SChen-Yu Tsai 136*157ce8f3SChen-Yu Tsai struct device_node *i2c_node __free(device_node) = i2c_of_probe_get_i2c_node(dev, type); 137*157ce8f3SChen-Yu Tsai if (!i2c_node) 138*157ce8f3SChen-Yu Tsai return -ENODEV; 139*157ce8f3SChen-Yu Tsai 140*157ce8f3SChen-Yu Tsai /* 141*157ce8f3SChen-Yu Tsai * If any devices of the given "type" are already enabled then this function is a no-op. 142*157ce8f3SChen-Yu Tsai * Either the device tree hasn't been modified to work with this probe function, or the 143*157ce8f3SChen-Yu Tsai * function had already run before and enabled some component. 144*157ce8f3SChen-Yu Tsai */ 145*157ce8f3SChen-Yu Tsai for_each_child_of_node_with_prefix(i2c_node, node, type) 146*157ce8f3SChen-Yu Tsai if (of_device_is_available(node)) 147*157ce8f3SChen-Yu Tsai return 0; 148*157ce8f3SChen-Yu Tsai 149*157ce8f3SChen-Yu Tsai i2c = of_get_i2c_adapter_by_node(i2c_node); 150*157ce8f3SChen-Yu Tsai if (!i2c) 151*157ce8f3SChen-Yu Tsai return dev_err_probe(dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n"); 152*157ce8f3SChen-Yu Tsai 153*157ce8f3SChen-Yu Tsai /* Grab and enable resources */ 154*157ce8f3SChen-Yu Tsai ret = 0; 155*157ce8f3SChen-Yu Tsai if (ops->enable) 156*157ce8f3SChen-Yu Tsai ret = ops->enable(dev, i2c_node, ctx); 157*157ce8f3SChen-Yu Tsai if (ret) 158*157ce8f3SChen-Yu Tsai goto out_put_i2c_adapter; 159*157ce8f3SChen-Yu Tsai 160*157ce8f3SChen-Yu Tsai for_each_child_of_node_with_prefix(i2c_node, node, type) { 161*157ce8f3SChen-Yu Tsai union i2c_smbus_data data; 162*157ce8f3SChen-Yu Tsai u32 addr; 163*157ce8f3SChen-Yu Tsai 164*157ce8f3SChen-Yu Tsai if (of_property_read_u32(node, "reg", &addr)) 165*157ce8f3SChen-Yu Tsai continue; 166*157ce8f3SChen-Yu Tsai if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0) 167*157ce8f3SChen-Yu Tsai continue; 168*157ce8f3SChen-Yu Tsai 169*157ce8f3SChen-Yu Tsai /* Found a device that is responding */ 170*157ce8f3SChen-Yu Tsai if (ops->cleanup_early) 171*157ce8f3SChen-Yu Tsai ops->cleanup_early(dev, ctx); 172*157ce8f3SChen-Yu Tsai ret = i2c_of_probe_enable_node(dev, node); 173*157ce8f3SChen-Yu Tsai break; 174*157ce8f3SChen-Yu Tsai } 175*157ce8f3SChen-Yu Tsai 176*157ce8f3SChen-Yu Tsai if (ops->cleanup) 177*157ce8f3SChen-Yu Tsai ops->cleanup(dev, ctx); 178*157ce8f3SChen-Yu Tsai out_put_i2c_adapter: 179*157ce8f3SChen-Yu Tsai i2c_put_adapter(i2c); 180*157ce8f3SChen-Yu Tsai 181*157ce8f3SChen-Yu Tsai return ret; 182*157ce8f3SChen-Yu Tsai } 183*157ce8f3SChen-Yu Tsai EXPORT_SYMBOL_NS_GPL(i2c_of_probe_component, I2C_OF_PROBER); 184