blob: 9fb38e99a6c610ec3b9d518d48abd7182b0658bf [file] [log] [blame]
Wolfram Sang5bf4fa72017-05-23 11:50:58 +02001/*
2 * Linux I2C core OF support code
3 *
4 * Copyright (C) 2008 Jochen Friedrich <jochen@scram.de>
5 * based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
6 *
Wolfram Sanga1671af2018-01-18 13:11:33 +01007 * Copyright (C) 2013, 2018 Wolfram Sang <wsa@the-dreams.de>
Wolfram Sang5bf4fa72017-05-23 11:50:58 +02008 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <dt-bindings/i2c/i2c.h>
16#include <linux/device.h>
17#include <linux/err.h>
18#include <linux/i2c.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22
23#include "i2c-core.h"
24
25static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
26 struct device_node *node)
27{
Wolfram Sangc49b0e02018-01-18 13:11:31 +010028 struct i2c_client *client;
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020029 struct i2c_board_info info = {};
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020030 u32 addr;
Wolfram Sanga1671af2018-01-18 13:11:33 +010031 int ret;
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020032
Rob Herring453a2372017-07-18 16:43:06 -050033 dev_dbg(&adap->dev, "of_i2c: register %pOF\n", node);
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020034
35 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
Rob Herring453a2372017-07-18 16:43:06 -050036 dev_err(&adap->dev, "of_i2c: modalias failure on %pOF\n",
37 node);
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020038 return ERR_PTR(-EINVAL);
39 }
40
Wolfram Sanga1671af2018-01-18 13:11:33 +010041 ret = of_property_read_u32(node, "reg", &addr);
42 if (ret) {
Rob Herring453a2372017-07-18 16:43:06 -050043 dev_err(&adap->dev, "of_i2c: invalid reg on %pOF\n", node);
Wolfram Sanga1671af2018-01-18 13:11:33 +010044 return ERR_PTR(ret);
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020045 }
46
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020047 if (addr & I2C_TEN_BIT_ADDRESS) {
48 addr &= ~I2C_TEN_BIT_ADDRESS;
49 info.flags |= I2C_CLIENT_TEN;
50 }
51
52 if (addr & I2C_OWN_SLAVE_ADDRESS) {
53 addr &= ~I2C_OWN_SLAVE_ADDRESS;
54 info.flags |= I2C_CLIENT_SLAVE;
55 }
56
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020057 info.addr = addr;
Boris Brezillon04782262018-03-25 14:49:02 +020058 info.of_node = node;
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020059
60 if (of_property_read_bool(node, "host-notify"))
61 info.flags |= I2C_CLIENT_HOST_NOTIFY;
62
63 if (of_get_property(node, "wakeup-source", NULL))
64 info.flags |= I2C_CLIENT_WAKE;
65
Wolfram Sangc49b0e02018-01-18 13:11:31 +010066 client = i2c_new_device(adap, &info);
67 if (!client) {
Rob Herring453a2372017-07-18 16:43:06 -050068 dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020069 return ERR_PTR(-EINVAL);
70 }
Wolfram Sangc49b0e02018-01-18 13:11:31 +010071 return client;
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020072}
73
74void of_i2c_register_devices(struct i2c_adapter *adap)
75{
76 struct device_node *bus, *node;
77 struct i2c_client *client;
78
79 /* Only register child devices if the adapter has a node pointer set */
80 if (!adap->dev.of_node)
81 return;
82
83 dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
84
85 bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
86 if (!bus)
87 bus = of_node_get(adap->dev.of_node);
88
89 for_each_available_child_of_node(bus, node) {
90 if (of_node_test_and_set_flag(node, OF_POPULATED))
91 continue;
92
93 client = of_i2c_register_device(adap, node);
94 if (IS_ERR(client)) {
Wolfram Sangf1c87ce2018-01-18 13:11:29 +010095 dev_err(&adap->dev,
Rob Herring453a2372017-07-18 16:43:06 -050096 "Failed to create I2C device for %pOF\n",
97 node);
Wolfram Sang5bf4fa72017-05-23 11:50:58 +020098 of_node_clear_flag(node, OF_POPULATED);
99 }
100 }
101
102 of_node_put(bus);
103}
104
105static int of_dev_node_match(struct device *dev, void *data)
106{
107 return dev->of_node == data;
108}
109
110/* must call put_device() when done with returned i2c_client device */
111struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
112{
113 struct device *dev;
114 struct i2c_client *client;
115
116 dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
117 if (!dev)
118 return NULL;
119
120 client = i2c_verify_client(dev);
121 if (!client)
122 put_device(dev);
123
124 return client;
125}
126EXPORT_SYMBOL(of_find_i2c_device_by_node);
127
128/* must call put_device() when done with returned i2c_adapter device */
129struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
130{
131 struct device *dev;
132 struct i2c_adapter *adapter;
133
134 dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
135 if (!dev)
136 return NULL;
137
138 adapter = i2c_verify_adapter(dev);
139 if (!adapter)
140 put_device(dev);
141
142 return adapter;
143}
144EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
145
146/* must call i2c_put_adapter() when done with returned i2c_adapter device */
147struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node)
148{
149 struct i2c_adapter *adapter;
150
151 adapter = of_find_i2c_adapter_by_node(node);
152 if (!adapter)
153 return NULL;
154
155 if (!try_module_get(adapter->owner)) {
156 put_device(&adapter->dev);
157 adapter = NULL;
158 }
159
160 return adapter;
161}
162EXPORT_SYMBOL(of_get_i2c_adapter_by_node);
163
164static const struct of_device_id*
165i2c_of_match_device_sysfs(const struct of_device_id *matches,
166 struct i2c_client *client)
167{
168 const char *name;
169
170 for (; matches->compatible[0]; matches++) {
171 /*
172 * Adding devices through the i2c sysfs interface provides us
173 * a string to match which may be compatible with the device
174 * tree compatible strings, however with no actual of_node the
175 * of_match_device() will not match
176 */
177 if (sysfs_streq(client->name, matches->compatible))
178 return matches;
179
180 name = strchr(matches->compatible, ',');
181 if (!name)
182 name = matches->compatible;
183 else
184 name++;
185
186 if (sysfs_streq(client->name, name))
187 return matches;
188 }
189
190 return NULL;
191}
192
193const struct of_device_id
194*i2c_of_match_device(const struct of_device_id *matches,
195 struct i2c_client *client)
196{
197 const struct of_device_id *match;
198
199 if (!(client && matches))
200 return NULL;
201
202 match = of_match_device(matches, &client->dev);
203 if (match)
204 return match;
205
206 return i2c_of_match_device_sysfs(matches, client);
207}
208EXPORT_SYMBOL_GPL(i2c_of_match_device);
209
210#if IS_ENABLED(CONFIG_OF_DYNAMIC)
211static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
212 void *arg)
213{
214 struct of_reconfig_data *rd = arg;
215 struct i2c_adapter *adap;
216 struct i2c_client *client;
217
218 switch (of_reconfig_get_state_change(action, rd)) {
219 case OF_RECONFIG_CHANGE_ADD:
220 adap = of_find_i2c_adapter_by_node(rd->dn->parent);
221 if (adap == NULL)
222 return NOTIFY_OK; /* not for us */
223
224 if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) {
225 put_device(&adap->dev);
226 return NOTIFY_OK;
227 }
228
229 client = of_i2c_register_device(adap, rd->dn);
230 put_device(&adap->dev);
231
232 if (IS_ERR(client)) {
Rob Herring453a2372017-07-18 16:43:06 -0500233 dev_err(&adap->dev, "failed to create client for '%pOF'\n",
234 rd->dn);
Wolfram Sang5bf4fa72017-05-23 11:50:58 +0200235 of_node_clear_flag(rd->dn, OF_POPULATED);
236 return notifier_from_errno(PTR_ERR(client));
237 }
238 break;
239 case OF_RECONFIG_CHANGE_REMOVE:
240 /* already depopulated? */
241 if (!of_node_check_flag(rd->dn, OF_POPULATED))
242 return NOTIFY_OK;
243
244 /* find our device by node */
245 client = of_find_i2c_device_by_node(rd->dn);
246 if (client == NULL)
247 return NOTIFY_OK; /* no? not meant for us */
248
249 /* unregister takes one ref away */
250 i2c_unregister_device(client);
251
252 /* and put the reference of the find */
253 put_device(&client->dev);
254 break;
255 }
256
257 return NOTIFY_OK;
258}
259
260struct notifier_block i2c_of_notifier = {
261 .notifier_call = of_i2c_notify,
262};
263#endif /* CONFIG_OF_DYNAMIC */