i2c-ljca.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Intel La Jolla Cove Adapter USB-I2C driver
  4. *
  5. * Copyright (c) 2023, Intel Corporation.
  6. */
  7. #include <linux/acpi.h>
  8. #include <linux/auxiliary_bus.h>
  9. #include <linux/bitfield.h>
  10. #include <linux/bits.h>
  11. #include <linux/dev_printk.h>
  12. #include <linux/i2c.h>
  13. #include <linux/module.h>
  14. #include <linux/usb/ljca.h>
  15. /* I2C init flags */
  16. #define LJCA_I2C_INIT_FLAG_MODE BIT(0)
  17. #define LJCA_I2C_INIT_FLAG_MODE_POLLING FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 0)
  18. #define LJCA_I2C_INIT_FLAG_MODE_INTERRUPT FIELD_PREP(LJCA_I2C_INIT_FLAG_MODE, 1)
  19. #define LJCA_I2C_INIT_FLAG_ADDR_16BIT BIT(0)
  20. #define LJCA_I2C_INIT_FLAG_FREQ GENMASK(2, 1)
  21. #define LJCA_I2C_INIT_FLAG_FREQ_100K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 0)
  22. #define LJCA_I2C_INIT_FLAG_FREQ_400K FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 1)
  23. #define LJCA_I2C_INIT_FLAG_FREQ_1M FIELD_PREP(LJCA_I2C_INIT_FLAG_FREQ, 2)
  24. #define LJCA_I2C_BUF_SIZE 60u
  25. #define LJCA_I2C_MAX_XFER_SIZE (LJCA_I2C_BUF_SIZE - sizeof(struct ljca_i2c_rw_packet))
  26. /* I2C commands */
  27. enum ljca_i2c_cmd {
  28. LJCA_I2C_INIT = 1,
  29. LJCA_I2C_XFER,
  30. LJCA_I2C_START,
  31. LJCA_I2C_STOP,
  32. LJCA_I2C_READ,
  33. LJCA_I2C_WRITE,
  34. };
  35. enum ljca_xfer_type {
  36. LJCA_I2C_WRITE_XFER_TYPE,
  37. LJCA_I2C_READ_XFER_TYPE,
  38. };
  39. /* I2C raw commands: Init/Start/Read/Write/Stop */
  40. struct ljca_i2c_rw_packet {
  41. u8 id;
  42. __le16 len;
  43. u8 data[] __counted_by(len);
  44. } __packed;
  45. struct ljca_i2c_dev {
  46. struct ljca_client *ljca;
  47. struct ljca_i2c_info *i2c_info;
  48. struct i2c_adapter adap;
  49. u8 obuf[LJCA_I2C_BUF_SIZE];
  50. u8 ibuf[LJCA_I2C_BUF_SIZE];
  51. };
  52. static int ljca_i2c_init(struct ljca_i2c_dev *ljca_i2c, u8 id)
  53. {
  54. struct ljca_i2c_rw_packet *w_packet =
  55. (struct ljca_i2c_rw_packet *)ljca_i2c->obuf;
  56. int ret;
  57. w_packet->id = id;
  58. w_packet->len = cpu_to_le16(sizeof(*w_packet->data));
  59. w_packet->data[0] = LJCA_I2C_INIT_FLAG_FREQ_400K;
  60. ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_INIT, (u8 *)w_packet,
  61. struct_size(w_packet, data, 1), NULL, 0);
  62. return ret < 0 ? ret : 0;
  63. }
  64. static int ljca_i2c_start(struct ljca_i2c_dev *ljca_i2c, u8 target_addr,
  65. enum ljca_xfer_type type)
  66. {
  67. struct ljca_i2c_rw_packet *w_packet =
  68. (struct ljca_i2c_rw_packet *)ljca_i2c->obuf;
  69. struct ljca_i2c_rw_packet *r_packet =
  70. (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf;
  71. s16 rp_len;
  72. int ret;
  73. w_packet->id = ljca_i2c->i2c_info->id;
  74. w_packet->len = cpu_to_le16(sizeof(*w_packet->data));
  75. w_packet->data[0] = (target_addr << 1) | type;
  76. ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_START, (u8 *)w_packet,
  77. struct_size(w_packet, data, 1), (u8 *)r_packet,
  78. LJCA_I2C_BUF_SIZE);
  79. if (ret < 0 || ret < sizeof(*r_packet))
  80. return ret < 0 ? ret : -EIO;
  81. rp_len = le16_to_cpu(r_packet->len);
  82. if (rp_len < 0 || r_packet->id != w_packet->id) {
  83. dev_dbg(&ljca_i2c->adap.dev,
  84. "i2c start failed len: %d id: %d %d\n",
  85. rp_len, r_packet->id, w_packet->id);
  86. return -EIO;
  87. }
  88. return 0;
  89. }
  90. static void ljca_i2c_stop(struct ljca_i2c_dev *ljca_i2c)
  91. {
  92. struct ljca_i2c_rw_packet *w_packet =
  93. (struct ljca_i2c_rw_packet *)ljca_i2c->obuf;
  94. struct ljca_i2c_rw_packet *r_packet =
  95. (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf;
  96. s16 rp_len;
  97. int ret;
  98. w_packet->id = ljca_i2c->i2c_info->id;
  99. w_packet->len = cpu_to_le16(sizeof(*w_packet->data));
  100. w_packet->data[0] = 0;
  101. ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_STOP, (u8 *)w_packet,
  102. struct_size(w_packet, data, 1), (u8 *)r_packet,
  103. LJCA_I2C_BUF_SIZE);
  104. if (ret < 0 || ret < sizeof(*r_packet)) {
  105. dev_dbg(&ljca_i2c->adap.dev,
  106. "i2c stop failed ret: %d id: %d\n",
  107. ret, w_packet->id);
  108. return;
  109. }
  110. rp_len = le16_to_cpu(r_packet->len);
  111. if (rp_len < 0 || r_packet->id != w_packet->id)
  112. dev_dbg(&ljca_i2c->adap.dev,
  113. "i2c stop failed len: %d id: %d %d\n",
  114. rp_len, r_packet->id, w_packet->id);
  115. }
  116. static int ljca_i2c_pure_read(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len)
  117. {
  118. struct ljca_i2c_rw_packet *w_packet =
  119. (struct ljca_i2c_rw_packet *)ljca_i2c->obuf;
  120. struct ljca_i2c_rw_packet *r_packet =
  121. (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf;
  122. s16 rp_len;
  123. int ret;
  124. w_packet->id = ljca_i2c->i2c_info->id;
  125. w_packet->len = cpu_to_le16(len);
  126. w_packet->data[0] = 0;
  127. ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_READ, (u8 *)w_packet,
  128. struct_size(w_packet, data, 1), (u8 *)r_packet,
  129. LJCA_I2C_BUF_SIZE);
  130. if (ret < 0 || ret < sizeof(*r_packet))
  131. return ret < 0 ? ret : -EIO;
  132. rp_len = le16_to_cpu(r_packet->len);
  133. if (rp_len != len || r_packet->id != w_packet->id) {
  134. dev_dbg(&ljca_i2c->adap.dev,
  135. "i2c raw read failed len: %d id: %d %d\n",
  136. rp_len, r_packet->id, w_packet->id);
  137. return -EIO;
  138. }
  139. memcpy(data, r_packet->data, len);
  140. return 0;
  141. }
  142. static int ljca_i2c_read(struct ljca_i2c_dev *ljca_i2c, u8 target_addr, u8 *data,
  143. u8 len)
  144. {
  145. int ret;
  146. ret = ljca_i2c_start(ljca_i2c, target_addr, LJCA_I2C_READ_XFER_TYPE);
  147. if (!ret)
  148. ret = ljca_i2c_pure_read(ljca_i2c, data, len);
  149. ljca_i2c_stop(ljca_i2c);
  150. return ret;
  151. }
  152. static int ljca_i2c_pure_write(struct ljca_i2c_dev *ljca_i2c, u8 *data, u8 len)
  153. {
  154. struct ljca_i2c_rw_packet *w_packet =
  155. (struct ljca_i2c_rw_packet *)ljca_i2c->obuf;
  156. struct ljca_i2c_rw_packet *r_packet =
  157. (struct ljca_i2c_rw_packet *)ljca_i2c->ibuf;
  158. s16 rplen;
  159. int ret;
  160. w_packet->id = ljca_i2c->i2c_info->id;
  161. w_packet->len = cpu_to_le16(len);
  162. memcpy(w_packet->data, data, len);
  163. ret = ljca_transfer(ljca_i2c->ljca, LJCA_I2C_WRITE, (u8 *)w_packet,
  164. struct_size(w_packet, data, len), (u8 *)r_packet,
  165. LJCA_I2C_BUF_SIZE);
  166. if (ret < 0 || ret < sizeof(*r_packet))
  167. return ret < 0 ? ret : -EIO;
  168. rplen = le16_to_cpu(r_packet->len);
  169. if (rplen != len || r_packet->id != w_packet->id) {
  170. dev_dbg(&ljca_i2c->adap.dev,
  171. "i2c write failed len: %d id: %d/%d\n",
  172. rplen, r_packet->id, w_packet->id);
  173. return -EIO;
  174. }
  175. return 0;
  176. }
  177. static int ljca_i2c_write(struct ljca_i2c_dev *ljca_i2c, u8 target_addr,
  178. u8 *data, u8 len)
  179. {
  180. int ret;
  181. ret = ljca_i2c_start(ljca_i2c, target_addr, LJCA_I2C_WRITE_XFER_TYPE);
  182. if (!ret)
  183. ret = ljca_i2c_pure_write(ljca_i2c, data, len);
  184. ljca_i2c_stop(ljca_i2c);
  185. return ret;
  186. }
  187. static int ljca_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg,
  188. int num)
  189. {
  190. struct ljca_i2c_dev *ljca_i2c;
  191. struct i2c_msg *cur_msg;
  192. int i, ret;
  193. ljca_i2c = i2c_get_adapdata(adapter);
  194. if (!ljca_i2c)
  195. return -EINVAL;
  196. for (i = 0; i < num; i++) {
  197. cur_msg = &msg[i];
  198. if (cur_msg->flags & I2C_M_RD)
  199. ret = ljca_i2c_read(ljca_i2c, cur_msg->addr,
  200. cur_msg->buf, cur_msg->len);
  201. else
  202. ret = ljca_i2c_write(ljca_i2c, cur_msg->addr,
  203. cur_msg->buf, cur_msg->len);
  204. if (ret)
  205. return ret;
  206. }
  207. return num;
  208. }
  209. static u32 ljca_i2c_func(struct i2c_adapter *adap)
  210. {
  211. return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
  212. }
  213. static const struct i2c_adapter_quirks ljca_i2c_quirks = {
  214. .flags = I2C_AQ_NO_ZERO_LEN,
  215. .max_read_len = LJCA_I2C_MAX_XFER_SIZE,
  216. .max_write_len = LJCA_I2C_MAX_XFER_SIZE,
  217. };
  218. static const struct i2c_algorithm ljca_i2c_algo = {
  219. .xfer = ljca_i2c_xfer,
  220. .functionality = ljca_i2c_func,
  221. };
  222. static int ljca_i2c_probe(struct auxiliary_device *auxdev,
  223. const struct auxiliary_device_id *aux_dev_id)
  224. {
  225. struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev);
  226. struct ljca_i2c_dev *ljca_i2c;
  227. int ret;
  228. ljca_i2c = devm_kzalloc(&auxdev->dev, sizeof(*ljca_i2c), GFP_KERNEL);
  229. if (!ljca_i2c)
  230. return -ENOMEM;
  231. ljca_i2c->ljca = ljca;
  232. ljca_i2c->i2c_info = dev_get_platdata(&auxdev->dev);
  233. ljca_i2c->adap.owner = THIS_MODULE;
  234. ljca_i2c->adap.class = I2C_CLASS_HWMON;
  235. ljca_i2c->adap.algo = &ljca_i2c_algo;
  236. ljca_i2c->adap.quirks = &ljca_i2c_quirks;
  237. ljca_i2c->adap.dev.parent = &auxdev->dev;
  238. snprintf(ljca_i2c->adap.name, sizeof(ljca_i2c->adap.name), "%s-%s-%d",
  239. dev_name(&auxdev->dev), dev_name(auxdev->dev.parent),
  240. ljca_i2c->i2c_info->id);
  241. device_set_node(&ljca_i2c->adap.dev, dev_fwnode(&auxdev->dev));
  242. i2c_set_adapdata(&ljca_i2c->adap, ljca_i2c);
  243. auxiliary_set_drvdata(auxdev, ljca_i2c);
  244. ret = ljca_i2c_init(ljca_i2c, ljca_i2c->i2c_info->id);
  245. if (ret)
  246. return dev_err_probe(&auxdev->dev, -EIO,
  247. "i2c init failed id: %d\n",
  248. ljca_i2c->i2c_info->id);
  249. ret = devm_i2c_add_adapter(&auxdev->dev, &ljca_i2c->adap);
  250. if (ret)
  251. return ret;
  252. if (has_acpi_companion(&ljca_i2c->adap.dev))
  253. acpi_dev_clear_dependencies(ACPI_COMPANION(&ljca_i2c->adap.dev));
  254. return 0;
  255. }
  256. static void ljca_i2c_remove(struct auxiliary_device *auxdev)
  257. {
  258. struct ljca_i2c_dev *ljca_i2c = auxiliary_get_drvdata(auxdev);
  259. i2c_del_adapter(&ljca_i2c->adap);
  260. }
  261. static const struct auxiliary_device_id ljca_i2c_id_table[] = {
  262. { "usb_ljca.ljca-i2c", 0 },
  263. { /* sentinel */ }
  264. };
  265. MODULE_DEVICE_TABLE(auxiliary, ljca_i2c_id_table);
  266. static struct auxiliary_driver ljca_i2c_driver = {
  267. .probe = ljca_i2c_probe,
  268. .remove = ljca_i2c_remove,
  269. .id_table = ljca_i2c_id_table,
  270. };
  271. module_auxiliary_driver(ljca_i2c_driver);
  272. MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>");
  273. MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>");
  274. MODULE_AUTHOR("Lixu Zhang <lixu.zhang@intel.com>");
  275. MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-I2C driver");
  276. MODULE_LICENSE("GPL");
  277. MODULE_IMPORT_NS(LJCA);