1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * vivid-cec.c - A Virtual Video Test Driver, cec emulation 4 * 5 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 6 */ 7 8 #include <linux/delay.h> 9 #include <media/cec.h> 10 11 #include "vivid-core.h" 12 #include "vivid-cec.h" 13 14 #define CEC_START_BIT_US 4500 15 #define CEC_DATA_BIT_US 2400 16 #define CEC_MARGIN_US 350 17 18 struct xfer_on_bus { 19 struct cec_adapter *adap; 20 u8 status; 21 }; 22 23 static bool find_dest_adap(struct vivid_dev *dev, 24 struct cec_adapter *adap, u8 dest) 25 { 26 unsigned int i; 27 28 if (dest >= 0xf) 29 return false; 30 31 if (adap != dev->cec_rx_adap && dev->cec_rx_adap && 32 dev->cec_rx_adap->is_configured && 33 cec_has_log_addr(dev->cec_rx_adap, dest)) 34 return true; 35 36 for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) { 37 if (adap == dev->cec_tx_adap[i]) 38 continue; 39 if (!dev->cec_tx_adap[i]->is_configured) 40 continue; 41 if (cec_has_log_addr(dev->cec_tx_adap[i], dest)) 42 return true; 43 } 44 return false; 45 } 46 47 static bool xfer_ready(struct vivid_dev *dev) 48 { 49 unsigned int i; 50 bool ready = false; 51 52 spin_lock(&dev->cec_xfers_slock); 53 for (i = 0; i < ARRAY_SIZE(dev->xfers); i++) { 54 if (dev->xfers[i].sft && 55 dev->xfers[i].sft <= dev->cec_sft) { 56 ready = true; 57 break; 58 } 59 } 60 spin_unlock(&dev->cec_xfers_slock); 61 62 return ready; 63 } 64 65 /* 66 * If an adapter tries to send successive messages, it must wait for the 67 * longest signal-free time between its transmissions. But, if another 68 * adapter sends a message in the interim, then the wait can be reduced 69 * because the messages are no longer successive. Make these adjustments 70 * if necessary. Should be called holding cec_xfers_slock. 71 */ 72 static void adjust_sfts(struct vivid_dev *dev) 73 { 74 unsigned int i; 75 u8 initiator; 76 77 for (i = 0; i < ARRAY_SIZE(dev->xfers); i++) { 78 if (dev->xfers[i].sft <= CEC_SIGNAL_FREE_TIME_RETRY) 79 continue; 80 initiator = dev->xfers[i].msg[0] >> 4; 81 if (initiator == dev->last_initiator) 82 dev->xfers[i].sft = CEC_SIGNAL_FREE_TIME_NEXT_XFER; 83 else 84 dev->xfers[i].sft = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; 85 } 86 } 87 88 /* 89 * The main emulation of the bus on which CEC adapters attempt to send 90 * messages to each other. The bus keeps track of how long it has been 91 * signal-free and accepts a pending transmission only if the state of 92 * the bus matches the transmission's signal-free requirements. It calls 93 * cec_transmit_attempt_done() for all transmits that enter the bus and 94 * cec_received_msg() for successful transmits. 95 */ 96 int vivid_cec_bus_thread(void *_dev) 97 { 98 u32 last_sft; 99 unsigned int i; 100 unsigned int dest; 101 ktime_t start, end; 102 s64 delta_us, retry_us; 103 struct vivid_dev *dev = _dev; 104 105 dev->cec_sft = CEC_SIGNAL_FREE_TIME_NEXT_XFER; 106 for (;;) { 107 bool first = true; 108 int wait_xfer_us = 0; 109 bool valid_dest = false; 110 int wait_arb_lost_us = 0; 111 unsigned int first_idx = 0; 112 unsigned int first_status = 0; 113 struct cec_msg first_msg = {}; 114 struct xfer_on_bus xfers_on_bus[MAX_OUTPUTS] = {}; 115 116 wait_event_interruptible(dev->kthread_waitq_cec, xfer_ready(dev) || 117 kthread_should_stop()); 118 if (kthread_should_stop()) 119 break; 120 last_sft = dev->cec_sft; 121 dev->cec_sft = 0; 122 /* 123 * Move the messages that are ready onto the bus. The adapter with 124 * the most leading zeros will win control of the bus and any other 125 * adapters will lose arbitration. 126 */ 127 spin_lock(&dev->cec_xfers_slock); 128 for (i = 0; i < ARRAY_SIZE(dev->xfers); i++) { 129 if (!dev->xfers[i].sft || dev->xfers[i].sft > last_sft) 130 continue; 131 if (first) { 132 first = false; 133 first_idx = i; 134 xfers_on_bus[first_idx].adap = dev->xfers[i].adap; 135 memcpy(first_msg.msg, dev->xfers[i].msg, dev->xfers[i].len); 136 first_msg.len = dev->xfers[i].len; 137 } else { 138 xfers_on_bus[i].adap = dev->xfers[i].adap; 139 xfers_on_bus[i].status = CEC_TX_STATUS_ARB_LOST; 140 /* 141 * For simplicity wait for all 4 bits of the initiator's 142 * address even though HDMI specification uses bit-level 143 * precision. 144 */ 145 wait_arb_lost_us = 4 * CEC_DATA_BIT_US + CEC_START_BIT_US; 146 } 147 dev->xfers[i].sft = 0; 148 } 149 dev->last_initiator = cec_msg_initiator(&first_msg); 150 adjust_sfts(dev); 151 spin_unlock(&dev->cec_xfers_slock); 152 153 dest = cec_msg_destination(&first_msg); 154 valid_dest = cec_msg_is_broadcast(&first_msg); 155 if (!valid_dest) 156 valid_dest = find_dest_adap(dev, xfers_on_bus[first_idx].adap, dest); 157 if (valid_dest) { 158 first_status = CEC_TX_STATUS_OK; 159 /* 160 * Message length is in bytes, but each byte is transmitted in 161 * a block of 10 bits. 162 */ 163 wait_xfer_us = first_msg.len * 10 * CEC_DATA_BIT_US; 164 } else { 165 first_status = CEC_TX_STATUS_NACK; 166 /* 167 * A message that is not acknowledged stops transmitting after 168 * the header block of 10 bits. 169 */ 170 wait_xfer_us = 10 * CEC_DATA_BIT_US; 171 } 172 wait_xfer_us += CEC_START_BIT_US; 173 xfers_on_bus[first_idx].status = first_status; 174 175 /* Sleep as if sending messages on a real hardware bus. */ 176 start = ktime_get(); 177 if (wait_arb_lost_us) { 178 usleep_range(wait_arb_lost_us - CEC_MARGIN_US, wait_arb_lost_us); 179 for (i = 0; i < ARRAY_SIZE(xfers_on_bus); i++) { 180 if (xfers_on_bus[i].status != CEC_TX_STATUS_ARB_LOST) 181 continue; 182 cec_transmit_attempt_done(xfers_on_bus[i].adap, 183 CEC_TX_STATUS_ARB_LOST); 184 } 185 if (kthread_should_stop()) 186 break; 187 } 188 wait_xfer_us -= wait_arb_lost_us; 189 usleep_range(wait_xfer_us - CEC_MARGIN_US, wait_xfer_us); 190 cec_transmit_attempt_done(xfers_on_bus[first_idx].adap, first_status); 191 if (kthread_should_stop()) 192 break; 193 if (first_status == CEC_TX_STATUS_OK) { 194 if (xfers_on_bus[first_idx].adap != dev->cec_rx_adap) 195 cec_received_msg(dev->cec_rx_adap, &first_msg); 196 for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) 197 if (xfers_on_bus[first_idx].adap != dev->cec_tx_adap[i]) 198 cec_received_msg(dev->cec_tx_adap[i], &first_msg); 199 } 200 end = ktime_get(); 201 /* 202 * If the emulated transfer took more or less time than it should 203 * have, then compensate by adjusting the wait time needed for the 204 * bus to be signal-free for 3 bit periods (the retry time). 205 */ 206 delta_us = div_s64(end - start, 1000); 207 delta_us -= wait_xfer_us + wait_arb_lost_us; 208 retry_us = CEC_SIGNAL_FREE_TIME_RETRY * CEC_DATA_BIT_US - delta_us; 209 if (retry_us > CEC_MARGIN_US) 210 usleep_range(retry_us - CEC_MARGIN_US, retry_us); 211 dev->cec_sft = CEC_SIGNAL_FREE_TIME_RETRY; 212 /* 213 * If there are no messages that need to be retried, check if any 214 * adapters that did not just transmit a message are ready to 215 * transmit. If none of these adapters are ready, then increase 216 * the signal-free time so that the bus is available to all 217 * adapters and go back to waiting for a transmission. 218 */ 219 while (dev->cec_sft >= CEC_SIGNAL_FREE_TIME_RETRY && 220 dev->cec_sft < CEC_SIGNAL_FREE_TIME_NEXT_XFER && 221 !xfer_ready(dev) && !kthread_should_stop()) { 222 usleep_range(2 * CEC_DATA_BIT_US - CEC_MARGIN_US, 223 2 * CEC_DATA_BIT_US); 224 dev->cec_sft += 2; 225 } 226 } 227 return 0; 228 } 229 230 static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable) 231 { 232 adap->cec_pin_is_high = true; 233 return 0; 234 } 235 236 static int vivid_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) 237 { 238 return 0; 239 } 240 241 static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 242 u32 signal_free_time, struct cec_msg *msg) 243 { 244 struct vivid_dev *dev = cec_get_drvdata(adap); 245 u8 idx = cec_msg_initiator(msg); 246 247 spin_lock(&dev->cec_xfers_slock); 248 dev->xfers[idx].adap = adap; 249 memcpy(dev->xfers[idx].msg, msg->msg, CEC_MAX_MSG_SIZE); 250 dev->xfers[idx].len = msg->len; 251 dev->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_RETRY; 252 if (signal_free_time > CEC_SIGNAL_FREE_TIME_RETRY) { 253 if (idx == dev->last_initiator) 254 dev->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_NEXT_XFER; 255 else 256 dev->xfers[idx].sft = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; 257 } 258 spin_unlock(&dev->cec_xfers_slock); 259 wake_up_interruptible(&dev->kthread_waitq_cec); 260 261 return 0; 262 } 263 264 static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) 265 { 266 struct vivid_dev *dev = cec_get_drvdata(adap); 267 struct cec_msg reply; 268 u8 dest = cec_msg_destination(msg); 269 u8 disp_ctl; 270 char osd[14]; 271 272 if (cec_msg_is_broadcast(msg)) 273 dest = adap->log_addrs.log_addr[0]; 274 cec_msg_init(&reply, dest, cec_msg_initiator(msg)); 275 276 switch (cec_msg_opcode(msg)) { 277 case CEC_MSG_SET_OSD_STRING: 278 if (!cec_is_sink(adap)) 279 return -ENOMSG; 280 cec_ops_set_osd_string(msg, &disp_ctl, osd); 281 switch (disp_ctl) { 282 case CEC_OP_DISP_CTL_DEFAULT: 283 strscpy(dev->osd, osd, sizeof(dev->osd)); 284 dev->osd_jiffies = jiffies; 285 break; 286 case CEC_OP_DISP_CTL_UNTIL_CLEARED: 287 strscpy(dev->osd, osd, sizeof(dev->osd)); 288 dev->osd_jiffies = 0; 289 break; 290 case CEC_OP_DISP_CTL_CLEAR: 291 dev->osd[0] = 0; 292 dev->osd_jiffies = 0; 293 break; 294 default: 295 cec_msg_feature_abort(&reply, cec_msg_opcode(msg), 296 CEC_OP_ABORT_INVALID_OP); 297 cec_transmit_msg(adap, &reply, false); 298 break; 299 } 300 break; 301 default: 302 return -ENOMSG; 303 } 304 return 0; 305 } 306 307 static const struct cec_adap_ops vivid_cec_adap_ops = { 308 .adap_enable = vivid_cec_adap_enable, 309 .adap_log_addr = vivid_cec_adap_log_addr, 310 .adap_transmit = vivid_cec_adap_transmit, 311 .received = vivid_received, 312 }; 313 314 struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, 315 unsigned int idx, 316 bool is_source) 317 { 318 u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN; 319 char name[32]; 320 321 snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d", 322 dev->inst, is_source ? "out" : "cap", idx); 323 return cec_allocate_adapter(&vivid_cec_adap_ops, dev, 324 name, caps, CEC_MAX_LOG_ADDRS); 325 } 326