Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Pulse Eight HDMI CEC driver
0004  *
0005  * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
0006  */
0007 
0008 /*
0009  * Notes:
0010  *
0011  * - Devices with firmware version < 2 do not store their configuration in
0012  *   EEPROM.
0013  *
0014  * - In autonomous mode, only messages from a TV will be acknowledged, even
0015  *   polling messages. Upon receiving a message from a TV, the dongle will
0016  *   respond to messages from any logical address.
0017  *
0018  * - In autonomous mode, the dongle will by default reply Feature Abort
0019  *   [Unrecognized Opcode] when it receives Give Device Vendor ID. It will
0020  *   however observe vendor ID's reported by other devices and possibly
0021  *   alter this behavior. When TV's (and TV's only) report that their vendor ID
0022  *   is LG (0x00e091), the dongle will itself reply that it has the same vendor
0023  *   ID, and it will respond to at least one vendor specific command.
0024  *
0025  * - In autonomous mode, the dongle is known to attempt wakeup if it receives
0026  *   <User Control Pressed> ["Power On"], ["Power] or ["Power Toggle"], or if it
0027  *   receives <Set Stream Path> with its own physical address. It also does this
0028  *   if it receives <Vendor Specific Command> [0x03 0x00] from an LG TV.
0029  */
0030 
0031 #include <linux/completion.h>
0032 #include <linux/init.h>
0033 #include <linux/interrupt.h>
0034 #include <linux/kernel.h>
0035 #include <linux/module.h>
0036 #include <linux/workqueue.h>
0037 #include <linux/serio.h>
0038 #include <linux/slab.h>
0039 #include <linux/time.h>
0040 #include <linux/delay.h>
0041 
0042 #include <media/cec.h>
0043 
0044 MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
0045 MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
0046 MODULE_LICENSE("GPL");
0047 
0048 static int debug;
0049 static int persistent_config;
0050 module_param(debug, int, 0644);
0051 module_param(persistent_config, int, 0644);
0052 MODULE_PARM_DESC(debug, "debug level (0-2)");
0053 MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)");
0054 
0055 enum pulse8_msgcodes {
0056     MSGCODE_NOTHING = 0,
0057     MSGCODE_PING,
0058     MSGCODE_TIMEOUT_ERROR,
0059     MSGCODE_HIGH_ERROR,
0060     MSGCODE_LOW_ERROR,
0061     MSGCODE_FRAME_START,
0062     MSGCODE_FRAME_DATA,
0063     MSGCODE_RECEIVE_FAILED,
0064     MSGCODE_COMMAND_ACCEPTED,   /* 0x08 */
0065     MSGCODE_COMMAND_REJECTED,
0066     MSGCODE_SET_ACK_MASK,
0067     MSGCODE_TRANSMIT,
0068     MSGCODE_TRANSMIT_EOM,
0069     MSGCODE_TRANSMIT_IDLETIME,
0070     MSGCODE_TRANSMIT_ACK_POLARITY,
0071     MSGCODE_TRANSMIT_LINE_TIMEOUT,
0072     MSGCODE_TRANSMIT_SUCCEEDED, /* 0x10 */
0073     MSGCODE_TRANSMIT_FAILED_LINE,
0074     MSGCODE_TRANSMIT_FAILED_ACK,
0075     MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA,
0076     MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE,
0077     MSGCODE_FIRMWARE_VERSION,
0078     MSGCODE_START_BOOTLOADER,
0079     MSGCODE_GET_BUILDDATE,
0080     MSGCODE_SET_CONTROLLED,     /* 0x18 */
0081     MSGCODE_GET_AUTO_ENABLED,
0082     MSGCODE_SET_AUTO_ENABLED,
0083     MSGCODE_GET_DEFAULT_LOGICAL_ADDRESS,
0084     MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS,
0085     MSGCODE_GET_LOGICAL_ADDRESS_MASK,
0086     MSGCODE_SET_LOGICAL_ADDRESS_MASK,
0087     MSGCODE_GET_PHYSICAL_ADDRESS,
0088     MSGCODE_SET_PHYSICAL_ADDRESS,   /* 0x20 */
0089     MSGCODE_GET_DEVICE_TYPE,
0090     MSGCODE_SET_DEVICE_TYPE,
0091     MSGCODE_GET_HDMI_VERSION,   /* Removed in FW >= 10 */
0092     MSGCODE_SET_HDMI_VERSION,
0093     MSGCODE_GET_OSD_NAME,
0094     MSGCODE_SET_OSD_NAME,
0095     MSGCODE_WRITE_EEPROM,
0096     MSGCODE_GET_ADAPTER_TYPE,   /* 0x28 */
0097     MSGCODE_SET_ACTIVE_SOURCE,
0098     MSGCODE_GET_AUTO_POWER_ON,  /* New for FW >= 10 */
0099     MSGCODE_SET_AUTO_POWER_ON,
0100 
0101     MSGCODE_FRAME_EOM = 0x80,
0102     MSGCODE_FRAME_ACK = 0x40,
0103 };
0104 
0105 static const char * const pulse8_msgnames[] = {
0106     "NOTHING",
0107     "PING",
0108     "TIMEOUT_ERROR",
0109     "HIGH_ERROR",
0110     "LOW_ERROR",
0111     "FRAME_START",
0112     "FRAME_DATA",
0113     "RECEIVE_FAILED",
0114     "COMMAND_ACCEPTED",
0115     "COMMAND_REJECTED",
0116     "SET_ACK_MASK",
0117     "TRANSMIT",
0118     "TRANSMIT_EOM",
0119     "TRANSMIT_IDLETIME",
0120     "TRANSMIT_ACK_POLARITY",
0121     "TRANSMIT_LINE_TIMEOUT",
0122     "TRANSMIT_SUCCEEDED",
0123     "TRANSMIT_FAILED_LINE",
0124     "TRANSMIT_FAILED_ACK",
0125     "TRANSMIT_FAILED_TIMEOUT_DATA",
0126     "TRANSMIT_FAILED_TIMEOUT_LINE",
0127     "FIRMWARE_VERSION",
0128     "START_BOOTLOADER",
0129     "GET_BUILDDATE",
0130     "SET_CONTROLLED",
0131     "GET_AUTO_ENABLED",
0132     "SET_AUTO_ENABLED",
0133     "GET_DEFAULT_LOGICAL_ADDRESS",
0134     "SET_DEFAULT_LOGICAL_ADDRESS",
0135     "GET_LOGICAL_ADDRESS_MASK",
0136     "SET_LOGICAL_ADDRESS_MASK",
0137     "GET_PHYSICAL_ADDRESS",
0138     "SET_PHYSICAL_ADDRESS",
0139     "GET_DEVICE_TYPE",
0140     "SET_DEVICE_TYPE",
0141     "GET_HDMI_VERSION",
0142     "SET_HDMI_VERSION",
0143     "GET_OSD_NAME",
0144     "SET_OSD_NAME",
0145     "WRITE_EEPROM",
0146     "GET_ADAPTER_TYPE",
0147     "SET_ACTIVE_SOURCE",
0148     "GET_AUTO_POWER_ON",
0149     "SET_AUTO_POWER_ON",
0150 };
0151 
0152 static const char *pulse8_msgname(u8 cmd)
0153 {
0154     static char unknown_msg[5];
0155 
0156     if ((cmd & 0x3f) < ARRAY_SIZE(pulse8_msgnames))
0157         return pulse8_msgnames[cmd & 0x3f];
0158     snprintf(unknown_msg, sizeof(unknown_msg), "0x%02x", cmd);
0159     return unknown_msg;
0160 }
0161 
0162 #define MSGSTART    0xff
0163 #define MSGEND      0xfe
0164 #define MSGESC      0xfd
0165 #define MSGOFFSET   3
0166 
0167 #define DATA_SIZE 256
0168 
0169 #define PING_PERIOD (15 * HZ)
0170 
0171 #define NUM_MSGS 8
0172 
0173 struct pulse8 {
0174     struct device *dev;
0175     struct serio *serio;
0176     struct cec_adapter *adap;
0177     unsigned int vers;
0178 
0179     struct delayed_work ping_eeprom_work;
0180 
0181     struct work_struct irq_work;
0182     struct cec_msg rx_msg[NUM_MSGS];
0183     unsigned int rx_msg_cur_idx, rx_msg_num;
0184     /* protect rx_msg_cur_idx and rx_msg_num */
0185     spinlock_t msg_lock;
0186     u8 new_rx_msg[CEC_MAX_MSG_SIZE];
0187     u8 new_rx_msg_len;
0188 
0189     struct work_struct tx_work;
0190     u32 tx_done_status;
0191     u32 tx_signal_free_time;
0192     struct cec_msg tx_msg;
0193     bool tx_msg_is_bcast;
0194 
0195     struct completion cmd_done;
0196     u8 data[DATA_SIZE];
0197     unsigned int len;
0198     u8 buf[DATA_SIZE];
0199     unsigned int idx;
0200     bool escape;
0201     bool started;
0202 
0203     /* locks access to the adapter */
0204     struct mutex lock;
0205     bool config_pending;
0206     bool restoring_config;
0207     bool autonomous;
0208 };
0209 
0210 static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len)
0211 {
0212     int err = 0;
0213 
0214     err = serio_write(serio, MSGSTART);
0215     if (err)
0216         return err;
0217     for (; !err && cmd_len; command++, cmd_len--) {
0218         if (*command >= MSGESC) {
0219             err = serio_write(serio, MSGESC);
0220             if (!err)
0221                 err = serio_write(serio, *command - MSGOFFSET);
0222         } else {
0223             err = serio_write(serio, *command);
0224         }
0225     }
0226     if (!err)
0227         err = serio_write(serio, MSGEND);
0228 
0229     return err;
0230 }
0231 
0232 static int pulse8_send_and_wait_once(struct pulse8 *pulse8,
0233                      const u8 *cmd, u8 cmd_len,
0234                      u8 response, u8 size)
0235 {
0236     int err;
0237 
0238     if (debug > 1)
0239         dev_info(pulse8->dev, "transmit %s: %*ph\n",
0240              pulse8_msgname(cmd[0]), cmd_len, cmd);
0241     init_completion(&pulse8->cmd_done);
0242 
0243     err = pulse8_send(pulse8->serio, cmd, cmd_len);
0244     if (err)
0245         return err;
0246 
0247     if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
0248         return -ETIMEDOUT;
0249     if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED &&
0250         cmd[0] != MSGCODE_SET_CONTROLLED &&
0251         cmd[0] != MSGCODE_SET_AUTO_ENABLED &&
0252         cmd[0] != MSGCODE_GET_BUILDDATE)
0253         return -ENOTTY;
0254     if (response &&
0255         ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) {
0256         dev_info(pulse8->dev, "transmit %s failed with %s\n",
0257              pulse8_msgname(cmd[0]),
0258              pulse8_msgname(pulse8->data[0]));
0259         return -EIO;
0260     }
0261     return 0;
0262 }
0263 
0264 static int pulse8_send_and_wait(struct pulse8 *pulse8,
0265                 const u8 *cmd, u8 cmd_len, u8 response, u8 size)
0266 {
0267     u8 cmd_sc[2];
0268     int err;
0269 
0270     err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size);
0271     if (err != -ENOTTY)
0272         return err;
0273 
0274     cmd_sc[0] = MSGCODE_SET_CONTROLLED;
0275     cmd_sc[1] = 1;
0276     err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2,
0277                     MSGCODE_COMMAND_ACCEPTED, 1);
0278     if (!err)
0279         err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len,
0280                         response, size);
0281     return err == -ENOTTY ? -EIO : err;
0282 }
0283 
0284 static void pulse8_tx_work_handler(struct work_struct *work)
0285 {
0286     struct pulse8 *pulse8 = container_of(work, struct pulse8, tx_work);
0287     struct cec_msg *msg = &pulse8->tx_msg;
0288     unsigned int i;
0289     u8 cmd[2];
0290     int err;
0291 
0292     if (msg->len == 0)
0293         return;
0294 
0295     mutex_lock(&pulse8->lock);
0296     cmd[0] = MSGCODE_TRANSMIT_IDLETIME;
0297     cmd[1] = pulse8->tx_signal_free_time;
0298     err = pulse8_send_and_wait(pulse8, cmd, 2,
0299                    MSGCODE_COMMAND_ACCEPTED, 1);
0300     cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
0301     cmd[1] = cec_msg_is_broadcast(msg);
0302     pulse8->tx_msg_is_bcast = cec_msg_is_broadcast(msg);
0303     if (!err)
0304         err = pulse8_send_and_wait(pulse8, cmd, 2,
0305                        MSGCODE_COMMAND_ACCEPTED, 1);
0306     cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
0307     cmd[1] = msg->msg[0];
0308     if (!err)
0309         err = pulse8_send_and_wait(pulse8, cmd, 2,
0310                        MSGCODE_COMMAND_ACCEPTED, 1);
0311     if (!err && msg->len > 1) {
0312         for (i = 1; !err && i < msg->len; i++) {
0313             cmd[0] = ((i == msg->len - 1)) ?
0314                 MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
0315             cmd[1] = msg->msg[i];
0316             err = pulse8_send_and_wait(pulse8, cmd, 2,
0317                            MSGCODE_COMMAND_ACCEPTED, 1);
0318         }
0319     }
0320     if (err && debug)
0321         dev_info(pulse8->dev, "%s(0x%02x) failed with error %d for msg %*ph\n",
0322              pulse8_msgname(cmd[0]), cmd[1],
0323              err, msg->len, msg->msg);
0324     msg->len = 0;
0325     mutex_unlock(&pulse8->lock);
0326     if (err)
0327         cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR);
0328 }
0329 
0330 static void pulse8_irq_work_handler(struct work_struct *work)
0331 {
0332     struct pulse8 *pulse8 =
0333         container_of(work, struct pulse8, irq_work);
0334     unsigned long flags;
0335     u32 status;
0336 
0337     spin_lock_irqsave(&pulse8->msg_lock, flags);
0338     while (pulse8->rx_msg_num) {
0339         spin_unlock_irqrestore(&pulse8->msg_lock, flags);
0340         if (debug)
0341             dev_info(pulse8->dev, "adap received %*ph\n",
0342                  pulse8->rx_msg[pulse8->rx_msg_cur_idx].len,
0343                  pulse8->rx_msg[pulse8->rx_msg_cur_idx].msg);
0344         cec_received_msg(pulse8->adap,
0345                  &pulse8->rx_msg[pulse8->rx_msg_cur_idx]);
0346         spin_lock_irqsave(&pulse8->msg_lock, flags);
0347         if (pulse8->rx_msg_num)
0348             pulse8->rx_msg_num--;
0349         pulse8->rx_msg_cur_idx =
0350             (pulse8->rx_msg_cur_idx + 1) % NUM_MSGS;
0351     }
0352     spin_unlock_irqrestore(&pulse8->msg_lock, flags);
0353 
0354     mutex_lock(&pulse8->lock);
0355     status = pulse8->tx_done_status;
0356     pulse8->tx_done_status = 0;
0357     mutex_unlock(&pulse8->lock);
0358     if (status)
0359         cec_transmit_attempt_done(pulse8->adap, status);
0360 }
0361 
0362 static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
0363                     unsigned int flags)
0364 {
0365     struct pulse8 *pulse8 = serio_get_drvdata(serio);
0366     unsigned long irq_flags;
0367     unsigned int idx;
0368 
0369     if (!pulse8->started && data != MSGSTART)
0370         return IRQ_HANDLED;
0371     if (data == MSGESC) {
0372         pulse8->escape = true;
0373         return IRQ_HANDLED;
0374     }
0375     if (pulse8->escape) {
0376         data += MSGOFFSET;
0377         pulse8->escape = false;
0378     } else if (data == MSGEND) {
0379         u8 msgcode = pulse8->buf[0];
0380 
0381         if (debug > 1)
0382             dev_info(pulse8->dev, "received %s: %*ph\n",
0383                  pulse8_msgname(msgcode),
0384                  pulse8->idx, pulse8->buf);
0385         switch (msgcode & 0x3f) {
0386         case MSGCODE_FRAME_START:
0387             /*
0388              * Test if we are receiving a new msg when a previous
0389              * message is still pending.
0390              */
0391             if (!(msgcode & MSGCODE_FRAME_EOM)) {
0392                 pulse8->new_rx_msg_len = 1;
0393                 pulse8->new_rx_msg[0] = pulse8->buf[1];
0394                 break;
0395             }
0396             fallthrough;
0397         case MSGCODE_FRAME_DATA:
0398             if (pulse8->new_rx_msg_len < CEC_MAX_MSG_SIZE)
0399                 pulse8->new_rx_msg[pulse8->new_rx_msg_len++] =
0400                     pulse8->buf[1];
0401             if (!(msgcode & MSGCODE_FRAME_EOM))
0402                 break;
0403 
0404             spin_lock_irqsave(&pulse8->msg_lock, irq_flags);
0405             idx = (pulse8->rx_msg_cur_idx + pulse8->rx_msg_num) %
0406                 NUM_MSGS;
0407             if (pulse8->rx_msg_num == NUM_MSGS) {
0408                 dev_warn(pulse8->dev,
0409                      "message queue is full, dropping %*ph\n",
0410                      pulse8->new_rx_msg_len,
0411                      pulse8->new_rx_msg);
0412                 spin_unlock_irqrestore(&pulse8->msg_lock,
0413                                irq_flags);
0414                 pulse8->new_rx_msg_len = 0;
0415                 break;
0416             }
0417             pulse8->rx_msg_num++;
0418             memcpy(pulse8->rx_msg[idx].msg, pulse8->new_rx_msg,
0419                    pulse8->new_rx_msg_len);
0420             pulse8->rx_msg[idx].len = pulse8->new_rx_msg_len;
0421             spin_unlock_irqrestore(&pulse8->msg_lock, irq_flags);
0422             schedule_work(&pulse8->irq_work);
0423             pulse8->new_rx_msg_len = 0;
0424             break;
0425         case MSGCODE_TRANSMIT_SUCCEEDED:
0426             WARN_ON(pulse8->tx_done_status);
0427             pulse8->tx_done_status = CEC_TX_STATUS_OK;
0428             schedule_work(&pulse8->irq_work);
0429             break;
0430         case MSGCODE_TRANSMIT_FAILED_ACK:
0431             /*
0432              * A NACK for a broadcast message makes no sense, these
0433              * seem to be spurious messages and are skipped.
0434              */
0435             if (pulse8->tx_msg_is_bcast)
0436                 break;
0437             WARN_ON(pulse8->tx_done_status);
0438             pulse8->tx_done_status = CEC_TX_STATUS_NACK;
0439             schedule_work(&pulse8->irq_work);
0440             break;
0441         case MSGCODE_TRANSMIT_FAILED_LINE:
0442         case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
0443         case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
0444             WARN_ON(pulse8->tx_done_status);
0445             pulse8->tx_done_status = CEC_TX_STATUS_ERROR;
0446             schedule_work(&pulse8->irq_work);
0447             break;
0448         case MSGCODE_HIGH_ERROR:
0449         case MSGCODE_LOW_ERROR:
0450         case MSGCODE_RECEIVE_FAILED:
0451         case MSGCODE_TIMEOUT_ERROR:
0452             pulse8->new_rx_msg_len = 0;
0453             break;
0454         case MSGCODE_COMMAND_ACCEPTED:
0455         case MSGCODE_COMMAND_REJECTED:
0456         default:
0457             if (pulse8->idx == 0)
0458                 break;
0459             memcpy(pulse8->data, pulse8->buf, pulse8->idx);
0460             pulse8->len = pulse8->idx;
0461             complete(&pulse8->cmd_done);
0462             break;
0463         }
0464         pulse8->idx = 0;
0465         pulse8->started = false;
0466         return IRQ_HANDLED;
0467     } else if (data == MSGSTART) {
0468         pulse8->idx = 0;
0469         pulse8->started = true;
0470         return IRQ_HANDLED;
0471     }
0472 
0473     if (pulse8->idx >= DATA_SIZE) {
0474         dev_dbg(pulse8->dev,
0475             "throwing away %d bytes of garbage\n", pulse8->idx);
0476         pulse8->idx = 0;
0477     }
0478     pulse8->buf[pulse8->idx++] = data;
0479     return IRQ_HANDLED;
0480 }
0481 
0482 static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
0483 {
0484     struct pulse8 *pulse8 = cec_get_drvdata(adap);
0485     u8 cmd[16];
0486     int err;
0487 
0488     mutex_lock(&pulse8->lock);
0489     cmd[0] = MSGCODE_SET_CONTROLLED;
0490     cmd[1] = enable;
0491     err = pulse8_send_and_wait(pulse8, cmd, 2,
0492                    MSGCODE_COMMAND_ACCEPTED, 1);
0493     if (!enable) {
0494         pulse8->rx_msg_num = 0;
0495         pulse8->tx_done_status = 0;
0496     }
0497     mutex_unlock(&pulse8->lock);
0498     return enable ? err : 0;
0499 }
0500 
0501 static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
0502 {
0503     struct pulse8 *pulse8 = cec_get_drvdata(adap);
0504     u16 mask = 0;
0505     u16 pa = adap->phys_addr;
0506     u8 cmd[16];
0507     int err = 0;
0508 
0509     mutex_lock(&pulse8->lock);
0510     if (log_addr != CEC_LOG_ADDR_INVALID)
0511         mask = 1 << log_addr;
0512     cmd[0] = MSGCODE_SET_ACK_MASK;
0513     cmd[1] = mask >> 8;
0514     cmd[2] = mask & 0xff;
0515     err = pulse8_send_and_wait(pulse8, cmd, 3,
0516                    MSGCODE_COMMAND_ACCEPTED, 0);
0517     if ((err && mask != 0) || pulse8->restoring_config)
0518         goto unlock;
0519 
0520     cmd[0] = MSGCODE_SET_AUTO_ENABLED;
0521     cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1;
0522     err = pulse8_send_and_wait(pulse8, cmd, 2,
0523                    MSGCODE_COMMAND_ACCEPTED, 0);
0524     if (err)
0525         goto unlock;
0526     pulse8->autonomous = cmd[1];
0527     if (log_addr == CEC_LOG_ADDR_INVALID)
0528         goto unlock;
0529 
0530     cmd[0] = MSGCODE_SET_DEVICE_TYPE;
0531     cmd[1] = adap->log_addrs.primary_device_type[0];
0532     err = pulse8_send_and_wait(pulse8, cmd, 2,
0533                    MSGCODE_COMMAND_ACCEPTED, 0);
0534     if (err)
0535         goto unlock;
0536 
0537     switch (adap->log_addrs.primary_device_type[0]) {
0538     case CEC_OP_PRIM_DEVTYPE_TV:
0539         mask = CEC_LOG_ADDR_MASK_TV;
0540         break;
0541     case CEC_OP_PRIM_DEVTYPE_RECORD:
0542         mask = CEC_LOG_ADDR_MASK_RECORD;
0543         break;
0544     case CEC_OP_PRIM_DEVTYPE_TUNER:
0545         mask = CEC_LOG_ADDR_MASK_TUNER;
0546         break;
0547     case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
0548         mask = CEC_LOG_ADDR_MASK_PLAYBACK;
0549         break;
0550     case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
0551         mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM;
0552         break;
0553     case CEC_OP_PRIM_DEVTYPE_SWITCH:
0554         mask = CEC_LOG_ADDR_MASK_UNREGISTERED;
0555         break;
0556     case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
0557         mask = CEC_LOG_ADDR_MASK_SPECIFIC;
0558         break;
0559     default:
0560         mask = 0;
0561         break;
0562     }
0563     cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK;
0564     cmd[1] = mask >> 8;
0565     cmd[2] = mask & 0xff;
0566     err = pulse8_send_and_wait(pulse8, cmd, 3,
0567                    MSGCODE_COMMAND_ACCEPTED, 0);
0568     if (err)
0569         goto unlock;
0570 
0571     cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS;
0572     cmd[1] = log_addr;
0573     err = pulse8_send_and_wait(pulse8, cmd, 2,
0574                    MSGCODE_COMMAND_ACCEPTED, 0);
0575     if (err)
0576         goto unlock;
0577 
0578     cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS;
0579     cmd[1] = pa >> 8;
0580     cmd[2] = pa & 0xff;
0581     err = pulse8_send_and_wait(pulse8, cmd, 3,
0582                    MSGCODE_COMMAND_ACCEPTED, 0);
0583     if (err)
0584         goto unlock;
0585 
0586     if (pulse8->vers < 10) {
0587         cmd[0] = MSGCODE_SET_HDMI_VERSION;
0588         cmd[1] = adap->log_addrs.cec_version;
0589         err = pulse8_send_and_wait(pulse8, cmd, 2,
0590                        MSGCODE_COMMAND_ACCEPTED, 0);
0591         if (err)
0592             goto unlock;
0593     }
0594 
0595     if (adap->log_addrs.osd_name[0]) {
0596         size_t osd_len = strlen(adap->log_addrs.osd_name);
0597         char *osd_str = cmd + 1;
0598 
0599         cmd[0] = MSGCODE_SET_OSD_NAME;
0600         strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1);
0601         if (osd_len < 4) {
0602             memset(osd_str + osd_len, ' ', 4 - osd_len);
0603             osd_len = 4;
0604             osd_str[osd_len] = '\0';
0605             strscpy(adap->log_addrs.osd_name, osd_str,
0606                 sizeof(adap->log_addrs.osd_name));
0607         }
0608         err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len,
0609                        MSGCODE_COMMAND_ACCEPTED, 0);
0610         if (err)
0611             goto unlock;
0612     }
0613 
0614 unlock:
0615     if (pulse8->restoring_config)
0616         pulse8->restoring_config = false;
0617     else
0618         pulse8->config_pending = true;
0619     mutex_unlock(&pulse8->lock);
0620     return log_addr == CEC_LOG_ADDR_INVALID ? 0 : err;
0621 }
0622 
0623 static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
0624                     u32 signal_free_time, struct cec_msg *msg)
0625 {
0626     struct pulse8 *pulse8 = cec_get_drvdata(adap);
0627 
0628     pulse8->tx_msg = *msg;
0629     if (debug)
0630         dev_info(pulse8->dev, "adap transmit %*ph\n",
0631              msg->len, msg->msg);
0632     pulse8->tx_signal_free_time = signal_free_time;
0633     schedule_work(&pulse8->tx_work);
0634     return 0;
0635 }
0636 
0637 static void pulse8_cec_adap_free(struct cec_adapter *adap)
0638 {
0639     struct pulse8 *pulse8 = cec_get_drvdata(adap);
0640 
0641     cancel_delayed_work_sync(&pulse8->ping_eeprom_work);
0642     cancel_work_sync(&pulse8->irq_work);
0643     cancel_work_sync(&pulse8->tx_work);
0644     kfree(pulse8);
0645 }
0646 
0647 static const struct cec_adap_ops pulse8_cec_adap_ops = {
0648     .adap_enable = pulse8_cec_adap_enable,
0649     .adap_log_addr = pulse8_cec_adap_log_addr,
0650     .adap_transmit = pulse8_cec_adap_transmit,
0651     .adap_free = pulse8_cec_adap_free,
0652 };
0653 
0654 static void pulse8_disconnect(struct serio *serio)
0655 {
0656     struct pulse8 *pulse8 = serio_get_drvdata(serio);
0657 
0658     cec_unregister_adapter(pulse8->adap);
0659     serio_set_drvdata(serio, NULL);
0660     serio_close(serio);
0661 }
0662 
0663 static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
0664             struct cec_log_addrs *log_addrs, u16 *pa)
0665 {
0666     u8 *data = pulse8->data + 1;
0667     u8 cmd[2];
0668     int err;
0669     time64_t date;
0670 
0671     pulse8->vers = 0;
0672 
0673     cmd[0] = MSGCODE_FIRMWARE_VERSION;
0674     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
0675     if (err)
0676         return err;
0677     pulse8->vers = (data[0] << 8) | data[1];
0678     dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers);
0679     if (pulse8->vers < 2) {
0680         *pa = CEC_PHYS_ADDR_INVALID;
0681         return 0;
0682     }
0683 
0684     cmd[0] = MSGCODE_GET_BUILDDATE;
0685     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4);
0686     if (err)
0687         return err;
0688     date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
0689     dev_info(pulse8->dev, "Firmware build date %ptT\n", &date);
0690 
0691     dev_dbg(pulse8->dev, "Persistent config:\n");
0692     cmd[0] = MSGCODE_GET_AUTO_ENABLED;
0693     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
0694     if (err)
0695         return err;
0696     pulse8->autonomous = data[0];
0697     dev_dbg(pulse8->dev, "Autonomous mode: %s",
0698         data[0] ? "on" : "off");
0699 
0700     if (pulse8->vers >= 10) {
0701         cmd[0] = MSGCODE_GET_AUTO_POWER_ON;
0702         err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
0703         if (!err)
0704             dev_dbg(pulse8->dev, "Auto Power On: %s",
0705                 data[0] ? "on" : "off");
0706     }
0707 
0708     cmd[0] = MSGCODE_GET_DEVICE_TYPE;
0709     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
0710     if (err)
0711         return err;
0712     log_addrs->primary_device_type[0] = data[0];
0713     dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]);
0714     switch (log_addrs->primary_device_type[0]) {
0715     case CEC_OP_PRIM_DEVTYPE_TV:
0716         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV;
0717         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV;
0718         break;
0719     case CEC_OP_PRIM_DEVTYPE_RECORD:
0720         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD;
0721         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD;
0722         break;
0723     case CEC_OP_PRIM_DEVTYPE_TUNER:
0724         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER;
0725         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER;
0726         break;
0727     case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
0728         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
0729         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK;
0730         break;
0731     case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
0732         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
0733         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
0734         break;
0735     case CEC_OP_PRIM_DEVTYPE_SWITCH:
0736         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
0737         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
0738         break;
0739     case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
0740         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC;
0741         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
0742         break;
0743     default:
0744         log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
0745         log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
0746         dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n",
0747              log_addrs->primary_device_type[0]);
0748         break;
0749     }
0750 
0751     cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK;
0752     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
0753     if (err)
0754         return err;
0755     log_addrs->log_addr_mask = (data[0] << 8) | data[1];
0756     dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n",
0757         log_addrs->log_addr_mask);
0758     if (log_addrs->log_addr_mask)
0759         log_addrs->num_log_addrs = 1;
0760 
0761     cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS;
0762     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
0763     if (err)
0764         return err;
0765     *pa = (data[0] << 8) | data[1];
0766     dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n",
0767         cec_phys_addr_exp(*pa));
0768 
0769     log_addrs->cec_version = CEC_OP_CEC_VERSION_1_4;
0770     if (pulse8->vers < 10) {
0771         cmd[0] = MSGCODE_GET_HDMI_VERSION;
0772         err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
0773         if (err)
0774             return err;
0775         log_addrs->cec_version = data[0];
0776         dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version);
0777     }
0778 
0779     cmd[0] = MSGCODE_GET_OSD_NAME;
0780     err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0);
0781     if (err)
0782         return err;
0783     strscpy(log_addrs->osd_name, data, sizeof(log_addrs->osd_name));
0784     dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name);
0785 
0786     return 0;
0787 }
0788 
0789 static int pulse8_apply_persistent_config(struct pulse8 *pulse8,
0790                       struct cec_log_addrs *log_addrs,
0791                       u16 pa)
0792 {
0793     int err;
0794 
0795     err = cec_s_log_addrs(pulse8->adap, log_addrs, false);
0796     if (err)
0797         return err;
0798 
0799     cec_s_phys_addr(pulse8->adap, pa, false);
0800 
0801     return 0;
0802 }
0803 
0804 static void pulse8_ping_eeprom_work_handler(struct work_struct *work)
0805 {
0806     struct pulse8 *pulse8 =
0807         container_of(work, struct pulse8, ping_eeprom_work.work);
0808     u8 cmd;
0809 
0810     mutex_lock(&pulse8->lock);
0811     cmd = MSGCODE_PING;
0812     pulse8_send_and_wait(pulse8, &cmd, 1,
0813                  MSGCODE_COMMAND_ACCEPTED, 0);
0814 
0815     if (pulse8->vers < 2)
0816         goto unlock;
0817 
0818     if (pulse8->config_pending && persistent_config) {
0819         dev_dbg(pulse8->dev, "writing pending config to EEPROM\n");
0820         cmd = MSGCODE_WRITE_EEPROM;
0821         if (pulse8_send_and_wait(pulse8, &cmd, 1,
0822                      MSGCODE_COMMAND_ACCEPTED, 0))
0823             dev_info(pulse8->dev, "failed to write pending config to EEPROM\n");
0824         else
0825             pulse8->config_pending = false;
0826     }
0827 unlock:
0828     schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
0829     mutex_unlock(&pulse8->lock);
0830 }
0831 
0832 static int pulse8_connect(struct serio *serio, struct serio_driver *drv)
0833 {
0834     u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
0835     struct pulse8 *pulse8;
0836     int err = -ENOMEM;
0837     struct cec_log_addrs log_addrs = {};
0838     u16 pa = CEC_PHYS_ADDR_INVALID;
0839 
0840     pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL);
0841 
0842     if (!pulse8)
0843         return -ENOMEM;
0844 
0845     pulse8->serio = serio;
0846     pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8,
0847                         dev_name(&serio->dev), caps, 1);
0848     err = PTR_ERR_OR_ZERO(pulse8->adap);
0849     if (err < 0) {
0850         kfree(pulse8);
0851         return err;
0852     }
0853 
0854     pulse8->dev = &serio->dev;
0855     serio_set_drvdata(serio, pulse8);
0856     INIT_WORK(&pulse8->irq_work, pulse8_irq_work_handler);
0857     INIT_WORK(&pulse8->tx_work, pulse8_tx_work_handler);
0858     INIT_DELAYED_WORK(&pulse8->ping_eeprom_work,
0859               pulse8_ping_eeprom_work_handler);
0860     mutex_init(&pulse8->lock);
0861     spin_lock_init(&pulse8->msg_lock);
0862     pulse8->config_pending = false;
0863 
0864     err = serio_open(serio, drv);
0865     if (err)
0866         goto delete_adap;
0867 
0868     err = pulse8_setup(pulse8, serio, &log_addrs, &pa);
0869     if (err)
0870         goto close_serio;
0871 
0872     err = cec_register_adapter(pulse8->adap, &serio->dev);
0873     if (err < 0)
0874         goto close_serio;
0875 
0876     pulse8->dev = &pulse8->adap->devnode.dev;
0877 
0878     if (persistent_config && pulse8->autonomous) {
0879         err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa);
0880         if (err)
0881             goto close_serio;
0882         pulse8->restoring_config = true;
0883     }
0884 
0885     schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
0886 
0887     return 0;
0888 
0889 close_serio:
0890     pulse8->serio = NULL;
0891     serio_set_drvdata(serio, NULL);
0892     serio_close(serio);
0893 delete_adap:
0894     cec_delete_adapter(pulse8->adap);
0895     return err;
0896 }
0897 
0898 static const struct serio_device_id pulse8_serio_ids[] = {
0899     {
0900         .type   = SERIO_RS232,
0901         .proto  = SERIO_PULSE8_CEC,
0902         .id = SERIO_ANY,
0903         .extra  = SERIO_ANY,
0904     },
0905     { 0 }
0906 };
0907 
0908 MODULE_DEVICE_TABLE(serio, pulse8_serio_ids);
0909 
0910 static struct serio_driver pulse8_drv = {
0911     .driver     = {
0912         .name   = "pulse8-cec",
0913     },
0914     .description    = "Pulse Eight HDMI CEC driver",
0915     .id_table   = pulse8_serio_ids,
0916     .interrupt  = pulse8_interrupt,
0917     .connect    = pulse8_connect,
0918     .disconnect = pulse8_disconnect,
0919 };
0920 
0921 module_serio_driver(pulse8_drv);