/* Probe/reomove functions */ static int mlxcpld_mux_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev); struct i2c_mux_core *muxc; int num, force; struct mlxcpld_mux *data; int err; if (!pdata) return -EINVAL; if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return -ENODEV; muxc = i2c_mux_alloc(adap, &client->dev, CPLD_MUX_MAX_NCHANS, sizeof(*data), 0, mlxcpld_mux_select_chan, mlxcpld_mux_deselect); if (!muxc) return -ENOMEM; data = i2c_mux_priv(muxc); i2c_set_clientdata(client, muxc); data->client = client; data->last_chan = 0; /* force the first selection */ /* Create an adapter for each channel. */ for (num = 0; num < CPLD_MUX_MAX_NCHANS; num++) { if (num >= pdata->num_adaps) /* discard unconfigured channels */ break; force = pdata->adap_ids[num]; err = i2c_mux_add_adapter(muxc, force, num, 0); if (err) goto virt_reg_failed; } return 0; virt_reg_failed: i2c_mux_del_adapters(muxc); return err; }
static int mpu3050_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regmap *regmap; const char *name; struct mpu3050 *mpu3050; int ret; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EOPNOTSUPP; if (id) name = id->name; else return -ENODEV; regmap = devm_regmap_init_i2c(client, &mpu3050_i2c_regmap_config); if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to register i2c regmap %d\n", (int)PTR_ERR(regmap)); return PTR_ERR(regmap); } ret = mpu3050_common_probe(&client->dev, regmap, client->irq, name); if (ret) return ret; /* The main driver is up, now register the I2C mux */ mpu3050 = iio_priv(dev_get_drvdata(&client->dev)); mpu3050->i2cmux = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE, mpu3050_i2c_bypass_select, mpu3050_i2c_bypass_deselect); /* Just fail the mux, there is no point in killing the driver */ if (!mpu3050->i2cmux) dev_err(&client->dev, "failed to allocate I2C mux\n"); else { mpu3050->i2cmux->priv = mpu3050; /* Ignore failure, not critical */ i2c_mux_add_adapter(mpu3050->i2cmux, 0, 0, 0); } return 0; }
/** * inv_mpu_probe() - probe function. * @client: i2c client. * @id: i2c device id. * * Returns 0 on success, a negative error code otherwise. */ static int inv_mpu_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct inv_mpu6050_state *st; int result, chip_type; struct regmap *regmap; const char *name; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EOPNOTSUPP; if (id) { chip_type = (int)id->driver_data; name = id->name; } else if (ACPI_HANDLE(&client->dev)) { name = inv_mpu_match_acpi_device(&client->dev, &chip_type); if (!name) return -ENODEV; } else { return -ENOSYS; } regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config); if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to register i2c regmap %d\n", (int)PTR_ERR(regmap)); return PTR_ERR(regmap); } result = inv_mpu_core_probe(regmap, client->irq, name, NULL, chip_type); if (result < 0) return result; st = iio_priv(dev_get_drvdata(&client->dev)); st->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE, inv_mpu6050_select_bypass, inv_mpu6050_deselect_bypass); if (!st->muxc) { result = -ENOMEM; goto out_unreg_device; } st->muxc->priv = dev_get_drvdata(&client->dev); result = i2c_mux_add_adapter(st->muxc, 0, 0, 0); if (result) goto out_unreg_device; result = inv_mpu_acpi_create_mux_client(client); if (result) goto out_del_mux; return 0; out_del_mux: i2c_mux_del_adapters(st->muxc); out_unreg_device: inv_mpu_core_remove(&client->dev); return result; }
static int i2c_arbitrator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device_node *parent_np; struct i2c_mux_core *muxc; struct i2c_arbitrator_data *arb; enum of_gpio_flags gpio_flags; unsigned long out_init; int ret; /* We only support probing from device tree; no platform_data */ if (!np) { dev_err(dev, "Cannot find device tree node\n"); return -ENODEV; } if (dev_get_platdata(dev)) { dev_err(dev, "Platform data is not supported\n"); return -EINVAL; } muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), I2C_MUX_ARBITRATOR, i2c_arbitrator_select, i2c_arbitrator_deselect); if (!muxc) return -ENOMEM; arb = i2c_mux_priv(muxc); platform_set_drvdata(pdev, muxc); /* Request GPIOs */ ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags); if (!gpio_is_valid(ret)) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error getting our-claim-gpio\n"); return ret; } arb->our_gpio = ret; arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; ret = devm_gpio_request_one(dev, arb->our_gpio, out_init, "our-claim-gpio"); if (ret) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error requesting our-claim-gpio\n"); return ret; } ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags); if (!gpio_is_valid(ret)) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error getting their-claim-gpio\n"); return ret; } arb->their_gpio = ret; arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN, "their-claim-gpio"); if (ret) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error requesting their-claim-gpio\n"); return ret; } /* At the moment we only support a single two master (us + 1 other) */ if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) { dev_err(dev, "Only one other master is supported\n"); return -EINVAL; } /* Arbitration parameters */ if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us)) arb->slew_delay_us = 10; if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us)) arb->wait_retry_us = 3000; if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us)) arb->wait_free_us = 50000; /* Find our parent */ parent_np = of_parse_phandle(np, "i2c-parent", 0); if (!parent_np) { dev_err(dev, "Cannot parse i2c-parent\n"); return -EINVAL; } muxc->parent = of_get_i2c_adapter_by_node(parent_np); of_node_put(parent_np); if (!muxc->parent) { dev_err(dev, "Cannot find parent bus\n"); return -EPROBE_DEFER; } /* Actually add the mux adapter */ ret = i2c_mux_add_adapter(muxc, 0, 0, 0); if (ret) { dev_err(dev, "Failed to add adapter\n"); i2c_put_adapter(muxc->parent); } return ret; }