/* * We need to unregister the i2c client * explicitly. We cannot rely on * i2c_del_adapter to always unregister * clients for us, since if the i2c bus is a * platform bus, then it is never deleted. * * Device tree or ACPI based devices must not * be unregistered as they have not been * registered by us, and would not be * re-created by just probing the V4L2 driver.
*/ if (client && !dev_fwnode(&client->dev))
i2c_unregister_device(client);
}
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, conststruct v4l2_subdev_ops *ops)
{
v4l2_subdev_init(sd, ops);
sd->flags |= V4L2_SUBDEV_FL_IS_I2C; /* the owner is the same as the i2c_client's driver owner */
sd->owner = client->dev.driver->owner;
sd->dev = &client->dev; /* i2c_client and v4l2_subdev point to one another */
v4l2_set_subdevdata(sd, client);
i2c_set_clientdata(client, sd);
v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
/* * Note: by loading the module first we are certain that c->driver * will be set if the driver was found. If the module was not loaded * first, then the i2c core tries to delay-load the module for us, * and then c->driver is still NULL until the module is finally * loaded. This delay-load mechanism doesn't work if other drivers * want to use the i2c device, so explicitly loading the module * is the best alternative.
*/ if (!i2c_client_has_driver(client)) goto error;
/* Lock the module so we can safely get the v4l2_subdev pointer */ if (!try_module_get(client->dev.driver->owner)) goto error;
sd = i2c_get_clientdata(client);
/* * Register with the v4l2_device which increases the module's * use count as well.
*/ if (__v4l2_device_register_subdev(v4l2_dev, sd, sd->owner))
sd = NULL; /* Decrease the module use count to match the first try_module_get. */
module_put(client->dev.driver->owner);
error: /* * If we have a client but no subdev, then something went wrong and * we must unregister the client.
*/ if (!IS_ERR(client) && !sd)
i2c_unregister_device(client); return sd;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
/* * Setup the i2c board info with the device type and * the device address.
*/
memset(&info, 0, sizeof(info));
strscpy(info.type, client_type, sizeof(info.type));
info.addr = addr;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.