xref: /openbmc/linux/drivers/i2c/muxes/i2c-demux-pinctrl.c (revision aad29a73199b7fbccfbabea3f1ee627ad1924f52)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Pinctrl based I2C DeMultiplexer
4   *
5   * Copyright (C) 2015-16 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
6   * Copyright (C) 2015-16 by Renesas Electronics Corporation
7   *
8   * See the bindings doc for DTS setup and the sysfs doc for usage information.
9   * (look for filenames containing 'i2c-demux-pinctrl' in Documentation/)
10   */
11  
12  #include <linux/i2c.h>
13  #include <linux/init.h>
14  #include <linux/module.h>
15  #include <linux/of.h>
16  #include <linux/pinctrl/consumer.h>
17  #include <linux/platform_device.h>
18  #include <linux/pm_runtime.h>
19  #include <linux/slab.h>
20  #include <linux/sysfs.h>
21  
22  struct i2c_demux_pinctrl_chan {
23  	struct device_node *parent_np;
24  	struct i2c_adapter *parent_adap;
25  	struct of_changeset chgset;
26  };
27  
28  struct i2c_demux_pinctrl_priv {
29  	int cur_chan;
30  	int num_chan;
31  	struct device *dev;
32  	const char *bus_name;
33  	struct i2c_adapter cur_adap;
34  	struct i2c_algorithm algo;
35  	struct i2c_demux_pinctrl_chan chan[];
36  };
37  
i2c_demux_master_xfer(struct i2c_adapter * adap,struct i2c_msg msgs[],int num)38  static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
39  {
40  	struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
41  	struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
42  
43  	return __i2c_transfer(parent, msgs, num);
44  }
45  
i2c_demux_functionality(struct i2c_adapter * adap)46  static u32 i2c_demux_functionality(struct i2c_adapter *adap)
47  {
48  	struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
49  	struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
50  
51  	return parent->algo->functionality(parent);
52  }
53  
i2c_demux_activate_master(struct i2c_demux_pinctrl_priv * priv,u32 new_chan)54  static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
55  {
56  	struct i2c_adapter *adap;
57  	struct pinctrl *p;
58  	int ret;
59  
60  	ret = of_changeset_apply(&priv->chan[new_chan].chgset);
61  	if (ret)
62  		goto err;
63  
64  	adap = of_get_i2c_adapter_by_node(priv->chan[new_chan].parent_np);
65  	if (!adap) {
66  		ret = -ENODEV;
67  		goto err_with_revert;
68  	}
69  
70  	/*
71  	 * Check if there are pinctrl states at all. Note: we cant' use
72  	 * devm_pinctrl_get_select() because we need to distinguish between
73  	 * the -ENODEV from devm_pinctrl_get() and pinctrl_lookup_state().
74  	 */
75  	p = devm_pinctrl_get(adap->dev.parent);
76  	if (IS_ERR(p)) {
77  		ret = PTR_ERR(p);
78  		/* continue if just no pinctrl states (e.g. i2c-gpio), otherwise exit */
79  		if (ret != -ENODEV)
80  			goto err_with_put;
81  	} else {
82  		/* there are states. check and use them */
83  		struct pinctrl_state *s = pinctrl_lookup_state(p, priv->bus_name);
84  
85  		if (IS_ERR(s)) {
86  			ret = PTR_ERR(s);
87  			goto err_with_put;
88  		}
89  		ret = pinctrl_select_state(p, s);
90  		if (ret < 0)
91  			goto err_with_put;
92  	}
93  
94  	priv->chan[new_chan].parent_adap = adap;
95  	priv->cur_chan = new_chan;
96  
97  	/* Now fill out current adapter structure. cur_chan must be up to date */
98  	priv->algo.master_xfer = i2c_demux_master_xfer;
99  	if (adap->algo->master_xfer_atomic)
100  		priv->algo.master_xfer_atomic = i2c_demux_master_xfer;
101  	priv->algo.functionality = i2c_demux_functionality;
102  
103  	snprintf(priv->cur_adap.name, sizeof(priv->cur_adap.name),
104  		 "i2c-demux (master i2c-%d)", i2c_adapter_id(adap));
105  	priv->cur_adap.owner = THIS_MODULE;
106  	priv->cur_adap.algo = &priv->algo;
107  	priv->cur_adap.algo_data = priv;
108  	priv->cur_adap.dev.parent = &adap->dev;
109  	priv->cur_adap.class = adap->class;
110  	priv->cur_adap.retries = adap->retries;
111  	priv->cur_adap.timeout = adap->timeout;
112  	priv->cur_adap.quirks = adap->quirks;
113  	priv->cur_adap.dev.of_node = priv->dev->of_node;
114  	ret = i2c_add_adapter(&priv->cur_adap);
115  	if (ret < 0)
116  		goto err_with_put;
117  
118  	return 0;
119  
120   err_with_put:
121  	i2c_put_adapter(adap);
122   err_with_revert:
123  	of_changeset_revert(&priv->chan[new_chan].chgset);
124   err:
125  	dev_err(priv->dev, "failed to setup demux-adapter %d (%d)\n", new_chan, ret);
126  	priv->cur_chan = -EINVAL;
127  	return ret;
128  }
129  
i2c_demux_deactivate_master(struct i2c_demux_pinctrl_priv * priv)130  static int i2c_demux_deactivate_master(struct i2c_demux_pinctrl_priv *priv)
131  {
132  	int ret, cur = priv->cur_chan;
133  
134  	if (cur < 0)
135  		return 0;
136  
137  	i2c_del_adapter(&priv->cur_adap);
138  	i2c_put_adapter(priv->chan[cur].parent_adap);
139  
140  	ret = of_changeset_revert(&priv->chan[cur].chgset);
141  
142  	priv->chan[cur].parent_adap = NULL;
143  	priv->cur_chan = -EINVAL;
144  
145  	return ret;
146  }
147  
i2c_demux_change_master(struct i2c_demux_pinctrl_priv * priv,u32 new_chan)148  static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
149  {
150  	int ret;
151  
152  	if (new_chan == priv->cur_chan)
153  		return 0;
154  
155  	ret = i2c_demux_deactivate_master(priv);
156  	if (ret)
157  		return ret;
158  
159  	return i2c_demux_activate_master(priv, new_chan);
160  }
161  
available_masters_show(struct device * dev,struct device_attribute * attr,char * buf)162  static ssize_t available_masters_show(struct device *dev,
163  				      struct device_attribute *attr,
164  				      char *buf)
165  {
166  	struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
167  	int count = 0, i;
168  
169  	for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++)
170  		count += scnprintf(buf + count, PAGE_SIZE - count, "%d:%pOF%c",
171  				   i, priv->chan[i].parent_np,
172  				   i == priv->num_chan - 1 ? '\n' : ' ');
173  
174  	return count;
175  }
176  static DEVICE_ATTR_RO(available_masters);
177  
current_master_show(struct device * dev,struct device_attribute * attr,char * buf)178  static ssize_t current_master_show(struct device *dev,
179  				   struct device_attribute *attr,
180  				   char *buf)
181  {
182  	struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
183  
184  	return sprintf(buf, "%d\n", priv->cur_chan);
185  }
186  
current_master_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)187  static ssize_t current_master_store(struct device *dev,
188  				    struct device_attribute *attr,
189  				    const char *buf, size_t count)
190  {
191  	struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
192  	unsigned int val;
193  	int ret;
194  
195  	ret = kstrtouint(buf, 0, &val);
196  	if (ret < 0)
197  		return ret;
198  
199  	if (val >= priv->num_chan)
200  		return -EINVAL;
201  
202  	ret = i2c_demux_change_master(priv, val);
203  
204  	return ret < 0 ? ret : count;
205  }
206  static DEVICE_ATTR_RW(current_master);
207  
i2c_demux_pinctrl_probe(struct platform_device * pdev)208  static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
209  {
210  	struct device_node *np = pdev->dev.of_node;
211  	struct i2c_demux_pinctrl_priv *priv;
212  	struct property *props;
213  	int num_chan, i, j, err;
214  
215  	num_chan = of_count_phandle_with_args(np, "i2c-parent", NULL);
216  	if (num_chan < 2) {
217  		dev_err(&pdev->dev, "Need at least two I2C masters to switch\n");
218  		return -EINVAL;
219  	}
220  
221  	priv = devm_kzalloc(&pdev->dev, struct_size(priv, chan, num_chan),
222  			    GFP_KERNEL);
223  
224  	props = devm_kcalloc(&pdev->dev, num_chan, sizeof(*props), GFP_KERNEL);
225  
226  	if (!priv || !props)
227  		return -ENOMEM;
228  
229  	err = of_property_read_string(np, "i2c-bus-name", &priv->bus_name);
230  	if (err)
231  		return err;
232  
233  	for (i = 0; i < num_chan; i++) {
234  		struct device_node *adap_np;
235  
236  		adap_np = of_parse_phandle(np, "i2c-parent", i);
237  		if (!adap_np) {
238  			dev_err(&pdev->dev, "can't get phandle for parent %d\n", i);
239  			err = -ENOENT;
240  			goto err_rollback;
241  		}
242  		priv->chan[i].parent_np = adap_np;
243  
244  		props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL);
245  		props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
246  		if (!props[i].name || !props[i].value) {
247  			err = -ENOMEM;
248  			goto err_rollback;
249  		}
250  		props[i].length = 3;
251  
252  		of_changeset_init(&priv->chan[i].chgset);
253  		of_changeset_update_property(&priv->chan[i].chgset, adap_np, &props[i]);
254  	}
255  
256  	priv->num_chan = num_chan;
257  	priv->dev = &pdev->dev;
258  
259  	platform_set_drvdata(pdev, priv);
260  
261  	pm_runtime_no_callbacks(&pdev->dev);
262  
263  	/* switch to first parent as active master */
264  	err = i2c_demux_activate_master(priv, 0);
265  	if (err)
266  		goto err_rollback;
267  
268  	err = device_create_file(&pdev->dev, &dev_attr_available_masters);
269  	if (err)
270  		goto err_rollback_activation;
271  
272  	err = device_create_file(&pdev->dev, &dev_attr_current_master);
273  	if (err)
274  		goto err_rollback_available;
275  
276  	return 0;
277  
278  err_rollback_available:
279  	device_remove_file(&pdev->dev, &dev_attr_available_masters);
280  err_rollback_activation:
281  	i2c_demux_deactivate_master(priv);
282  err_rollback:
283  	for (j = 0; j < i; j++) {
284  		of_node_put(priv->chan[j].parent_np);
285  		of_changeset_destroy(&priv->chan[j].chgset);
286  	}
287  
288  	return err;
289  }
290  
i2c_demux_pinctrl_remove(struct platform_device * pdev)291  static void i2c_demux_pinctrl_remove(struct platform_device *pdev)
292  {
293  	struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
294  	int i;
295  
296  	device_remove_file(&pdev->dev, &dev_attr_current_master);
297  	device_remove_file(&pdev->dev, &dev_attr_available_masters);
298  
299  	i2c_demux_deactivate_master(priv);
300  
301  	for (i = 0; i < priv->num_chan; i++) {
302  		of_node_put(priv->chan[i].parent_np);
303  		of_changeset_destroy(&priv->chan[i].chgset);
304  	}
305  }
306  
307  static const struct of_device_id i2c_demux_pinctrl_of_match[] = {
308  	{ .compatible = "i2c-demux-pinctrl", },
309  	{},
310  };
311  MODULE_DEVICE_TABLE(of, i2c_demux_pinctrl_of_match);
312  
313  static struct platform_driver i2c_demux_pinctrl_driver = {
314  	.driver	= {
315  		.name = "i2c-demux-pinctrl",
316  		.of_match_table = i2c_demux_pinctrl_of_match,
317  	},
318  	.probe	= i2c_demux_pinctrl_probe,
319  	.remove_new = i2c_demux_pinctrl_remove,
320  };
321  module_platform_driver(i2c_demux_pinctrl_driver);
322  
323  MODULE_DESCRIPTION("pinctrl-based I2C demux driver");
324  MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
325  MODULE_LICENSE("GPL v2");
326  MODULE_ALIAS("platform:i2c-demux-pinctrl");
327