i2c-tegra-bpmp.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /*
  2. * drivers/i2c/busses/i2c-tegra-bpmp.c
  3. *
  4. * Copyright (c) 2016 NVIDIA Corporation. All rights reserved.
  5. *
  6. * Author: Shardar Shariff Md <smohammed@nvidia.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms and conditions of the GNU General Public License,
  10. * version 2, as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope it will be useful, but WITHOUT
  13. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  15. * more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <linux/err.h>
  21. #include <linux/i2c.h>
  22. #include <linux/init.h>
  23. #include <linux/kernel.h>
  24. #include <linux/module.h>
  25. #include <linux/of_device.h>
  26. #include <linux/platform_device.h>
  27. #include <linux/pm_runtime.h>
  28. #include <soc/tegra/bpmp-abi.h>
  29. #include <soc/tegra/bpmp.h>
  30. /*
  31. * Serialized I2C message header size is 6 bytes and includes address, flags
  32. * and length
  33. */
  34. #define SERIALI2C_HDR_SIZE 6
  35. struct tegra_bpmp_i2c {
  36. struct i2c_adapter adapter;
  37. struct device *dev;
  38. struct tegra_bpmp *bpmp;
  39. unsigned int bus;
  40. };
  41. /*
  42. * Linux flags are translated to BPMP defined I2C flags that are used in BPMP
  43. * firmware I2C driver to avoid any issues in future if Linux I2C flags are
  44. * changed.
  45. */
  46. static int tegra_bpmp_xlate_flags(u16 flags, u16 *out)
  47. {
  48. if (flags & I2C_M_TEN) {
  49. *out |= SERIALI2C_TEN;
  50. flags &= ~I2C_M_TEN;
  51. }
  52. if (flags & I2C_M_RD) {
  53. *out |= SERIALI2C_RD;
  54. flags &= ~I2C_M_RD;
  55. }
  56. if (flags & I2C_M_STOP) {
  57. *out |= SERIALI2C_STOP;
  58. flags &= ~I2C_M_STOP;
  59. }
  60. if (flags & I2C_M_NOSTART) {
  61. *out |= SERIALI2C_NOSTART;
  62. flags &= ~I2C_M_NOSTART;
  63. }
  64. if (flags & I2C_M_REV_DIR_ADDR) {
  65. *out |= SERIALI2C_REV_DIR_ADDR;
  66. flags &= ~I2C_M_REV_DIR_ADDR;
  67. }
  68. if (flags & I2C_M_IGNORE_NAK) {
  69. *out |= SERIALI2C_IGNORE_NAK;
  70. flags &= ~I2C_M_IGNORE_NAK;
  71. }
  72. if (flags & I2C_M_NO_RD_ACK) {
  73. *out |= SERIALI2C_NO_RD_ACK;
  74. flags &= ~I2C_M_NO_RD_ACK;
  75. }
  76. if (flags & I2C_M_RECV_LEN) {
  77. *out |= SERIALI2C_RECV_LEN;
  78. flags &= ~I2C_M_RECV_LEN;
  79. }
  80. return 0;
  81. }
  82. /**
  83. * The serialized I2C format is simply the following:
  84. * [addr little-endian][flags little-endian][len little-endian][data if write]
  85. * [addr little-endian][flags little-endian][len little-endian][data if write]
  86. * ...
  87. *
  88. * The flags are translated from Linux kernel representation to seriali2c
  89. * representation. Any undefined flag being set causes an error.
  90. *
  91. * The data is there only for writes. Reads have the data transferred in the
  92. * other direction, and thus data is not present.
  93. *
  94. * See deserialize_i2c documentation for the data format in the other direction.
  95. */
  96. static int tegra_bpmp_serialize_i2c_msg(struct tegra_bpmp_i2c *i2c,
  97. struct mrq_i2c_request *request,
  98. struct i2c_msg *msgs,
  99. unsigned int num)
  100. {
  101. char *buf = request->xfer.data_buf;
  102. unsigned int i, j, pos = 0;
  103. int err;
  104. for (i = 0; i < num; i++) {
  105. struct i2c_msg *msg = &msgs[i];
  106. u16 flags = 0;
  107. err = tegra_bpmp_xlate_flags(msg->flags, &flags);
  108. if (err < 0)
  109. return err;
  110. buf[pos++] = msg->addr & 0xff;
  111. buf[pos++] = (msg->addr & 0xff00) >> 8;
  112. buf[pos++] = flags & 0xff;
  113. buf[pos++] = (flags & 0xff00) >> 8;
  114. buf[pos++] = msg->len & 0xff;
  115. buf[pos++] = (msg->len & 0xff00) >> 8;
  116. if ((flags & SERIALI2C_RD) == 0) {
  117. for (j = 0; j < msg->len; j++)
  118. buf[pos++] = msg->buf[j];
  119. }
  120. }
  121. request->xfer.data_size = pos;
  122. return 0;
  123. }
  124. /**
  125. * The data in the BPMP -> CPU direction is composed of sequential blocks for
  126. * those messages that have I2C_M_RD. So, for example, if you have:
  127. *
  128. * - !I2C_M_RD, len == 5, data == a0 01 02 03 04
  129. * - !I2C_M_RD, len == 1, data == a0
  130. * - I2C_M_RD, len == 2, data == [uninitialized buffer 1]
  131. * - !I2C_M_RD, len == 1, data == a2
  132. * - I2C_M_RD, len == 2, data == [uninitialized buffer 2]
  133. *
  134. * ...then the data in the BPMP -> CPU direction would be 4 bytes total, and
  135. * would contain 2 bytes that will go to uninitialized buffer 1, and 2 bytes
  136. * that will go to uninitialized buffer 2.
  137. */
  138. static int tegra_bpmp_i2c_deserialize(struct tegra_bpmp_i2c *i2c,
  139. struct mrq_i2c_response *response,
  140. struct i2c_msg *msgs,
  141. unsigned int num)
  142. {
  143. size_t size = response->xfer.data_size, len = 0, pos = 0;
  144. char *buf = response->xfer.data_buf;
  145. unsigned int i;
  146. for (i = 0; i < num; i++)
  147. if (msgs[i].flags & I2C_M_RD)
  148. len += msgs[i].len;
  149. if (len != size)
  150. return -EINVAL;
  151. for (i = 0; i < num; i++) {
  152. if (msgs[i].flags & I2C_M_RD) {
  153. memcpy(msgs[i].buf, buf + pos, msgs[i].len);
  154. pos += msgs[i].len;
  155. }
  156. }
  157. return 0;
  158. }
  159. static int tegra_bpmp_i2c_msg_len_check(struct i2c_msg *msgs, unsigned int num)
  160. {
  161. size_t tx_len = 0, rx_len = 0;
  162. unsigned int i;
  163. for (i = 0; i < num; i++)
  164. if (!(msgs[i].flags & I2C_M_RD))
  165. tx_len += SERIALI2C_HDR_SIZE + msgs[i].len;
  166. if (tx_len > TEGRA_I2C_IPC_MAX_IN_BUF_SIZE)
  167. return -EINVAL;
  168. for (i = 0; i < num; i++)
  169. if ((msgs[i].flags & I2C_M_RD))
  170. rx_len += msgs[i].len;
  171. if (rx_len > TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE)
  172. return -EINVAL;
  173. return 0;
  174. }
  175. static int tegra_bpmp_i2c_msg_xfer(struct tegra_bpmp_i2c *i2c,
  176. struct mrq_i2c_request *request,
  177. struct mrq_i2c_response *response)
  178. {
  179. struct tegra_bpmp_message msg;
  180. int err;
  181. request->cmd = CMD_I2C_XFER;
  182. request->xfer.bus_id = i2c->bus;
  183. memset(&msg, 0, sizeof(msg));
  184. msg.mrq = MRQ_I2C;
  185. msg.tx.data = request;
  186. msg.tx.size = sizeof(*request);
  187. msg.rx.data = response;
  188. msg.rx.size = sizeof(*response);
  189. if (irqs_disabled())
  190. err = tegra_bpmp_transfer_atomic(i2c->bpmp, &msg);
  191. else
  192. err = tegra_bpmp_transfer(i2c->bpmp, &msg);
  193. return err;
  194. }
  195. static int tegra_bpmp_i2c_xfer(struct i2c_adapter *adapter,
  196. struct i2c_msg *msgs, int num)
  197. {
  198. struct tegra_bpmp_i2c *i2c = i2c_get_adapdata(adapter);
  199. struct mrq_i2c_response response;
  200. struct mrq_i2c_request request;
  201. int err;
  202. err = tegra_bpmp_i2c_msg_len_check(msgs, num);
  203. if (err < 0) {
  204. dev_err(i2c->dev, "unsupported message length\n");
  205. return err;
  206. }
  207. memset(&request, 0, sizeof(request));
  208. memset(&response, 0, sizeof(response));
  209. err = tegra_bpmp_serialize_i2c_msg(i2c, &request, msgs, num);
  210. if (err < 0) {
  211. dev_err(i2c->dev, "failed to serialize message: %d\n", err);
  212. return err;
  213. }
  214. err = tegra_bpmp_i2c_msg_xfer(i2c, &request, &response);
  215. if (err < 0) {
  216. dev_err(i2c->dev, "failed to transfer message: %d\n", err);
  217. return err;
  218. }
  219. err = tegra_bpmp_i2c_deserialize(i2c, &response, msgs, num);
  220. if (err < 0) {
  221. dev_err(i2c->dev, "failed to deserialize message: %d\n", err);
  222. return err;
  223. }
  224. return num;
  225. }
  226. static u32 tegra_bpmp_i2c_func(struct i2c_adapter *adapter)
  227. {
  228. return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
  229. I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
  230. }
  231. static const struct i2c_algorithm tegra_bpmp_i2c_algo = {
  232. .master_xfer = tegra_bpmp_i2c_xfer,
  233. .functionality = tegra_bpmp_i2c_func,
  234. };
  235. static int tegra_bpmp_i2c_probe(struct platform_device *pdev)
  236. {
  237. struct tegra_bpmp_i2c *i2c;
  238. u32 value;
  239. int err;
  240. i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
  241. if (!i2c)
  242. return -ENOMEM;
  243. i2c->dev = &pdev->dev;
  244. i2c->bpmp = dev_get_drvdata(pdev->dev.parent);
  245. if (!i2c->bpmp)
  246. return -ENODEV;
  247. err = of_property_read_u32(pdev->dev.of_node, "nvidia,bpmp-bus-id",
  248. &value);
  249. if (err < 0)
  250. return err;
  251. i2c->bus = value;
  252. i2c_set_adapdata(&i2c->adapter, i2c);
  253. i2c->adapter.owner = THIS_MODULE;
  254. strlcpy(i2c->adapter.name, "Tegra BPMP I2C adapter",
  255. sizeof(i2c->adapter.name));
  256. i2c->adapter.algo = &tegra_bpmp_i2c_algo;
  257. i2c->adapter.dev.parent = &pdev->dev;
  258. i2c->adapter.dev.of_node = pdev->dev.of_node;
  259. platform_set_drvdata(pdev, i2c);
  260. return i2c_add_adapter(&i2c->adapter);
  261. }
  262. static int tegra_bpmp_i2c_remove(struct platform_device *pdev)
  263. {
  264. struct tegra_bpmp_i2c *i2c = platform_get_drvdata(pdev);
  265. i2c_del_adapter(&i2c->adapter);
  266. return 0;
  267. }
  268. static const struct of_device_id tegra_bpmp_i2c_of_match[] = {
  269. { .compatible = "nvidia,tegra186-bpmp-i2c", },
  270. { }
  271. };
  272. MODULE_DEVICE_TABLE(of, tegra_bpmp_i2c_of_match);
  273. static struct platform_driver tegra_bpmp_i2c_driver = {
  274. .driver = {
  275. .name = "tegra-bpmp-i2c",
  276. .of_match_table = tegra_bpmp_i2c_of_match,
  277. },
  278. .probe = tegra_bpmp_i2c_probe,
  279. .remove = tegra_bpmp_i2c_remove,
  280. };
  281. module_platform_driver(tegra_bpmp_i2c_driver);
  282. MODULE_DESCRIPTION("NVIDIA Tegra BPMP I2C bus controller driver");
  283. MODULE_AUTHOR("Shardar Shariff Md <smohammed@nvidia.com>");
  284. MODULE_AUTHOR("Juha-Matti Tilli");
  285. MODULE_LICENSE("GPL v2");