Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9f1373b authored by David Brownell's avatar David Brownell Committed by Jean Delvare
Browse files

i2c: Add i2c_new_dummy() utility



This adds a i2c_new_dummy() primitive to help work with devices
that consume multiple addresses, which include many I2C eeproms
and at least one RTC.

Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 0b987dcd
Loading
Loading
Loading
Loading
+58 −1
Original line number Diff line number Diff line
@@ -296,6 +296,50 @@ void i2c_unregister_device(struct i2c_client *client)
EXPORT_SYMBOL_GPL(i2c_unregister_device);


static int dummy_nop(struct i2c_client *client)
{
	return 0;
}

static struct i2c_driver dummy_driver = {
	.driver.name	= "dummy",
	.probe		= dummy_nop,
	.remove		= dummy_nop,
};

/**
 * i2c_new_dummy - return a new i2c device bound to a dummy driver
 * @adapter: the adapter managing the device
 * @address: seven bit address to be used
 * @type: optional label used for i2c_client.name
 * Context: can sleep
 *
 * This returns an I2C client bound to the "dummy" driver, intended for use
 * with devices that consume multiple addresses.  Examples of such chips
 * include various EEPROMS (like 24c04 and 24c08 models).
 *
 * These dummy devices have two main uses.  First, most I2C and SMBus calls
 * except i2c_transfer() need a client handle; the dummy will be that handle.
 * And second, this prevents the specified address from being bound to a
 * different driver.
 *
 * This returns the new i2c client, which should be saved for later use with
 * i2c_unregister_device(); or NULL to indicate an error.
 */
struct i2c_client *
i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type)
{
	struct i2c_board_info info = {
		.driver_name	= "dummy",
		.addr		= address,
	};

	if (type)
		strlcpy(info.type, type, sizeof info.type);
	return i2c_new_device(adapter, &info);
}
EXPORT_SYMBOL_GPL(i2c_new_dummy);

/* ------------------------------------------------------------------------- */

/* I2C bus adapters -- one roots each I2C or SMBUS segment */
@@ -841,11 +885,24 @@ static int __init i2c_init(void)
	retval = bus_register(&i2c_bus_type);
	if (retval)
		return retval;
	return class_register(&i2c_adapter_class);
	retval = class_register(&i2c_adapter_class);
	if (retval)
		goto bus_err;
	retval = i2c_add_driver(&dummy_driver);
	if (retval)
		goto class_err;
	return 0;

class_err:
	class_unregister(&i2c_adapter_class);
bus_err:
	bus_unregister(&i2c_bus_type);
	return retval;
}

static void __exit i2c_exit(void)
{
	i2c_del_driver(&dummy_driver);
	class_unregister(&i2c_adapter_class);
	bus_unregister(&i2c_bus_type);
}
+6 −0
Original line number Diff line number Diff line
@@ -259,6 +259,12 @@ i2c_new_probed_device(struct i2c_adapter *adap,
		      struct i2c_board_info *info,
		      unsigned short const *addr_list);

/* For devices that use several addresses, use i2c_new_dummy() to make
 * client handles for the extra addresses.
 */
extern struct i2c_client *
i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type);

extern void i2c_unregister_device(struct i2c_client *);

/* Mainboard arch_initcall() code should register all its I2C devices.