aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/i2c-core.c59
-rw-r--r--include/linux/i2c.h6
2 files changed, 64 insertions, 1 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index cd3fcb85ca7f..96da22e9a5a4 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -296,6 +296,50 @@ void i2c_unregister_device(struct i2c_client *client)
296EXPORT_SYMBOL_GPL(i2c_unregister_device); 296EXPORT_SYMBOL_GPL(i2c_unregister_device);
297 297
298 298
299static int dummy_nop(struct i2c_client *client)
300{
301 return 0;
302}
303
304static struct i2c_driver dummy_driver = {
305 .driver.name = "dummy",
306 .probe = dummy_nop,
307 .remove = dummy_nop,
308};
309
310/**
311 * i2c_new_dummy - return a new i2c device bound to a dummy driver
312 * @adapter: the adapter managing the device
313 * @address: seven bit address to be used
314 * @type: optional label used for i2c_client.name
315 * Context: can sleep
316 *
317 * This returns an I2C client bound to the "dummy" driver, intended for use
318 * with devices that consume multiple addresses. Examples of such chips
319 * include various EEPROMS (like 24c04 and 24c08 models).
320 *
321 * These dummy devices have two main uses. First, most I2C and SMBus calls
322 * except i2c_transfer() need a client handle; the dummy will be that handle.
323 * And second, this prevents the specified address from being bound to a
324 * different driver.
325 *
326 * This returns the new i2c client, which should be saved for later use with
327 * i2c_unregister_device(); or NULL to indicate an error.
328 */
329struct i2c_client *
330i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type)
331{
332 struct i2c_board_info info = {
333 .driver_name = "dummy",
334 .addr = address,
335 };
336
337 if (type)
338 strlcpy(info.type, type, sizeof info.type);
339 return i2c_new_device(adapter, &info);
340}
341EXPORT_SYMBOL_GPL(i2c_new_dummy);
342
299/* ------------------------------------------------------------------------- */ 343/* ------------------------------------------------------------------------- */
300 344
301/* I2C bus adapters -- one roots each I2C or SMBUS segment */ 345/* I2C bus adapters -- one roots each I2C or SMBUS segment */
@@ -841,11 +885,24 @@ static int __init i2c_init(void)
841 retval = bus_register(&i2c_bus_type); 885 retval = bus_register(&i2c_bus_type);
842 if (retval) 886 if (retval)
843 return retval; 887 return retval;
844 return class_register(&i2c_adapter_class); 888 retval = class_register(&i2c_adapter_class);
889 if (retval)
890 goto bus_err;
891 retval = i2c_add_driver(&dummy_driver);
892 if (retval)
893 goto class_err;
894 return 0;
895
896class_err:
897 class_unregister(&i2c_adapter_class);
898bus_err:
899 bus_unregister(&i2c_bus_type);
900 return retval;
845} 901}
846 902
847static void __exit i2c_exit(void) 903static void __exit i2c_exit(void)
848{ 904{
905 i2c_del_driver(&dummy_driver);
849 class_unregister(&i2c_adapter_class); 906 class_unregister(&i2c_adapter_class);
850 bus_unregister(&i2c_bus_type); 907 bus_unregister(&i2c_bus_type);
851} 908}
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 731928ae972c..76014f8f3c60 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -259,6 +259,12 @@ i2c_new_probed_device(struct i2c_adapter *adap,
259 struct i2c_board_info *info, 259 struct i2c_board_info *info,
260 unsigned short const *addr_list); 260 unsigned short const *addr_list);
261 261
262/* For devices that use several addresses, use i2c_new_dummy() to make
263 * client handles for the extra addresses.
264 */
265extern struct i2c_client *
266i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type);
267
262extern void i2c_unregister_device(struct i2c_client *); 268extern void i2c_unregister_device(struct i2c_client *);
263 269
264/* Mainboard arch_initcall() code should register all its I2C devices. 270/* Mainboard arch_initcall() code should register all its I2C devices.