ti_fpc202.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ti_fpc202.c - FPC202 Dual Port Controller driver
  4. *
  5. * Copyright (C) 2024 Bootlin
  6. *
  7. */
  8. #include <linux/cleanup.h>
  9. #include <linux/err.h>
  10. #include <linux/i2c.h>
  11. #include <linux/i2c-atr.h>
  12. #include <linux/gpio/consumer.h>
  13. #include <linux/gpio/driver.h>
  14. #include <linux/module.h>
  15. #define FPC202_NUM_PORTS 2
  16. #define FPC202_ALIASES_PER_PORT 2
  17. /*
  18. * GPIO: port mapping
  19. *
  20. * 0: P0_S0_IN_A
  21. * 1: P0_S1_IN_A
  22. * 2: P1_S0_IN_A
  23. * 3: P1_S1_IN_A
  24. * 4: P0_S0_IN_B
  25. * ...
  26. * 8: P0_S0_IN_C
  27. * ...
  28. * 12: P0_S0_OUT_A
  29. * ...
  30. * 16: P0_S0_OUT_B
  31. * ...
  32. * 19: P1_S1_OUT_B
  33. *
  34. */
  35. #define FPC202_GPIO_COUNT 20
  36. #define FPC202_GPIO_P0_S0_IN_B 4
  37. #define FPC202_GPIO_P0_S0_OUT_A 12
  38. #define FPC202_REG_IN_A_INT 0x6
  39. #define FPC202_REG_IN_C_IN_B 0x7
  40. #define FPC202_REG_OUT_A_OUT_B 0x8
  41. #define FPC202_REG_OUT_A_OUT_B_VAL 0xa
  42. #define FPC202_REG_MOD_DEV(port, dev) (0xb4 + ((port) * 4) + (dev))
  43. #define FPC202_REG_AUX_DEV(port, dev) (0xb6 + ((port) * 4) + (dev))
  44. /*
  45. * The FPC202 doesn't support turning off address translation on a single port.
  46. * So just set an invalid I2C address as the translation target when no client
  47. * address is attached.
  48. */
  49. #define FPC202_REG_DEV_INVALID 0
  50. /* Even aliases are assigned to device 0 and odd aliases to device 1 */
  51. #define fpc202_dev_num_from_alias(alias) ((alias) % 2)
  52. struct fpc202_priv {
  53. struct i2c_client *client;
  54. struct i2c_atr *atr;
  55. struct gpio_desc *en_gpio;
  56. struct gpio_chip gpio;
  57. /* Lock REG_MOD/AUX_DEV and addr_caches during attach/detach */
  58. struct mutex reg_dev_lock;
  59. /* Cached device addresses for both ports and their devices */
  60. u8 addr_caches[2][2];
  61. /* Keep track of which ports were probed */
  62. DECLARE_BITMAP(probed_ports, FPC202_NUM_PORTS);
  63. };
  64. static void fpc202_fill_alias_table(struct i2c_client *client, u16 *aliases, int port_id)
  65. {
  66. u16 first_alias;
  67. int i;
  68. /*
  69. * There is a predefined list of aliases for each FPC202 I2C
  70. * self-address. This allows daisy-chained FPC202 units to
  71. * automatically take on different sets of aliases.
  72. * Each port of an FPC202 unit is assigned two aliases from this list.
  73. */
  74. first_alias = 0x10 + 4 * port_id + 8 * ((u16)client->addr - 2);
  75. for (i = 0; i < FPC202_ALIASES_PER_PORT; i++)
  76. aliases[i] = first_alias + i;
  77. }
  78. static int fpc202_gpio_get_dir(int offset)
  79. {
  80. return offset < FPC202_GPIO_P0_S0_OUT_A ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
  81. }
  82. static int fpc202_read(struct fpc202_priv *priv, u8 reg)
  83. {
  84. int val;
  85. val = i2c_smbus_read_byte_data(priv->client, reg);
  86. return val;
  87. }
  88. static int fpc202_write(struct fpc202_priv *priv, u8 reg, u8 value)
  89. {
  90. return i2c_smbus_write_byte_data(priv->client, reg, value);
  91. }
  92. static void fpc202_set_enable(struct fpc202_priv *priv, int enable)
  93. {
  94. if (!priv->en_gpio)
  95. return;
  96. gpiod_set_value(priv->en_gpio, enable);
  97. }
  98. static int fpc202_gpio_set(struct gpio_chip *chip, unsigned int offset,
  99. int value)
  100. {
  101. struct fpc202_priv *priv = gpiochip_get_data(chip);
  102. int ret;
  103. u8 val;
  104. ret = fpc202_read(priv, FPC202_REG_OUT_A_OUT_B_VAL);
  105. if (ret < 0) {
  106. dev_err(&priv->client->dev, "Failed to set GPIO %d value! err %d\n", offset, ret);
  107. return ret;
  108. }
  109. val = (u8)ret;
  110. if (value)
  111. val |= BIT(offset - FPC202_GPIO_P0_S0_OUT_A);
  112. else
  113. val &= ~BIT(offset - FPC202_GPIO_P0_S0_OUT_A);
  114. return fpc202_write(priv, FPC202_REG_OUT_A_OUT_B_VAL, val);
  115. }
  116. static int fpc202_gpio_get(struct gpio_chip *chip, unsigned int offset)
  117. {
  118. struct fpc202_priv *priv = gpiochip_get_data(chip);
  119. u8 reg, bit;
  120. int ret;
  121. if (offset < FPC202_GPIO_P0_S0_IN_B) {
  122. reg = FPC202_REG_IN_A_INT;
  123. bit = BIT(4 + offset);
  124. } else if (offset < FPC202_GPIO_P0_S0_OUT_A) {
  125. reg = FPC202_REG_IN_C_IN_B;
  126. bit = BIT(offset - FPC202_GPIO_P0_S0_IN_B);
  127. } else {
  128. reg = FPC202_REG_OUT_A_OUT_B_VAL;
  129. bit = BIT(offset - FPC202_GPIO_P0_S0_OUT_A);
  130. }
  131. ret = fpc202_read(priv, reg);
  132. if (ret < 0)
  133. return ret;
  134. return !!(((u8)ret) & bit);
  135. }
  136. static int fpc202_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
  137. {
  138. if (fpc202_gpio_get_dir(offset) == GPIO_LINE_DIRECTION_OUT)
  139. return -EINVAL;
  140. return 0;
  141. }
  142. static int fpc202_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
  143. int value)
  144. {
  145. struct fpc202_priv *priv = gpiochip_get_data(chip);
  146. int ret;
  147. u8 val;
  148. if (fpc202_gpio_get_dir(offset) == GPIO_LINE_DIRECTION_IN)
  149. return -EINVAL;
  150. fpc202_gpio_set(chip, offset, value);
  151. ret = fpc202_read(priv, FPC202_REG_OUT_A_OUT_B);
  152. if (ret < 0)
  153. return ret;
  154. val = (u8)ret | BIT(offset - FPC202_GPIO_P0_S0_OUT_A);
  155. return fpc202_write(priv, FPC202_REG_OUT_A_OUT_B, val);
  156. }
  157. /*
  158. * Set the translation table entry associated with a port and device number.
  159. *
  160. * Each downstream port of the FPC202 has two fixed aliases corresponding to
  161. * device numbers 0 and 1. If one of these aliases is found in an incoming I2C
  162. * transfer, it will be translated to the address given by the corresponding
  163. * translation table entry.
  164. */
  165. static int fpc202_write_dev_addr(struct fpc202_priv *priv, u32 port_id, int dev_num, u16 addr)
  166. {
  167. int ret, reg_mod, reg_aux;
  168. u8 val;
  169. guard(mutex)(&priv->reg_dev_lock);
  170. reg_mod = FPC202_REG_MOD_DEV(port_id, dev_num);
  171. reg_aux = FPC202_REG_AUX_DEV(port_id, dev_num);
  172. val = addr & 0x7f;
  173. ret = fpc202_write(priv, reg_mod, val);
  174. if (ret)
  175. return ret;
  176. /*
  177. * The FPC202 datasheet is unclear about the role of the AUX registers.
  178. * Empirically, writing to them as well seems to be necessary for
  179. * address translation to function properly.
  180. */
  181. ret = fpc202_write(priv, reg_aux, val);
  182. priv->addr_caches[port_id][dev_num] = val;
  183. return ret;
  184. }
  185. static int fpc202_attach_addr(struct i2c_atr *atr, u32 chan_id,
  186. u16 addr, u16 alias)
  187. {
  188. struct fpc202_priv *priv = i2c_atr_get_driver_data(atr);
  189. dev_dbg(&priv->client->dev, "attaching address 0x%02x to alias 0x%02x\n", addr, alias);
  190. return fpc202_write_dev_addr(priv, chan_id, fpc202_dev_num_from_alias(alias), addr);
  191. }
  192. static void fpc202_detach_addr(struct i2c_atr *atr, u32 chan_id,
  193. u16 addr)
  194. {
  195. struct fpc202_priv *priv = i2c_atr_get_driver_data(atr);
  196. int dev_num, reg_mod, val;
  197. for (dev_num = 0; dev_num < 2; dev_num++) {
  198. reg_mod = FPC202_REG_MOD_DEV(chan_id, dev_num);
  199. mutex_lock(&priv->reg_dev_lock);
  200. val = priv->addr_caches[chan_id][dev_num];
  201. mutex_unlock(&priv->reg_dev_lock);
  202. if (val < 0) {
  203. dev_err(&priv->client->dev, "failed to read register 0x%x while detaching address 0x%02x\n",
  204. reg_mod, addr);
  205. return;
  206. }
  207. if (val == (addr & 0x7f)) {
  208. fpc202_write_dev_addr(priv, chan_id, dev_num, FPC202_REG_DEV_INVALID);
  209. return;
  210. }
  211. }
  212. }
  213. static const struct i2c_atr_ops fpc202_atr_ops = {
  214. .attach_addr = fpc202_attach_addr,
  215. .detach_addr = fpc202_detach_addr,
  216. };
  217. static int fpc202_probe_port(struct fpc202_priv *priv, struct device_node *i2c_handle, int port_id)
  218. {
  219. u16 aliases[FPC202_ALIASES_PER_PORT] = { };
  220. struct device *dev = &priv->client->dev;
  221. struct i2c_atr_adap_desc desc = { };
  222. int ret = 0;
  223. desc.chan_id = port_id;
  224. desc.parent = dev;
  225. desc.bus_handle = of_fwnode_handle(i2c_handle);
  226. desc.num_aliases = FPC202_ALIASES_PER_PORT;
  227. fpc202_fill_alias_table(priv->client, aliases, port_id);
  228. desc.aliases = aliases;
  229. ret = i2c_atr_add_adapter(priv->atr, &desc);
  230. if (ret)
  231. return ret;
  232. set_bit(port_id, priv->probed_ports);
  233. ret = fpc202_write_dev_addr(priv, port_id, 0, FPC202_REG_DEV_INVALID);
  234. if (ret)
  235. return ret;
  236. return fpc202_write_dev_addr(priv, port_id, 1, FPC202_REG_DEV_INVALID);
  237. }
  238. static void fpc202_remove_port(struct fpc202_priv *priv, int port_id)
  239. {
  240. i2c_atr_del_adapter(priv->atr, port_id);
  241. clear_bit(port_id, priv->probed_ports);
  242. }
  243. static int fpc202_probe(struct i2c_client *client)
  244. {
  245. struct device *dev = &client->dev;
  246. struct fpc202_priv *priv;
  247. int ret, port_id;
  248. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  249. if (!priv)
  250. return -ENOMEM;
  251. mutex_init(&priv->reg_dev_lock);
  252. priv->client = client;
  253. i2c_set_clientdata(client, priv);
  254. priv->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
  255. if (IS_ERR(priv->en_gpio)) {
  256. ret = PTR_ERR(priv->en_gpio);
  257. dev_err(dev, "failed to fetch enable GPIO! err %d\n", ret);
  258. goto destroy_mutex;
  259. }
  260. priv->gpio.label = "gpio-fpc202";
  261. priv->gpio.base = -1;
  262. priv->gpio.direction_input = fpc202_gpio_direction_input;
  263. priv->gpio.direction_output = fpc202_gpio_direction_output;
  264. priv->gpio.set = fpc202_gpio_set;
  265. priv->gpio.get = fpc202_gpio_get;
  266. priv->gpio.ngpio = FPC202_GPIO_COUNT;
  267. priv->gpio.parent = dev;
  268. priv->gpio.owner = THIS_MODULE;
  269. ret = gpiochip_add_data(&priv->gpio, priv);
  270. if (ret) {
  271. priv->gpio.parent = NULL;
  272. dev_err(dev, "failed to add gpiochip err %d\n", ret);
  273. goto disable_gpio;
  274. }
  275. priv->atr = i2c_atr_new(client->adapter, dev, &fpc202_atr_ops, 2, 0);
  276. if (IS_ERR(priv->atr)) {
  277. ret = PTR_ERR(priv->atr);
  278. dev_err(dev, "failed to create i2c atr err %d\n", ret);
  279. goto disable_gpio;
  280. }
  281. i2c_atr_set_driver_data(priv->atr, priv);
  282. bitmap_zero(priv->probed_ports, FPC202_NUM_PORTS);
  283. for_each_child_of_node_scoped(dev->of_node, i2c_handle) {
  284. ret = of_property_read_u32(i2c_handle, "reg", &port_id);
  285. if (ret) {
  286. if (ret == -EINVAL)
  287. continue;
  288. dev_err(dev, "failed to read 'reg' property of child node, err %d\n", ret);
  289. goto unregister_chans;
  290. }
  291. if (port_id > FPC202_NUM_PORTS) {
  292. dev_err(dev, "port ID %d is out of range!\n", port_id);
  293. ret = -EINVAL;
  294. goto unregister_chans;
  295. }
  296. ret = fpc202_probe_port(priv, i2c_handle, port_id);
  297. if (ret) {
  298. dev_err(dev, "Failed to probe port %d, err %d\n", port_id, ret);
  299. goto unregister_chans;
  300. }
  301. }
  302. goto out;
  303. unregister_chans:
  304. for_each_set_bit(port_id, priv->probed_ports, FPC202_NUM_PORTS)
  305. fpc202_remove_port(priv, port_id);
  306. i2c_atr_delete(priv->atr);
  307. disable_gpio:
  308. fpc202_set_enable(priv, 0);
  309. gpiochip_remove(&priv->gpio);
  310. destroy_mutex:
  311. mutex_destroy(&priv->reg_dev_lock);
  312. out:
  313. return ret;
  314. }
  315. static void fpc202_remove(struct i2c_client *client)
  316. {
  317. struct fpc202_priv *priv = i2c_get_clientdata(client);
  318. int port_id;
  319. for_each_set_bit(port_id, priv->probed_ports, FPC202_NUM_PORTS)
  320. fpc202_remove_port(priv, port_id);
  321. mutex_destroy(&priv->reg_dev_lock);
  322. i2c_atr_delete(priv->atr);
  323. fpc202_set_enable(priv, 0);
  324. gpiochip_remove(&priv->gpio);
  325. }
  326. static const struct of_device_id fpc202_of_match[] = {
  327. { .compatible = "ti,fpc202" },
  328. {}
  329. };
  330. MODULE_DEVICE_TABLE(of, fpc202_of_match);
  331. static struct i2c_driver fpc202_driver = {
  332. .driver = {
  333. .name = "fpc202",
  334. .of_match_table = fpc202_of_match,
  335. },
  336. .probe = fpc202_probe,
  337. .remove = fpc202_remove,
  338. };
  339. module_i2c_driver(fpc202_driver);
  340. MODULE_AUTHOR("Romain Gantois <romain.gantois@bootlin.com>");
  341. MODULE_DESCRIPTION("TI FPC202 Dual Port Controller driver");
  342. MODULE_LICENSE("GPL");
  343. MODULE_IMPORT_NS("I2C_ATR");