0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/i2c.h>
0013 #include <linux/init.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/pinctrl/consumer.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/pm_runtime.h>
0019 #include <linux/slab.h>
0020 #include <linux/sysfs.h>
0021
0022 struct i2c_demux_pinctrl_chan {
0023 struct device_node *parent_np;
0024 struct i2c_adapter *parent_adap;
0025 struct of_changeset chgset;
0026 };
0027
0028 struct i2c_demux_pinctrl_priv {
0029 int cur_chan;
0030 int num_chan;
0031 struct device *dev;
0032 const char *bus_name;
0033 struct i2c_adapter cur_adap;
0034 struct i2c_algorithm algo;
0035 struct i2c_demux_pinctrl_chan chan[];
0036 };
0037
0038 static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
0039 {
0040 struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
0041 struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
0042
0043 return __i2c_transfer(parent, msgs, num);
0044 }
0045
0046 static u32 i2c_demux_functionality(struct i2c_adapter *adap)
0047 {
0048 struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
0049 struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
0050
0051 return parent->algo->functionality(parent);
0052 }
0053
0054 static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
0055 {
0056 struct i2c_adapter *adap;
0057 struct pinctrl *p;
0058 int ret;
0059
0060 ret = of_changeset_apply(&priv->chan[new_chan].chgset);
0061 if (ret)
0062 goto err;
0063
0064 adap = of_find_i2c_adapter_by_node(priv->chan[new_chan].parent_np);
0065 if (!adap) {
0066 ret = -ENODEV;
0067 goto err_with_revert;
0068 }
0069
0070
0071
0072
0073
0074
0075 p = devm_pinctrl_get(adap->dev.parent);
0076 if (IS_ERR(p)) {
0077 ret = PTR_ERR(p);
0078
0079 if (ret != -ENODEV)
0080 goto err_with_put;
0081 } else {
0082
0083 struct pinctrl_state *s = pinctrl_lookup_state(p, priv->bus_name);
0084
0085 if (IS_ERR(s)) {
0086 ret = PTR_ERR(s);
0087 goto err_with_put;
0088 }
0089 ret = pinctrl_select_state(p, s);
0090 if (ret < 0)
0091 goto err_with_put;
0092 }
0093
0094 priv->chan[new_chan].parent_adap = adap;
0095 priv->cur_chan = new_chan;
0096
0097
0098 priv->algo.master_xfer = i2c_demux_master_xfer;
0099 if (adap->algo->master_xfer_atomic)
0100 priv->algo.master_xfer_atomic = i2c_demux_master_xfer;
0101 priv->algo.functionality = i2c_demux_functionality;
0102
0103 snprintf(priv->cur_adap.name, sizeof(priv->cur_adap.name),
0104 "i2c-demux (master i2c-%d)", i2c_adapter_id(adap));
0105 priv->cur_adap.owner = THIS_MODULE;
0106 priv->cur_adap.algo = &priv->algo;
0107 priv->cur_adap.algo_data = priv;
0108 priv->cur_adap.dev.parent = &adap->dev;
0109 priv->cur_adap.class = adap->class;
0110 priv->cur_adap.retries = adap->retries;
0111 priv->cur_adap.timeout = adap->timeout;
0112 priv->cur_adap.quirks = adap->quirks;
0113 priv->cur_adap.dev.of_node = priv->dev->of_node;
0114 ret = i2c_add_adapter(&priv->cur_adap);
0115 if (ret < 0)
0116 goto err_with_put;
0117
0118 return 0;
0119
0120 err_with_put:
0121 i2c_put_adapter(adap);
0122 err_with_revert:
0123 of_changeset_revert(&priv->chan[new_chan].chgset);
0124 err:
0125 dev_err(priv->dev, "failed to setup demux-adapter %d (%d)\n", new_chan, ret);
0126 priv->cur_chan = -EINVAL;
0127 return ret;
0128 }
0129
0130 static int i2c_demux_deactivate_master(struct i2c_demux_pinctrl_priv *priv)
0131 {
0132 int ret, cur = priv->cur_chan;
0133
0134 if (cur < 0)
0135 return 0;
0136
0137 i2c_del_adapter(&priv->cur_adap);
0138 i2c_put_adapter(priv->chan[cur].parent_adap);
0139
0140 ret = of_changeset_revert(&priv->chan[cur].chgset);
0141
0142 priv->chan[cur].parent_adap = NULL;
0143 priv->cur_chan = -EINVAL;
0144
0145 return ret;
0146 }
0147
0148 static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
0149 {
0150 int ret;
0151
0152 if (new_chan == priv->cur_chan)
0153 return 0;
0154
0155 ret = i2c_demux_deactivate_master(priv);
0156 if (ret)
0157 return ret;
0158
0159 return i2c_demux_activate_master(priv, new_chan);
0160 }
0161
0162 static ssize_t available_masters_show(struct device *dev,
0163 struct device_attribute *attr,
0164 char *buf)
0165 {
0166 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
0167 int count = 0, i;
0168
0169 for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++)
0170 count += scnprintf(buf + count, PAGE_SIZE - count, "%d:%pOF%c",
0171 i, priv->chan[i].parent_np,
0172 i == priv->num_chan - 1 ? '\n' : ' ');
0173
0174 return count;
0175 }
0176 static DEVICE_ATTR_RO(available_masters);
0177
0178 static ssize_t current_master_show(struct device *dev,
0179 struct device_attribute *attr,
0180 char *buf)
0181 {
0182 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
0183
0184 return sprintf(buf, "%d\n", priv->cur_chan);
0185 }
0186
0187 static ssize_t current_master_store(struct device *dev,
0188 struct device_attribute *attr,
0189 const char *buf, size_t count)
0190 {
0191 struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
0192 unsigned int val;
0193 int ret;
0194
0195 ret = kstrtouint(buf, 0, &val);
0196 if (ret < 0)
0197 return ret;
0198
0199 if (val >= priv->num_chan)
0200 return -EINVAL;
0201
0202 ret = i2c_demux_change_master(priv, val);
0203
0204 return ret < 0 ? ret : count;
0205 }
0206 static DEVICE_ATTR_RW(current_master);
0207
0208 static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
0209 {
0210 struct device_node *np = pdev->dev.of_node;
0211 struct i2c_demux_pinctrl_priv *priv;
0212 struct property *props;
0213 int num_chan, i, j, err;
0214
0215 num_chan = of_count_phandle_with_args(np, "i2c-parent", NULL);
0216 if (num_chan < 2) {
0217 dev_err(&pdev->dev, "Need at least two I2C masters to switch\n");
0218 return -EINVAL;
0219 }
0220
0221 priv = devm_kzalloc(&pdev->dev, struct_size(priv, chan, num_chan),
0222 GFP_KERNEL);
0223
0224 props = devm_kcalloc(&pdev->dev, num_chan, sizeof(*props), GFP_KERNEL);
0225
0226 if (!priv || !props)
0227 return -ENOMEM;
0228
0229 err = of_property_read_string(np, "i2c-bus-name", &priv->bus_name);
0230 if (err)
0231 return err;
0232
0233 for (i = 0; i < num_chan; i++) {
0234 struct device_node *adap_np;
0235
0236 adap_np = of_parse_phandle(np, "i2c-parent", i);
0237 if (!adap_np) {
0238 dev_err(&pdev->dev, "can't get phandle for parent %d\n", i);
0239 err = -ENOENT;
0240 goto err_rollback;
0241 }
0242 priv->chan[i].parent_np = adap_np;
0243
0244 props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL);
0245 props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL);
0246 props[i].length = 3;
0247
0248 of_changeset_init(&priv->chan[i].chgset);
0249 of_changeset_update_property(&priv->chan[i].chgset, adap_np, &props[i]);
0250 }
0251
0252 priv->num_chan = num_chan;
0253 priv->dev = &pdev->dev;
0254
0255 platform_set_drvdata(pdev, priv);
0256
0257 pm_runtime_no_callbacks(&pdev->dev);
0258
0259
0260 i2c_demux_activate_master(priv, 0);
0261
0262 err = device_create_file(&pdev->dev, &dev_attr_available_masters);
0263 if (err)
0264 goto err_rollback_activation;
0265
0266 err = device_create_file(&pdev->dev, &dev_attr_current_master);
0267 if (err)
0268 goto err_rollback_available;
0269
0270 return 0;
0271
0272 err_rollback_available:
0273 device_remove_file(&pdev->dev, &dev_attr_available_masters);
0274 err_rollback_activation:
0275 i2c_demux_deactivate_master(priv);
0276 err_rollback:
0277 for (j = 0; j < i; j++) {
0278 of_node_put(priv->chan[j].parent_np);
0279 of_changeset_destroy(&priv->chan[j].chgset);
0280 }
0281
0282 return err;
0283 }
0284
0285 static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
0286 {
0287 struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
0288 int i;
0289
0290 device_remove_file(&pdev->dev, &dev_attr_current_master);
0291 device_remove_file(&pdev->dev, &dev_attr_available_masters);
0292
0293 i2c_demux_deactivate_master(priv);
0294
0295 for (i = 0; i < priv->num_chan; i++) {
0296 of_node_put(priv->chan[i].parent_np);
0297 of_changeset_destroy(&priv->chan[i].chgset);
0298 }
0299
0300 return 0;
0301 }
0302
0303 static const struct of_device_id i2c_demux_pinctrl_of_match[] = {
0304 { .compatible = "i2c-demux-pinctrl", },
0305 {},
0306 };
0307 MODULE_DEVICE_TABLE(of, i2c_demux_pinctrl_of_match);
0308
0309 static struct platform_driver i2c_demux_pinctrl_driver = {
0310 .driver = {
0311 .name = "i2c-demux-pinctrl",
0312 .of_match_table = i2c_demux_pinctrl_of_match,
0313 },
0314 .probe = i2c_demux_pinctrl_probe,
0315 .remove = i2c_demux_pinctrl_remove,
0316 };
0317 module_platform_driver(i2c_demux_pinctrl_driver);
0318
0319 MODULE_DESCRIPTION("pinctrl-based I2C demux driver");
0320 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
0321 MODULE_LICENSE("GPL v2");
0322 MODULE_ALIAS("platform:i2c-demux-pinctrl");