i2c-powermac.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. i2c Support for Apple SMU Controller
  4. Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.
  5. <benh@kernel.crashing.org>
  6. */
  7. #include <linux/module.h>
  8. #include <linux/kernel.h>
  9. #include <linux/types.h>
  10. #include <linux/i2c.h>
  11. #include <linux/device.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/of_irq.h>
  14. #include <asm/pmac_low_i2c.h>
  15. MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
  16. MODULE_DESCRIPTION("I2C driver for Apple PowerMac");
  17. MODULE_LICENSE("GPL");
  18. /*
  19. * SMBUS-type transfer entrypoint
  20. */
  21. static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap,
  22. u16 addr,
  23. unsigned short flags,
  24. char read_write,
  25. u8 command,
  26. int size,
  27. union i2c_smbus_data* data)
  28. {
  29. struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
  30. int rc = 0;
  31. int read = (read_write == I2C_SMBUS_READ);
  32. int addrdir = (addr << 1) | read;
  33. int mode, subsize, len;
  34. u32 subaddr;
  35. u8 *buf;
  36. u8 local[2];
  37. if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE) {
  38. mode = pmac_i2c_mode_std;
  39. subsize = 0;
  40. subaddr = 0;
  41. } else {
  42. mode = read ? pmac_i2c_mode_combined : pmac_i2c_mode_stdsub;
  43. subsize = 1;
  44. subaddr = command;
  45. }
  46. switch (size) {
  47. case I2C_SMBUS_QUICK:
  48. buf = NULL;
  49. len = 0;
  50. break;
  51. case I2C_SMBUS_BYTE:
  52. case I2C_SMBUS_BYTE_DATA:
  53. buf = &data->byte;
  54. len = 1;
  55. break;
  56. case I2C_SMBUS_WORD_DATA:
  57. if (!read) {
  58. local[0] = data->word & 0xff;
  59. local[1] = (data->word >> 8) & 0xff;
  60. }
  61. buf = local;
  62. len = 2;
  63. break;
  64. /* Note that these are broken vs. the expected smbus API where
  65. * on reads, the length is actually returned from the function,
  66. * but I think the current API makes no sense and I don't want
  67. * any driver that I haven't verified for correctness to go
  68. * anywhere near a pmac i2c bus anyway ...
  69. */
  70. case I2C_SMBUS_BLOCK_DATA:
  71. buf = data->block;
  72. len = data->block[0] + 1;
  73. break;
  74. case I2C_SMBUS_I2C_BLOCK_DATA:
  75. buf = &data->block[1];
  76. len = data->block[0];
  77. break;
  78. default:
  79. return -EINVAL;
  80. }
  81. rc = pmac_i2c_open(bus, 0);
  82. if (rc) {
  83. dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
  84. return rc;
  85. }
  86. rc = pmac_i2c_setmode(bus, mode);
  87. if (rc) {
  88. dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
  89. mode, rc);
  90. goto bail;
  91. }
  92. rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
  93. if (rc) {
  94. if (rc == -ENXIO)
  95. dev_dbg(&adap->dev,
  96. "I2C transfer at 0x%02x failed, size %d, "
  97. "err %d\n", addrdir >> 1, size, rc);
  98. else
  99. dev_err(&adap->dev,
  100. "I2C transfer at 0x%02x failed, size %d, "
  101. "err %d\n", addrdir >> 1, size, rc);
  102. goto bail;
  103. }
  104. if (size == I2C_SMBUS_WORD_DATA && read) {
  105. data->word = ((u16)local[1]) << 8;
  106. data->word |= local[0];
  107. }
  108. bail:
  109. pmac_i2c_close(bus);
  110. return rc;
  111. }
  112. /*
  113. * Generic i2c transfer entrypoint. This driver only supports single
  114. * messages (for "lame i2c" transfers). Anything else should use the smbus
  115. * entry point
  116. */
  117. static int i2c_powermac_xfer(struct i2c_adapter *adap,
  118. struct i2c_msg *msgs,
  119. int num)
  120. {
  121. struct pmac_i2c_bus *bus = i2c_get_adapdata(adap);
  122. int rc = 0;
  123. int addrdir;
  124. if (msgs->flags & I2C_M_TEN)
  125. return -EINVAL;
  126. addrdir = i2c_8bit_addr_from_msg(msgs);
  127. rc = pmac_i2c_open(bus, 0);
  128. if (rc) {
  129. dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
  130. return rc;
  131. }
  132. rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
  133. if (rc) {
  134. dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
  135. pmac_i2c_mode_std, rc);
  136. goto bail;
  137. }
  138. rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
  139. if (rc < 0) {
  140. if (rc == -ENXIO)
  141. dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
  142. addrdir & 1 ? "read from" : "write to",
  143. addrdir >> 1, rc);
  144. else
  145. dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
  146. addrdir & 1 ? "read from" : "write to",
  147. addrdir >> 1, rc);
  148. }
  149. bail:
  150. pmac_i2c_close(bus);
  151. return rc < 0 ? rc : 1;
  152. }
  153. static u32 i2c_powermac_func(struct i2c_adapter * adapter)
  154. {
  155. return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
  156. I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
  157. I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C;
  158. }
  159. /* For now, we only handle smbus */
  160. static const struct i2c_algorithm i2c_powermac_algorithm = {
  161. .smbus_xfer = i2c_powermac_smbus_xfer,
  162. .xfer = i2c_powermac_xfer,
  163. .functionality = i2c_powermac_func,
  164. };
  165. static const struct i2c_adapter_quirks i2c_powermac_quirks = {
  166. .max_num_msgs = 1,
  167. };
  168. static void i2c_powermac_remove(struct platform_device *dev)
  169. {
  170. struct i2c_adapter *adapter = platform_get_drvdata(dev);
  171. i2c_del_adapter(adapter);
  172. memset(adapter, 0, sizeof(*adapter));
  173. }
  174. static u32 i2c_powermac_get_addr(struct i2c_adapter *adap,
  175. struct pmac_i2c_bus *bus,
  176. struct device_node *node)
  177. {
  178. u32 prop;
  179. int ret;
  180. /* First check for valid "reg" */
  181. ret = of_property_read_u32(node, "reg", &prop);
  182. if (ret == 0)
  183. return (prop & 0xff) >> 1;
  184. /* Then check old-style "i2c-address" */
  185. ret = of_property_read_u32(node, "i2c-address", &prop);
  186. if (ret == 0)
  187. return (prop & 0xff) >> 1;
  188. /* Now handle some devices with missing "reg" properties */
  189. if (of_node_name_eq(node, "cereal"))
  190. return 0x60;
  191. else if (of_node_name_eq(node, "deq"))
  192. return 0x34;
  193. dev_warn(&adap->dev, "No i2c address for %pOF\n", node);
  194. return 0xffffffff;
  195. }
  196. static void i2c_powermac_create_one(struct i2c_adapter *adap,
  197. const char *type,
  198. u32 addr)
  199. {
  200. struct i2c_board_info info = {};
  201. struct i2c_client *newdev;
  202. strscpy(info.type, type, sizeof(info.type));
  203. info.addr = addr;
  204. newdev = i2c_new_client_device(adap, &info);
  205. if (IS_ERR(newdev))
  206. dev_err(&adap->dev,
  207. "i2c-powermac: Failure to register missing %s\n",
  208. type);
  209. }
  210. static void i2c_powermac_add_missing(struct i2c_adapter *adap,
  211. struct pmac_i2c_bus *bus,
  212. bool found_onyx)
  213. {
  214. struct device_node *busnode = pmac_i2c_get_bus_node(bus);
  215. int rc;
  216. /* Check for the onyx audio codec */
  217. #define ONYX_REG_CONTROL 67
  218. if (of_device_is_compatible(busnode, "k2-i2c") && !found_onyx) {
  219. union i2c_smbus_data data;
  220. rc = i2c_smbus_xfer(adap, 0x46, 0, I2C_SMBUS_READ,
  221. ONYX_REG_CONTROL, I2C_SMBUS_BYTE_DATA,
  222. &data);
  223. if (rc >= 0)
  224. i2c_powermac_create_one(adap, "MAC,pcm3052", 0x46);
  225. rc = i2c_smbus_xfer(adap, 0x47, 0, I2C_SMBUS_READ,
  226. ONYX_REG_CONTROL, I2C_SMBUS_BYTE_DATA,
  227. &data);
  228. if (rc >= 0)
  229. i2c_powermac_create_one(adap, "MAC,pcm3052", 0x47);
  230. }
  231. }
  232. static bool i2c_powermac_get_type(struct i2c_adapter *adap,
  233. struct device_node *node,
  234. u32 addr, char *type, int type_size)
  235. {
  236. char tmp[16];
  237. /*
  238. * Note: we do _NOT_ want the standard i2c drivers to match with any of
  239. * our powermac stuff unless they have been specifically modified to
  240. * handle it on a case by case basis. For example, for thermal control,
  241. * things like lm75 etc... shall match with their corresponding
  242. * windfarm drivers, _NOT_ the generic ones, so we force a prefix of
  243. * 'MAC', onto the modalias to make that happen
  244. */
  245. /* First try proper modalias */
  246. if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) {
  247. snprintf(type, type_size, "MAC,%s", tmp);
  248. return true;
  249. }
  250. /* Now look for known workarounds */
  251. if (of_node_name_eq(node, "deq")) {
  252. /* Apple uses address 0x34 for TAS3001 and 0x35 for TAS3004 */
  253. if (addr == 0x34) {
  254. snprintf(type, type_size, "MAC,tas3001");
  255. return true;
  256. } else if (addr == 0x35) {
  257. snprintf(type, type_size, "MAC,tas3004");
  258. return true;
  259. }
  260. }
  261. dev_err(&adap->dev, "i2c-powermac: modalias failure on %pOF\n", node);
  262. return false;
  263. }
  264. static void i2c_powermac_register_devices(struct i2c_adapter *adap,
  265. struct pmac_i2c_bus *bus)
  266. {
  267. struct i2c_client *newdev;
  268. struct device_node *node;
  269. bool found_onyx = false;
  270. /*
  271. * In some cases we end up with the via-pmu node itself, in this
  272. * case we skip this function completely as the device-tree will
  273. * not contain anything useful.
  274. */
  275. if (of_node_name_eq(adap->dev.of_node, "via-pmu"))
  276. return;
  277. for_each_child_of_node(adap->dev.of_node, node) {
  278. struct i2c_board_info info = {};
  279. u32 addr;
  280. /* Get address & channel */
  281. addr = i2c_powermac_get_addr(adap, bus, node);
  282. if (addr == 0xffffffff)
  283. continue;
  284. /* Multibus setup, check channel */
  285. if (!pmac_i2c_match_adapter(node, adap))
  286. continue;
  287. dev_dbg(&adap->dev, "i2c-powermac: register %pOF\n", node);
  288. /*
  289. * Keep track of some device existence to handle
  290. * workarounds later.
  291. */
  292. if (of_device_is_compatible(node, "pcm3052"))
  293. found_onyx = true;
  294. /* Make up a modalias */
  295. if (!i2c_powermac_get_type(adap, node, addr,
  296. info.type, sizeof(info.type))) {
  297. continue;
  298. }
  299. /* Fill out the rest of the info structure */
  300. info.addr = addr;
  301. info.irq = irq_of_parse_and_map(node, 0);
  302. info.of_node = of_node_get(node);
  303. newdev = i2c_new_client_device(adap, &info);
  304. if (IS_ERR(newdev)) {
  305. dev_err(&adap->dev, "i2c-powermac: Failure to register"
  306. " %pOF\n", node);
  307. of_node_put(node);
  308. /* We do not dispose of the interrupt mapping on
  309. * purpose. It's not necessary (interrupt cannot be
  310. * re-used) and somebody else might have grabbed it
  311. * via direct DT lookup so let's not bother
  312. */
  313. continue;
  314. }
  315. }
  316. /* Additional workarounds */
  317. i2c_powermac_add_missing(adap, bus, found_onyx);
  318. }
  319. static int i2c_powermac_probe(struct platform_device *dev)
  320. {
  321. struct pmac_i2c_bus *bus = dev_get_platdata(&dev->dev);
  322. struct device_node *parent;
  323. struct i2c_adapter *adapter;
  324. int rc;
  325. if (bus == NULL)
  326. return -EINVAL;
  327. adapter = pmac_i2c_get_adapter(bus);
  328. /* Ok, now we need to make up a name for the interface that will
  329. * match what we used to do in the past, that is basically the
  330. * controller's parent device node for keywest. PMU didn't have a
  331. * naming convention and SMU has a different one
  332. */
  333. switch(pmac_i2c_get_type(bus)) {
  334. case pmac_i2c_bus_keywest:
  335. parent = of_get_parent(pmac_i2c_get_controller(bus));
  336. if (parent == NULL)
  337. return -EINVAL;
  338. snprintf(adapter->name, sizeof(adapter->name), "%pOFn %d",
  339. parent,
  340. pmac_i2c_get_channel(bus));
  341. of_node_put(parent);
  342. break;
  343. case pmac_i2c_bus_pmu:
  344. snprintf(adapter->name, sizeof(adapter->name), "pmu %d",
  345. pmac_i2c_get_channel(bus));
  346. break;
  347. case pmac_i2c_bus_smu:
  348. /* This is not what we used to do but I'm fixing drivers at
  349. * the same time as this change
  350. */
  351. snprintf(adapter->name, sizeof(adapter->name), "smu %d",
  352. pmac_i2c_get_channel(bus));
  353. break;
  354. default:
  355. return -EINVAL;
  356. }
  357. platform_set_drvdata(dev, adapter);
  358. adapter->algo = &i2c_powermac_algorithm;
  359. adapter->quirks = &i2c_powermac_quirks;
  360. i2c_set_adapdata(adapter, bus);
  361. adapter->dev.parent = &dev->dev;
  362. /* Clear of_node to skip automatic registration of i2c child nodes */
  363. adapter->dev.of_node = NULL;
  364. rc = i2c_add_adapter(adapter);
  365. if (rc) {
  366. printk(KERN_ERR "i2c-powermac: Adapter %s registration "
  367. "failed\n", adapter->name);
  368. memset(adapter, 0, sizeof(*adapter));
  369. return rc;
  370. }
  371. printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
  372. /* Use custom child registration due to Apple device-tree funkyness */
  373. adapter->dev.of_node = dev->dev.of_node;
  374. i2c_powermac_register_devices(adapter, bus);
  375. return 0;
  376. }
  377. static struct platform_driver i2c_powermac_driver = {
  378. .probe = i2c_powermac_probe,
  379. .remove_new = i2c_powermac_remove,
  380. .driver = {
  381. .name = "i2c-powermac",
  382. .bus = &platform_bus_type,
  383. },
  384. };
  385. module_platform_driver(i2c_powermac_driver);
  386. MODULE_ALIAS("platform:i2c-powermac");