rainshadow-cec.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * RainShadow Tech HDMI CEC driver
  3. *
  4. * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version of 2 of the License, or (at your
  9. * option) any later version. See the file COPYING in the main directory of
  10. * this archive for more details.
  11. */
  12. /*
  13. * Notes:
  14. *
  15. * The higher level protocols are currently disabled. This can be added
  16. * later, similar to how this is done for the Pulse Eight CEC driver.
  17. *
  18. * Documentation of the protocol is available here:
  19. *
  20. * http://rainshadowtech.com/doc/HDMICECtoUSBandRS232v2.0.pdf
  21. */
  22. #include <linux/completion.h>
  23. #include <linux/ctype.h>
  24. #include <linux/delay.h>
  25. #include <linux/init.h>
  26. #include <linux/interrupt.h>
  27. #include <linux/kernel.h>
  28. #include <linux/module.h>
  29. #include <linux/serio.h>
  30. #include <linux/slab.h>
  31. #include <linux/spinlock.h>
  32. #include <linux/time.h>
  33. #include <linux/workqueue.h>
  34. #include <media/cec.h>
  35. MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
  36. MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
  37. MODULE_LICENSE("GPL");
  38. #define DATA_SIZE 256
  39. struct rain {
  40. struct device *dev;
  41. struct serio *serio;
  42. struct cec_adapter *adap;
  43. struct completion cmd_done;
  44. struct work_struct work;
  45. /* Low-level ringbuffer, collecting incoming characters */
  46. char buf[DATA_SIZE];
  47. unsigned int buf_rd_idx;
  48. unsigned int buf_wr_idx;
  49. unsigned int buf_len;
  50. spinlock_t buf_lock;
  51. /* command buffer */
  52. char cmd[DATA_SIZE];
  53. unsigned int cmd_idx;
  54. bool cmd_started;
  55. /* reply to a command, only used to store the firmware version */
  56. char cmd_reply[DATA_SIZE];
  57. struct mutex write_lock;
  58. };
  59. static void rain_process_msg(struct rain *rain)
  60. {
  61. struct cec_msg msg = {};
  62. const char *cmd = rain->cmd + 3;
  63. int stat = -1;
  64. for (; *cmd; cmd++) {
  65. if (!isxdigit(*cmd))
  66. continue;
  67. if (isxdigit(cmd[0]) && isxdigit(cmd[1])) {
  68. if (msg.len == CEC_MAX_MSG_SIZE)
  69. break;
  70. if (hex2bin(msg.msg + msg.len, cmd, 1))
  71. continue;
  72. msg.len++;
  73. cmd++;
  74. continue;
  75. }
  76. if (!cmd[1])
  77. stat = hex_to_bin(cmd[0]);
  78. break;
  79. }
  80. if (rain->cmd[0] == 'R') {
  81. if (stat == 1 || stat == 2)
  82. cec_received_msg(rain->adap, &msg);
  83. return;
  84. }
  85. switch (stat) {
  86. case 1:
  87. cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_OK);
  88. break;
  89. case 2:
  90. cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_NACK);
  91. break;
  92. default:
  93. cec_transmit_attempt_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE);
  94. break;
  95. }
  96. }
  97. static void rain_irq_work_handler(struct work_struct *work)
  98. {
  99. struct rain *rain =
  100. container_of(work, struct rain, work);
  101. while (true) {
  102. unsigned long flags;
  103. char data;
  104. spin_lock_irqsave(&rain->buf_lock, flags);
  105. if (!rain->buf_len) {
  106. spin_unlock_irqrestore(&rain->buf_lock, flags);
  107. break;
  108. }
  109. data = rain->buf[rain->buf_rd_idx];
  110. rain->buf_len--;
  111. rain->buf_rd_idx = (rain->buf_rd_idx + 1) & 0xff;
  112. spin_unlock_irqrestore(&rain->buf_lock, flags);
  113. if (!rain->cmd_started && data != '?')
  114. continue;
  115. switch (data) {
  116. case '\r':
  117. rain->cmd[rain->cmd_idx] = '\0';
  118. dev_dbg(rain->dev, "received: %s\n", rain->cmd);
  119. if (!memcmp(rain->cmd, "REC", 3) ||
  120. !memcmp(rain->cmd, "STA", 3)) {
  121. rain_process_msg(rain);
  122. } else {
  123. strcpy(rain->cmd_reply, rain->cmd);
  124. complete(&rain->cmd_done);
  125. }
  126. rain->cmd_idx = 0;
  127. rain->cmd_started = false;
  128. break;
  129. case '\n':
  130. rain->cmd_idx = 0;
  131. rain->cmd_started = false;
  132. break;
  133. case '?':
  134. rain->cmd_idx = 0;
  135. rain->cmd_started = true;
  136. break;
  137. default:
  138. if (rain->cmd_idx >= DATA_SIZE - 1) {
  139. dev_dbg(rain->dev,
  140. "throwing away %d bytes of garbage\n", rain->cmd_idx);
  141. rain->cmd_idx = 0;
  142. }
  143. rain->cmd[rain->cmd_idx++] = data;
  144. break;
  145. }
  146. }
  147. }
  148. static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data,
  149. unsigned int flags)
  150. {
  151. struct rain *rain = serio_get_drvdata(serio);
  152. if (rain->buf_len == DATA_SIZE) {
  153. dev_warn_once(rain->dev, "buffer overflow\n");
  154. return IRQ_HANDLED;
  155. }
  156. spin_lock(&rain->buf_lock);
  157. rain->buf_len++;
  158. rain->buf[rain->buf_wr_idx] = data;
  159. rain->buf_wr_idx = (rain->buf_wr_idx + 1) & 0xff;
  160. spin_unlock(&rain->buf_lock);
  161. schedule_work(&rain->work);
  162. return IRQ_HANDLED;
  163. }
  164. static void rain_disconnect(struct serio *serio)
  165. {
  166. struct rain *rain = serio_get_drvdata(serio);
  167. cancel_work_sync(&rain->work);
  168. cec_unregister_adapter(rain->adap);
  169. dev_info(&serio->dev, "disconnected\n");
  170. serio_close(serio);
  171. serio_set_drvdata(serio, NULL);
  172. kfree(rain);
  173. }
  174. static int rain_send(struct rain *rain, const char *command)
  175. {
  176. int err = serio_write(rain->serio, '!');
  177. dev_dbg(rain->dev, "send: %s\n", command);
  178. while (!err && *command)
  179. err = serio_write(rain->serio, *command++);
  180. if (!err)
  181. err = serio_write(rain->serio, '~');
  182. return err;
  183. }
  184. static int rain_send_and_wait(struct rain *rain,
  185. const char *cmd, const char *reply)
  186. {
  187. int err;
  188. init_completion(&rain->cmd_done);
  189. mutex_lock(&rain->write_lock);
  190. err = rain_send(rain, cmd);
  191. if (err)
  192. goto err;
  193. if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) {
  194. err = -ETIMEDOUT;
  195. goto err;
  196. }
  197. if (reply && strncmp(rain->cmd_reply, reply, strlen(reply))) {
  198. dev_dbg(rain->dev,
  199. "transmit of '%s': received '%s' instead of '%s'\n",
  200. cmd, rain->cmd_reply, reply);
  201. err = -EIO;
  202. }
  203. err:
  204. mutex_unlock(&rain->write_lock);
  205. return err;
  206. }
  207. static int rain_setup(struct rain *rain, struct serio *serio,
  208. struct cec_log_addrs *log_addrs, u16 *pa)
  209. {
  210. int err;
  211. err = rain_send_and_wait(rain, "R", "REV");
  212. if (err)
  213. return err;
  214. dev_info(rain->dev, "Firmware version %s\n", rain->cmd_reply + 4);
  215. err = rain_send_and_wait(rain, "Q 1", "QTY");
  216. if (err)
  217. return err;
  218. err = rain_send_and_wait(rain, "c0000", "CFG");
  219. if (err)
  220. return err;
  221. return rain_send_and_wait(rain, "A F 0000", "ADR");
  222. }
  223. static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable)
  224. {
  225. return 0;
  226. }
  227. static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
  228. {
  229. struct rain *rain = cec_get_drvdata(adap);
  230. u8 cmd[16];
  231. if (log_addr == CEC_LOG_ADDR_INVALID)
  232. log_addr = CEC_LOG_ADDR_UNREGISTERED;
  233. snprintf(cmd, sizeof(cmd), "A %x", log_addr);
  234. return rain_send_and_wait(rain, cmd, "ADR");
  235. }
  236. static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
  237. u32 signal_free_time, struct cec_msg *msg)
  238. {
  239. struct rain *rain = cec_get_drvdata(adap);
  240. char cmd[2 * CEC_MAX_MSG_SIZE + 16];
  241. unsigned int i;
  242. int err;
  243. if (msg->len == 1) {
  244. snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg));
  245. } else {
  246. char hex[3];
  247. snprintf(cmd, sizeof(cmd), "x%x %02x ",
  248. cec_msg_destination(msg), msg->msg[1]);
  249. for (i = 2; i < msg->len; i++) {
  250. snprintf(hex, sizeof(hex), "%02x", msg->msg[i]);
  251. strlcat(cmd, hex, sizeof(cmd));
  252. }
  253. }
  254. mutex_lock(&rain->write_lock);
  255. err = rain_send(rain, cmd);
  256. mutex_unlock(&rain->write_lock);
  257. return err;
  258. }
  259. static const struct cec_adap_ops rain_cec_adap_ops = {
  260. .adap_enable = rain_cec_adap_enable,
  261. .adap_log_addr = rain_cec_adap_log_addr,
  262. .adap_transmit = rain_cec_adap_transmit,
  263. };
  264. static int rain_connect(struct serio *serio, struct serio_driver *drv)
  265. {
  266. u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
  267. struct rain *rain;
  268. int err = -ENOMEM;
  269. struct cec_log_addrs log_addrs = {};
  270. u16 pa = CEC_PHYS_ADDR_INVALID;
  271. rain = kzalloc(sizeof(*rain), GFP_KERNEL);
  272. if (!rain)
  273. return -ENOMEM;
  274. rain->serio = serio;
  275. rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain,
  276. dev_name(&serio->dev), caps, 1);
  277. err = PTR_ERR_OR_ZERO(rain->adap);
  278. if (err < 0)
  279. goto free_device;
  280. rain->dev = &serio->dev;
  281. serio_set_drvdata(serio, rain);
  282. INIT_WORK(&rain->work, rain_irq_work_handler);
  283. mutex_init(&rain->write_lock);
  284. spin_lock_init(&rain->buf_lock);
  285. err = serio_open(serio, drv);
  286. if (err)
  287. goto delete_adap;
  288. err = rain_setup(rain, serio, &log_addrs, &pa);
  289. if (err)
  290. goto close_serio;
  291. err = cec_register_adapter(rain->adap, &serio->dev);
  292. if (err < 0)
  293. goto close_serio;
  294. rain->dev = &rain->adap->devnode.dev;
  295. return 0;
  296. close_serio:
  297. serio_close(serio);
  298. delete_adap:
  299. cec_delete_adapter(rain->adap);
  300. serio_set_drvdata(serio, NULL);
  301. free_device:
  302. kfree(rain);
  303. return err;
  304. }
  305. static const struct serio_device_id rain_serio_ids[] = {
  306. {
  307. .type = SERIO_RS232,
  308. .proto = SERIO_RAINSHADOW_CEC,
  309. .id = SERIO_ANY,
  310. .extra = SERIO_ANY,
  311. },
  312. { 0 }
  313. };
  314. MODULE_DEVICE_TABLE(serio, rain_serio_ids);
  315. static struct serio_driver rain_drv = {
  316. .driver = {
  317. .name = "rainshadow-cec",
  318. },
  319. .description = "RainShadow Tech HDMI CEC driver",
  320. .id_table = rain_serio_ids,
  321. .interrupt = rain_interrupt,
  322. .connect = rain_connect,
  323. .disconnect = rain_disconnect,
  324. };
  325. module_serio_driver(rain_drv);