xref: /linux/drivers/i2c/i2c-core.h (revision 26ba30221c03364d6ed9910be8da4c1fd871b07b)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * i2c-core.h - interfaces internal to the I2C framework
4  */
5 
6 #include <linux/i2c.h>
7 #include <linux/kconfig.h>
8 #include <linux/rwsem.h>
9 
10 struct i2c_devinfo {
11 	struct list_head	list;
12 	int			busnum;
13 	struct i2c_board_info	board_info;
14 };
15 
16 /* board_lock protects board_list and first_dynamic_bus_num.
17  * only i2c core components are allowed to use these symbols.
18  */
19 extern struct rw_semaphore	__i2c_board_lock;
20 extern struct list_head	__i2c_board_list;
21 extern int		__i2c_first_dynamic_bus_num;
22 
23 int i2c_check_7bit_addr_validity_strict(unsigned short addr);
24 int i2c_dev_irq_from_resources(const struct resource *resources,
25 			       unsigned int num_resources);
26 
27 /*
28  * We only allow atomic transfers for very late communication, e.g. to access a
29  * PMIC when powering down. Atomic transfers are a corner case and not for
30  * generic use!
31  */
32 static inline bool i2c_in_atomic_xfer_mode(void)
33 {
34 	return system_state > SYSTEM_RUNNING &&
35 	       (IS_ENABLED(CONFIG_PREEMPT_COUNT) ? !preemptible() : irqs_disabled());
36 }
37 
38 static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap)
39 {
40 	int ret = 0;
41 
42 	if (i2c_in_atomic_xfer_mode()) {
43 		WARN(!adap->algo->master_xfer_atomic && !adap->algo->smbus_xfer_atomic,
44 		     "No atomic I2C transfer handler for '%s'\n", dev_name(&adap->dev));
45 		ret = i2c_trylock_bus(adap, I2C_LOCK_SEGMENT) ? 0 : -EAGAIN;
46 	} else {
47 		i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
48 	}
49 
50 	return ret;
51 }
52 
53 static inline int __i2c_check_suspended(struct i2c_adapter *adap)
54 {
55 	if (test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags)) {
56 		if (!test_and_set_bit(I2C_ALF_SUSPEND_REPORTED, &adap->locked_flags))
57 			dev_WARN(&adap->dev, "Transfer while suspended\n");
58 		return -ESHUTDOWN;
59 	}
60 
61 	return 0;
62 }
63 
64 #ifdef CONFIG_ACPI
65 void i2c_acpi_register_devices(struct i2c_adapter *adap);
66 
67 int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable);
68 #else /* CONFIG_ACPI */
69 static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
70 
71 static inline int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable)
72 {
73 	return 0;
74 }
75 #endif /* CONFIG_ACPI */
76 extern struct notifier_block i2c_acpi_notifier;
77 
78 #ifdef CONFIG_ACPI_I2C_OPREGION
79 int i2c_acpi_install_space_handler(struct i2c_adapter *adapter);
80 void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter);
81 #else /* CONFIG_ACPI_I2C_OPREGION */
82 static inline int i2c_acpi_install_space_handler(struct i2c_adapter *adapter) { return 0; }
83 static inline void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter) { }
84 #endif /* CONFIG_ACPI_I2C_OPREGION */
85 
86 #ifdef CONFIG_OF
87 void of_i2c_register_devices(struct i2c_adapter *adap);
88 const struct of_device_id *i2c_of_match_device(const struct of_device_id *matches,
89 					       struct i2c_client *client);
90 
91 #else
92 static inline void of_i2c_register_devices(struct i2c_adapter *adap) { }
93 static inline
94 const struct of_device_id *i2c_of_match_device(const struct of_device_id *matches,
95 					       struct i2c_client *client)
96 {
97 	return NULL;
98 }
99 #endif
100 extern struct notifier_block i2c_of_notifier;
101 
102 #if IS_ENABLED(CONFIG_I2C_SMBUS)
103 int i2c_setup_smbus_alert(struct i2c_adapter *adap);
104 #else
105 static inline int i2c_setup_smbus_alert(struct i2c_adapter *adap)
106 {
107 	return 0;
108 }
109 #endif
110