1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Pulse Eight HDMI CEC driver
5 * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
11 * - Devices with firmware version < 2 do not store their configuration in
14 * - In autonomous mode, only messages from a TV will be acknowledged, even
15 * polling messages. Upon receiving a message from a TV, the dongle will
16 * respond to messages from any logical address.
18 * - In autonomous mode, the dongle will by default reply Feature Abort
19 * [Unrecognized Opcode] when it receives Give Device Vendor ID. It will
20 * however observe vendor ID's reported by other devices and possibly
21 * alter this behavior. When TV's (and TV's only) report that their vendor ID
22 * is LG (0x00e091), the dongle will itself reply that it has the same vendor
23 * ID, and it will respond to at least one vendor specific command.
25 * - In autonomous mode, the dongle is known to attempt wakeup if it receives
26 * <User Control Pressed> ["Power On"], ["Power] or ["Power Toggle"], or if it
27 * receives <Set Stream Path> with its own physical address. It also does this
28 * if it receives <Vendor Specific Command> [0x03 0x00] from an LG TV.
31 #include <linux/completion.h>
32 #include <linux/init.h>
33 #include <linux/interrupt.h>
34 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/workqueue.h>
37 #include <linux/serio.h>
38 #include <linux/slab.h>
39 #include <linux/time.h>
40 #include <linux/delay.h>
42 #include <media/cec.h>
44 MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
45 MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
46 MODULE_LICENSE("GPL");
49 static int persistent_config
;
50 module_param(debug
, int, 0644);
51 module_param(persistent_config
, int, 0644);
52 MODULE_PARM_DESC(debug
, "debug level (0-2)");
53 MODULE_PARM_DESC(persistent_config
, "read config from persistent memory (0-1)");
55 enum pulse8_msgcodes
{
58 MSGCODE_TIMEOUT_ERROR
,
63 MSGCODE_RECEIVE_FAILED
,
64 MSGCODE_COMMAND_ACCEPTED
, /* 0x08 */
65 MSGCODE_COMMAND_REJECTED
,
69 MSGCODE_TRANSMIT_IDLETIME
,
70 MSGCODE_TRANSMIT_ACK_POLARITY
,
71 MSGCODE_TRANSMIT_LINE_TIMEOUT
,
72 MSGCODE_TRANSMIT_SUCCEEDED
, /* 0x10 */
73 MSGCODE_TRANSMIT_FAILED_LINE
,
74 MSGCODE_TRANSMIT_FAILED_ACK
,
75 MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA
,
76 MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE
,
77 MSGCODE_FIRMWARE_VERSION
,
78 MSGCODE_START_BOOTLOADER
,
79 MSGCODE_GET_BUILDDATE
,
80 MSGCODE_SET_CONTROLLED
, /* 0x18 */
81 MSGCODE_GET_AUTO_ENABLED
,
82 MSGCODE_SET_AUTO_ENABLED
,
83 MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS
,
84 MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS
,
85 MSGCODE_GET_LOGICAL_ADDRESS_MASK
,
86 MSGCODE_SET_LOGICAL_ADDRESS_MASK
,
87 MSGCODE_GET_PHYSICAL_ADDRESS
,
88 MSGCODE_SET_PHYSICAL_ADDRESS
, /* 0x20 */
89 MSGCODE_GET_DEVICE_TYPE
,
90 MSGCODE_SET_DEVICE_TYPE
,
91 MSGCODE_GET_HDMI_VERSION
,
92 MSGCODE_SET_HDMI_VERSION
,
96 MSGCODE_GET_ADAPTER_TYPE
, /* 0x28 */
97 MSGCODE_SET_ACTIVE_SOURCE
,
99 MSGCODE_FRAME_EOM
= 0x80,
100 MSGCODE_FRAME_ACK
= 0x40,
103 static const char * const pulse8_msgnames
[] = {
118 "TRANSMIT_ACK_POLARITY",
119 "TRANSMIT_LINE_TIMEOUT",
120 "TRANSMIT_SUCCEEDED",
121 "TRANSMIT_FAILED_LINE",
122 "TRANSMIT_FAILED_ACK",
123 "TRANSMIT_FAILED_TIMEOUT_DATA",
124 "TRANSMIT_FAILED_TIMEOUT_LINE",
131 "GET_DEFAULT_LOGICAL_ADDRESS",
132 "SET_DEFAULT_LOGICAL_ADDRESS",
133 "GET_LOGICAL_ADDRESS_MASK",
134 "SET_LOGICAL_ADDRESS_MASK",
135 "GET_PHYSICAL_ADDRESS",
136 "SET_PHYSICAL_ADDRESS",
148 static const char *pulse8_msgname(u8 cmd
)
150 static char unknown_msg
[5];
152 if ((cmd
& 0x3f) < ARRAY_SIZE(pulse8_msgnames
))
153 return pulse8_msgnames
[cmd
& 0x3f];
154 snprintf(unknown_msg
, sizeof(unknown_msg
), "0x%02x", cmd
);
158 #define MSGSTART 0xff
163 #define DATA_SIZE 256
165 #define PING_PERIOD (15 * HZ)
172 struct cec_adapter
*adap
;
175 struct delayed_work ping_eeprom_work
;
177 struct work_struct irq_work
;
178 struct cec_msg rx_msg
[NUM_MSGS
];
179 unsigned int rx_msg_cur_idx
, rx_msg_num
;
180 /* protect rx_msg_cur_idx and rx_msg_num */
182 u8 new_rx_msg
[CEC_MAX_MSG_SIZE
];
185 struct work_struct tx_work
;
187 u32 tx_signal_free_time
;
188 struct cec_msg tx_msg
;
189 bool tx_msg_is_bcast
;
191 struct completion cmd_done
;
199 /* locks access to the adapter */
202 bool restoring_config
;
206 static int pulse8_send(struct serio
*serio
, const u8
*command
, u8 cmd_len
)
210 err
= serio_write(serio
, MSGSTART
);
213 for (; !err
&& cmd_len
; command
++, cmd_len
--) {
214 if (*command
>= MSGESC
) {
215 err
= serio_write(serio
, MSGESC
);
217 err
= serio_write(serio
, *command
- MSGOFFSET
);
219 err
= serio_write(serio
, *command
);
223 err
= serio_write(serio
, MSGEND
);
228 static int pulse8_send_and_wait_once(struct pulse8
*pulse8
,
229 const u8
*cmd
, u8 cmd_len
,
230 u8 response
, u8 size
)
235 dev_info(pulse8
->dev
, "transmit %s: %*ph\n",
236 pulse8_msgname(cmd
[0]), cmd_len
, cmd
);
237 init_completion(&pulse8
->cmd_done
);
239 err
= pulse8_send(pulse8
->serio
, cmd
, cmd_len
);
243 if (!wait_for_completion_timeout(&pulse8
->cmd_done
, HZ
))
245 if ((pulse8
->data
[0] & 0x3f) == MSGCODE_COMMAND_REJECTED
&&
246 cmd
[0] != MSGCODE_SET_CONTROLLED
&&
247 cmd
[0] != MSGCODE_SET_AUTO_ENABLED
&&
248 cmd
[0] != MSGCODE_GET_BUILDDATE
)
251 ((pulse8
->data
[0] & 0x3f) != response
|| pulse8
->len
< size
+ 1)) {
252 dev_info(pulse8
->dev
, "transmit %s failed with %s\n",
253 pulse8_msgname(cmd
[0]),
254 pulse8_msgname(pulse8
->data
[0]));
260 static int pulse8_send_and_wait(struct pulse8
*pulse8
,
261 const u8
*cmd
, u8 cmd_len
, u8 response
, u8 size
)
266 err
= pulse8_send_and_wait_once(pulse8
, cmd
, cmd_len
, response
, size
);
270 cmd_sc
[0] = MSGCODE_SET_CONTROLLED
;
272 err
= pulse8_send_and_wait_once(pulse8
, cmd_sc
, 2,
273 MSGCODE_COMMAND_ACCEPTED
, 1);
275 err
= pulse8_send_and_wait_once(pulse8
, cmd
, cmd_len
,
277 return err
== -ENOTTY
? -EIO
: err
;
280 static void pulse8_tx_work_handler(struct work_struct
*work
)
282 struct pulse8
*pulse8
= container_of(work
, struct pulse8
, tx_work
);
283 struct cec_msg
*msg
= &pulse8
->tx_msg
;
291 mutex_lock(&pulse8
->lock
);
292 cmd
[0] = MSGCODE_TRANSMIT_IDLETIME
;
293 cmd
[1] = pulse8
->tx_signal_free_time
;
294 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
295 MSGCODE_COMMAND_ACCEPTED
, 1);
296 cmd
[0] = MSGCODE_TRANSMIT_ACK_POLARITY
;
297 cmd
[1] = cec_msg_is_broadcast(msg
);
298 pulse8
->tx_msg_is_bcast
= cec_msg_is_broadcast(msg
);
300 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
301 MSGCODE_COMMAND_ACCEPTED
, 1);
302 cmd
[0] = msg
->len
== 1 ? MSGCODE_TRANSMIT_EOM
: MSGCODE_TRANSMIT
;
303 cmd
[1] = msg
->msg
[0];
305 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
306 MSGCODE_COMMAND_ACCEPTED
, 1);
307 if (!err
&& msg
->len
> 1) {
308 for (i
= 1; !err
&& i
< msg
->len
; i
++) {
309 cmd
[0] = ((i
== msg
->len
- 1)) ?
310 MSGCODE_TRANSMIT_EOM
: MSGCODE_TRANSMIT
;
311 cmd
[1] = msg
->msg
[i
];
312 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
313 MSGCODE_COMMAND_ACCEPTED
, 1);
317 dev_info(pulse8
->dev
, "%s(0x%02x) failed with error %d for msg %*ph\n",
318 pulse8_msgname(cmd
[0]), cmd
[1],
319 err
, msg
->len
, msg
->msg
);
321 mutex_unlock(&pulse8
->lock
);
323 cec_transmit_attempt_done(pulse8
->adap
, CEC_TX_STATUS_ERROR
);
326 static void pulse8_irq_work_handler(struct work_struct
*work
)
328 struct pulse8
*pulse8
=
329 container_of(work
, struct pulse8
, irq_work
);
333 spin_lock_irqsave(&pulse8
->msg_lock
, flags
);
334 while (pulse8
->rx_msg_num
) {
335 spin_unlock_irqrestore(&pulse8
->msg_lock
, flags
);
337 dev_info(pulse8
->dev
, "adap received %*ph\n",
338 pulse8
->rx_msg
[pulse8
->rx_msg_cur_idx
].len
,
339 pulse8
->rx_msg
[pulse8
->rx_msg_cur_idx
].msg
);
340 cec_received_msg(pulse8
->adap
,
341 &pulse8
->rx_msg
[pulse8
->rx_msg_cur_idx
]);
342 spin_lock_irqsave(&pulse8
->msg_lock
, flags
);
343 if (pulse8
->rx_msg_num
)
344 pulse8
->rx_msg_num
--;
345 pulse8
->rx_msg_cur_idx
=
346 (pulse8
->rx_msg_cur_idx
+ 1) % NUM_MSGS
;
348 spin_unlock_irqrestore(&pulse8
->msg_lock
, flags
);
350 mutex_lock(&pulse8
->lock
);
351 status
= pulse8
->tx_done_status
;
352 pulse8
->tx_done_status
= 0;
353 mutex_unlock(&pulse8
->lock
);
355 cec_transmit_attempt_done(pulse8
->adap
, status
);
358 static irqreturn_t
pulse8_interrupt(struct serio
*serio
, unsigned char data
,
361 struct pulse8
*pulse8
= serio_get_drvdata(serio
);
362 unsigned long irq_flags
;
365 if (!pulse8
->started
&& data
!= MSGSTART
)
367 if (data
== MSGESC
) {
368 pulse8
->escape
= true;
371 if (pulse8
->escape
) {
373 pulse8
->escape
= false;
374 } else if (data
== MSGEND
) {
375 u8 msgcode
= pulse8
->buf
[0];
378 dev_info(pulse8
->dev
, "received %s: %*ph\n",
379 pulse8_msgname(msgcode
),
380 pulse8
->idx
, pulse8
->buf
);
381 switch (msgcode
& 0x3f) {
382 case MSGCODE_FRAME_START
:
384 * Test if we are receiving a new msg when a previous
385 * message is still pending.
387 if (!(msgcode
& MSGCODE_FRAME_EOM
)) {
388 pulse8
->new_rx_msg_len
= 1;
389 pulse8
->new_rx_msg
[0] = pulse8
->buf
[1];
393 case MSGCODE_FRAME_DATA
:
394 if (pulse8
->new_rx_msg_len
< CEC_MAX_MSG_SIZE
)
395 pulse8
->new_rx_msg
[pulse8
->new_rx_msg_len
++] =
397 if (!(msgcode
& MSGCODE_FRAME_EOM
))
400 spin_lock_irqsave(&pulse8
->msg_lock
, irq_flags
);
401 idx
= (pulse8
->rx_msg_cur_idx
+ pulse8
->rx_msg_num
) %
403 if (pulse8
->rx_msg_num
== NUM_MSGS
) {
404 dev_warn(pulse8
->dev
,
405 "message queue is full, dropping %*ph\n",
406 pulse8
->new_rx_msg_len
,
408 spin_unlock_irqrestore(&pulse8
->msg_lock
,
410 pulse8
->new_rx_msg_len
= 0;
413 pulse8
->rx_msg_num
++;
414 memcpy(pulse8
->rx_msg
[idx
].msg
, pulse8
->new_rx_msg
,
415 pulse8
->new_rx_msg_len
);
416 pulse8
->rx_msg
[idx
].len
= pulse8
->new_rx_msg_len
;
417 spin_unlock_irqrestore(&pulse8
->msg_lock
, irq_flags
);
418 schedule_work(&pulse8
->irq_work
);
419 pulse8
->new_rx_msg_len
= 0;
421 case MSGCODE_TRANSMIT_SUCCEEDED
:
422 WARN_ON(pulse8
->tx_done_status
);
423 pulse8
->tx_done_status
= CEC_TX_STATUS_OK
;
424 schedule_work(&pulse8
->irq_work
);
426 case MSGCODE_TRANSMIT_FAILED_ACK
:
428 * A NACK for a broadcast message makes no sense, these
429 * seem to be spurious messages and are skipped.
431 if (pulse8
->tx_msg_is_bcast
)
433 WARN_ON(pulse8
->tx_done_status
);
434 pulse8
->tx_done_status
= CEC_TX_STATUS_NACK
;
435 schedule_work(&pulse8
->irq_work
);
437 case MSGCODE_TRANSMIT_FAILED_LINE
:
438 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA
:
439 case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE
:
440 WARN_ON(pulse8
->tx_done_status
);
441 pulse8
->tx_done_status
= CEC_TX_STATUS_ERROR
;
442 schedule_work(&pulse8
->irq_work
);
444 case MSGCODE_HIGH_ERROR
:
445 case MSGCODE_LOW_ERROR
:
446 case MSGCODE_RECEIVE_FAILED
:
447 case MSGCODE_TIMEOUT_ERROR
:
448 pulse8
->new_rx_msg_len
= 0;
450 case MSGCODE_COMMAND_ACCEPTED
:
451 case MSGCODE_COMMAND_REJECTED
:
453 if (pulse8
->idx
== 0)
455 memcpy(pulse8
->data
, pulse8
->buf
, pulse8
->idx
);
456 pulse8
->len
= pulse8
->idx
;
457 complete(&pulse8
->cmd_done
);
461 pulse8
->started
= false;
463 } else if (data
== MSGSTART
) {
465 pulse8
->started
= true;
469 if (pulse8
->idx
>= DATA_SIZE
) {
471 "throwing away %d bytes of garbage\n", pulse8
->idx
);
474 pulse8
->buf
[pulse8
->idx
++] = data
;
478 static int pulse8_cec_adap_enable(struct cec_adapter
*adap
, bool enable
)
480 struct pulse8
*pulse8
= cec_get_drvdata(adap
);
484 mutex_lock(&pulse8
->lock
);
485 cmd
[0] = MSGCODE_SET_CONTROLLED
;
487 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
488 MSGCODE_COMMAND_ACCEPTED
, 1);
490 pulse8
->rx_msg_num
= 0;
491 pulse8
->tx_done_status
= 0;
493 mutex_unlock(&pulse8
->lock
);
494 return enable
? err
: 0;
497 static int pulse8_cec_adap_log_addr(struct cec_adapter
*adap
, u8 log_addr
)
499 struct pulse8
*pulse8
= cec_get_drvdata(adap
);
501 u16 pa
= adap
->phys_addr
;
505 mutex_lock(&pulse8
->lock
);
506 if (log_addr
!= CEC_LOG_ADDR_INVALID
)
507 mask
= 1 << log_addr
;
508 cmd
[0] = MSGCODE_SET_ACK_MASK
;
510 cmd
[2] = mask
& 0xff;
511 err
= pulse8_send_and_wait(pulse8
, cmd
, 3,
512 MSGCODE_COMMAND_ACCEPTED
, 0);
513 if ((err
&& mask
!= 0) || pulse8
->restoring_config
)
516 cmd
[0] = MSGCODE_SET_AUTO_ENABLED
;
517 cmd
[1] = log_addr
== CEC_LOG_ADDR_INVALID
? 0 : 1;
518 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
519 MSGCODE_COMMAND_ACCEPTED
, 0);
522 pulse8
->autonomous
= cmd
[1];
523 if (log_addr
== CEC_LOG_ADDR_INVALID
)
526 cmd
[0] = MSGCODE_SET_DEVICE_TYPE
;
527 cmd
[1] = adap
->log_addrs
.primary_device_type
[0];
528 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
529 MSGCODE_COMMAND_ACCEPTED
, 0);
533 switch (adap
->log_addrs
.primary_device_type
[0]) {
534 case CEC_OP_PRIM_DEVTYPE_TV
:
535 mask
= CEC_LOG_ADDR_MASK_TV
;
537 case CEC_OP_PRIM_DEVTYPE_RECORD
:
538 mask
= CEC_LOG_ADDR_MASK_RECORD
;
540 case CEC_OP_PRIM_DEVTYPE_TUNER
:
541 mask
= CEC_LOG_ADDR_MASK_TUNER
;
543 case CEC_OP_PRIM_DEVTYPE_PLAYBACK
:
544 mask
= CEC_LOG_ADDR_MASK_PLAYBACK
;
546 case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
:
547 mask
= CEC_LOG_ADDR_MASK_AUDIOSYSTEM
;
549 case CEC_OP_PRIM_DEVTYPE_SWITCH
:
550 mask
= CEC_LOG_ADDR_MASK_UNREGISTERED
;
552 case CEC_OP_PRIM_DEVTYPE_PROCESSOR
:
553 mask
= CEC_LOG_ADDR_MASK_SPECIFIC
;
559 cmd
[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK
;
561 cmd
[2] = mask
& 0xff;
562 err
= pulse8_send_and_wait(pulse8
, cmd
, 3,
563 MSGCODE_COMMAND_ACCEPTED
, 0);
567 cmd
[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS
;
569 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
570 MSGCODE_COMMAND_ACCEPTED
, 0);
574 cmd
[0] = MSGCODE_SET_PHYSICAL_ADDRESS
;
577 err
= pulse8_send_and_wait(pulse8
, cmd
, 3,
578 MSGCODE_COMMAND_ACCEPTED
, 0);
582 cmd
[0] = MSGCODE_SET_HDMI_VERSION
;
583 cmd
[1] = adap
->log_addrs
.cec_version
;
584 err
= pulse8_send_and_wait(pulse8
, cmd
, 2,
585 MSGCODE_COMMAND_ACCEPTED
, 0);
589 if (adap
->log_addrs
.osd_name
[0]) {
590 size_t osd_len
= strlen(adap
->log_addrs
.osd_name
);
591 char *osd_str
= cmd
+ 1;
593 cmd
[0] = MSGCODE_SET_OSD_NAME
;
594 strscpy(cmd
+ 1, adap
->log_addrs
.osd_name
, sizeof(cmd
) - 1);
596 memset(osd_str
+ osd_len
, ' ', 4 - osd_len
);
598 osd_str
[osd_len
] = '\0';
599 strscpy(adap
->log_addrs
.osd_name
, osd_str
,
600 sizeof(adap
->log_addrs
.osd_name
));
602 err
= pulse8_send_and_wait(pulse8
, cmd
, 1 + osd_len
,
603 MSGCODE_COMMAND_ACCEPTED
, 0);
609 if (pulse8
->restoring_config
)
610 pulse8
->restoring_config
= false;
612 pulse8
->config_pending
= true;
613 mutex_unlock(&pulse8
->lock
);
614 return log_addr
== CEC_LOG_ADDR_INVALID
? 0 : err
;
617 static int pulse8_cec_adap_transmit(struct cec_adapter
*adap
, u8 attempts
,
618 u32 signal_free_time
, struct cec_msg
*msg
)
620 struct pulse8
*pulse8
= cec_get_drvdata(adap
);
622 pulse8
->tx_msg
= *msg
;
624 dev_info(pulse8
->dev
, "adap transmit %*ph\n",
626 pulse8
->tx_signal_free_time
= signal_free_time
;
627 schedule_work(&pulse8
->tx_work
);
631 static void pulse8_cec_adap_free(struct cec_adapter
*adap
)
633 struct pulse8
*pulse8
= cec_get_drvdata(adap
);
635 cancel_delayed_work_sync(&pulse8
->ping_eeprom_work
);
636 cancel_work_sync(&pulse8
->irq_work
);
637 cancel_work_sync(&pulse8
->tx_work
);
638 serio_close(pulse8
->serio
);
639 serio_set_drvdata(pulse8
->serio
, NULL
);
643 static const struct cec_adap_ops pulse8_cec_adap_ops
= {
644 .adap_enable
= pulse8_cec_adap_enable
,
645 .adap_log_addr
= pulse8_cec_adap_log_addr
,
646 .adap_transmit
= pulse8_cec_adap_transmit
,
647 .adap_free
= pulse8_cec_adap_free
,
650 static void pulse8_disconnect(struct serio
*serio
)
652 struct pulse8
*pulse8
= serio_get_drvdata(serio
);
654 cec_unregister_adapter(pulse8
->adap
);
657 static int pulse8_setup(struct pulse8
*pulse8
, struct serio
*serio
,
658 struct cec_log_addrs
*log_addrs
, u16
*pa
)
660 u8
*data
= pulse8
->data
+ 1;
668 cmd
[0] = MSGCODE_FIRMWARE_VERSION
;
669 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 2);
672 pulse8
->vers
= (data
[0] << 8) | data
[1];
673 dev_info(pulse8
->dev
, "Firmware version %04x\n", pulse8
->vers
);
674 if (pulse8
->vers
< 2) {
675 *pa
= CEC_PHYS_ADDR_INVALID
;
679 cmd
[0] = MSGCODE_GET_BUILDDATE
;
680 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 4);
683 date
= (data
[0] << 24) | (data
[1] << 16) | (data
[2] << 8) | data
[3];
684 time64_to_tm(date
, 0, &tm
);
685 dev_info(pulse8
->dev
, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n",
686 tm
.tm_year
+ 1900, tm
.tm_mon
+ 1, tm
.tm_mday
,
687 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
);
689 dev_dbg(pulse8
->dev
, "Persistent config:\n");
690 cmd
[0] = MSGCODE_GET_AUTO_ENABLED
;
691 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 1);
694 pulse8
->autonomous
= data
[0];
695 dev_dbg(pulse8
->dev
, "Autonomous mode: %s",
696 data
[0] ? "on" : "off");
698 cmd
[0] = MSGCODE_GET_DEVICE_TYPE
;
699 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 1);
702 log_addrs
->primary_device_type
[0] = data
[0];
703 dev_dbg(pulse8
->dev
, "Primary device type: %d\n", data
[0]);
704 switch (log_addrs
->primary_device_type
[0]) {
705 case CEC_OP_PRIM_DEVTYPE_TV
:
706 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_TV
;
707 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_TV
;
709 case CEC_OP_PRIM_DEVTYPE_RECORD
:
710 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_RECORD
;
711 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_RECORD
;
713 case CEC_OP_PRIM_DEVTYPE_TUNER
:
714 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_TUNER
;
715 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_TUNER
;
717 case CEC_OP_PRIM_DEVTYPE_PLAYBACK
:
718 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_PLAYBACK
;
719 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK
;
721 case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM
:
722 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_PLAYBACK
;
723 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM
;
725 case CEC_OP_PRIM_DEVTYPE_SWITCH
:
726 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED
;
727 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_SWITCH
;
729 case CEC_OP_PRIM_DEVTYPE_PROCESSOR
:
730 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_SPECIFIC
;
731 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_SWITCH
;
734 log_addrs
->log_addr_type
[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED
;
735 log_addrs
->all_device_types
[0] = CEC_OP_ALL_DEVTYPE_SWITCH
;
736 dev_info(pulse8
->dev
, "Unknown Primary Device Type: %d\n",
737 log_addrs
->primary_device_type
[0]);
741 cmd
[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK
;
742 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 2);
745 log_addrs
->log_addr_mask
= (data
[0] << 8) | data
[1];
746 dev_dbg(pulse8
->dev
, "Logical address ACK mask: %x\n",
747 log_addrs
->log_addr_mask
);
748 if (log_addrs
->log_addr_mask
)
749 log_addrs
->num_log_addrs
= 1;
751 cmd
[0] = MSGCODE_GET_PHYSICAL_ADDRESS
;
752 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 1);
755 *pa
= (data
[0] << 8) | data
[1];
756 dev_dbg(pulse8
->dev
, "Physical address: %x.%x.%x.%x\n",
757 cec_phys_addr_exp(*pa
));
759 cmd
[0] = MSGCODE_GET_HDMI_VERSION
;
760 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 1);
763 log_addrs
->cec_version
= data
[0];
764 dev_dbg(pulse8
->dev
, "CEC version: %d\n", log_addrs
->cec_version
);
766 cmd
[0] = MSGCODE_GET_OSD_NAME
;
767 err
= pulse8_send_and_wait(pulse8
, cmd
, 1, cmd
[0], 0);
770 strscpy(log_addrs
->osd_name
, data
, sizeof(log_addrs
->osd_name
));
771 dev_dbg(pulse8
->dev
, "OSD name: %s\n", log_addrs
->osd_name
);
776 static int pulse8_apply_persistent_config(struct pulse8
*pulse8
,
777 struct cec_log_addrs
*log_addrs
,
782 err
= cec_s_log_addrs(pulse8
->adap
, log_addrs
, false);
786 cec_s_phys_addr(pulse8
->adap
, pa
, false);
791 static void pulse8_ping_eeprom_work_handler(struct work_struct
*work
)
793 struct pulse8
*pulse8
=
794 container_of(work
, struct pulse8
, ping_eeprom_work
.work
);
797 mutex_lock(&pulse8
->lock
);
799 pulse8_send_and_wait(pulse8
, &cmd
, 1,
800 MSGCODE_COMMAND_ACCEPTED
, 0);
802 if (pulse8
->vers
< 2)
805 if (pulse8
->config_pending
&& persistent_config
) {
806 dev_dbg(pulse8
->dev
, "writing pending config to EEPROM\n");
807 cmd
= MSGCODE_WRITE_EEPROM
;
808 if (pulse8_send_and_wait(pulse8
, &cmd
, 1,
809 MSGCODE_COMMAND_ACCEPTED
, 0))
810 dev_info(pulse8
->dev
, "failed to write pending config to EEPROM\n");
812 pulse8
->config_pending
= false;
815 schedule_delayed_work(&pulse8
->ping_eeprom_work
, PING_PERIOD
);
816 mutex_unlock(&pulse8
->lock
);
819 static int pulse8_connect(struct serio
*serio
, struct serio_driver
*drv
)
821 u32 caps
= CEC_CAP_DEFAULTS
| CEC_CAP_PHYS_ADDR
| CEC_CAP_MONITOR_ALL
;
822 struct pulse8
*pulse8
;
824 struct cec_log_addrs log_addrs
= {};
825 u16 pa
= CEC_PHYS_ADDR_INVALID
;
827 pulse8
= kzalloc(sizeof(*pulse8
), GFP_KERNEL
);
832 pulse8
->serio
= serio
;
833 pulse8
->adap
= cec_allocate_adapter(&pulse8_cec_adap_ops
, pulse8
,
834 dev_name(&serio
->dev
), caps
, 1);
835 err
= PTR_ERR_OR_ZERO(pulse8
->adap
);
839 pulse8
->dev
= &serio
->dev
;
840 serio_set_drvdata(serio
, pulse8
);
841 INIT_WORK(&pulse8
->irq_work
, pulse8_irq_work_handler
);
842 INIT_WORK(&pulse8
->tx_work
, pulse8_tx_work_handler
);
843 mutex_init(&pulse8
->lock
);
844 spin_lock_init(&pulse8
->msg_lock
);
845 pulse8
->config_pending
= false;
847 err
= serio_open(serio
, drv
);
851 err
= pulse8_setup(pulse8
, serio
, &log_addrs
, &pa
);
855 err
= cec_register_adapter(pulse8
->adap
, &serio
->dev
);
859 pulse8
->dev
= &pulse8
->adap
->devnode
.dev
;
861 if (persistent_config
&& pulse8
->autonomous
) {
862 err
= pulse8_apply_persistent_config(pulse8
, &log_addrs
, pa
);
865 pulse8
->restoring_config
= true;
868 INIT_DELAYED_WORK(&pulse8
->ping_eeprom_work
,
869 pulse8_ping_eeprom_work_handler
);
870 schedule_delayed_work(&pulse8
->ping_eeprom_work
, PING_PERIOD
);
877 cec_delete_adapter(pulse8
->adap
);
878 serio_set_drvdata(serio
, NULL
);
884 static const struct serio_device_id pulse8_serio_ids
[] = {
887 .proto
= SERIO_PULSE8_CEC
,
894 MODULE_DEVICE_TABLE(serio
, pulse8_serio_ids
);
896 static struct serio_driver pulse8_drv
= {
898 .name
= "pulse8-cec",
900 .description
= "Pulse Eight HDMI CEC driver",
901 .id_table
= pulse8_serio_ids
,
902 .interrupt
= pulse8_interrupt
,
903 .connect
= pulse8_connect
,
904 .disconnect
= pulse8_disconnect
,
907 module_serio_driver(pulse8_drv
);