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