// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * v4l2-i2c - I2C helpers for Video4Linux2
 */

#include <linux/i2c.h>
#include <linux/module.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>

void v4l2_i2c_subdev_unregister(struct v4l2_subdev *sd)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	/*
	 * 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 && !client->dev.of_node && !client->dev.fwnode)
		i2c_unregister_device(client);
}

void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd,
			      struct i2c_client *client,
			      const char *devname, const char *postfix)
{
	if (!devname)
		devname = client->dev.driver->name;
	if (!postfix)
		postfix = "";

	snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
		 i2c_adapter_id(client->adapter), client->addr);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);

void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
			  const struct 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);

/* Load an i2c sub-device. */
struct v4l2_subdev
*v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
			   struct i2c_adapter *adapter,
			   struct i2c_board_info *info,
			   const unsigned short *probe_addrs)
{
	struct v4l2_subdev *sd = NULL;
	struct i2c_client *client;

	if (!v4l2_dev)
		return NULL;

	request_module(I2C_MODULE_PREFIX "%s", info->type);

	/* Create the i2c client */
	if (info->addr == 0 && probe_addrs)
		client = i2c_new_probed_device(adapter, info, probe_addrs,
					       NULL);
	else
		client = i2c_new_device(adapter, info);

	/*
	 * 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 (!client || !client->dev.driver)
		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 = 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 (client && !sd)
		i2c_unregister_device(client);
	return sd;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);

struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
					struct i2c_adapter *adapter,
					const char *client_type,
					u8 addr,
					const unsigned short *probe_addrs)
{
	struct i2c_board_info info;

	/*
	 * 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;

	return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info,
					 probe_addrs);
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);

/* Return i2c client address of v4l2_subdev. */
unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return client ? client->addr : I2C_CLIENT_END;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);

/*
 * Return a list of I2C tuner addresses to probe. Use only if the tuner
 * addresses are unknown.
 */
const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
{
	static const unsigned short radio_addrs[] = {
#if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761)
		0x10,
#endif
		0x60,
		I2C_CLIENT_END
	};
	static const unsigned short demod_addrs[] = {
		0x42, 0x43, 0x4a, 0x4b,
		I2C_CLIENT_END
	};
	static const unsigned short tv_addrs[] = {
		0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
		0x60, 0x61, 0x62, 0x63, 0x64,
		I2C_CLIENT_END
	};

	switch (type) {
	case ADDRS_RADIO:
		return radio_addrs;
	case ADDRS_DEMOD:
		return demod_addrs;
	case ADDRS_TV:
		return tv_addrs;
	case ADDRS_TV_WITH_DEMOD:
		return tv_addrs + 4;
	}
	return NULL;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
