2 * Pinctrl based I2C DeMultiplexer
4 * Copyright (C) 2015-16 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
5 * Copyright (C) 2015-16 by Renesas Electronics Corporation
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; version 2 of the License.
11 * See the bindings doc for DTS setup and the sysfs doc for usage information.
12 * (look for filenames containing 'i2c-demux-pinctrl' in Documentation/)
15 #include <linux/i2c.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
19 #include <linux/pinctrl/consumer.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
22 #include <linux/sysfs.h>
24 struct i2c_demux_pinctrl_chan
{
25 struct device_node
*parent_np
;
26 struct i2c_adapter
*parent_adap
;
27 struct of_changeset chgset
;
30 struct i2c_demux_pinctrl_priv
{
35 struct i2c_adapter cur_adap
;
36 struct i2c_algorithm algo
;
37 struct i2c_demux_pinctrl_chan chan
[];
40 static struct property status_okay
= { .name
= "status", .length
= 3, .value
= "ok" };
42 static int i2c_demux_master_xfer(struct i2c_adapter
*adap
, struct i2c_msg msgs
[], int num
)
44 struct i2c_demux_pinctrl_priv
*priv
= adap
->algo_data
;
45 struct i2c_adapter
*parent
= priv
->chan
[priv
->cur_chan
].parent_adap
;
47 return __i2c_transfer(parent
, msgs
, num
);
50 static u32
i2c_demux_functionality(struct i2c_adapter
*adap
)
52 struct i2c_demux_pinctrl_priv
*priv
= adap
->algo_data
;
53 struct i2c_adapter
*parent
= priv
->chan
[priv
->cur_chan
].parent_adap
;
55 return parent
->algo
->functionality(parent
);
58 static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv
*priv
, u32 new_chan
)
60 struct i2c_adapter
*adap
;
64 ret
= of_changeset_apply(&priv
->chan
[new_chan
].chgset
);
68 adap
= of_find_i2c_adapter_by_node(priv
->chan
[new_chan
].parent_np
);
74 p
= devm_pinctrl_get_select(adap
->dev
.parent
, priv
->bus_name
);
80 priv
->chan
[new_chan
].parent_adap
= adap
;
81 priv
->cur_chan
= new_chan
;
83 /* Now fill out current adapter structure. cur_chan must be up to date */
84 priv
->algo
.master_xfer
= i2c_demux_master_xfer
;
85 priv
->algo
.functionality
= i2c_demux_functionality
;
87 snprintf(priv
->cur_adap
.name
, sizeof(priv
->cur_adap
.name
),
88 "i2c-demux (master i2c-%d)", i2c_adapter_id(adap
));
89 priv
->cur_adap
.owner
= THIS_MODULE
;
90 priv
->cur_adap
.algo
= &priv
->algo
;
91 priv
->cur_adap
.algo_data
= priv
;
92 priv
->cur_adap
.dev
.parent
= priv
->dev
;
93 priv
->cur_adap
.class = adap
->class;
94 priv
->cur_adap
.retries
= adap
->retries
;
95 priv
->cur_adap
.timeout
= adap
->timeout
;
96 priv
->cur_adap
.quirks
= adap
->quirks
;
97 priv
->cur_adap
.dev
.of_node
= priv
->dev
->of_node
;
98 ret
= i2c_add_adapter(&priv
->cur_adap
);
105 i2c_put_adapter(adap
);
107 dev_err(priv
->dev
, "failed to setup demux-adapter %d (%d)\n", new_chan
, ret
);
111 static int i2c_demux_deactivate_master(struct i2c_demux_pinctrl_priv
*priv
)
113 int ret
, cur
= priv
->cur_chan
;
118 i2c_del_adapter(&priv
->cur_adap
);
119 i2c_put_adapter(priv
->chan
[cur
].parent_adap
);
121 ret
= of_changeset_revert(&priv
->chan
[cur
].chgset
);
123 priv
->chan
[cur
].parent_adap
= NULL
;
124 priv
->cur_chan
= -EINVAL
;
129 static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv
*priv
, u32 new_chan
)
133 if (new_chan
== priv
->cur_chan
)
136 ret
= i2c_demux_deactivate_master(priv
);
140 return i2c_demux_activate_master(priv
, new_chan
);
143 static ssize_t
available_masters_show(struct device
*dev
,
144 struct device_attribute
*attr
,
147 struct i2c_demux_pinctrl_priv
*priv
= dev_get_drvdata(dev
);
150 for (i
= 0; i
< priv
->num_chan
&& count
< PAGE_SIZE
; i
++)
151 count
+= scnprintf(buf
+ count
, PAGE_SIZE
- count
, "%d:%s%c",
152 i
, priv
->chan
[i
].parent_np
->full_name
,
153 i
== priv
->num_chan
- 1 ? '\n' : ' ');
157 static DEVICE_ATTR_RO(available_masters
);
159 static ssize_t
current_master_show(struct device
*dev
,
160 struct device_attribute
*attr
,
163 struct i2c_demux_pinctrl_priv
*priv
= dev_get_drvdata(dev
);
165 return sprintf(buf
, "%d\n", priv
->cur_chan
);
168 static ssize_t
current_master_store(struct device
*dev
,
169 struct device_attribute
*attr
,
170 const char *buf
, size_t count
)
172 struct i2c_demux_pinctrl_priv
*priv
= dev_get_drvdata(dev
);
176 ret
= kstrtouint(buf
, 0, &val
);
180 if (val
>= priv
->num_chan
)
183 ret
= i2c_demux_change_master(priv
, val
);
185 return ret
< 0 ? ret
: count
;
187 static DEVICE_ATTR_RW(current_master
);
189 static int i2c_demux_pinctrl_probe(struct platform_device
*pdev
)
191 struct device_node
*np
= pdev
->dev
.of_node
;
192 struct i2c_demux_pinctrl_priv
*priv
;
193 int num_chan
, i
, j
, err
;
195 num_chan
= of_count_phandle_with_args(np
, "i2c-parent", NULL
);
197 dev_err(&pdev
->dev
, "Need at least two I2C masters to switch\n");
201 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
)
202 + num_chan
* sizeof(struct i2c_demux_pinctrl_chan
), GFP_KERNEL
);
206 err
= of_property_read_string(np
, "i2c-bus-name", &priv
->bus_name
);
210 for (i
= 0; i
< num_chan
; i
++) {
211 struct device_node
*adap_np
;
213 adap_np
= of_parse_phandle(np
, "i2c-parent", i
);
215 dev_err(&pdev
->dev
, "can't get phandle for parent %d\n", i
);
219 priv
->chan
[i
].parent_np
= adap_np
;
221 of_changeset_init(&priv
->chan
[i
].chgset
);
222 of_changeset_update_property(&priv
->chan
[i
].chgset
, adap_np
, &status_okay
);
225 priv
->num_chan
= num_chan
;
226 priv
->dev
= &pdev
->dev
;
228 platform_set_drvdata(pdev
, priv
);
230 /* switch to first parent as active master */
231 i2c_demux_activate_master(priv
, 0);
233 err
= device_create_file(&pdev
->dev
, &dev_attr_available_masters
);
237 err
= device_create_file(&pdev
->dev
, &dev_attr_current_master
);
239 goto err_rollback_available
;
243 err_rollback_available
:
244 device_remove_file(&pdev
->dev
, &dev_attr_available_masters
);
246 for (j
= 0; j
< i
; j
++) {
247 of_node_put(priv
->chan
[j
].parent_np
);
248 of_changeset_destroy(&priv
->chan
[j
].chgset
);
254 static int i2c_demux_pinctrl_remove(struct platform_device
*pdev
)
256 struct i2c_demux_pinctrl_priv
*priv
= platform_get_drvdata(pdev
);
259 device_remove_file(&pdev
->dev
, &dev_attr_current_master
);
260 device_remove_file(&pdev
->dev
, &dev_attr_available_masters
);
262 i2c_demux_deactivate_master(priv
);
264 for (i
= 0; i
< priv
->num_chan
; i
++) {
265 of_node_put(priv
->chan
[i
].parent_np
);
266 of_changeset_destroy(&priv
->chan
[i
].chgset
);
272 static const struct of_device_id i2c_demux_pinctrl_of_match
[] = {
273 { .compatible
= "i2c-demux-pinctrl", },
276 MODULE_DEVICE_TABLE(of
, i2c_demux_pinctrl_of_match
);
278 static struct platform_driver i2c_demux_pinctrl_driver
= {
280 .name
= "i2c-demux-pinctrl",
281 .of_match_table
= i2c_demux_pinctrl_of_match
,
283 .probe
= i2c_demux_pinctrl_probe
,
284 .remove
= i2c_demux_pinctrl_remove
,
286 module_platform_driver(i2c_demux_pinctrl_driver
);
288 MODULE_DESCRIPTION("pinctrl-based I2C demux driver");
289 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
290 MODULE_LICENSE("GPL v2");
291 MODULE_ALIAS("platform:i2c-demux-pinctrl");