i2c-demux-pinctrl.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*
  2. * Pinctrl based I2C DeMultiplexer
  3. *
  4. * Copyright (C) 2015-16 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
  5. * Copyright (C) 2015-16 by Renesas Electronics Corporation
  6. *
  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.
  10. *
  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/)
  13. */
  14. #include <linux/i2c.h>
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/of.h>
  18. #include <linux/pinctrl/consumer.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/slab.h>
  21. #include <linux/sysfs.h>
  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. struct i2c_demux_pinctrl_priv {
  28. int cur_chan;
  29. int num_chan;
  30. struct device *dev;
  31. const char *bus_name;
  32. struct i2c_adapter cur_adap;
  33. struct i2c_algorithm algo;
  34. struct i2c_demux_pinctrl_chan chan[];
  35. };
  36. static struct property status_okay = { .name = "status", .length = 3, .value = "ok" };
  37. static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
  38. {
  39. struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
  40. struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
  41. return __i2c_transfer(parent, msgs, num);
  42. }
  43. static u32 i2c_demux_functionality(struct i2c_adapter *adap)
  44. {
  45. struct i2c_demux_pinctrl_priv *priv = adap->algo_data;
  46. struct i2c_adapter *parent = priv->chan[priv->cur_chan].parent_adap;
  47. return parent->algo->functionality(parent);
  48. }
  49. static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
  50. {
  51. struct i2c_adapter *adap;
  52. struct pinctrl *p;
  53. int ret;
  54. ret = of_changeset_apply(&priv->chan[new_chan].chgset);
  55. if (ret)
  56. goto err;
  57. adap = of_find_i2c_adapter_by_node(priv->chan[new_chan].parent_np);
  58. if (!adap) {
  59. ret = -ENODEV;
  60. goto err_with_revert;
  61. }
  62. p = devm_pinctrl_get_select(adap->dev.parent, priv->bus_name);
  63. if (IS_ERR(p)) {
  64. ret = PTR_ERR(p);
  65. goto err_with_put;
  66. }
  67. priv->chan[new_chan].parent_adap = adap;
  68. priv->cur_chan = new_chan;
  69. /* Now fill out current adapter structure. cur_chan must be up to date */
  70. priv->algo.master_xfer = i2c_demux_master_xfer;
  71. priv->algo.functionality = i2c_demux_functionality;
  72. snprintf(priv->cur_adap.name, sizeof(priv->cur_adap.name),
  73. "i2c-demux (master i2c-%d)", i2c_adapter_id(adap));
  74. priv->cur_adap.owner = THIS_MODULE;
  75. priv->cur_adap.algo = &priv->algo;
  76. priv->cur_adap.algo_data = priv;
  77. priv->cur_adap.dev.parent = priv->dev;
  78. priv->cur_adap.class = adap->class;
  79. priv->cur_adap.retries = adap->retries;
  80. priv->cur_adap.timeout = adap->timeout;
  81. priv->cur_adap.quirks = adap->quirks;
  82. priv->cur_adap.dev.of_node = priv->dev->of_node;
  83. ret = i2c_add_adapter(&priv->cur_adap);
  84. if (ret < 0)
  85. goto err_with_put;
  86. return 0;
  87. err_with_put:
  88. i2c_put_adapter(adap);
  89. err_with_revert:
  90. of_changeset_revert(&priv->chan[new_chan].chgset);
  91. err:
  92. dev_err(priv->dev, "failed to setup demux-adapter %d (%d)\n", new_chan, ret);
  93. return ret;
  94. }
  95. static int i2c_demux_deactivate_master(struct i2c_demux_pinctrl_priv *priv)
  96. {
  97. int ret, cur = priv->cur_chan;
  98. if (cur < 0)
  99. return 0;
  100. i2c_del_adapter(&priv->cur_adap);
  101. i2c_put_adapter(priv->chan[cur].parent_adap);
  102. ret = of_changeset_revert(&priv->chan[cur].chgset);
  103. priv->chan[cur].parent_adap = NULL;
  104. priv->cur_chan = -EINVAL;
  105. return ret;
  106. }
  107. static int i2c_demux_change_master(struct i2c_demux_pinctrl_priv *priv, u32 new_chan)
  108. {
  109. int ret;
  110. if (new_chan == priv->cur_chan)
  111. return 0;
  112. ret = i2c_demux_deactivate_master(priv);
  113. if (ret)
  114. return ret;
  115. return i2c_demux_activate_master(priv, new_chan);
  116. }
  117. static ssize_t available_masters_show(struct device *dev,
  118. struct device_attribute *attr,
  119. char *buf)
  120. {
  121. struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
  122. int count = 0, i;
  123. for (i = 0; i < priv->num_chan && count < PAGE_SIZE; i++)
  124. count += scnprintf(buf + count, PAGE_SIZE - count, "%d:%s%c",
  125. i, priv->chan[i].parent_np->full_name,
  126. i == priv->num_chan - 1 ? '\n' : ' ');
  127. return count;
  128. }
  129. static DEVICE_ATTR_RO(available_masters);
  130. static ssize_t current_master_show(struct device *dev,
  131. struct device_attribute *attr,
  132. char *buf)
  133. {
  134. struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
  135. return sprintf(buf, "%d\n", priv->cur_chan);
  136. }
  137. static ssize_t current_master_store(struct device *dev,
  138. struct device_attribute *attr,
  139. const char *buf, size_t count)
  140. {
  141. struct i2c_demux_pinctrl_priv *priv = dev_get_drvdata(dev);
  142. unsigned int val;
  143. int ret;
  144. ret = kstrtouint(buf, 0, &val);
  145. if (ret < 0)
  146. return ret;
  147. if (val >= priv->num_chan)
  148. return -EINVAL;
  149. ret = i2c_demux_change_master(priv, val);
  150. return ret < 0 ? ret : count;
  151. }
  152. static DEVICE_ATTR_RW(current_master);
  153. static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
  154. {
  155. struct device_node *np = pdev->dev.of_node;
  156. struct i2c_demux_pinctrl_priv *priv;
  157. int num_chan, i, j, err;
  158. num_chan = of_count_phandle_with_args(np, "i2c-parent", NULL);
  159. if (num_chan < 2) {
  160. dev_err(&pdev->dev, "Need at least two I2C masters to switch\n");
  161. return -EINVAL;
  162. }
  163. priv = devm_kzalloc(&pdev->dev, sizeof(*priv)
  164. + num_chan * sizeof(struct i2c_demux_pinctrl_chan), GFP_KERNEL);
  165. if (!priv)
  166. return -ENOMEM;
  167. err = of_property_read_string(np, "i2c-bus-name", &priv->bus_name);
  168. if (err)
  169. return err;
  170. for (i = 0; i < num_chan; i++) {
  171. struct device_node *adap_np;
  172. adap_np = of_parse_phandle(np, "i2c-parent", i);
  173. if (!adap_np) {
  174. dev_err(&pdev->dev, "can't get phandle for parent %d\n", i);
  175. err = -ENOENT;
  176. goto err_rollback;
  177. }
  178. priv->chan[i].parent_np = adap_np;
  179. of_changeset_init(&priv->chan[i].chgset);
  180. of_changeset_update_property(&priv->chan[i].chgset, adap_np, &status_okay);
  181. }
  182. priv->num_chan = num_chan;
  183. priv->dev = &pdev->dev;
  184. platform_set_drvdata(pdev, priv);
  185. /* switch to first parent as active master */
  186. i2c_demux_activate_master(priv, 0);
  187. err = device_create_file(&pdev->dev, &dev_attr_available_masters);
  188. if (err)
  189. goto err_rollback;
  190. err = device_create_file(&pdev->dev, &dev_attr_current_master);
  191. if (err)
  192. goto err_rollback_available;
  193. return 0;
  194. err_rollback_available:
  195. device_remove_file(&pdev->dev, &dev_attr_available_masters);
  196. err_rollback:
  197. for (j = 0; j < i; j++) {
  198. of_node_put(priv->chan[j].parent_np);
  199. of_changeset_destroy(&priv->chan[j].chgset);
  200. }
  201. return err;
  202. }
  203. static int i2c_demux_pinctrl_remove(struct platform_device *pdev)
  204. {
  205. struct i2c_demux_pinctrl_priv *priv = platform_get_drvdata(pdev);
  206. int i;
  207. device_remove_file(&pdev->dev, &dev_attr_current_master);
  208. device_remove_file(&pdev->dev, &dev_attr_available_masters);
  209. i2c_demux_deactivate_master(priv);
  210. for (i = 0; i < priv->num_chan; i++) {
  211. of_node_put(priv->chan[i].parent_np);
  212. of_changeset_destroy(&priv->chan[i].chgset);
  213. }
  214. return 0;
  215. }
  216. static const struct of_device_id i2c_demux_pinctrl_of_match[] = {
  217. { .compatible = "i2c-demux-pinctrl", },
  218. {},
  219. };
  220. MODULE_DEVICE_TABLE(of, i2c_demux_pinctrl_of_match);
  221. static struct platform_driver i2c_demux_pinctrl_driver = {
  222. .driver = {
  223. .name = "i2c-demux-pinctrl",
  224. .of_match_table = i2c_demux_pinctrl_of_match,
  225. },
  226. .probe = i2c_demux_pinctrl_probe,
  227. .remove = i2c_demux_pinctrl_remove,
  228. };
  229. module_platform_driver(i2c_demux_pinctrl_driver);
  230. MODULE_DESCRIPTION("pinctrl-based I2C demux driver");
  231. MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
  232. MODULE_LICENSE("GPL v2");
  233. MODULE_ALIAS("platform:i2c-demux-pinctrl");