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 <media/cec.h> 9 10 #include "vivid-core.h" 11 #include "vivid-cec.h" 12 13 #define CEC_TIM_START_BIT_TOTAL 4500 14 #define CEC_TIM_START_BIT_LOW 3700 15 #define CEC_TIM_START_BIT_HIGH 800 16 #define CEC_TIM_DATA_BIT_TOTAL 2400 17 #define CEC_TIM_DATA_BIT_0_LOW 1500 18 #define CEC_TIM_DATA_BIT_0_HIGH 900 19 #define CEC_TIM_DATA_BIT_1_LOW 600 20 #define CEC_TIM_DATA_BIT_1_HIGH 1800 21 22 void vivid_cec_bus_free_work(struct vivid_dev *dev) 23 { 24 spin_lock(&dev->cec_slock); 25 while (!list_empty(&dev->cec_work_list)) { 26 struct vivid_cec_work *cw = 27 list_first_entry(&dev->cec_work_list, 28 struct vivid_cec_work, list); 29 30 spin_unlock(&dev->cec_slock); 31 cancel_delayed_work_sync(&cw->work); 32 spin_lock(&dev->cec_slock); 33 list_del(&cw->list); 34 cec_transmit_attempt_done(cw->adap, CEC_TX_STATUS_LOW_DRIVE); 35 kfree(cw); 36 } 37 spin_unlock(&dev->cec_slock); 38 } 39 40 static bool vivid_cec_find_dest_adap(struct vivid_dev *dev, 41 struct cec_adapter *adap, u8 dest) 42 { 43 unsigned int i; 44 45 if (dest >= 0xf) 46 return false; 47 48 if (adap != dev->cec_rx_adap && dev->cec_rx_adap && 49 dev->cec_rx_adap->is_configured && 50 cec_has_log_addr(dev->cec_rx_adap, dest)) 51 return true; 52 53 for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) { 54 if (adap == dev->cec_tx_adap[i]) 55 continue; 56 if (!dev->cec_tx_adap[i]->is_configured) 57 continue; 58 if (cec_has_log_addr(dev->cec_tx_adap[i], dest)) 59 return true; 60 } 61 return false; 62 } 63 64 static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts, 65 const struct cec_msg *msg, bool nacked) 66 { 67 unsigned int len = nacked ? 1 : msg->len; 68 unsigned int i; 69 bool bit; 70 71 if (adap == NULL) 72 return; 73 74 /* 75 * Suffix ULL on constant 10 makes the expression 76 * CEC_TIM_START_BIT_TOTAL + 10ULL * len * CEC_TIM_DATA_BIT_TOTAL 77 * to be evaluated using 64-bit unsigned arithmetic (u64), which 78 * is what ktime_sub_us expects as second argument. 79 */ 80 ts = ktime_sub_us(ts, CEC_TIM_START_BIT_TOTAL + 81 10ULL * len * CEC_TIM_DATA_BIT_TOTAL); 82 cec_queue_pin_cec_event(adap, false, false, ts); 83 ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW); 84 cec_queue_pin_cec_event(adap, true, false, ts); 85 ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH); 86 87 for (i = 0; i < 10 * len; i++) { 88 switch (i % 10) { 89 case 0 ... 7: 90 bit = msg->msg[i / 10] & (0x80 >> (i % 10)); 91 break; 92 case 8: /* EOM */ 93 bit = i / 10 == msg->len - 1; 94 break; 95 case 9: /* ACK */ 96 bit = cec_msg_is_broadcast(msg) ^ nacked; 97 break; 98 } 99 cec_queue_pin_cec_event(adap, false, false, ts); 100 if (bit) 101 ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW); 102 else 103 ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW); 104 cec_queue_pin_cec_event(adap, true, false, ts); 105 if (bit) 106 ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH); 107 else 108 ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_HIGH); 109 } 110 } 111 112 static void vivid_cec_pin_events(struct vivid_dev *dev, 113 const struct cec_msg *msg, bool nacked) 114 { 115 ktime_t ts = ktime_get(); 116 unsigned int i; 117 118 vivid_cec_pin_adap_events(dev->cec_rx_adap, ts, msg, nacked); 119 for (i = 0; i < MAX_OUTPUTS; i++) 120 vivid_cec_pin_adap_events(dev->cec_tx_adap[i], ts, msg, nacked); 121 } 122 123 static void vivid_cec_xfer_done_worker(struct work_struct *work) 124 { 125 struct vivid_cec_work *cw = 126 container_of(work, struct vivid_cec_work, work.work); 127 struct vivid_dev *dev = cw->dev; 128 struct cec_adapter *adap = cw->adap; 129 u8 dest = cec_msg_destination(&cw->msg); 130 bool valid_dest; 131 unsigned int i; 132 133 valid_dest = cec_msg_is_broadcast(&cw->msg); 134 if (!valid_dest) 135 valid_dest = vivid_cec_find_dest_adap(dev, adap, dest); 136 137 cw->tx_status = valid_dest ? CEC_TX_STATUS_OK : CEC_TX_STATUS_NACK; 138 spin_lock(&dev->cec_slock); 139 dev->cec_xfer_time_jiffies = 0; 140 dev->cec_xfer_start_jiffies = 0; 141 list_del(&cw->list); 142 spin_unlock(&dev->cec_slock); 143 vivid_cec_pin_events(dev, &cw->msg, !valid_dest); 144 cec_transmit_attempt_done(cw->adap, cw->tx_status); 145 146 /* Broadcast message */ 147 if (adap != dev->cec_rx_adap) 148 cec_received_msg(dev->cec_rx_adap, &cw->msg); 149 for (i = 0; i < MAX_OUTPUTS && dev->cec_tx_adap[i]; i++) 150 if (adap != dev->cec_tx_adap[i]) 151 cec_received_msg(dev->cec_tx_adap[i], &cw->msg); 152 kfree(cw); 153 } 154 155 static void vivid_cec_xfer_try_worker(struct work_struct *work) 156 { 157 struct vivid_cec_work *cw = 158 container_of(work, struct vivid_cec_work, work.work); 159 struct vivid_dev *dev = cw->dev; 160 161 spin_lock(&dev->cec_slock); 162 if (dev->cec_xfer_time_jiffies) { 163 list_del(&cw->list); 164 spin_unlock(&dev->cec_slock); 165 cec_transmit_attempt_done(cw->adap, CEC_TX_STATUS_ARB_LOST); 166 kfree(cw); 167 } else { 168 INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker); 169 dev->cec_xfer_start_jiffies = jiffies; 170 dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs); 171 spin_unlock(&dev->cec_slock); 172 schedule_delayed_work(&cw->work, dev->cec_xfer_time_jiffies); 173 } 174 } 175 176 static int vivid_cec_adap_enable(struct cec_adapter *adap, bool enable) 177 { 178 adap->cec_pin_is_high = true; 179 return 0; 180 } 181 182 static int vivid_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) 183 { 184 return 0; 185 } 186 187 /* 188 * One data bit takes 2400 us, each byte needs 10 bits so that's 24000 us 189 * per byte. 190 */ 191 #define USECS_PER_BYTE 24000 192 193 static int vivid_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 194 u32 signal_free_time, struct cec_msg *msg) 195 { 196 struct vivid_dev *dev = cec_get_drvdata(adap); 197 struct vivid_cec_work *cw = kzalloc(sizeof(*cw), GFP_KERNEL); 198 long delta_jiffies = 0; 199 200 if (cw == NULL) 201 return -ENOMEM; 202 cw->dev = dev; 203 cw->adap = adap; 204 cw->usecs = CEC_FREE_TIME_TO_USEC(signal_free_time) + 205 msg->len * USECS_PER_BYTE; 206 cw->msg = *msg; 207 208 spin_lock(&dev->cec_slock); 209 list_add(&cw->list, &dev->cec_work_list); 210 if (dev->cec_xfer_time_jiffies == 0) { 211 INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_done_worker); 212 dev->cec_xfer_start_jiffies = jiffies; 213 dev->cec_xfer_time_jiffies = usecs_to_jiffies(cw->usecs); 214 delta_jiffies = dev->cec_xfer_time_jiffies; 215 } else { 216 INIT_DELAYED_WORK(&cw->work, vivid_cec_xfer_try_worker); 217 delta_jiffies = dev->cec_xfer_start_jiffies + 218 dev->cec_xfer_time_jiffies - jiffies; 219 } 220 spin_unlock(&dev->cec_slock); 221 schedule_delayed_work(&cw->work, delta_jiffies < 0 ? 0 : delta_jiffies); 222 return 0; 223 } 224 225 static int vivid_received(struct cec_adapter *adap, struct cec_msg *msg) 226 { 227 struct vivid_dev *dev = cec_get_drvdata(adap); 228 struct cec_msg reply; 229 u8 dest = cec_msg_destination(msg); 230 u8 disp_ctl; 231 char osd[14]; 232 233 if (cec_msg_is_broadcast(msg)) 234 dest = adap->log_addrs.log_addr[0]; 235 cec_msg_init(&reply, dest, cec_msg_initiator(msg)); 236 237 switch (cec_msg_opcode(msg)) { 238 case CEC_MSG_SET_OSD_STRING: 239 if (!cec_is_sink(adap)) 240 return -ENOMSG; 241 cec_ops_set_osd_string(msg, &disp_ctl, osd); 242 switch (disp_ctl) { 243 case CEC_OP_DISP_CTL_DEFAULT: 244 strscpy(dev->osd, osd, sizeof(dev->osd)); 245 dev->osd_jiffies = jiffies; 246 break; 247 case CEC_OP_DISP_CTL_UNTIL_CLEARED: 248 strscpy(dev->osd, osd, sizeof(dev->osd)); 249 dev->osd_jiffies = 0; 250 break; 251 case CEC_OP_DISP_CTL_CLEAR: 252 dev->osd[0] = 0; 253 dev->osd_jiffies = 0; 254 break; 255 default: 256 cec_msg_feature_abort(&reply, cec_msg_opcode(msg), 257 CEC_OP_ABORT_INVALID_OP); 258 cec_transmit_msg(adap, &reply, false); 259 break; 260 } 261 break; 262 default: 263 return -ENOMSG; 264 } 265 return 0; 266 } 267 268 static const struct cec_adap_ops vivid_cec_adap_ops = { 269 .adap_enable = vivid_cec_adap_enable, 270 .adap_log_addr = vivid_cec_adap_log_addr, 271 .adap_transmit = vivid_cec_adap_transmit, 272 .received = vivid_received, 273 }; 274 275 struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev, 276 unsigned int idx, 277 bool is_source) 278 { 279 u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN; 280 char name[32]; 281 282 snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d", 283 dev->inst, is_source ? "out" : "cap", idx); 284 return cec_allocate_adapter(&vivid_cec_adap_ops, dev, 285 name, caps, 1); 286 } 287