1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Linux I2C core slave support code 4 * 5 * Copyright (C) 2014 by Wolfram Sang <wsa@sang-engineering.com> 6 */ 7 8 #include <dt-bindings/i2c/i2c.h> 9 #include <linux/acpi.h> 10 #include <linux/device.h> 11 #include <linux/err.h> 12 #include <linux/i2c.h> 13 #include <linux/of.h> 14 15 #include "i2c-core.h" 16 17 int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) 18 { 19 int ret; 20 21 if (!client || !slave_cb) { 22 WARN(1, "insufficient data\n"); 23 return -EINVAL; 24 } 25 26 if (!(client->flags & I2C_CLIENT_SLAVE)) 27 dev_warn(&client->dev, "%s: client slave flag not set. You might see address collisions\n", 28 __func__); 29 30 if (!(client->flags & I2C_CLIENT_TEN)) { 31 /* Enforce stricter address checking */ 32 ret = i2c_check_7bit_addr_validity_strict(client->addr); 33 if (ret) { 34 dev_err(&client->dev, "%s: invalid address\n", __func__); 35 return ret; 36 } 37 } 38 39 if (!client->adapter->algo->reg_slave) { 40 dev_err(&client->dev, "%s: not supported by adapter\n", __func__); 41 return -EOPNOTSUPP; 42 } 43 44 client->slave_cb = slave_cb; 45 46 i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER); 47 ret = client->adapter->algo->reg_slave(client); 48 i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER); 49 50 if (ret) { 51 client->slave_cb = NULL; 52 dev_err(&client->dev, "%s: adapter returned error %d\n", __func__, ret); 53 } 54 55 return ret; 56 } 57 EXPORT_SYMBOL_GPL(i2c_slave_register); 58 59 int i2c_slave_unregister(struct i2c_client *client) 60 { 61 int ret; 62 63 if (!client->adapter->algo->unreg_slave) { 64 dev_err(&client->dev, "%s: not supported by adapter\n", __func__); 65 return -EOPNOTSUPP; 66 } 67 68 i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER); 69 ret = client->adapter->algo->unreg_slave(client); 70 i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER); 71 72 if (ret == 0) 73 client->slave_cb = NULL; 74 else 75 dev_err(&client->dev, "%s: adapter returned error %d\n", __func__, ret); 76 77 return ret; 78 } 79 EXPORT_SYMBOL_GPL(i2c_slave_unregister); 80 81 /** 82 * i2c_detect_slave_mode - detect operation mode 83 * @dev: The device owning the bus 84 * 85 * This checks the device nodes for an I2C slave by checking the address 86 * used in the reg property. If the address match the I2C_OWN_SLAVE_ADDRESS 87 * flag this means the device is configured to act as a I2C slave and it will 88 * be listening at that address. 89 * 90 * Returns true if an I2C own slave address is detected, otherwise returns 91 * false. 92 */ 93 bool i2c_detect_slave_mode(struct device *dev) 94 { 95 if (IS_BUILTIN(CONFIG_OF) && dev->of_node) { 96 struct device_node *child; 97 u32 reg; 98 99 for_each_child_of_node(dev->of_node, child) { 100 of_property_read_u32(child, "reg", ®); 101 if (reg & I2C_OWN_SLAVE_ADDRESS) { 102 of_node_put(child); 103 return true; 104 } 105 } 106 } else if (IS_BUILTIN(CONFIG_ACPI) && ACPI_HANDLE(dev)) { 107 dev_dbg(dev, "ACPI slave is not supported yet\n"); 108 } 109 return false; 110 } 111 EXPORT_SYMBOL_GPL(i2c_detect_slave_mode); 112