2 * I2C multiplexer using pinctrl API
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <linux/i2c.h>
20 #include <linux/i2c-mux.h>
21 #include <linux/module.h>
22 #include <linux/pinctrl/consumer.h>
23 #include <linux/platform_device.h>
24 #include <linux/slab.h>
26 #include "../../pinctrl/core.h"
28 struct i2c_mux_pinctrl
{
29 struct pinctrl
*pinctrl
;
30 struct pinctrl_state
**states
;
33 static int i2c_mux_pinctrl_select(struct i2c_mux_core
*muxc
, u32 chan
)
35 struct i2c_mux_pinctrl
*mux
= i2c_mux_priv(muxc
);
37 return pinctrl_select_state(mux
->pinctrl
, mux
->states
[chan
]);
40 static int i2c_mux_pinctrl_deselect(struct i2c_mux_core
*muxc
, u32 chan
)
42 return i2c_mux_pinctrl_select(muxc
, muxc
->num_adapters
);
45 static struct i2c_adapter
*i2c_mux_pinctrl_root_adapter(
46 struct pinctrl_state
*state
)
48 struct i2c_adapter
*root
= NULL
;
49 struct pinctrl_setting
*setting
;
50 struct i2c_adapter
*pin_root
;
52 list_for_each_entry(setting
, &state
->settings
, node
) {
53 pin_root
= i2c_root_adapter(setting
->pctldev
->dev
);
58 else if (root
!= pin_root
)
65 static struct i2c_adapter
*i2c_mux_pinctrl_parent_adapter(struct device
*dev
)
67 struct device_node
*np
= dev
->of_node
;
68 struct device_node
*parent_np
;
69 struct i2c_adapter
*parent
;
71 parent_np
= of_parse_phandle(np
, "i2c-parent", 0);
73 dev_err(dev
, "Cannot parse i2c-parent\n");
74 return ERR_PTR(-ENODEV
);
76 parent
= of_find_i2c_adapter_by_node(parent_np
);
77 of_node_put(parent_np
);
79 return ERR_PTR(-EPROBE_DEFER
);
84 static int i2c_mux_pinctrl_probe(struct platform_device
*pdev
)
86 struct device
*dev
= &pdev
->dev
;
87 struct device_node
*np
= dev
->of_node
;
88 struct i2c_mux_core
*muxc
;
89 struct i2c_mux_pinctrl
*mux
;
90 struct i2c_adapter
*parent
;
91 struct i2c_adapter
*root
;
92 int num_names
, i
, ret
;
95 num_names
= of_property_count_strings(np
, "pinctrl-names");
97 dev_err(dev
, "Cannot parse pinctrl-names: %d\n",
102 parent
= i2c_mux_pinctrl_parent_adapter(dev
);
104 return PTR_ERR(parent
);
106 muxc
= i2c_mux_alloc(parent
, dev
, num_names
,
107 sizeof(*mux
) + num_names
* sizeof(*mux
->states
),
108 0, i2c_mux_pinctrl_select
, NULL
);
113 mux
= i2c_mux_priv(muxc
);
114 mux
->states
= (struct pinctrl_state
**)(mux
+ 1);
116 platform_set_drvdata(pdev
, muxc
);
118 mux
->pinctrl
= devm_pinctrl_get(dev
);
119 if (IS_ERR(mux
->pinctrl
)) {
120 ret
= PTR_ERR(mux
->pinctrl
);
121 dev_err(dev
, "Cannot get pinctrl: %d\n", ret
);
125 for (i
= 0; i
< num_names
; i
++) {
126 ret
= of_property_read_string_index(np
, "pinctrl-names", i
,
129 dev_err(dev
, "Cannot parse pinctrl-names: %d\n", ret
);
133 mux
->states
[i
] = pinctrl_lookup_state(mux
->pinctrl
, name
);
134 if (IS_ERR(mux
->states
[i
])) {
135 ret
= PTR_ERR(mux
->states
[i
]);
136 dev_err(dev
, "Cannot look up pinctrl state %s: %d\n",
141 if (strcmp(name
, "idle"))
144 if (i
!= num_names
- 1) {
145 dev_err(dev
, "idle state must be last\n");
149 muxc
->deselect
= i2c_mux_pinctrl_deselect
;
152 root
= i2c_root_adapter(&muxc
->parent
->dev
);
154 muxc
->mux_locked
= true;
155 for (i
= 0; i
< num_names
; i
++) {
156 if (root
!= i2c_mux_pinctrl_root_adapter(mux
->states
[i
])) {
157 muxc
->mux_locked
= false;
161 if (muxc
->mux_locked
)
162 dev_info(dev
, "mux-locked i2c mux\n");
164 /* Do not add any adapter for the idle state (if it's there at all). */
165 for (i
= 0; i
< num_names
- !!muxc
->deselect
; i
++) {
166 ret
= i2c_mux_add_adapter(muxc
, 0, i
, 0);
168 goto err_del_adapter
;
174 i2c_mux_del_adapters(muxc
);
176 i2c_put_adapter(parent
);
181 static int i2c_mux_pinctrl_remove(struct platform_device
*pdev
)
183 struct i2c_mux_core
*muxc
= platform_get_drvdata(pdev
);
185 i2c_mux_del_adapters(muxc
);
186 i2c_put_adapter(muxc
->parent
);
191 static const struct of_device_id i2c_mux_pinctrl_of_match
[] = {
192 { .compatible
= "i2c-mux-pinctrl", },
195 MODULE_DEVICE_TABLE(of
, i2c_mux_pinctrl_of_match
);
197 static struct platform_driver i2c_mux_pinctrl_driver
= {
199 .name
= "i2c-mux-pinctrl",
200 .of_match_table
= of_match_ptr(i2c_mux_pinctrl_of_match
),
202 .probe
= i2c_mux_pinctrl_probe
,
203 .remove
= i2c_mux_pinctrl_remove
,
205 module_platform_driver(i2c_mux_pinctrl_driver
);
207 MODULE_DESCRIPTION("pinctrl-based I2C multiplexer driver");
208 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
209 MODULE_LICENSE("GPL v2");
210 MODULE_ALIAS("platform:i2c-mux-pinctrl");