]>
Commit | Line | Data |
---|---|---|
9881fe0c HV |
1 | /* |
2 | * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter | |
3 | * | |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | |
5 | * | |
6 | * This program is free software; you may redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; version 2 of the License. | |
9 | * | |
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
17 | * SOFTWARE. | |
18 | */ | |
19 | ||
20 | #include <linux/errno.h> | |
21 | #include <linux/init.h> | |
22 | #include <linux/module.h> | |
23 | #include <linux/kernel.h> | |
24 | #include <linux/kmod.h> | |
25 | #include <linux/ktime.h> | |
26 | #include <linux/slab.h> | |
27 | #include <linux/mm.h> | |
28 | #include <linux/string.h> | |
29 | #include <linux/types.h> | |
30 | ||
23111ec3 HV |
31 | #include <drm/drm_edid.h> |
32 | ||
9881fe0c HV |
33 | #include "cec-priv.h" |
34 | ||
52bc30fd HV |
35 | static void cec_fill_msg_report_features(struct cec_adapter *adap, |
36 | struct cec_msg *msg, | |
37 | unsigned int la_idx); | |
9881fe0c HV |
38 | |
39 | /* | |
40 | * 400 ms is the time it takes for one 16 byte message to be | |
41 | * transferred and 5 is the maximum number of retries. Add | |
42 | * another 100 ms as a margin. So if the transmit doesn't | |
43 | * finish before that time something is really wrong and we | |
44 | * have to time out. | |
45 | * | |
46 | * This is a sign that something it really wrong and a warning | |
47 | * will be issued. | |
48 | */ | |
49 | #define CEC_XFER_TIMEOUT_MS (5 * 400 + 100) | |
50 | ||
51 | #define call_op(adap, op, arg...) \ | |
52 | (adap->ops->op ? adap->ops->op(adap, ## arg) : 0) | |
53 | ||
54 | #define call_void_op(adap, op, arg...) \ | |
55 | do { \ | |
56 | if (adap->ops->op) \ | |
57 | adap->ops->op(adap, ## arg); \ | |
58 | } while (0) | |
59 | ||
60 | static int cec_log_addr2idx(const struct cec_adapter *adap, u8 log_addr) | |
61 | { | |
62 | int i; | |
63 | ||
64 | for (i = 0; i < adap->log_addrs.num_log_addrs; i++) | |
65 | if (adap->log_addrs.log_addr[i] == log_addr) | |
66 | return i; | |
67 | return -1; | |
68 | } | |
69 | ||
70 | static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr) | |
71 | { | |
72 | int i = cec_log_addr2idx(adap, log_addr); | |
73 | ||
74 | return adap->log_addrs.primary_device_type[i < 0 ? 0 : i]; | |
75 | } | |
76 | ||
77 | /* | |
78 | * Queue a new event for this filehandle. If ts == 0, then set it | |
79 | * to the current time. | |
80 | * | |
6b2bbb08 HV |
81 | * We keep a queue of at most max_event events where max_event differs |
82 | * per event. If the queue becomes full, then drop the oldest event and | |
83 | * keep track of how many events we've dropped. | |
9881fe0c HV |
84 | */ |
85 | void cec_queue_event_fh(struct cec_fh *fh, | |
86 | const struct cec_event *new_ev, u64 ts) | |
87 | { | |
6b2bbb08 HV |
88 | static const u8 max_events[CEC_NUM_EVENTS] = { |
89 | 1, 1, 64, 64, | |
90 | }; | |
91 | struct cec_event_entry *entry; | |
92 | unsigned int ev_idx = new_ev->event - 1; | |
93 | ||
94 | if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events))) | |
95 | return; | |
9881fe0c HV |
96 | |
97 | if (ts == 0) | |
98 | ts = ktime_get_ns(); | |
99 | ||
100 | mutex_lock(&fh->lock); | |
6b2bbb08 HV |
101 | if (ev_idx < CEC_NUM_CORE_EVENTS) |
102 | entry = &fh->core_events[ev_idx]; | |
103 | else | |
104 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | |
105 | if (entry) { | |
106 | if (new_ev->event == CEC_EVENT_LOST_MSGS && | |
107 | fh->queued_events[ev_idx]) { | |
108 | entry->ev.lost_msgs.lost_msgs += | |
109 | new_ev->lost_msgs.lost_msgs; | |
110 | goto unlock; | |
111 | } | |
112 | entry->ev = *new_ev; | |
113 | entry->ev.ts = ts; | |
114 | ||
115 | if (fh->queued_events[ev_idx] < max_events[ev_idx]) { | |
116 | /* Add new msg at the end of the queue */ | |
117 | list_add_tail(&entry->list, &fh->events[ev_idx]); | |
118 | fh->queued_events[ev_idx]++; | |
119 | fh->total_queued_events++; | |
120 | goto unlock; | |
121 | } | |
122 | ||
123 | if (ev_idx >= CEC_NUM_CORE_EVENTS) { | |
124 | list_add_tail(&entry->list, &fh->events[ev_idx]); | |
125 | /* drop the oldest event */ | |
126 | entry = list_first_entry(&fh->events[ev_idx], | |
127 | struct cec_event_entry, list); | |
128 | list_del(&entry->list); | |
129 | kfree(entry); | |
130 | } | |
9881fe0c | 131 | } |
6b2bbb08 HV |
132 | /* Mark that events were lost */ |
133 | entry = list_first_entry_or_null(&fh->events[ev_idx], | |
134 | struct cec_event_entry, list); | |
135 | if (entry) | |
136 | entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS; | |
9881fe0c HV |
137 | |
138 | unlock: | |
139 | mutex_unlock(&fh->lock); | |
140 | wake_up_interruptible(&fh->wait); | |
141 | } | |
142 | ||
143 | /* Queue a new event for all open filehandles. */ | |
144 | static void cec_queue_event(struct cec_adapter *adap, | |
145 | const struct cec_event *ev) | |
146 | { | |
147 | u64 ts = ktime_get_ns(); | |
148 | struct cec_fh *fh; | |
149 | ||
62148f09 | 150 | mutex_lock(&adap->devnode.lock); |
9881fe0c HV |
151 | list_for_each_entry(fh, &adap->devnode.fhs, list) |
152 | cec_queue_event_fh(fh, ev, ts); | |
62148f09 | 153 | mutex_unlock(&adap->devnode.lock); |
9881fe0c HV |
154 | } |
155 | ||
b8d62f50 | 156 | /* Notify userspace that the CEC pin changed state at the given time. */ |
9a6b2a87 | 157 | void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts) |
b8d62f50 HV |
158 | { |
159 | struct cec_event ev = { | |
9a6b2a87 HV |
160 | .event = is_high ? CEC_EVENT_PIN_CEC_HIGH : |
161 | CEC_EVENT_PIN_CEC_LOW, | |
b8d62f50 HV |
162 | }; |
163 | struct cec_fh *fh; | |
164 | ||
165 | mutex_lock(&adap->devnode.lock); | |
166 | list_for_each_entry(fh, &adap->devnode.fhs, list) | |
167 | if (fh->mode_follower == CEC_MODE_MONITOR_PIN) | |
168 | cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); | |
169 | mutex_unlock(&adap->devnode.lock); | |
170 | } | |
9a6b2a87 | 171 | EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event); |
b8d62f50 | 172 | |
9881fe0c | 173 | /* |
6b2bbb08 HV |
174 | * Queue a new message for this filehandle. |
175 | * | |
176 | * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the | |
177 | * queue becomes full, then drop the oldest message and keep track | |
178 | * of how many messages we've dropped. | |
9881fe0c HV |
179 | */ |
180 | static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) | |
181 | { | |
6b2bbb08 | 182 | static const struct cec_event ev_lost_msgs = { |
9881fe0c | 183 | .event = CEC_EVENT_LOST_MSGS, |
6b2bbb08 | 184 | .lost_msgs.lost_msgs = 1, |
9881fe0c HV |
185 | }; |
186 | struct cec_msg_entry *entry; | |
187 | ||
188 | mutex_lock(&fh->lock); | |
189 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | |
6b2bbb08 HV |
190 | if (entry) { |
191 | entry->msg = *msg; | |
192 | /* Add new msg at the end of the queue */ | |
193 | list_add_tail(&entry->list, &fh->msgs); | |
194 | ||
195 | if (fh->queued_msgs < CEC_MAX_MSG_RX_QUEUE_SZ) { | |
196 | /* All is fine if there is enough room */ | |
197 | fh->queued_msgs++; | |
198 | mutex_unlock(&fh->lock); | |
199 | wake_up_interruptible(&fh->wait); | |
200 | return; | |
201 | } | |
9881fe0c | 202 | |
6b2bbb08 HV |
203 | /* |
204 | * if the message queue is full, then drop the oldest one and | |
205 | * send a lost message event. | |
206 | */ | |
207 | entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list); | |
9881fe0c | 208 | list_del(&entry->list); |
6b2bbb08 | 209 | kfree(entry); |
9881fe0c | 210 | } |
9881fe0c | 211 | mutex_unlock(&fh->lock); |
9881fe0c | 212 | |
6b2bbb08 HV |
213 | /* |
214 | * We lost a message, either because kmalloc failed or the queue | |
215 | * was full. | |
216 | */ | |
217 | cec_queue_event_fh(fh, &ev_lost_msgs, ktime_get_ns()); | |
9881fe0c HV |
218 | } |
219 | ||
220 | /* | |
221 | * Queue the message for those filehandles that are in monitor mode. | |
222 | * If valid_la is true (this message is for us or was sent by us), | |
223 | * then pass it on to any monitoring filehandle. If this message | |
224 | * isn't for us or from us, then only give it to filehandles that | |
225 | * are in MONITOR_ALL mode. | |
226 | * | |
227 | * This can only happen if the CEC_CAP_MONITOR_ALL capability is | |
228 | * set and the CEC adapter was placed in 'monitor all' mode. | |
229 | */ | |
230 | static void cec_queue_msg_monitor(struct cec_adapter *adap, | |
231 | const struct cec_msg *msg, | |
232 | bool valid_la) | |
233 | { | |
234 | struct cec_fh *fh; | |
235 | u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : | |
236 | CEC_MODE_MONITOR_ALL; | |
237 | ||
62148f09 | 238 | mutex_lock(&adap->devnode.lock); |
9881fe0c HV |
239 | list_for_each_entry(fh, &adap->devnode.fhs, list) { |
240 | if (fh->mode_follower >= monitor_mode) | |
241 | cec_queue_msg_fh(fh, msg); | |
242 | } | |
62148f09 | 243 | mutex_unlock(&adap->devnode.lock); |
9881fe0c HV |
244 | } |
245 | ||
246 | /* | |
247 | * Queue the message for follower filehandles. | |
248 | */ | |
249 | static void cec_queue_msg_followers(struct cec_adapter *adap, | |
250 | const struct cec_msg *msg) | |
251 | { | |
252 | struct cec_fh *fh; | |
253 | ||
62148f09 | 254 | mutex_lock(&adap->devnode.lock); |
9881fe0c HV |
255 | list_for_each_entry(fh, &adap->devnode.fhs, list) { |
256 | if (fh->mode_follower == CEC_MODE_FOLLOWER) | |
257 | cec_queue_msg_fh(fh, msg); | |
258 | } | |
62148f09 | 259 | mutex_unlock(&adap->devnode.lock); |
9881fe0c HV |
260 | } |
261 | ||
262 | /* Notify userspace of an adapter state change. */ | |
263 | static void cec_post_state_event(struct cec_adapter *adap) | |
264 | { | |
265 | struct cec_event ev = { | |
266 | .event = CEC_EVENT_STATE_CHANGE, | |
267 | }; | |
268 | ||
269 | ev.state_change.phys_addr = adap->phys_addr; | |
270 | ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask; | |
271 | cec_queue_event(adap, &ev); | |
272 | } | |
273 | ||
274 | /* | |
275 | * A CEC transmit (and a possible wait for reply) completed. | |
276 | * If this was in blocking mode, then complete it, otherwise | |
277 | * queue the message for userspace to dequeue later. | |
278 | * | |
279 | * This function is called with adap->lock held. | |
280 | */ | |
281 | static void cec_data_completed(struct cec_data *data) | |
282 | { | |
283 | /* | |
284 | * Delete this transmit from the filehandle's xfer_list since | |
285 | * we're done with it. | |
286 | * | |
287 | * Note that if the filehandle is closed before this transmit | |
288 | * finished, then the release() function will set data->fh to NULL. | |
289 | * Without that we would be referring to a closed filehandle. | |
290 | */ | |
291 | if (data->fh) | |
292 | list_del(&data->xfer_list); | |
293 | ||
294 | if (data->blocking) { | |
295 | /* | |
296 | * Someone is blocking so mark the message as completed | |
297 | * and call complete. | |
298 | */ | |
299 | data->completed = true; | |
300 | complete(&data->c); | |
301 | } else { | |
302 | /* | |
303 | * No blocking, so just queue the message if needed and | |
304 | * free the memory. | |
305 | */ | |
306 | if (data->fh) | |
307 | cec_queue_msg_fh(data->fh, &data->msg); | |
308 | kfree(data); | |
309 | } | |
310 | } | |
311 | ||
312 | /* | |
313 | * A pending CEC transmit needs to be cancelled, either because the CEC | |
314 | * adapter is disabled or the transmit takes an impossibly long time to | |
315 | * finish. | |
316 | * | |
317 | * This function is called with adap->lock held. | |
318 | */ | |
319 | static void cec_data_cancel(struct cec_data *data) | |
320 | { | |
321 | /* | |
322 | * It's either the current transmit, or it is a pending | |
323 | * transmit. Take the appropriate action to clear it. | |
324 | */ | |
11065f85 | 325 | if (data->adap->transmitting == data) { |
9881fe0c | 326 | data->adap->transmitting = NULL; |
11065f85 | 327 | } else { |
9881fe0c | 328 | list_del_init(&data->list); |
11065f85 HV |
329 | if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) |
330 | data->adap->transmit_queue_sz--; | |
331 | } | |
9881fe0c HV |
332 | |
333 | /* Mark it as an error */ | |
980e0b36 | 334 | data->msg.tx_ts = ktime_get_ns(); |
12047612 HV |
335 | data->msg.tx_status |= CEC_TX_STATUS_ERROR | |
336 | CEC_TX_STATUS_MAX_RETRIES; | |
337 | data->msg.tx_error_cnt++; | |
9881fe0c | 338 | data->attempts = 0; |
9881fe0c HV |
339 | /* Queue transmitted message for monitoring purposes */ |
340 | cec_queue_msg_monitor(data->adap, &data->msg, 1); | |
341 | ||
342 | cec_data_completed(data); | |
343 | } | |
344 | ||
b39f93ef HV |
345 | /* |
346 | * Flush all pending transmits and cancel any pending timeout work. | |
347 | * | |
348 | * This function is called with adap->lock held. | |
349 | */ | |
350 | static void cec_flush(struct cec_adapter *adap) | |
351 | { | |
352 | struct cec_data *data, *n; | |
353 | ||
354 | /* | |
355 | * If the adapter is disabled, or we're asked to stop, | |
356 | * then cancel any pending transmits. | |
357 | */ | |
358 | while (!list_empty(&adap->transmit_queue)) { | |
359 | data = list_first_entry(&adap->transmit_queue, | |
360 | struct cec_data, list); | |
361 | cec_data_cancel(data); | |
362 | } | |
363 | if (adap->transmitting) | |
364 | cec_data_cancel(adap->transmitting); | |
365 | ||
366 | /* Cancel the pending timeout work. */ | |
367 | list_for_each_entry_safe(data, n, &adap->wait_queue, list) { | |
368 | if (cancel_delayed_work(&data->work)) | |
369 | cec_data_cancel(data); | |
370 | /* | |
371 | * If cancel_delayed_work returned false, then | |
372 | * the cec_wait_timeout function is running, | |
373 | * which will call cec_data_completed. So no | |
374 | * need to do anything special in that case. | |
375 | */ | |
376 | } | |
377 | } | |
378 | ||
9881fe0c HV |
379 | /* |
380 | * Main CEC state machine | |
381 | * | |
382 | * Wait until the thread should be stopped, or we are not transmitting and | |
383 | * a new transmit message is queued up, in which case we start transmitting | |
384 | * that message. When the adapter finished transmitting the message it will | |
385 | * call cec_transmit_done(). | |
386 | * | |
387 | * If the adapter is disabled, then remove all queued messages instead. | |
388 | * | |
389 | * If the current transmit times out, then cancel that transmit. | |
390 | */ | |
391 | int cec_thread_func(void *_adap) | |
392 | { | |
393 | struct cec_adapter *adap = _adap; | |
394 | ||
395 | for (;;) { | |
396 | unsigned int signal_free_time; | |
397 | struct cec_data *data; | |
398 | bool timeout = false; | |
399 | u8 attempts; | |
400 | ||
401 | if (adap->transmitting) { | |
402 | int err; | |
403 | ||
404 | /* | |
405 | * We are transmitting a message, so add a timeout | |
406 | * to prevent the state machine to get stuck waiting | |
407 | * for this message to finalize and add a check to | |
408 | * see if the adapter is disabled in which case the | |
409 | * transmit should be canceled. | |
410 | */ | |
411 | err = wait_event_interruptible_timeout(adap->kthread_waitq, | |
f902c1e9 HV |
412 | (adap->needs_hpd && |
413 | (!adap->is_configured && !adap->is_configuring)) || | |
9881fe0c | 414 | kthread_should_stop() || |
9881fe0c HV |
415 | (!adap->transmitting && |
416 | !list_empty(&adap->transmit_queue)), | |
417 | msecs_to_jiffies(CEC_XFER_TIMEOUT_MS)); | |
418 | timeout = err == 0; | |
419 | } else { | |
420 | /* Otherwise we just wait for something to happen. */ | |
421 | wait_event_interruptible(adap->kthread_waitq, | |
422 | kthread_should_stop() || | |
423 | (!adap->transmitting && | |
424 | !list_empty(&adap->transmit_queue))); | |
425 | } | |
426 | ||
427 | mutex_lock(&adap->lock); | |
428 | ||
f902c1e9 HV |
429 | if ((adap->needs_hpd && |
430 | (!adap->is_configured && !adap->is_configuring)) || | |
431 | kthread_should_stop()) { | |
b39f93ef | 432 | cec_flush(adap); |
9881fe0c HV |
433 | goto unlock; |
434 | } | |
435 | ||
436 | if (adap->transmitting && timeout) { | |
437 | /* | |
bb789e03 HV |
438 | * If we timeout, then log that. Normally this does |
439 | * not happen and it is an indication of a faulty CEC | |
440 | * adapter driver, or the CEC bus is in some weird | |
441 | * state. On rare occasions it can happen if there is | |
442 | * so much traffic on the bus that the adapter was | |
443 | * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). | |
9881fe0c | 444 | */ |
bb789e03 | 445 | dprintk(1, "%s: message %*ph timed out\n", __func__, |
9881fe0c HV |
446 | adap->transmitting->msg.len, |
447 | adap->transmitting->msg.msg); | |
bb789e03 | 448 | adap->tx_timeouts++; |
9881fe0c HV |
449 | /* Just give up on this. */ |
450 | cec_data_cancel(adap->transmitting); | |
451 | goto unlock; | |
452 | } | |
453 | ||
454 | /* | |
455 | * If we are still transmitting, or there is nothing new to | |
456 | * transmit, then just continue waiting. | |
457 | */ | |
458 | if (adap->transmitting || list_empty(&adap->transmit_queue)) | |
459 | goto unlock; | |
460 | ||
461 | /* Get a new message to transmit */ | |
462 | data = list_first_entry(&adap->transmit_queue, | |
463 | struct cec_data, list); | |
464 | list_del_init(&data->list); | |
11065f85 | 465 | adap->transmit_queue_sz--; |
533a3f7b | 466 | |
9881fe0c HV |
467 | /* Make this the current transmitting message */ |
468 | adap->transmitting = data; | |
469 | ||
470 | /* | |
471 | * Suggested number of attempts as per the CEC 2.0 spec: | |
472 | * 4 attempts is the default, except for 'secondary poll | |
473 | * messages', i.e. poll messages not sent during the adapter | |
474 | * configuration phase when it allocates logical addresses. | |
475 | */ | |
476 | if (data->msg.len == 1 && adap->is_configured) | |
477 | attempts = 2; | |
478 | else | |
479 | attempts = 4; | |
480 | ||
481 | /* Set the suggested signal free time */ | |
482 | if (data->attempts) { | |
483 | /* should be >= 3 data bit periods for a retry */ | |
484 | signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY; | |
485 | } else if (data->new_initiator) { | |
486 | /* should be >= 5 data bit periods for new initiator */ | |
487 | signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR; | |
488 | } else { | |
489 | /* | |
490 | * should be >= 7 data bit periods for sending another | |
491 | * frame immediately after another. | |
492 | */ | |
493 | signal_free_time = CEC_SIGNAL_FREE_TIME_NEXT_XFER; | |
494 | } | |
495 | if (data->attempts == 0) | |
496 | data->attempts = attempts; | |
497 | ||
498 | /* Tell the adapter to transmit, cancel on error */ | |
499 | if (adap->ops->adap_transmit(adap, data->attempts, | |
500 | signal_free_time, &data->msg)) | |
501 | cec_data_cancel(data); | |
502 | ||
503 | unlock: | |
504 | mutex_unlock(&adap->lock); | |
505 | ||
506 | if (kthread_should_stop()) | |
507 | break; | |
508 | } | |
509 | return 0; | |
510 | } | |
511 | ||
512 | /* | |
513 | * Called by the CEC adapter if a transmit finished. | |
514 | */ | |
0861ad14 HV |
515 | void cec_transmit_done_ts(struct cec_adapter *adap, u8 status, |
516 | u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt, | |
517 | u8 error_cnt, ktime_t ts) | |
9881fe0c HV |
518 | { |
519 | struct cec_data *data; | |
520 | struct cec_msg *msg; | |
688318c3 HV |
521 | unsigned int attempts_made = arb_lost_cnt + nack_cnt + |
522 | low_drive_cnt + error_cnt; | |
9881fe0c | 523 | |
a7a04b5b | 524 | dprintk(2, "%s: status %02x\n", __func__, status); |
688318c3 HV |
525 | if (attempts_made < 1) |
526 | attempts_made = 1; | |
527 | ||
9881fe0c HV |
528 | mutex_lock(&adap->lock); |
529 | data = adap->transmitting; | |
530 | if (!data) { | |
531 | /* | |
532 | * This can happen if a transmit was issued and the cable is | |
533 | * unplugged while the transmit is ongoing. Ignore this | |
534 | * transmit in that case. | |
535 | */ | |
a7a04b5b HV |
536 | dprintk(1, "%s was called without an ongoing transmit!\n", |
537 | __func__); | |
9881fe0c HV |
538 | goto unlock; |
539 | } | |
540 | ||
541 | msg = &data->msg; | |
542 | ||
543 | /* Drivers must fill in the status! */ | |
544 | WARN_ON(status == 0); | |
0861ad14 | 545 | msg->tx_ts = ktime_to_ns(ts); |
9881fe0c HV |
546 | msg->tx_status |= status; |
547 | msg->tx_arb_lost_cnt += arb_lost_cnt; | |
548 | msg->tx_nack_cnt += nack_cnt; | |
549 | msg->tx_low_drive_cnt += low_drive_cnt; | |
550 | msg->tx_error_cnt += error_cnt; | |
551 | ||
552 | /* Mark that we're done with this transmit */ | |
553 | adap->transmitting = NULL; | |
554 | ||
555 | /* | |
556 | * If there are still retry attempts left and there was an error and | |
557 | * the hardware didn't signal that it retried itself (by setting | |
558 | * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves. | |
559 | */ | |
688318c3 | 560 | if (data->attempts > attempts_made && |
9881fe0c HV |
561 | !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) { |
562 | /* Retry this message */ | |
688318c3 | 563 | data->attempts -= attempts_made; |
a7a04b5b HV |
564 | if (msg->timeout) |
565 | dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n", | |
566 | msg->len, msg->msg, data->attempts, msg->reply); | |
567 | else | |
568 | dprintk(2, "retransmit: %*ph (attempts: %d)\n", | |
569 | msg->len, msg->msg, data->attempts); | |
9881fe0c HV |
570 | /* Add the message in front of the transmit queue */ |
571 | list_add(&data->list, &adap->transmit_queue); | |
11065f85 | 572 | adap->transmit_queue_sz++; |
9881fe0c HV |
573 | goto wake_thread; |
574 | } | |
575 | ||
576 | data->attempts = 0; | |
577 | ||
578 | /* Always set CEC_TX_STATUS_MAX_RETRIES on error */ | |
579 | if (!(status & CEC_TX_STATUS_OK)) | |
580 | msg->tx_status |= CEC_TX_STATUS_MAX_RETRIES; | |
581 | ||
582 | /* Queue transmitted message for monitoring purposes */ | |
583 | cec_queue_msg_monitor(adap, msg, 1); | |
584 | ||
86e3577f HV |
585 | if ((status & CEC_TX_STATUS_OK) && adap->is_configured && |
586 | msg->timeout) { | |
9881fe0c HV |
587 | /* |
588 | * Queue the message into the wait queue if we want to wait | |
589 | * for a reply. | |
590 | */ | |
591 | list_add_tail(&data->list, &adap->wait_queue); | |
592 | schedule_delayed_work(&data->work, | |
593 | msecs_to_jiffies(msg->timeout)); | |
594 | } else { | |
595 | /* Otherwise we're done */ | |
596 | cec_data_completed(data); | |
597 | } | |
598 | ||
599 | wake_thread: | |
600 | /* | |
601 | * Wake up the main thread to see if another message is ready | |
602 | * for transmitting or to retry the current message. | |
603 | */ | |
604 | wake_up_interruptible(&adap->kthread_waitq); | |
605 | unlock: | |
606 | mutex_unlock(&adap->lock); | |
607 | } | |
0861ad14 | 608 | EXPORT_SYMBOL_GPL(cec_transmit_done_ts); |
9881fe0c | 609 | |
0861ad14 HV |
610 | void cec_transmit_attempt_done_ts(struct cec_adapter *adap, |
611 | u8 status, ktime_t ts) | |
c94cdc1e | 612 | { |
bd34ca87 | 613 | switch (status & ~CEC_TX_STATUS_MAX_RETRIES) { |
c94cdc1e | 614 | case CEC_TX_STATUS_OK: |
0861ad14 | 615 | cec_transmit_done_ts(adap, status, 0, 0, 0, 0, ts); |
c94cdc1e HV |
616 | return; |
617 | case CEC_TX_STATUS_ARB_LOST: | |
0861ad14 | 618 | cec_transmit_done_ts(adap, status, 1, 0, 0, 0, ts); |
c94cdc1e HV |
619 | return; |
620 | case CEC_TX_STATUS_NACK: | |
0861ad14 | 621 | cec_transmit_done_ts(adap, status, 0, 1, 0, 0, ts); |
c94cdc1e HV |
622 | return; |
623 | case CEC_TX_STATUS_LOW_DRIVE: | |
0861ad14 | 624 | cec_transmit_done_ts(adap, status, 0, 0, 1, 0, ts); |
c94cdc1e HV |
625 | return; |
626 | case CEC_TX_STATUS_ERROR: | |
0861ad14 | 627 | cec_transmit_done_ts(adap, status, 0, 0, 0, 1, ts); |
c94cdc1e HV |
628 | return; |
629 | default: | |
630 | /* Should never happen */ | |
631 | WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status); | |
632 | return; | |
633 | } | |
634 | } | |
0861ad14 | 635 | EXPORT_SYMBOL_GPL(cec_transmit_attempt_done_ts); |
c94cdc1e | 636 | |
9881fe0c HV |
637 | /* |
638 | * Called when waiting for a reply times out. | |
639 | */ | |
640 | static void cec_wait_timeout(struct work_struct *work) | |
641 | { | |
642 | struct cec_data *data = container_of(work, struct cec_data, work.work); | |
643 | struct cec_adapter *adap = data->adap; | |
644 | ||
645 | mutex_lock(&adap->lock); | |
646 | /* | |
647 | * Sanity check in case the timeout and the arrival of the message | |
648 | * happened at the same time. | |
649 | */ | |
650 | if (list_empty(&data->list)) | |
651 | goto unlock; | |
652 | ||
653 | /* Mark the message as timed out */ | |
654 | list_del_init(&data->list); | |
980e0b36 | 655 | data->msg.rx_ts = ktime_get_ns(); |
9881fe0c HV |
656 | data->msg.rx_status = CEC_RX_STATUS_TIMEOUT; |
657 | cec_data_completed(data); | |
658 | unlock: | |
659 | mutex_unlock(&adap->lock); | |
660 | } | |
661 | ||
662 | /* | |
663 | * Transmit a message. The fh argument may be NULL if the transmit is not | |
664 | * associated with a specific filehandle. | |
665 | * | |
666 | * This function is called with adap->lock held. | |
667 | */ | |
668 | int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, | |
669 | struct cec_fh *fh, bool block) | |
670 | { | |
671 | struct cec_data *data; | |
672 | u8 last_initiator = 0xff; | |
673 | unsigned int timeout; | |
674 | int res = 0; | |
675 | ||
40df3a7e HV |
676 | msg->rx_ts = 0; |
677 | msg->tx_ts = 0; | |
678 | msg->rx_status = 0; | |
679 | msg->tx_status = 0; | |
680 | msg->tx_arb_lost_cnt = 0; | |
681 | msg->tx_nack_cnt = 0; | |
682 | msg->tx_low_drive_cnt = 0; | |
683 | msg->tx_error_cnt = 0; | |
15e809e9 | 684 | msg->sequence = 0; |
40df3a7e | 685 | |
9881fe0c HV |
686 | if (msg->reply && msg->timeout == 0) { |
687 | /* Make sure the timeout isn't 0. */ | |
688 | msg->timeout = 1000; | |
689 | } | |
7ae2a888 HV |
690 | if (msg->timeout) |
691 | msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS; | |
692 | else | |
693 | msg->flags = 0; | |
9881fe0c HV |
694 | |
695 | /* Sanity checks */ | |
696 | if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { | |
5a137df1 | 697 | dprintk(1, "%s: invalid length %d\n", __func__, msg->len); |
9881fe0c HV |
698 | return -EINVAL; |
699 | } | |
700 | if (msg->timeout && msg->len == 1) { | |
5a137df1 | 701 | dprintk(1, "%s: can't reply for poll msg\n", __func__); |
9881fe0c HV |
702 | return -EINVAL; |
703 | } | |
045344c3 | 704 | memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); |
9881fe0c | 705 | if (msg->len == 1) { |
42980da2 | 706 | if (cec_msg_destination(msg) == 0xf) { |
5a137df1 | 707 | dprintk(1, "%s: invalid poll message\n", __func__); |
9881fe0c HV |
708 | return -EINVAL; |
709 | } | |
710 | if (cec_has_log_addr(adap, cec_msg_destination(msg))) { | |
711 | /* | |
712 | * If the destination is a logical address our adapter | |
713 | * has already claimed, then just NACK this. | |
714 | * It depends on the hardware what it will do with a | |
715 | * POLL to itself (some OK this), so it is just as | |
716 | * easy to handle it here so the behavior will be | |
717 | * consistent. | |
718 | */ | |
9a3f14ea | 719 | msg->tx_ts = ktime_get_ns(); |
9881fe0c HV |
720 | msg->tx_status = CEC_TX_STATUS_NACK | |
721 | CEC_TX_STATUS_MAX_RETRIES; | |
722 | msg->tx_nack_cnt = 1; | |
15e809e9 HV |
723 | msg->sequence = ++adap->sequence; |
724 | if (!msg->sequence) | |
725 | msg->sequence = ++adap->sequence; | |
9881fe0c HV |
726 | return 0; |
727 | } | |
728 | } | |
729 | if (msg->len > 1 && !cec_msg_is_broadcast(msg) && | |
730 | cec_has_log_addr(adap, cec_msg_destination(msg))) { | |
5a137df1 | 731 | dprintk(1, "%s: destination is the adapter itself\n", __func__); |
9881fe0c HV |
732 | return -EINVAL; |
733 | } | |
42980da2 | 734 | if (msg->len > 1 && adap->is_configured && |
9881fe0c | 735 | !cec_has_log_addr(adap, cec_msg_initiator(msg))) { |
5a137df1 HV |
736 | dprintk(1, "%s: initiator has unknown logical address %d\n", |
737 | __func__, cec_msg_initiator(msg)); | |
9881fe0c HV |
738 | return -EINVAL; |
739 | } | |
25c21078 | 740 | if (!adap->is_configured && !adap->is_configuring) { |
f902c1e9 | 741 | if (adap->needs_hpd || msg->msg[0] != 0xf0) { |
25c21078 HV |
742 | dprintk(1, "%s: adapter is unconfigured\n", __func__); |
743 | return -ENONET; | |
744 | } | |
745 | if (msg->reply) { | |
746 | dprintk(1, "%s: invalid msg->reply\n", __func__); | |
747 | return -EINVAL; | |
748 | } | |
749 | } | |
9881fe0c | 750 | |
25c21078 HV |
751 | if (adap->transmit_queue_sz >= CEC_MAX_MSG_TX_QUEUE_SZ) { |
752 | dprintk(1, "%s: transmit queue full\n", __func__); | |
11065f85 | 753 | return -EBUSY; |
25c21078 | 754 | } |
11065f85 | 755 | |
9881fe0c HV |
756 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
757 | if (!data) | |
758 | return -ENOMEM; | |
759 | ||
15e809e9 HV |
760 | msg->sequence = ++adap->sequence; |
761 | if (!msg->sequence) | |
762 | msg->sequence = ++adap->sequence; | |
763 | ||
9881fe0c HV |
764 | if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { |
765 | msg->msg[2] = adap->phys_addr >> 8; | |
766 | msg->msg[3] = adap->phys_addr & 0xff; | |
767 | } | |
768 | ||
769 | if (msg->timeout) | |
5a137df1 | 770 | dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n", |
0861ad14 HV |
771 | __func__, msg->len, msg->msg, msg->reply, |
772 | !block ? ", nb" : ""); | |
9881fe0c | 773 | else |
5a137df1 HV |
774 | dprintk(2, "%s: %*ph%s\n", |
775 | __func__, msg->len, msg->msg, !block ? " (nb)" : ""); | |
9881fe0c | 776 | |
9881fe0c HV |
777 | data->msg = *msg; |
778 | data->fh = fh; | |
779 | data->adap = adap; | |
780 | data->blocking = block; | |
781 | ||
782 | /* | |
783 | * Determine if this message follows a message from the same | |
784 | * initiator. Needed to determine the free signal time later on. | |
785 | */ | |
786 | if (msg->len > 1) { | |
787 | if (!(list_empty(&adap->transmit_queue))) { | |
788 | const struct cec_data *last; | |
789 | ||
790 | last = list_last_entry(&adap->transmit_queue, | |
791 | const struct cec_data, list); | |
792 | last_initiator = cec_msg_initiator(&last->msg); | |
793 | } else if (adap->transmitting) { | |
794 | last_initiator = | |
795 | cec_msg_initiator(&adap->transmitting->msg); | |
796 | } | |
797 | } | |
798 | data->new_initiator = last_initiator != cec_msg_initiator(msg); | |
799 | init_completion(&data->c); | |
800 | INIT_DELAYED_WORK(&data->work, cec_wait_timeout); | |
801 | ||
9881fe0c HV |
802 | if (fh) |
803 | list_add_tail(&data->xfer_list, &fh->xfer_list); | |
533a3f7b | 804 | |
9881fe0c | 805 | list_add_tail(&data->list, &adap->transmit_queue); |
11065f85 | 806 | adap->transmit_queue_sz++; |
9881fe0c HV |
807 | if (!adap->transmitting) |
808 | wake_up_interruptible(&adap->kthread_waitq); | |
809 | ||
810 | /* All done if we don't need to block waiting for completion */ | |
811 | if (!block) | |
812 | return 0; | |
813 | ||
814 | /* | |
815 | * If we don't get a completion before this time something is really | |
816 | * wrong and we time out. | |
817 | */ | |
818 | timeout = CEC_XFER_TIMEOUT_MS; | |
819 | /* Add the requested timeout if we have to wait for a reply as well */ | |
820 | if (msg->timeout) | |
821 | timeout += msg->timeout; | |
822 | ||
823 | /* | |
824 | * Release the lock and wait, retake the lock afterwards. | |
825 | */ | |
826 | mutex_unlock(&adap->lock); | |
827 | res = wait_for_completion_killable_timeout(&data->c, | |
828 | msecs_to_jiffies(timeout)); | |
829 | mutex_lock(&adap->lock); | |
830 | ||
831 | if (data->completed) { | |
832 | /* The transmit completed (possibly with an error) */ | |
833 | *msg = data->msg; | |
834 | kfree(data); | |
835 | return 0; | |
836 | } | |
837 | /* | |
838 | * The wait for completion timed out or was interrupted, so mark this | |
839 | * as non-blocking and disconnect from the filehandle since it is | |
840 | * still 'in flight'. When it finally completes it will just drop the | |
841 | * result silently. | |
842 | */ | |
843 | data->blocking = false; | |
844 | if (data->fh) | |
845 | list_del(&data->xfer_list); | |
846 | data->fh = NULL; | |
847 | ||
848 | if (res == 0) { /* timed out */ | |
849 | /* Check if the reply or the transmit failed */ | |
850 | if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK)) | |
851 | msg->rx_status = CEC_RX_STATUS_TIMEOUT; | |
852 | else | |
853 | msg->tx_status = CEC_TX_STATUS_MAX_RETRIES; | |
854 | } | |
855 | return res > 0 ? 0 : res; | |
856 | } | |
857 | ||
858 | /* Helper function to be used by drivers and this framework. */ | |
859 | int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, | |
860 | bool block) | |
861 | { | |
862 | int ret; | |
863 | ||
864 | mutex_lock(&adap->lock); | |
865 | ret = cec_transmit_msg_fh(adap, msg, NULL, block); | |
866 | mutex_unlock(&adap->lock); | |
867 | return ret; | |
868 | } | |
869 | EXPORT_SYMBOL_GPL(cec_transmit_msg); | |
870 | ||
871 | /* | |
872 | * I don't like forward references but without this the low-level | |
873 | * cec_received_msg() function would come after a bunch of high-level | |
874 | * CEC protocol handling functions. That was very confusing. | |
875 | */ | |
876 | static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, | |
877 | bool is_reply); | |
878 | ||
3074fe4a HV |
879 | #define DIRECTED 0x80 |
880 | #define BCAST1_4 0x40 | |
881 | #define BCAST2_0 0x20 /* broadcast only allowed for >= 2.0 */ | |
882 | #define BCAST (BCAST1_4 | BCAST2_0) | |
883 | #define BOTH (BCAST | DIRECTED) | |
884 | ||
885 | /* | |
886 | * Specify minimum length and whether the message is directed, broadcast | |
887 | * or both. Messages that do not match the criteria are ignored as per | |
888 | * the CEC specification. | |
889 | */ | |
890 | static const u8 cec_msg_size[256] = { | |
891 | [CEC_MSG_ACTIVE_SOURCE] = 4 | BCAST, | |
892 | [CEC_MSG_IMAGE_VIEW_ON] = 2 | DIRECTED, | |
893 | [CEC_MSG_TEXT_VIEW_ON] = 2 | DIRECTED, | |
894 | [CEC_MSG_INACTIVE_SOURCE] = 4 | DIRECTED, | |
895 | [CEC_MSG_REQUEST_ACTIVE_SOURCE] = 2 | BCAST, | |
896 | [CEC_MSG_ROUTING_CHANGE] = 6 | BCAST, | |
897 | [CEC_MSG_ROUTING_INFORMATION] = 4 | BCAST, | |
898 | [CEC_MSG_SET_STREAM_PATH] = 4 | BCAST, | |
899 | [CEC_MSG_STANDBY] = 2 | BOTH, | |
900 | [CEC_MSG_RECORD_OFF] = 2 | DIRECTED, | |
901 | [CEC_MSG_RECORD_ON] = 3 | DIRECTED, | |
902 | [CEC_MSG_RECORD_STATUS] = 3 | DIRECTED, | |
903 | [CEC_MSG_RECORD_TV_SCREEN] = 2 | DIRECTED, | |
904 | [CEC_MSG_CLEAR_ANALOGUE_TIMER] = 13 | DIRECTED, | |
905 | [CEC_MSG_CLEAR_DIGITAL_TIMER] = 16 | DIRECTED, | |
906 | [CEC_MSG_CLEAR_EXT_TIMER] = 13 | DIRECTED, | |
907 | [CEC_MSG_SET_ANALOGUE_TIMER] = 13 | DIRECTED, | |
908 | [CEC_MSG_SET_DIGITAL_TIMER] = 16 | DIRECTED, | |
909 | [CEC_MSG_SET_EXT_TIMER] = 13 | DIRECTED, | |
910 | [CEC_MSG_SET_TIMER_PROGRAM_TITLE] = 2 | DIRECTED, | |
911 | [CEC_MSG_TIMER_CLEARED_STATUS] = 3 | DIRECTED, | |
912 | [CEC_MSG_TIMER_STATUS] = 3 | DIRECTED, | |
913 | [CEC_MSG_CEC_VERSION] = 3 | DIRECTED, | |
914 | [CEC_MSG_GET_CEC_VERSION] = 2 | DIRECTED, | |
915 | [CEC_MSG_GIVE_PHYSICAL_ADDR] = 2 | DIRECTED, | |
916 | [CEC_MSG_GET_MENU_LANGUAGE] = 2 | DIRECTED, | |
917 | [CEC_MSG_REPORT_PHYSICAL_ADDR] = 5 | BCAST, | |
918 | [CEC_MSG_SET_MENU_LANGUAGE] = 5 | BCAST, | |
919 | [CEC_MSG_REPORT_FEATURES] = 6 | BCAST, | |
920 | [CEC_MSG_GIVE_FEATURES] = 2 | DIRECTED, | |
921 | [CEC_MSG_DECK_CONTROL] = 3 | DIRECTED, | |
922 | [CEC_MSG_DECK_STATUS] = 3 | DIRECTED, | |
923 | [CEC_MSG_GIVE_DECK_STATUS] = 3 | DIRECTED, | |
924 | [CEC_MSG_PLAY] = 3 | DIRECTED, | |
925 | [CEC_MSG_GIVE_TUNER_DEVICE_STATUS] = 3 | DIRECTED, | |
926 | [CEC_MSG_SELECT_ANALOGUE_SERVICE] = 6 | DIRECTED, | |
927 | [CEC_MSG_SELECT_DIGITAL_SERVICE] = 9 | DIRECTED, | |
928 | [CEC_MSG_TUNER_DEVICE_STATUS] = 7 | DIRECTED, | |
929 | [CEC_MSG_TUNER_STEP_DECREMENT] = 2 | DIRECTED, | |
930 | [CEC_MSG_TUNER_STEP_INCREMENT] = 2 | DIRECTED, | |
931 | [CEC_MSG_DEVICE_VENDOR_ID] = 5 | BCAST, | |
932 | [CEC_MSG_GIVE_DEVICE_VENDOR_ID] = 2 | DIRECTED, | |
933 | [CEC_MSG_VENDOR_COMMAND] = 2 | DIRECTED, | |
934 | [CEC_MSG_VENDOR_COMMAND_WITH_ID] = 5 | BOTH, | |
935 | [CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN] = 2 | BOTH, | |
936 | [CEC_MSG_VENDOR_REMOTE_BUTTON_UP] = 2 | BOTH, | |
937 | [CEC_MSG_SET_OSD_STRING] = 3 | DIRECTED, | |
938 | [CEC_MSG_GIVE_OSD_NAME] = 2 | DIRECTED, | |
939 | [CEC_MSG_SET_OSD_NAME] = 2 | DIRECTED, | |
940 | [CEC_MSG_MENU_REQUEST] = 3 | DIRECTED, | |
941 | [CEC_MSG_MENU_STATUS] = 3 | DIRECTED, | |
942 | [CEC_MSG_USER_CONTROL_PRESSED] = 3 | DIRECTED, | |
943 | [CEC_MSG_USER_CONTROL_RELEASED] = 2 | DIRECTED, | |
944 | [CEC_MSG_GIVE_DEVICE_POWER_STATUS] = 2 | DIRECTED, | |
945 | [CEC_MSG_REPORT_POWER_STATUS] = 3 | DIRECTED | BCAST2_0, | |
946 | [CEC_MSG_FEATURE_ABORT] = 4 | DIRECTED, | |
947 | [CEC_MSG_ABORT] = 2 | DIRECTED, | |
948 | [CEC_MSG_GIVE_AUDIO_STATUS] = 2 | DIRECTED, | |
949 | [CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS] = 2 | DIRECTED, | |
950 | [CEC_MSG_REPORT_AUDIO_STATUS] = 3 | DIRECTED, | |
951 | [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, | |
952 | [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, | |
953 | [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH, | |
954 | [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED, | |
955 | [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED, | |
956 | [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED, | |
957 | [CEC_MSG_INITIATE_ARC] = 2 | DIRECTED, | |
958 | [CEC_MSG_REPORT_ARC_INITIATED] = 2 | DIRECTED, | |
959 | [CEC_MSG_REPORT_ARC_TERMINATED] = 2 | DIRECTED, | |
960 | [CEC_MSG_REQUEST_ARC_INITIATION] = 2 | DIRECTED, | |
961 | [CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED, | |
962 | [CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED, | |
963 | [CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST, | |
f3854973 | 964 | [CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST, |
3074fe4a HV |
965 | [CEC_MSG_CDC_MESSAGE] = 2 | BCAST, |
966 | }; | |
967 | ||
9881fe0c | 968 | /* Called by the CEC adapter if a message is received */ |
0861ad14 HV |
969 | void cec_received_msg_ts(struct cec_adapter *adap, |
970 | struct cec_msg *msg, ktime_t ts) | |
9881fe0c HV |
971 | { |
972 | struct cec_data *data; | |
973 | u8 msg_init = cec_msg_initiator(msg); | |
974 | u8 msg_dest = cec_msg_destination(msg); | |
3074fe4a | 975 | u8 cmd = msg->msg[1]; |
9881fe0c HV |
976 | bool is_reply = false; |
977 | bool valid_la = true; | |
3074fe4a | 978 | u8 min_len = 0; |
9881fe0c | 979 | |
52d802d6 HV |
980 | if (WARN_ON(!msg->len || msg->len > CEC_MAX_MSG_SIZE)) |
981 | return; | |
982 | ||
3f98da96 HV |
983 | /* |
984 | * Some CEC adapters will receive the messages that they transmitted. | |
985 | * This test filters out those messages by checking if we are the | |
986 | * initiator, and just returning in that case. | |
987 | * | |
988 | * Note that this won't work if this is an Unregistered device. | |
989 | * | |
990 | * It is bad practice if the hardware receives the message that it | |
991 | * transmitted and luckily most CEC adapters behave correctly in this | |
992 | * respect. | |
993 | */ | |
994 | if (msg_init != CEC_LOG_ADDR_UNREGISTERED && | |
995 | cec_has_log_addr(adap, msg_init)) | |
996 | return; | |
997 | ||
0861ad14 | 998 | msg->rx_ts = ktime_to_ns(ts); |
9881fe0c | 999 | msg->rx_status = CEC_RX_STATUS_OK; |
9881fe0c | 1000 | msg->sequence = msg->reply = msg->timeout = 0; |
980e0b36 HV |
1001 | msg->tx_status = 0; |
1002 | msg->tx_ts = 0; | |
8991a63d HV |
1003 | msg->tx_arb_lost_cnt = 0; |
1004 | msg->tx_nack_cnt = 0; | |
1005 | msg->tx_low_drive_cnt = 0; | |
1006 | msg->tx_error_cnt = 0; | |
9881fe0c | 1007 | msg->flags = 0; |
045344c3 | 1008 | memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); |
9881fe0c | 1009 | |
980e0b36 | 1010 | mutex_lock(&adap->lock); |
a7a04b5b | 1011 | dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); |
9881fe0c HV |
1012 | |
1013 | /* Check if this message was for us (directed or broadcast). */ | |
1014 | if (!cec_msg_is_broadcast(msg)) | |
1015 | valid_la = cec_has_log_addr(adap, msg_dest); | |
1016 | ||
3074fe4a HV |
1017 | /* |
1018 | * Check if the length is not too short or if the message is a | |
1019 | * broadcast message where a directed message was expected or | |
1020 | * vice versa. If so, then the message has to be ignored (according | |
1021 | * to section CEC 7.3 and CEC 12.2). | |
1022 | */ | |
1023 | if (valid_la && msg->len > 1 && cec_msg_size[cmd]) { | |
1024 | u8 dir_fl = cec_msg_size[cmd] & BOTH; | |
1025 | ||
1026 | min_len = cec_msg_size[cmd] & 0x1f; | |
1027 | if (msg->len < min_len) | |
1028 | valid_la = false; | |
1029 | else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) | |
1030 | valid_la = false; | |
1031 | else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) | |
1032 | valid_la = false; | |
1033 | else if (cec_msg_is_broadcast(msg) && | |
1034 | adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && | |
1035 | !(dir_fl & BCAST2_0)) | |
1036 | valid_la = false; | |
1037 | } | |
1038 | if (valid_la && min_len) { | |
1039 | /* These messages have special length requirements */ | |
1040 | switch (cmd) { | |
1041 | case CEC_MSG_TIMER_STATUS: | |
1042 | if (msg->msg[2] & 0x10) { | |
1043 | switch (msg->msg[2] & 0xf) { | |
1044 | case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE: | |
1045 | case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE: | |
1046 | if (msg->len < 5) | |
1047 | valid_la = false; | |
1048 | break; | |
1049 | } | |
1050 | } else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) { | |
1051 | if (msg->len < 5) | |
1052 | valid_la = false; | |
1053 | } | |
1054 | break; | |
1055 | case CEC_MSG_RECORD_ON: | |
1056 | switch (msg->msg[2]) { | |
1057 | case CEC_OP_RECORD_SRC_OWN: | |
1058 | break; | |
1059 | case CEC_OP_RECORD_SRC_DIGITAL: | |
1060 | if (msg->len < 10) | |
1061 | valid_la = false; | |
1062 | break; | |
1063 | case CEC_OP_RECORD_SRC_ANALOG: | |
1064 | if (msg->len < 7) | |
1065 | valid_la = false; | |
1066 | break; | |
1067 | case CEC_OP_RECORD_SRC_EXT_PLUG: | |
1068 | if (msg->len < 4) | |
1069 | valid_la = false; | |
1070 | break; | |
1071 | case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR: | |
1072 | if (msg->len < 5) | |
1073 | valid_la = false; | |
1074 | break; | |
1075 | } | |
1076 | break; | |
1077 | } | |
1078 | } | |
1079 | ||
9881fe0c | 1080 | /* It's a valid message and not a poll or CDC message */ |
3074fe4a | 1081 | if (valid_la && msg->len > 1 && cmd != CEC_MSG_CDC_MESSAGE) { |
9881fe0c HV |
1082 | bool abort = cmd == CEC_MSG_FEATURE_ABORT; |
1083 | ||
1084 | /* The aborted command is in msg[2] */ | |
1085 | if (abort) | |
1086 | cmd = msg->msg[2]; | |
1087 | ||
1088 | /* | |
1089 | * Walk over all transmitted messages that are waiting for a | |
1090 | * reply. | |
1091 | */ | |
1092 | list_for_each_entry(data, &adap->wait_queue, list) { | |
1093 | struct cec_msg *dst = &data->msg; | |
9881fe0c | 1094 | |
f5580d8d HV |
1095 | /* |
1096 | * The *only* CEC message that has two possible replies | |
1097 | * is CEC_MSG_INITIATE_ARC. | |
1098 | * In this case allow either of the two replies. | |
1099 | */ | |
1100 | if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC && | |
1101 | (cmd == CEC_MSG_REPORT_ARC_INITIATED || | |
1102 | cmd == CEC_MSG_REPORT_ARC_TERMINATED) && | |
1103 | (dst->reply == CEC_MSG_REPORT_ARC_INITIATED || | |
1104 | dst->reply == CEC_MSG_REPORT_ARC_TERMINATED)) | |
1105 | dst->reply = cmd; | |
1106 | ||
9881fe0c HV |
1107 | /* Does the command match? */ |
1108 | if ((abort && cmd != dst->msg[1]) || | |
1109 | (!abort && cmd != dst->reply)) | |
1110 | continue; | |
1111 | ||
1112 | /* Does the addressing match? */ | |
1113 | if (msg_init != cec_msg_destination(dst) && | |
1114 | !cec_msg_is_broadcast(dst)) | |
1115 | continue; | |
1116 | ||
1117 | /* We got a reply */ | |
980e0b36 HV |
1118 | memcpy(dst->msg, msg->msg, msg->len); |
1119 | dst->len = msg->len; | |
1120 | dst->rx_ts = msg->rx_ts; | |
1121 | dst->rx_status = msg->rx_status; | |
86e3577f | 1122 | if (abort) |
9881fe0c | 1123 | dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; |
adc0c622 | 1124 | msg->flags = dst->flags; |
9881fe0c HV |
1125 | /* Remove it from the wait_queue */ |
1126 | list_del_init(&data->list); | |
1127 | ||
1128 | /* Cancel the pending timeout work */ | |
1129 | if (!cancel_delayed_work(&data->work)) { | |
1130 | mutex_unlock(&adap->lock); | |
1131 | flush_scheduled_work(); | |
1132 | mutex_lock(&adap->lock); | |
1133 | } | |
1134 | /* | |
1135 | * Mark this as a reply, provided someone is still | |
1136 | * waiting for the answer. | |
1137 | */ | |
1138 | if (data->fh) | |
1139 | is_reply = true; | |
1140 | cec_data_completed(data); | |
1141 | break; | |
1142 | } | |
1143 | } | |
1144 | mutex_unlock(&adap->lock); | |
1145 | ||
1146 | /* Pass the message on to any monitoring filehandles */ | |
1147 | cec_queue_msg_monitor(adap, msg, valid_la); | |
1148 | ||
1149 | /* We're done if it is not for us or a poll message */ | |
1150 | if (!valid_la || msg->len <= 1) | |
1151 | return; | |
1152 | ||
3e92d8b2 HV |
1153 | if (adap->log_addrs.log_addr_mask == 0) |
1154 | return; | |
1155 | ||
9881fe0c HV |
1156 | /* |
1157 | * Process the message on the protocol level. If is_reply is true, | |
1158 | * then cec_receive_notify() won't pass on the reply to the listener(s) | |
1159 | * since that was already done by cec_data_completed() above. | |
1160 | */ | |
1161 | cec_receive_notify(adap, msg, is_reply); | |
1162 | } | |
0861ad14 | 1163 | EXPORT_SYMBOL_GPL(cec_received_msg_ts); |
9881fe0c HV |
1164 | |
1165 | /* Logical Address Handling */ | |
1166 | ||
1167 | /* | |
1168 | * Attempt to claim a specific logical address. | |
1169 | * | |
1170 | * This function is called with adap->lock held. | |
1171 | */ | |
1172 | static int cec_config_log_addr(struct cec_adapter *adap, | |
1173 | unsigned int idx, | |
1174 | unsigned int log_addr) | |
1175 | { | |
1176 | struct cec_log_addrs *las = &adap->log_addrs; | |
1177 | struct cec_msg msg = { }; | |
1178 | int err; | |
1179 | ||
1180 | if (cec_has_log_addr(adap, log_addr)) | |
1181 | return 0; | |
1182 | ||
1183 | /* Send poll message */ | |
1184 | msg.len = 1; | |
42980da2 | 1185 | msg.msg[0] = (log_addr << 4) | log_addr; |
9881fe0c HV |
1186 | err = cec_transmit_msg_fh(adap, &msg, NULL, true); |
1187 | ||
1188 | /* | |
1189 | * While trying to poll the physical address was reset | |
1190 | * and the adapter was unconfigured, so bail out. | |
1191 | */ | |
1192 | if (!adap->is_configuring) | |
1193 | return -EINTR; | |
1194 | ||
1195 | if (err) | |
1196 | return err; | |
1197 | ||
1198 | if (msg.tx_status & CEC_TX_STATUS_OK) | |
1199 | return 0; | |
1200 | ||
1201 | /* | |
1202 | * Message not acknowledged, so this logical | |
1203 | * address is free to use. | |
1204 | */ | |
1205 | err = adap->ops->adap_log_addr(adap, log_addr); | |
1206 | if (err) | |
1207 | return err; | |
1208 | ||
1209 | las->log_addr[idx] = log_addr; | |
1210 | las->log_addr_mask |= 1 << log_addr; | |
1211 | adap->phys_addrs[log_addr] = adap->phys_addr; | |
9881fe0c HV |
1212 | return 1; |
1213 | } | |
1214 | ||
1215 | /* | |
1216 | * Unconfigure the adapter: clear all logical addresses and send | |
1217 | * the state changed event. | |
1218 | * | |
1219 | * This function is called with adap->lock held. | |
1220 | */ | |
1221 | static void cec_adap_unconfigure(struct cec_adapter *adap) | |
1222 | { | |
f902c1e9 HV |
1223 | if (!adap->needs_hpd || |
1224 | adap->phys_addr != CEC_PHYS_ADDR_INVALID) | |
1225 | WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); | |
9881fe0c HV |
1226 | adap->log_addrs.log_addr_mask = 0; |
1227 | adap->is_configuring = false; | |
1228 | adap->is_configured = false; | |
1229 | memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); | |
533a3f7b | 1230 | cec_flush(adap); |
9881fe0c HV |
1231 | wake_up_interruptible(&adap->kthread_waitq); |
1232 | cec_post_state_event(adap); | |
1233 | } | |
1234 | ||
1235 | /* | |
1236 | * Attempt to claim the required logical addresses. | |
1237 | */ | |
1238 | static int cec_config_thread_func(void *arg) | |
1239 | { | |
1240 | /* The various LAs for each type of device */ | |
1241 | static const u8 tv_log_addrs[] = { | |
1242 | CEC_LOG_ADDR_TV, CEC_LOG_ADDR_SPECIFIC, | |
1243 | CEC_LOG_ADDR_INVALID | |
1244 | }; | |
1245 | static const u8 record_log_addrs[] = { | |
1246 | CEC_LOG_ADDR_RECORD_1, CEC_LOG_ADDR_RECORD_2, | |
1247 | CEC_LOG_ADDR_RECORD_3, | |
1248 | CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, | |
1249 | CEC_LOG_ADDR_INVALID | |
1250 | }; | |
1251 | static const u8 tuner_log_addrs[] = { | |
1252 | CEC_LOG_ADDR_TUNER_1, CEC_LOG_ADDR_TUNER_2, | |
1253 | CEC_LOG_ADDR_TUNER_3, CEC_LOG_ADDR_TUNER_4, | |
1254 | CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, | |
1255 | CEC_LOG_ADDR_INVALID | |
1256 | }; | |
1257 | static const u8 playback_log_addrs[] = { | |
1258 | CEC_LOG_ADDR_PLAYBACK_1, CEC_LOG_ADDR_PLAYBACK_2, | |
1259 | CEC_LOG_ADDR_PLAYBACK_3, | |
1260 | CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, | |
1261 | CEC_LOG_ADDR_INVALID | |
1262 | }; | |
1263 | static const u8 audiosystem_log_addrs[] = { | |
1264 | CEC_LOG_ADDR_AUDIOSYSTEM, | |
1265 | CEC_LOG_ADDR_INVALID | |
1266 | }; | |
1267 | static const u8 specific_use_log_addrs[] = { | |
1268 | CEC_LOG_ADDR_SPECIFIC, | |
1269 | CEC_LOG_ADDR_BACKUP_1, CEC_LOG_ADDR_BACKUP_2, | |
1270 | CEC_LOG_ADDR_INVALID | |
1271 | }; | |
1272 | static const u8 *type2addrs[6] = { | |
1273 | [CEC_LOG_ADDR_TYPE_TV] = tv_log_addrs, | |
1274 | [CEC_LOG_ADDR_TYPE_RECORD] = record_log_addrs, | |
1275 | [CEC_LOG_ADDR_TYPE_TUNER] = tuner_log_addrs, | |
1276 | [CEC_LOG_ADDR_TYPE_PLAYBACK] = playback_log_addrs, | |
1277 | [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = audiosystem_log_addrs, | |
1278 | [CEC_LOG_ADDR_TYPE_SPECIFIC] = specific_use_log_addrs, | |
1279 | }; | |
1280 | static const u16 type2mask[] = { | |
1281 | [CEC_LOG_ADDR_TYPE_TV] = CEC_LOG_ADDR_MASK_TV, | |
1282 | [CEC_LOG_ADDR_TYPE_RECORD] = CEC_LOG_ADDR_MASK_RECORD, | |
1283 | [CEC_LOG_ADDR_TYPE_TUNER] = CEC_LOG_ADDR_MASK_TUNER, | |
1284 | [CEC_LOG_ADDR_TYPE_PLAYBACK] = CEC_LOG_ADDR_MASK_PLAYBACK, | |
1285 | [CEC_LOG_ADDR_TYPE_AUDIOSYSTEM] = CEC_LOG_ADDR_MASK_AUDIOSYSTEM, | |
1286 | [CEC_LOG_ADDR_TYPE_SPECIFIC] = CEC_LOG_ADDR_MASK_SPECIFIC, | |
1287 | }; | |
1288 | struct cec_adapter *adap = arg; | |
1289 | struct cec_log_addrs *las = &adap->log_addrs; | |
1290 | int err; | |
1291 | int i, j; | |
1292 | ||
1293 | mutex_lock(&adap->lock); | |
1294 | dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n", | |
1295 | cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs); | |
1296 | las->log_addr_mask = 0; | |
1297 | ||
1298 | if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED) | |
1299 | goto configured; | |
1300 | ||
1301 | for (i = 0; i < las->num_log_addrs; i++) { | |
1302 | unsigned int type = las->log_addr_type[i]; | |
1303 | const u8 *la_list; | |
1304 | u8 last_la; | |
1305 | ||
1306 | /* | |
1307 | * The TV functionality can only map to physical address 0. | |
1308 | * For any other address, try the Specific functionality | |
1309 | * instead as per the spec. | |
1310 | */ | |
1311 | if (adap->phys_addr && type == CEC_LOG_ADDR_TYPE_TV) | |
1312 | type = CEC_LOG_ADDR_TYPE_SPECIFIC; | |
1313 | ||
1314 | la_list = type2addrs[type]; | |
1315 | last_la = las->log_addr[i]; | |
1316 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | |
1317 | if (last_la == CEC_LOG_ADDR_INVALID || | |
1318 | last_la == CEC_LOG_ADDR_UNREGISTERED || | |
f9f96fc1 | 1319 | !((1 << last_la) & type2mask[type])) |
9881fe0c HV |
1320 | last_la = la_list[0]; |
1321 | ||
1322 | err = cec_config_log_addr(adap, i, last_la); | |
1323 | if (err > 0) /* Reused last LA */ | |
1324 | continue; | |
1325 | ||
1326 | if (err < 0) | |
1327 | goto unconfigure; | |
1328 | ||
1329 | for (j = 0; la_list[j] != CEC_LOG_ADDR_INVALID; j++) { | |
1330 | /* Tried this one already, skip it */ | |
1331 | if (la_list[j] == last_la) | |
1332 | continue; | |
1333 | /* The backup addresses are CEC 2.0 specific */ | |
1334 | if ((la_list[j] == CEC_LOG_ADDR_BACKUP_1 || | |
1335 | la_list[j] == CEC_LOG_ADDR_BACKUP_2) && | |
1336 | las->cec_version < CEC_OP_CEC_VERSION_2_0) | |
1337 | continue; | |
1338 | ||
1339 | err = cec_config_log_addr(adap, i, la_list[j]); | |
1340 | if (err == 0) /* LA is in use */ | |
1341 | continue; | |
1342 | if (err < 0) | |
1343 | goto unconfigure; | |
1344 | /* Done, claimed an LA */ | |
1345 | break; | |
1346 | } | |
1347 | ||
1348 | if (la_list[j] == CEC_LOG_ADDR_INVALID) | |
1349 | dprintk(1, "could not claim LA %d\n", i); | |
1350 | } | |
1351 | ||
dcceb1ea HV |
1352 | if (adap->log_addrs.log_addr_mask == 0 && |
1353 | !(las->flags & CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK)) | |
1354 | goto unconfigure; | |
1355 | ||
9881fe0c HV |
1356 | configured: |
1357 | if (adap->log_addrs.log_addr_mask == 0) { | |
1358 | /* Fall back to unregistered */ | |
1359 | las->log_addr[0] = CEC_LOG_ADDR_UNREGISTERED; | |
1360 | las->log_addr_mask = 1 << las->log_addr[0]; | |
0c1d61b0 HV |
1361 | for (i = 1; i < las->num_log_addrs; i++) |
1362 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | |
9881fe0c | 1363 | } |
7af26f88 HV |
1364 | for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) |
1365 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | |
9881fe0c HV |
1366 | adap->is_configured = true; |
1367 | adap->is_configuring = false; | |
1368 | cec_post_state_event(adap); | |
9881fe0c | 1369 | |
f60f3560 HV |
1370 | /* |
1371 | * Now post the Report Features and Report Physical Address broadcast | |
1372 | * messages. Note that these are non-blocking transmits, meaning that | |
1373 | * they are just queued up and once adap->lock is unlocked the main | |
1374 | * thread will kick in and start transmitting these. | |
1375 | * | |
1376 | * If after this function is done (but before one or more of these | |
1377 | * messages are actually transmitted) the CEC adapter is unconfigured, | |
1378 | * then any remaining messages will be dropped by the main thread. | |
1379 | */ | |
9881fe0c | 1380 | for (i = 0; i < las->num_log_addrs; i++) { |
52bc30fd HV |
1381 | struct cec_msg msg = {}; |
1382 | ||
a69a168a HV |
1383 | if (las->log_addr[i] == CEC_LOG_ADDR_INVALID || |
1384 | (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY)) | |
9881fe0c HV |
1385 | continue; |
1386 | ||
52bc30fd HV |
1387 | msg.msg[0] = (las->log_addr[i] << 4) | 0x0f; |
1388 | ||
1389 | /* Report Features must come first according to CEC 2.0 */ | |
1390 | if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED && | |
1391 | adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) { | |
1392 | cec_fill_msg_report_features(adap, &msg, i); | |
f60f3560 | 1393 | cec_transmit_msg_fh(adap, &msg, NULL, false); |
52bc30fd HV |
1394 | } |
1395 | ||
d3d64bc7 HV |
1396 | /* Report Physical Address */ |
1397 | cec_msg_report_physical_addr(&msg, adap->phys_addr, | |
1398 | las->primary_device_type[i]); | |
a7a04b5b | 1399 | dprintk(1, "config: la %d pa %x.%x.%x.%x\n", |
d3d64bc7 HV |
1400 | las->log_addr[i], |
1401 | cec_phys_addr_exp(adap->phys_addr)); | |
f60f3560 | 1402 | cec_transmit_msg_fh(adap, &msg, NULL, false); |
9881fe0c | 1403 | } |
9881fe0c | 1404 | adap->kthread_config = NULL; |
9881fe0c | 1405 | complete(&adap->config_completion); |
f60f3560 | 1406 | mutex_unlock(&adap->lock); |
9881fe0c HV |
1407 | return 0; |
1408 | ||
1409 | unconfigure: | |
1410 | for (i = 0; i < las->num_log_addrs; i++) | |
1411 | las->log_addr[i] = CEC_LOG_ADDR_INVALID; | |
1412 | cec_adap_unconfigure(adap); | |
1413 | adap->kthread_config = NULL; | |
1414 | mutex_unlock(&adap->lock); | |
1415 | complete(&adap->config_completion); | |
1416 | return 0; | |
1417 | } | |
1418 | ||
1419 | /* | |
1420 | * Called from either __cec_s_phys_addr or __cec_s_log_addrs to claim the | |
1421 | * logical addresses. | |
1422 | * | |
1423 | * This function is called with adap->lock held. | |
1424 | */ | |
1425 | static void cec_claim_log_addrs(struct cec_adapter *adap, bool block) | |
1426 | { | |
1427 | if (WARN_ON(adap->is_configuring || adap->is_configured)) | |
1428 | return; | |
1429 | ||
1430 | init_completion(&adap->config_completion); | |
1431 | ||
1432 | /* Ready to kick off the thread */ | |
1433 | adap->is_configuring = true; | |
1434 | adap->kthread_config = kthread_run(cec_config_thread_func, adap, | |
1435 | "ceccfg-%s", adap->name); | |
1436 | if (IS_ERR(adap->kthread_config)) { | |
1437 | adap->kthread_config = NULL; | |
1438 | } else if (block) { | |
1439 | mutex_unlock(&adap->lock); | |
1440 | wait_for_completion(&adap->config_completion); | |
1441 | mutex_lock(&adap->lock); | |
1442 | } | |
1443 | } | |
1444 | ||
1445 | /* Set a new physical address and send an event notifying userspace of this. | |
1446 | * | |
1447 | * This function is called with adap->lock held. | |
1448 | */ | |
1449 | void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) | |
1450 | { | |
152b0a9a HV |
1451 | if (phys_addr == adap->phys_addr) |
1452 | return; | |
1453 | if (phys_addr != CEC_PHYS_ADDR_INVALID && adap->devnode.unregistered) | |
9881fe0c HV |
1454 | return; |
1455 | ||
f902c1e9 HV |
1456 | dprintk(1, "new physical address %x.%x.%x.%x\n", |
1457 | cec_phys_addr_exp(phys_addr)); | |
9881fe0c HV |
1458 | if (phys_addr == CEC_PHYS_ADDR_INVALID || |
1459 | adap->phys_addr != CEC_PHYS_ADDR_INVALID) { | |
1460 | adap->phys_addr = CEC_PHYS_ADDR_INVALID; | |
1461 | cec_post_state_event(adap); | |
1462 | cec_adap_unconfigure(adap); | |
1463 | /* Disabling monitor all mode should always succeed */ | |
1464 | if (adap->monitor_all_cnt) | |
1465 | WARN_ON(call_op(adap, adap_monitor_all_enable, false)); | |
533a3f7b | 1466 | mutex_lock(&adap->devnode.lock); |
f902c1e9 | 1467 | if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) |
533a3f7b HV |
1468 | WARN_ON(adap->ops->adap_enable(adap, false)); |
1469 | mutex_unlock(&adap->devnode.lock); | |
9881fe0c HV |
1470 | if (phys_addr == CEC_PHYS_ADDR_INVALID) |
1471 | return; | |
1472 | } | |
1473 | ||
533a3f7b | 1474 | mutex_lock(&adap->devnode.lock); |
f902c1e9 | 1475 | if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && |
533a3f7b HV |
1476 | adap->ops->adap_enable(adap, true)) { |
1477 | mutex_unlock(&adap->devnode.lock); | |
9881fe0c | 1478 | return; |
533a3f7b | 1479 | } |
9881fe0c HV |
1480 | |
1481 | if (adap->monitor_all_cnt && | |
1482 | call_op(adap, adap_monitor_all_enable, true)) { | |
f902c1e9 | 1483 | if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) |
533a3f7b HV |
1484 | WARN_ON(adap->ops->adap_enable(adap, false)); |
1485 | mutex_unlock(&adap->devnode.lock); | |
9881fe0c HV |
1486 | return; |
1487 | } | |
533a3f7b HV |
1488 | mutex_unlock(&adap->devnode.lock); |
1489 | ||
9881fe0c HV |
1490 | adap->phys_addr = phys_addr; |
1491 | cec_post_state_event(adap); | |
1492 | if (adap->log_addrs.num_log_addrs) | |
1493 | cec_claim_log_addrs(adap, block); | |
1494 | } | |
1495 | ||
1496 | void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) | |
1497 | { | |
1498 | if (IS_ERR_OR_NULL(adap)) | |
1499 | return; | |
1500 | ||
9881fe0c HV |
1501 | mutex_lock(&adap->lock); |
1502 | __cec_s_phys_addr(adap, phys_addr, block); | |
1503 | mutex_unlock(&adap->lock); | |
1504 | } | |
1505 | EXPORT_SYMBOL_GPL(cec_s_phys_addr); | |
1506 | ||
23111ec3 HV |
1507 | void cec_s_phys_addr_from_edid(struct cec_adapter *adap, |
1508 | const struct edid *edid) | |
1509 | { | |
1510 | u16 pa = CEC_PHYS_ADDR_INVALID; | |
1511 | ||
1512 | if (edid && edid->extensions) | |
1513 | pa = cec_get_edid_phys_addr((const u8 *)edid, | |
1514 | EDID_LENGTH * (edid->extensions + 1), NULL); | |
1515 | cec_s_phys_addr(adap, pa, false); | |
1516 | } | |
1517 | EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid); | |
1518 | ||
9881fe0c HV |
1519 | /* |
1520 | * Called from either the ioctl or a driver to set the logical addresses. | |
1521 | * | |
1522 | * This function is called with adap->lock held. | |
1523 | */ | |
1524 | int __cec_s_log_addrs(struct cec_adapter *adap, | |
1525 | struct cec_log_addrs *log_addrs, bool block) | |
1526 | { | |
1527 | u16 type_mask = 0; | |
1528 | int i; | |
1529 | ||
c000e5da HV |
1530 | if (adap->devnode.unregistered) |
1531 | return -ENODEV; | |
1532 | ||
9881fe0c | 1533 | if (!log_addrs || log_addrs->num_log_addrs == 0) { |
9881fe0c | 1534 | cec_adap_unconfigure(adap); |
299708e4 HV |
1535 | adap->log_addrs.num_log_addrs = 0; |
1536 | for (i = 0; i < CEC_MAX_LOG_ADDRS; i++) | |
1537 | adap->log_addrs.log_addr[i] = CEC_LOG_ADDR_INVALID; | |
1538 | adap->log_addrs.osd_name[0] = '\0'; | |
1539 | adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; | |
1540 | adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; | |
9881fe0c HV |
1541 | return 0; |
1542 | } | |
1543 | ||
a69a168a HV |
1544 | if (log_addrs->flags & CEC_LOG_ADDRS_FL_CDC_ONLY) { |
1545 | /* | |
1546 | * Sanitize log_addrs fields if a CDC-Only device is | |
1547 | * requested. | |
1548 | */ | |
1549 | log_addrs->num_log_addrs = 1; | |
1550 | log_addrs->osd_name[0] = '\0'; | |
1551 | log_addrs->vendor_id = CEC_VENDOR_ID_NONE; | |
1552 | log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED; | |
1553 | /* | |
1554 | * This is just an internal convention since a CDC-Only device | |
1555 | * doesn't have to be a switch. But switches already use | |
1556 | * unregistered, so it makes some kind of sense to pick this | |
1557 | * as the primary device. Since a CDC-Only device never sends | |
1558 | * any 'normal' CEC messages this primary device type is never | |
1559 | * sent over the CEC bus. | |
1560 | */ | |
1561 | log_addrs->primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_SWITCH; | |
1562 | log_addrs->all_device_types[0] = 0; | |
1563 | log_addrs->features[0][0] = 0; | |
1564 | log_addrs->features[0][1] = 0; | |
1565 | } | |
1566 | ||
9881fe0c HV |
1567 | /* Ensure the osd name is 0-terminated */ |
1568 | log_addrs->osd_name[sizeof(log_addrs->osd_name) - 1] = '\0'; | |
1569 | ||
1570 | /* Sanity checks */ | |
1571 | if (log_addrs->num_log_addrs > adap->available_log_addrs) { | |
1572 | dprintk(1, "num_log_addrs > %d\n", adap->available_log_addrs); | |
1573 | return -EINVAL; | |
1574 | } | |
1575 | ||
1576 | /* | |
1577 | * Vendor ID is a 24 bit number, so check if the value is | |
1578 | * within the correct range. | |
1579 | */ | |
1580 | if (log_addrs->vendor_id != CEC_VENDOR_ID_NONE && | |
79cabaa3 HV |
1581 | (log_addrs->vendor_id & 0xff000000) != 0) { |
1582 | dprintk(1, "invalid vendor ID\n"); | |
9881fe0c | 1583 | return -EINVAL; |
79cabaa3 | 1584 | } |
9881fe0c HV |
1585 | |
1586 | if (log_addrs->cec_version != CEC_OP_CEC_VERSION_1_4 && | |
79cabaa3 HV |
1587 | log_addrs->cec_version != CEC_OP_CEC_VERSION_2_0) { |
1588 | dprintk(1, "invalid CEC version\n"); | |
9881fe0c | 1589 | return -EINVAL; |
79cabaa3 | 1590 | } |
9881fe0c HV |
1591 | |
1592 | if (log_addrs->num_log_addrs > 1) | |
1593 | for (i = 0; i < log_addrs->num_log_addrs; i++) | |
1594 | if (log_addrs->log_addr_type[i] == | |
1595 | CEC_LOG_ADDR_TYPE_UNREGISTERED) { | |
1596 | dprintk(1, "num_log_addrs > 1 can't be combined with unregistered LA\n"); | |
1597 | return -EINVAL; | |
1598 | } | |
1599 | ||
9881fe0c | 1600 | for (i = 0; i < log_addrs->num_log_addrs; i++) { |
009a6208 | 1601 | const u8 feature_sz = ARRAY_SIZE(log_addrs->features[0]); |
9881fe0c HV |
1602 | u8 *features = log_addrs->features[i]; |
1603 | bool op_is_dev_features = false; | |
a161bef0 | 1604 | unsigned j; |
9881fe0c HV |
1605 | |
1606 | log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID; | |
1607 | if (type_mask & (1 << log_addrs->log_addr_type[i])) { | |
1608 | dprintk(1, "duplicate logical address type\n"); | |
1609 | return -EINVAL; | |
1610 | } | |
1611 | type_mask |= 1 << log_addrs->log_addr_type[i]; | |
1612 | if ((type_mask & (1 << CEC_LOG_ADDR_TYPE_RECORD)) && | |
1613 | (type_mask & (1 << CEC_LOG_ADDR_TYPE_PLAYBACK))) { | |
1614 | /* Record already contains the playback functionality */ | |
1615 | dprintk(1, "invalid record + playback combination\n"); | |
1616 | return -EINVAL; | |
1617 | } | |
1618 | if (log_addrs->primary_device_type[i] > | |
1619 | CEC_OP_PRIM_DEVTYPE_PROCESSOR) { | |
1620 | dprintk(1, "unknown primary device type\n"); | |
1621 | return -EINVAL; | |
1622 | } | |
1623 | if (log_addrs->primary_device_type[i] == 2) { | |
1624 | dprintk(1, "invalid primary device type\n"); | |
1625 | return -EINVAL; | |
1626 | } | |
1627 | if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) { | |
1628 | dprintk(1, "unknown logical address type\n"); | |
1629 | return -EINVAL; | |
1630 | } | |
a161bef0 HV |
1631 | for (j = 0; j < feature_sz; j++) { |
1632 | if ((features[j] & 0x80) == 0) { | |
9881fe0c HV |
1633 | if (op_is_dev_features) |
1634 | break; | |
1635 | op_is_dev_features = true; | |
1636 | } | |
1637 | } | |
a161bef0 | 1638 | if (!op_is_dev_features || j == feature_sz) { |
9881fe0c HV |
1639 | dprintk(1, "malformed features\n"); |
1640 | return -EINVAL; | |
1641 | } | |
009a6208 | 1642 | /* Zero unused part of the feature array */ |
a161bef0 | 1643 | memset(features + j + 1, 0, feature_sz - j - 1); |
9881fe0c HV |
1644 | } |
1645 | ||
1646 | if (log_addrs->cec_version >= CEC_OP_CEC_VERSION_2_0) { | |
1647 | if (log_addrs->num_log_addrs > 2) { | |
1648 | dprintk(1, "CEC 2.0 allows no more than 2 logical addresses\n"); | |
1649 | return -EINVAL; | |
1650 | } | |
1651 | if (log_addrs->num_log_addrs == 2) { | |
1652 | if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) | | |
1653 | (1 << CEC_LOG_ADDR_TYPE_TV)))) { | |
a7a04b5b | 1654 | dprintk(1, "two LAs is only allowed for audiosystem and TV\n"); |
9881fe0c HV |
1655 | return -EINVAL; |
1656 | } | |
1657 | if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) | | |
1658 | (1 << CEC_LOG_ADDR_TYPE_RECORD)))) { | |
a7a04b5b | 1659 | dprintk(1, "an audiosystem/TV can only be combined with record or playback\n"); |
9881fe0c HV |
1660 | return -EINVAL; |
1661 | } | |
1662 | } | |
1663 | } | |
1664 | ||
009a6208 HV |
1665 | /* Zero unused LAs */ |
1666 | for (i = log_addrs->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++) { | |
1667 | log_addrs->primary_device_type[i] = 0; | |
1668 | log_addrs->log_addr_type[i] = 0; | |
1669 | log_addrs->all_device_types[i] = 0; | |
1670 | memset(log_addrs->features[i], 0, | |
1671 | sizeof(log_addrs->features[i])); | |
1672 | } | |
1673 | ||
9881fe0c HV |
1674 | log_addrs->log_addr_mask = adap->log_addrs.log_addr_mask; |
1675 | adap->log_addrs = *log_addrs; | |
1676 | if (adap->phys_addr != CEC_PHYS_ADDR_INVALID) | |
1677 | cec_claim_log_addrs(adap, block); | |
1678 | return 0; | |
1679 | } | |
1680 | ||
1681 | int cec_s_log_addrs(struct cec_adapter *adap, | |
1682 | struct cec_log_addrs *log_addrs, bool block) | |
1683 | { | |
1684 | int err; | |
1685 | ||
9881fe0c HV |
1686 | mutex_lock(&adap->lock); |
1687 | err = __cec_s_log_addrs(adap, log_addrs, block); | |
1688 | mutex_unlock(&adap->lock); | |
1689 | return err; | |
1690 | } | |
1691 | EXPORT_SYMBOL_GPL(cec_s_log_addrs); | |
1692 | ||
1693 | /* High-level core CEC message handling */ | |
1694 | ||
52bc30fd HV |
1695 | /* Fill in the Report Features message */ |
1696 | static void cec_fill_msg_report_features(struct cec_adapter *adap, | |
1697 | struct cec_msg *msg, | |
1698 | unsigned int la_idx) | |
9881fe0c | 1699 | { |
9881fe0c HV |
1700 | const struct cec_log_addrs *las = &adap->log_addrs; |
1701 | const u8 *features = las->features[la_idx]; | |
1702 | bool op_is_dev_features = false; | |
1703 | unsigned int idx; | |
1704 | ||
9881fe0c | 1705 | /* Report Features */ |
52bc30fd HV |
1706 | msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f; |
1707 | msg->len = 4; | |
1708 | msg->msg[1] = CEC_MSG_REPORT_FEATURES; | |
1709 | msg->msg[2] = adap->log_addrs.cec_version; | |
1710 | msg->msg[3] = las->all_device_types[la_idx]; | |
9881fe0c HV |
1711 | |
1712 | /* Write RC Profiles first, then Device Features */ | |
1713 | for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) { | |
52bc30fd | 1714 | msg->msg[msg->len++] = features[idx]; |
9881fe0c HV |
1715 | if ((features[idx] & CEC_OP_FEAT_EXT) == 0) { |
1716 | if (op_is_dev_features) | |
1717 | break; | |
1718 | op_is_dev_features = true; | |
1719 | } | |
1720 | } | |
9881fe0c HV |
1721 | } |
1722 | ||
9881fe0c HV |
1723 | /* Transmit the Feature Abort message */ |
1724 | static int cec_feature_abort_reason(struct cec_adapter *adap, | |
1725 | struct cec_msg *msg, u8 reason) | |
1726 | { | |
1727 | struct cec_msg tx_msg = { }; | |
1728 | ||
1729 | /* | |
1730 | * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT | |
1731 | * message! | |
1732 | */ | |
1733 | if (msg->msg[1] == CEC_MSG_FEATURE_ABORT) | |
1734 | return 0; | |
a8e97e53 HV |
1735 | /* Don't Feature Abort messages from 'Unregistered' */ |
1736 | if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED) | |
1737 | return 0; | |
9881fe0c HV |
1738 | cec_msg_set_reply_to(&tx_msg, msg); |
1739 | cec_msg_feature_abort(&tx_msg, msg->msg[1], reason); | |
1740 | return cec_transmit_msg(adap, &tx_msg, false); | |
1741 | } | |
1742 | ||
1743 | static int cec_feature_abort(struct cec_adapter *adap, struct cec_msg *msg) | |
1744 | { | |
1745 | return cec_feature_abort_reason(adap, msg, | |
1746 | CEC_OP_ABORT_UNRECOGNIZED_OP); | |
1747 | } | |
1748 | ||
1749 | static int cec_feature_refused(struct cec_adapter *adap, struct cec_msg *msg) | |
1750 | { | |
1751 | return cec_feature_abort_reason(adap, msg, | |
1752 | CEC_OP_ABORT_REFUSED); | |
1753 | } | |
1754 | ||
1755 | /* | |
1756 | * Called when a CEC message is received. This function will do any | |
1757 | * necessary core processing. The is_reply bool is true if this message | |
1758 | * is a reply to an earlier transmit. | |
1759 | * | |
1760 | * The message is either a broadcast message or a valid directed message. | |
1761 | */ | |
1762 | static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg, | |
1763 | bool is_reply) | |
1764 | { | |
1765 | bool is_broadcast = cec_msg_is_broadcast(msg); | |
1766 | u8 dest_laddr = cec_msg_destination(msg); | |
1767 | u8 init_laddr = cec_msg_initiator(msg); | |
1768 | u8 devtype = cec_log_addr2dev(adap, dest_laddr); | |
1769 | int la_idx = cec_log_addr2idx(adap, dest_laddr); | |
9881fe0c HV |
1770 | bool from_unregistered = init_laddr == 0xf; |
1771 | struct cec_msg tx_cec_msg = { }; | |
a9a249a2 HV |
1772 | #ifdef CONFIG_MEDIA_CEC_RC |
1773 | int scancode; | |
1774 | #endif | |
9881fe0c | 1775 | |
a7a04b5b | 1776 | dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); |
9881fe0c | 1777 | |
a69a168a HV |
1778 | /* If this is a CDC-Only device, then ignore any non-CDC messages */ |
1779 | if (cec_is_cdc_only(&adap->log_addrs) && | |
1780 | msg->msg[1] != CEC_MSG_CDC_MESSAGE) | |
1781 | return 0; | |
1782 | ||
9881fe0c HV |
1783 | if (adap->ops->received) { |
1784 | /* Allow drivers to process the message first */ | |
1785 | if (adap->ops->received(adap, msg) != -ENOMSG) | |
1786 | return 0; | |
1787 | } | |
1788 | ||
1789 | /* | |
1790 | * REPORT_PHYSICAL_ADDR, CEC_MSG_USER_CONTROL_PRESSED and | |
1791 | * CEC_MSG_USER_CONTROL_RELEASED messages always have to be | |
1792 | * handled by the CEC core, even if the passthrough mode is on. | |
1793 | * The others are just ignored if passthrough mode is on. | |
1794 | */ | |
1795 | switch (msg->msg[1]) { | |
1796 | case CEC_MSG_GET_CEC_VERSION: | |
1797 | case CEC_MSG_GIVE_DEVICE_VENDOR_ID: | |
1798 | case CEC_MSG_ABORT: | |
1799 | case CEC_MSG_GIVE_DEVICE_POWER_STATUS: | |
1800 | case CEC_MSG_GIVE_PHYSICAL_ADDR: | |
1801 | case CEC_MSG_GIVE_OSD_NAME: | |
1802 | case CEC_MSG_GIVE_FEATURES: | |
1803 | /* | |
1804 | * Skip processing these messages if the passthrough mode | |
1805 | * is on. | |
1806 | */ | |
1807 | if (adap->passthrough) | |
1808 | goto skip_processing; | |
1809 | /* Ignore if addressing is wrong */ | |
1810 | if (is_broadcast || from_unregistered) | |
1811 | return 0; | |
1812 | break; | |
1813 | ||
1814 | case CEC_MSG_USER_CONTROL_PRESSED: | |
1815 | case CEC_MSG_USER_CONTROL_RELEASED: | |
1816 | /* Wrong addressing mode: don't process */ | |
1817 | if (is_broadcast || from_unregistered) | |
1818 | goto skip_processing; | |
1819 | break; | |
1820 | ||
1821 | case CEC_MSG_REPORT_PHYSICAL_ADDR: | |
1822 | /* | |
1823 | * This message is always processed, regardless of the | |
1824 | * passthrough setting. | |
1825 | * | |
1826 | * Exception: don't process if wrong addressing mode. | |
1827 | */ | |
1828 | if (!is_broadcast) | |
1829 | goto skip_processing; | |
1830 | break; | |
1831 | ||
1832 | default: | |
1833 | break; | |
1834 | } | |
1835 | ||
1836 | cec_msg_set_reply_to(&tx_cec_msg, msg); | |
1837 | ||
1838 | switch (msg->msg[1]) { | |
1839 | /* The following messages are processed but still passed through */ | |
f8db65fe HV |
1840 | case CEC_MSG_REPORT_PHYSICAL_ADDR: { |
1841 | u16 pa = (msg->msg[2] << 8) | msg->msg[3]; | |
1842 | ||
1843 | if (!from_unregistered) | |
1844 | adap->phys_addrs[init_laddr] = pa; | |
a7a04b5b | 1845 | dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n", |
f8db65fe | 1846 | cec_phys_addr_exp(pa), init_laddr); |
9881fe0c | 1847 | break; |
f8db65fe | 1848 | } |
9881fe0c HV |
1849 | |
1850 | case CEC_MSG_USER_CONTROL_PRESSED: | |
f4062625 HV |
1851 | if (!(adap->capabilities & CEC_CAP_RC) || |
1852 | !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) | |
9881fe0c HV |
1853 | break; |
1854 | ||
5f2c467c | 1855 | #ifdef CONFIG_MEDIA_CEC_RC |
9881fe0c HV |
1856 | switch (msg->msg[2]) { |
1857 | /* | |
1858 | * Play function, this message can have variable length | |
1859 | * depending on the specific play function that is used. | |
1860 | */ | |
1861 | case 0x60: | |
1862 | if (msg->len == 2) | |
a9a249a2 | 1863 | scancode = msg->msg[2]; |
9881fe0c | 1864 | else |
a9a249a2 | 1865 | scancode = msg->msg[2] << 8 | msg->msg[3]; |
9881fe0c HV |
1866 | break; |
1867 | /* | |
1868 | * Other function messages that are not handled. | |
1869 | * Currently the RC framework does not allow to supply an | |
1870 | * additional parameter to a keypress. These "keys" contain | |
1871 | * other information such as channel number, an input number | |
1872 | * etc. | |
1873 | * For the time being these messages are not processed by the | |
1874 | * framework and are simply forwarded to the user space. | |
1875 | */ | |
1876 | case 0x56: case 0x57: | |
1877 | case 0x67: case 0x68: case 0x69: case 0x6a: | |
a9a249a2 | 1878 | scancode = -1; |
9881fe0c HV |
1879 | break; |
1880 | default: | |
a9a249a2 HV |
1881 | scancode = msg->msg[2]; |
1882 | break; | |
1883 | } | |
1884 | ||
1885 | /* Was repeating, but keypress timed out */ | |
1886 | if (adap->rc_repeating && !adap->rc->keypressed) { | |
1887 | adap->rc_repeating = false; | |
1888 | adap->rc_last_scancode = -1; | |
1889 | } | |
1890 | /* Different keypress from last time, ends repeat mode */ | |
1891 | if (adap->rc_last_scancode != scancode) { | |
1892 | rc_keyup(adap->rc); | |
1893 | adap->rc_repeating = false; | |
1894 | } | |
1895 | /* We can't handle this scancode */ | |
1896 | if (scancode < 0) { | |
1897 | adap->rc_last_scancode = scancode; | |
1898 | break; | |
1899 | } | |
1900 | ||
1901 | /* Send key press */ | |
6d741bfe | 1902 | rc_keydown(adap->rc, RC_PROTO_CEC, scancode, 0); |
a9a249a2 HV |
1903 | |
1904 | /* When in repeating mode, we're done */ | |
1905 | if (adap->rc_repeating) | |
1906 | break; | |
1907 | ||
1908 | /* | |
1909 | * We are not repeating, but the new scancode is | |
1910 | * the same as the last one, and this second key press is | |
1911 | * within 550 ms (the 'Follower Safety Timeout') from the | |
1912 | * previous key press, so we now enable the repeating mode. | |
1913 | */ | |
1914 | if (adap->rc_last_scancode == scancode && | |
1915 | msg->rx_ts - adap->rc_last_keypress < 550 * NSEC_PER_MSEC) { | |
1916 | adap->rc_repeating = true; | |
9881fe0c HV |
1917 | break; |
1918 | } | |
a9a249a2 HV |
1919 | /* |
1920 | * Not in repeating mode, so avoid triggering repeat mode | |
1921 | * by calling keyup. | |
1922 | */ | |
1923 | rc_keyup(adap->rc); | |
1924 | adap->rc_last_scancode = scancode; | |
1925 | adap->rc_last_keypress = msg->rx_ts; | |
9881fe0c HV |
1926 | #endif |
1927 | break; | |
1928 | ||
1929 | case CEC_MSG_USER_CONTROL_RELEASED: | |
f4062625 HV |
1930 | if (!(adap->capabilities & CEC_CAP_RC) || |
1931 | !(adap->log_addrs.flags & CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU)) | |
9881fe0c | 1932 | break; |
5f2c467c | 1933 | #ifdef CONFIG_MEDIA_CEC_RC |
9881fe0c | 1934 | rc_keyup(adap->rc); |
a9a249a2 HV |
1935 | adap->rc_repeating = false; |
1936 | adap->rc_last_scancode = -1; | |
9881fe0c HV |
1937 | #endif |
1938 | break; | |
1939 | ||
1940 | /* | |
1941 | * The remaining messages are only processed if the passthrough mode | |
1942 | * is off. | |
1943 | */ | |
1944 | case CEC_MSG_GET_CEC_VERSION: | |
1945 | cec_msg_cec_version(&tx_cec_msg, adap->log_addrs.cec_version); | |
1946 | return cec_transmit_msg(adap, &tx_cec_msg, false); | |
1947 | ||
1948 | case CEC_MSG_GIVE_PHYSICAL_ADDR: | |
1949 | /* Do nothing for CEC switches using addr 15 */ | |
1950 | if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH && dest_laddr == 15) | |
1951 | return 0; | |
1952 | cec_msg_report_physical_addr(&tx_cec_msg, adap->phys_addr, devtype); | |
1953 | return cec_transmit_msg(adap, &tx_cec_msg, false); | |
1954 | ||
1955 | case CEC_MSG_GIVE_DEVICE_VENDOR_ID: | |
1956 | if (adap->log_addrs.vendor_id == CEC_VENDOR_ID_NONE) | |
1957 | return cec_feature_abort(adap, msg); | |
1958 | cec_msg_device_vendor_id(&tx_cec_msg, adap->log_addrs.vendor_id); | |
1959 | return cec_transmit_msg(adap, &tx_cec_msg, false); | |
1960 | ||
1961 | case CEC_MSG_ABORT: | |
1962 | /* Do nothing for CEC switches */ | |
1963 | if (devtype == CEC_OP_PRIM_DEVTYPE_SWITCH) | |
1964 | return 0; | |
1965 | return cec_feature_refused(adap, msg); | |
1966 | ||
1967 | case CEC_MSG_GIVE_OSD_NAME: { | |
1968 | if (adap->log_addrs.osd_name[0] == 0) | |
1969 | return cec_feature_abort(adap, msg); | |
1970 | cec_msg_set_osd_name(&tx_cec_msg, adap->log_addrs.osd_name); | |
1971 | return cec_transmit_msg(adap, &tx_cec_msg, false); | |
1972 | } | |
1973 | ||
1974 | case CEC_MSG_GIVE_FEATURES: | |
a24f56d4 HV |
1975 | if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0) |
1976 | return cec_feature_abort(adap, msg); | |
52bc30fd HV |
1977 | cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx); |
1978 | return cec_transmit_msg(adap, &tx_cec_msg, false); | |
9881fe0c HV |
1979 | |
1980 | default: | |
1981 | /* | |
1982 | * Unprocessed messages are aborted if userspace isn't doing | |
1983 | * any processing either. | |
1984 | */ | |
a179b693 | 1985 | if (!is_broadcast && !is_reply && !adap->follower_cnt && |
9881fe0c HV |
1986 | !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) |
1987 | return cec_feature_abort(adap, msg); | |
1988 | break; | |
1989 | } | |
1990 | ||
1991 | skip_processing: | |
adc0c622 HV |
1992 | /* If this was a reply, then we're done, unless otherwise specified */ |
1993 | if (is_reply && !(msg->flags & CEC_MSG_FL_REPLY_TO_FOLLOWERS)) | |
9881fe0c HV |
1994 | return 0; |
1995 | ||
1996 | /* | |
1997 | * Send to the exclusive follower if there is one, otherwise send | |
1998 | * to all followers. | |
1999 | */ | |
2000 | if (adap->cec_follower) | |
2001 | cec_queue_msg_fh(adap->cec_follower, msg); | |
2002 | else | |
2003 | cec_queue_msg_followers(adap, msg); | |
2004 | return 0; | |
2005 | } | |
2006 | ||
2007 | /* | |
2008 | * Helper functions to keep track of the 'monitor all' use count. | |
2009 | * | |
2010 | * These functions are called with adap->lock held. | |
2011 | */ | |
2012 | int cec_monitor_all_cnt_inc(struct cec_adapter *adap) | |
2013 | { | |
2014 | int ret = 0; | |
2015 | ||
2016 | if (adap->monitor_all_cnt == 0) | |
2017 | ret = call_op(adap, adap_monitor_all_enable, 1); | |
2018 | if (ret == 0) | |
2019 | adap->monitor_all_cnt++; | |
2020 | return ret; | |
2021 | } | |
2022 | ||
2023 | void cec_monitor_all_cnt_dec(struct cec_adapter *adap) | |
2024 | { | |
2025 | adap->monitor_all_cnt--; | |
2026 | if (adap->monitor_all_cnt == 0) | |
2027 | WARN_ON(call_op(adap, adap_monitor_all_enable, 0)); | |
2028 | } | |
2029 | ||
20249f84 | 2030 | #ifdef CONFIG_DEBUG_FS |
9881fe0c HV |
2031 | /* |
2032 | * Log the current state of the CEC adapter. | |
2033 | * Very useful for debugging. | |
2034 | */ | |
2035 | int cec_adap_status(struct seq_file *file, void *priv) | |
2036 | { | |
2037 | struct cec_adapter *adap = dev_get_drvdata(file->private); | |
2038 | struct cec_data *data; | |
2039 | ||
2040 | mutex_lock(&adap->lock); | |
2041 | seq_printf(file, "configured: %d\n", adap->is_configured); | |
2042 | seq_printf(file, "configuring: %d\n", adap->is_configuring); | |
2043 | seq_printf(file, "phys_addr: %x.%x.%x.%x\n", | |
2044 | cec_phys_addr_exp(adap->phys_addr)); | |
2045 | seq_printf(file, "number of LAs: %d\n", adap->log_addrs.num_log_addrs); | |
2046 | seq_printf(file, "LA mask: 0x%04x\n", adap->log_addrs.log_addr_mask); | |
2047 | if (adap->cec_follower) | |
2048 | seq_printf(file, "has CEC follower%s\n", | |
2049 | adap->passthrough ? " (in passthrough mode)" : ""); | |
2050 | if (adap->cec_initiator) | |
2051 | seq_puts(file, "has CEC initiator\n"); | |
2052 | if (adap->monitor_all_cnt) | |
2053 | seq_printf(file, "file handles in Monitor All mode: %u\n", | |
2054 | adap->monitor_all_cnt); | |
bb789e03 HV |
2055 | if (adap->tx_timeouts) { |
2056 | seq_printf(file, "transmit timeouts: %u\n", | |
2057 | adap->tx_timeouts); | |
2058 | adap->tx_timeouts = 0; | |
2059 | } | |
9881fe0c HV |
2060 | data = adap->transmitting; |
2061 | if (data) | |
11065f85 HV |
2062 | seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", |
2063 | data->msg.len, data->msg.msg, data->msg.reply, | |
2064 | data->msg.timeout); | |
2065 | seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz); | |
9881fe0c | 2066 | list_for_each_entry(data, &adap->transmit_queue, list) { |
11065f85 HV |
2067 | seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n", |
2068 | data->msg.len, data->msg.msg, data->msg.reply, | |
2069 | data->msg.timeout); | |
9881fe0c HV |
2070 | } |
2071 | list_for_each_entry(data, &adap->wait_queue, list) { | |
11065f85 HV |
2072 | seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n", |
2073 | data->msg.len, data->msg.msg, data->msg.reply, | |
2074 | data->msg.timeout); | |
9881fe0c HV |
2075 | } |
2076 | ||
2077 | call_void_op(adap, adap_status, file); | |
2078 | mutex_unlock(&adap->lock); | |
2079 | return 0; | |
2080 | } | |
2081 | #endif |