ch7322.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Driver for the Chrontel CH7322 CEC Controller
  4. *
  5. * Copyright 2020 Google LLC.
  6. */
  7. /*
  8. * Notes
  9. *
  10. * - This device powers on in Auto Mode which has limited functionality. This
  11. * driver disables Auto Mode when it attaches.
  12. *
  13. */
  14. #include <linux/cec.h>
  15. #include <linux/dmi.h>
  16. #include <linux/i2c.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/module.h>
  19. #include <linux/mutex.h>
  20. #include <linux/pci.h>
  21. #include <linux/regmap.h>
  22. #include <media/cec.h>
  23. #include <media/cec-notifier.h>
  24. #define CH7322_WRITE 0x00
  25. #define CH7322_WRITE_MSENT 0x80
  26. #define CH7322_WRITE_BOK 0x40
  27. #define CH7322_WRITE_NMASK 0x0f
  28. /* Write buffer is 0x01-0x10 */
  29. #define CH7322_WRBUF 0x01
  30. #define CH7322_WRBUF_LEN 0x10
  31. #define CH7322_READ 0x40
  32. #define CH7322_READ_NRDT 0x80
  33. #define CH7322_READ_MSENT 0x20
  34. #define CH7322_READ_NMASK 0x0f
  35. /* Read buffer is 0x41-0x50 */
  36. #define CH7322_RDBUF 0x41
  37. #define CH7322_RDBUF_LEN 0x10
  38. #define CH7322_MODE 0x11
  39. #define CH7322_MODE_AUTO 0x78
  40. #define CH7322_MODE_SW 0xb5
  41. #define CH7322_RESET 0x12
  42. #define CH7322_RESET_RST 0x00
  43. #define CH7322_POWER 0x13
  44. #define CH7322_POWER_FPD 0x04
  45. #define CH7322_CFG0 0x17
  46. #define CH7322_CFG0_EOBEN 0x40
  47. #define CH7322_CFG0_PEOB 0x20
  48. #define CH7322_CFG0_CLRSPP 0x10
  49. #define CH7322_CFG0_FLOW 0x08
  50. #define CH7322_CFG1 0x1a
  51. #define CH7322_CFG1_STDBYO 0x04
  52. #define CH7322_CFG1_HPBP 0x02
  53. #define CH7322_CFG1_PIO 0x01
  54. #define CH7322_INTCTL 0x1b
  55. #define CH7322_INTCTL_INTPB 0x80
  56. #define CH7322_INTCTL_STDBY 0x40
  57. #define CH7322_INTCTL_HPDFALL 0x20
  58. #define CH7322_INTCTL_HPDRISE 0x10
  59. #define CH7322_INTCTL_RXMSG 0x08
  60. #define CH7322_INTCTL_TXMSG 0x04
  61. #define CH7322_INTCTL_NEWPHA 0x02
  62. #define CH7322_INTCTL_ERROR 0x01
  63. #define CH7322_DVCLKFNH 0x1d
  64. #define CH7322_DVCLKFNL 0x1e
  65. #define CH7322_CTL 0x31
  66. #define CH7322_CTL_FSTDBY 0x80
  67. #define CH7322_CTL_PLSEN 0x40
  68. #define CH7322_CTL_PLSPB 0x20
  69. #define CH7322_CTL_SPADL 0x10
  70. #define CH7322_CTL_HINIT 0x08
  71. #define CH7322_CTL_WPHYA 0x04
  72. #define CH7322_CTL_H1T 0x02
  73. #define CH7322_CTL_S1T 0x01
  74. #define CH7322_PAWH 0x32
  75. #define CH7322_PAWL 0x33
  76. #define CH7322_ADDLW 0x34
  77. #define CH7322_ADDLW_MASK 0xf0
  78. #define CH7322_ADDLR 0x3d
  79. #define CH7322_ADDLR_HPD 0x80
  80. #define CH7322_ADDLR_MASK 0x0f
  81. #define CH7322_INTDATA 0x3e
  82. #define CH7322_INTDATA_MODE 0x80
  83. #define CH7322_INTDATA_STDBY 0x40
  84. #define CH7322_INTDATA_HPDFALL 0x20
  85. #define CH7322_INTDATA_HPDRISE 0x10
  86. #define CH7322_INTDATA_RXMSG 0x08
  87. #define CH7322_INTDATA_TXMSG 0x04
  88. #define CH7322_INTDATA_NEWPHA 0x02
  89. #define CH7322_INTDATA_ERROR 0x01
  90. #define CH7322_EVENT 0x3f
  91. #define CH7322_EVENT_TXERR 0x80
  92. #define CH7322_EVENT_HRST 0x40
  93. #define CH7322_EVENT_HFST 0x20
  94. #define CH7322_EVENT_PHACHG 0x10
  95. #define CH7322_EVENT_ACTST 0x08
  96. #define CH7322_EVENT_PHARDY 0x04
  97. #define CH7322_EVENT_BSOK 0x02
  98. #define CH7322_EVENT_ERRADCF 0x01
  99. #define CH7322_DID 0x51
  100. #define CH7322_DID_CH7322 0x5b
  101. #define CH7322_DID_CH7323 0x5f
  102. #define CH7322_REVISIONID 0x52
  103. #define CH7322_PARH 0x53
  104. #define CH7322_PARL 0x54
  105. #define CH7322_IOCFG2 0x75
  106. #define CH7322_IOCFG_CIO 0x80
  107. #define CH7322_IOCFG_IOCFGMASK 0x78
  108. #define CH7322_IOCFG_AUDIO 0x04
  109. #define CH7322_IOCFG_SPAMST 0x02
  110. #define CH7322_IOCFG_SPAMSP 0x01
  111. #define CH7322_CTL3 0x7b
  112. #define CH7322_CTL3_SWENA 0x80
  113. #define CH7322_CTL3_FC_INIT 0x40
  114. #define CH7322_CTL3_SML_FL 0x20
  115. #define CH7322_CTL3_SM_RDST 0x10
  116. #define CH7322_CTL3_SPP_CIAH 0x08
  117. #define CH7322_CTL3_SPP_CIAL 0x04
  118. #define CH7322_CTL3_SPP_ACTH 0x02
  119. #define CH7322_CTL3_SPP_ACTL 0x01
  120. /* BOK status means NACK */
  121. #define CH7322_TX_FLAG_NACK BIT(0)
  122. /* Device will retry automatically */
  123. #define CH7322_TX_FLAG_RETRY BIT(1)
  124. struct ch7322 {
  125. struct i2c_client *i2c;
  126. struct regmap *regmap;
  127. struct cec_adapter *cec;
  128. struct mutex mutex; /* device access mutex */
  129. u8 tx_flags;
  130. };
  131. static const struct regmap_config ch7322_regmap = {
  132. .reg_bits = 8,
  133. .val_bits = 8,
  134. .max_register = 0x7f,
  135. .disable_locking = true,
  136. };
  137. static int ch7322_send_message(struct ch7322 *ch7322, const struct cec_msg *msg)
  138. {
  139. unsigned int val;
  140. unsigned int len = msg->len;
  141. int ret;
  142. int i;
  143. WARN_ON(!mutex_is_locked(&ch7322->mutex));
  144. if (len > CH7322_WRBUF_LEN || len < 1)
  145. return -EINVAL;
  146. ret = regmap_read(ch7322->regmap, CH7322_WRITE, &val);
  147. if (ret)
  148. return ret;
  149. /* Buffer not ready */
  150. if (!(val & CH7322_WRITE_MSENT))
  151. return -EBUSY;
  152. if (cec_msg_opcode(msg) == -1 &&
  153. cec_msg_initiator(msg) == cec_msg_destination(msg)) {
  154. ch7322->tx_flags = CH7322_TX_FLAG_NACK | CH7322_TX_FLAG_RETRY;
  155. } else if (cec_msg_is_broadcast(msg)) {
  156. ch7322->tx_flags = CH7322_TX_FLAG_NACK;
  157. } else {
  158. ch7322->tx_flags = CH7322_TX_FLAG_RETRY;
  159. }
  160. ret = regmap_write(ch7322->regmap, CH7322_WRITE, len - 1);
  161. if (ret)
  162. return ret;
  163. for (i = 0; i < len; i++) {
  164. ret = regmap_write(ch7322->regmap,
  165. CH7322_WRBUF + i, msg->msg[i]);
  166. if (ret)
  167. return ret;
  168. }
  169. return 0;
  170. }
  171. static int ch7322_receive_message(struct ch7322 *ch7322, struct cec_msg *msg)
  172. {
  173. unsigned int val;
  174. int ret = 0;
  175. int i;
  176. WARN_ON(!mutex_is_locked(&ch7322->mutex));
  177. ret = regmap_read(ch7322->regmap, CH7322_READ, &val);
  178. if (ret)
  179. return ret;
  180. /* Message not ready */
  181. if (!(val & CH7322_READ_NRDT))
  182. return -EIO;
  183. msg->len = (val & CH7322_READ_NMASK) + 1;
  184. /* Read entire RDBUF to clear state */
  185. for (i = 0; i < CH7322_RDBUF_LEN; i++) {
  186. ret = regmap_read(ch7322->regmap, CH7322_RDBUF + i, &val);
  187. if (ret)
  188. return ret;
  189. msg->msg[i] = (u8)val;
  190. }
  191. return 0;
  192. }
  193. static void ch7322_tx_done(struct ch7322 *ch7322)
  194. {
  195. int ret;
  196. unsigned int val;
  197. u8 status, flags;
  198. mutex_lock(&ch7322->mutex);
  199. ret = regmap_read(ch7322->regmap, CH7322_WRITE, &val);
  200. flags = ch7322->tx_flags;
  201. mutex_unlock(&ch7322->mutex);
  202. /*
  203. * The device returns a one-bit OK status which usually means ACK but
  204. * actually means NACK when sending a logical address query or a
  205. * broadcast.
  206. */
  207. if (ret)
  208. status = CEC_TX_STATUS_ERROR;
  209. else if ((val & CH7322_WRITE_BOK) && (flags & CH7322_TX_FLAG_NACK))
  210. status = CEC_TX_STATUS_NACK;
  211. else if (val & CH7322_WRITE_BOK)
  212. status = CEC_TX_STATUS_OK;
  213. else if (flags & CH7322_TX_FLAG_NACK)
  214. status = CEC_TX_STATUS_OK;
  215. else
  216. status = CEC_TX_STATUS_NACK;
  217. if (status == CEC_TX_STATUS_NACK && (flags & CH7322_TX_FLAG_RETRY))
  218. status |= CEC_TX_STATUS_MAX_RETRIES;
  219. cec_transmit_attempt_done(ch7322->cec, status);
  220. }
  221. static void ch7322_rx_done(struct ch7322 *ch7322)
  222. {
  223. struct cec_msg msg;
  224. int ret;
  225. mutex_lock(&ch7322->mutex);
  226. ret = ch7322_receive_message(ch7322, &msg);
  227. mutex_unlock(&ch7322->mutex);
  228. if (ret)
  229. dev_err(&ch7322->i2c->dev, "cec receive error: %d\n", ret);
  230. else
  231. cec_received_msg(ch7322->cec, &msg);
  232. }
  233. /*
  234. * This device can either monitor the DDC lines to obtain the physical address
  235. * or it can allow the host to program it. This driver lets the device obtain
  236. * it.
  237. */
  238. static void ch7322_phys_addr(struct ch7322 *ch7322)
  239. {
  240. unsigned int pah, pal;
  241. int ret = 0;
  242. mutex_lock(&ch7322->mutex);
  243. ret |= regmap_read(ch7322->regmap, CH7322_PARH, &pah);
  244. ret |= regmap_read(ch7322->regmap, CH7322_PARL, &pal);
  245. mutex_unlock(&ch7322->mutex);
  246. if (ret)
  247. dev_err(&ch7322->i2c->dev, "phys addr error\n");
  248. else
  249. cec_s_phys_addr(ch7322->cec, pal | (pah << 8), false);
  250. }
  251. static irqreturn_t ch7322_irq(int irq, void *dev)
  252. {
  253. struct ch7322 *ch7322 = dev;
  254. unsigned int data = 0;
  255. mutex_lock(&ch7322->mutex);
  256. regmap_read(ch7322->regmap, CH7322_INTDATA, &data);
  257. regmap_write(ch7322->regmap, CH7322_INTDATA, data);
  258. mutex_unlock(&ch7322->mutex);
  259. if (data & CH7322_INTDATA_HPDFALL)
  260. cec_phys_addr_invalidate(ch7322->cec);
  261. if (data & CH7322_INTDATA_TXMSG)
  262. ch7322_tx_done(ch7322);
  263. if (data & CH7322_INTDATA_RXMSG)
  264. ch7322_rx_done(ch7322);
  265. if (data & CH7322_INTDATA_NEWPHA)
  266. ch7322_phys_addr(ch7322);
  267. if (data & CH7322_INTDATA_ERROR)
  268. dev_dbg(&ch7322->i2c->dev, "unknown error\n");
  269. return IRQ_HANDLED;
  270. }
  271. /* This device is always enabled */
  272. static int ch7322_cec_adap_enable(struct cec_adapter *adap, bool enable)
  273. {
  274. return 0;
  275. }
  276. static int ch7322_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
  277. {
  278. struct ch7322 *ch7322 = cec_get_drvdata(adap);
  279. int ret;
  280. mutex_lock(&ch7322->mutex);
  281. ret = regmap_update_bits(ch7322->regmap, CH7322_ADDLW,
  282. CH7322_ADDLW_MASK, log_addr << 4);
  283. mutex_unlock(&ch7322->mutex);
  284. return ret;
  285. }
  286. static int ch7322_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
  287. u32 signal_free_time, struct cec_msg *msg)
  288. {
  289. struct ch7322 *ch7322 = cec_get_drvdata(adap);
  290. int ret;
  291. mutex_lock(&ch7322->mutex);
  292. ret = ch7322_send_message(ch7322, msg);
  293. mutex_unlock(&ch7322->mutex);
  294. return ret;
  295. }
  296. static const struct cec_adap_ops ch7322_cec_adap_ops = {
  297. .adap_enable = ch7322_cec_adap_enable,
  298. .adap_log_addr = ch7322_cec_adap_log_addr,
  299. .adap_transmit = ch7322_cec_adap_transmit,
  300. };
  301. #if IS_ENABLED(CONFIG_PCI) && IS_ENABLED(CONFIG_DMI)
  302. struct ch7322_conn_match {
  303. const char *dev_name;
  304. const char *pci_name;
  305. const char *port_name;
  306. };
  307. static struct ch7322_conn_match google_endeavour[] = {
  308. { "i2c-PRP0001:00", "0000:00:02.0", "Port B" },
  309. { "i2c-PRP0001:01", "0000:00:02.0", "Port C" },
  310. { },
  311. };
  312. static const struct dmi_system_id ch7322_dmi_table[] = {
  313. {
  314. .matches = {
  315. DMI_MATCH(DMI_BOARD_VENDOR, "Google"),
  316. DMI_MATCH(DMI_BOARD_NAME, "Endeavour"),
  317. },
  318. .driver_data = google_endeavour,
  319. },
  320. { },
  321. };
  322. /* Make a best-effort attempt to locate a matching HDMI port */
  323. static int ch7322_get_port(struct i2c_client *client,
  324. struct device **dev,
  325. const char **port)
  326. {
  327. const struct dmi_system_id *system;
  328. const struct ch7322_conn_match *conn;
  329. *dev = NULL;
  330. *port = NULL;
  331. system = dmi_first_match(ch7322_dmi_table);
  332. if (!system)
  333. return 0;
  334. for (conn = system->driver_data; conn->dev_name; conn++) {
  335. if (!strcmp(dev_name(&client->dev), conn->dev_name)) {
  336. struct device *d;
  337. d = bus_find_device_by_name(&pci_bus_type, NULL,
  338. conn->pci_name);
  339. if (!d)
  340. return -EPROBE_DEFER;
  341. put_device(d);
  342. *dev = d;
  343. *port = conn->port_name;
  344. return 0;
  345. }
  346. }
  347. return 0;
  348. }
  349. #else
  350. static int ch7322_get_port(struct i2c_client *client,
  351. struct device **dev,
  352. const char **port)
  353. {
  354. *dev = NULL;
  355. *port = NULL;
  356. return 0;
  357. }
  358. #endif
  359. static int ch7322_probe(struct i2c_client *client)
  360. {
  361. struct device *hdmi_dev;
  362. const char *port_name;
  363. struct ch7322 *ch7322;
  364. struct cec_notifier *notifier = NULL;
  365. u32 caps = CEC_CAP_DEFAULTS;
  366. int ret;
  367. unsigned int val;
  368. ret = ch7322_get_port(client, &hdmi_dev, &port_name);
  369. if (ret)
  370. return ret;
  371. if (hdmi_dev)
  372. caps |= CEC_CAP_CONNECTOR_INFO;
  373. ch7322 = devm_kzalloc(&client->dev, sizeof(*ch7322), GFP_KERNEL);
  374. if (!ch7322)
  375. return -ENOMEM;
  376. ch7322->regmap = devm_regmap_init_i2c(client, &ch7322_regmap);
  377. if (IS_ERR(ch7322->regmap))
  378. return PTR_ERR(ch7322->regmap);
  379. ret = regmap_read(ch7322->regmap, CH7322_DID, &val);
  380. if (ret)
  381. return ret;
  382. if (val != CH7322_DID_CH7322)
  383. return -EOPNOTSUPP;
  384. mutex_init(&ch7322->mutex);
  385. ch7322->i2c = client;
  386. ch7322->tx_flags = 0;
  387. i2c_set_clientdata(client, ch7322);
  388. /* Disable auto mode */
  389. ret = regmap_write(ch7322->regmap, CH7322_MODE, CH7322_MODE_SW);
  390. if (ret)
  391. goto err_mutex;
  392. /* Enable logical address register */
  393. ret = regmap_update_bits(ch7322->regmap, CH7322_CTL,
  394. CH7322_CTL_SPADL, CH7322_CTL_SPADL);
  395. if (ret)
  396. goto err_mutex;
  397. ch7322->cec = cec_allocate_adapter(&ch7322_cec_adap_ops, ch7322,
  398. dev_name(&client->dev),
  399. caps, 1);
  400. if (IS_ERR(ch7322->cec)) {
  401. ret = PTR_ERR(ch7322->cec);
  402. goto err_mutex;
  403. }
  404. ch7322->cec->adap_controls_phys_addr = true;
  405. if (hdmi_dev) {
  406. notifier = cec_notifier_cec_adap_register(hdmi_dev,
  407. port_name,
  408. ch7322->cec);
  409. if (!notifier) {
  410. ret = -ENOMEM;
  411. goto err_cec;
  412. }
  413. }
  414. /* Configure, mask, and clear interrupt */
  415. ret = regmap_write(ch7322->regmap, CH7322_CFG1, 0);
  416. if (ret)
  417. goto err_notifier;
  418. ret = regmap_write(ch7322->regmap, CH7322_INTCTL, CH7322_INTCTL_INTPB);
  419. if (ret)
  420. goto err_notifier;
  421. ret = regmap_write(ch7322->regmap, CH7322_INTDATA, 0xff);
  422. if (ret)
  423. goto err_notifier;
  424. /* If HPD is up read physical address */
  425. ret = regmap_read(ch7322->regmap, CH7322_ADDLR, &val);
  426. if (ret)
  427. goto err_notifier;
  428. if (val & CH7322_ADDLR_HPD)
  429. ch7322_phys_addr(ch7322);
  430. ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
  431. ch7322_irq,
  432. IRQF_ONESHOT | IRQF_TRIGGER_RISING,
  433. client->name, ch7322);
  434. if (ret)
  435. goto err_notifier;
  436. /* Unmask interrupt */
  437. mutex_lock(&ch7322->mutex);
  438. ret = regmap_write(ch7322->regmap, CH7322_INTCTL, 0xff);
  439. mutex_unlock(&ch7322->mutex);
  440. if (ret)
  441. goto err_notifier;
  442. ret = cec_register_adapter(ch7322->cec, &client->dev);
  443. if (ret)
  444. goto err_notifier;
  445. dev_info(&client->dev, "device registered\n");
  446. return 0;
  447. err_notifier:
  448. if (notifier)
  449. cec_notifier_cec_adap_unregister(notifier, ch7322->cec);
  450. err_cec:
  451. cec_delete_adapter(ch7322->cec);
  452. err_mutex:
  453. mutex_destroy(&ch7322->mutex);
  454. return ret;
  455. }
  456. static void ch7322_remove(struct i2c_client *client)
  457. {
  458. struct ch7322 *ch7322 = i2c_get_clientdata(client);
  459. /* Mask interrupt */
  460. mutex_lock(&ch7322->mutex);
  461. regmap_write(ch7322->regmap, CH7322_INTCTL, CH7322_INTCTL_INTPB);
  462. mutex_unlock(&ch7322->mutex);
  463. cec_unregister_adapter(ch7322->cec);
  464. mutex_destroy(&ch7322->mutex);
  465. dev_info(&client->dev, "device unregistered\n");
  466. }
  467. static const struct of_device_id ch7322_of_match[] = {
  468. { .compatible = "chrontel,ch7322", },
  469. {},
  470. };
  471. MODULE_DEVICE_TABLE(of, ch7322_of_match);
  472. static struct i2c_driver ch7322_i2c_driver = {
  473. .driver = {
  474. .name = "ch7322",
  475. .of_match_table = of_match_ptr(ch7322_of_match),
  476. },
  477. .probe_new = ch7322_probe,
  478. .remove = ch7322_remove,
  479. };
  480. module_i2c_driver(ch7322_i2c_driver);
  481. MODULE_DESCRIPTION("Chrontel CH7322 CEC Controller Driver");
  482. MODULE_AUTHOR("Jeff Chase <[email protected]>");
  483. MODULE_LICENSE("GPL");