linux/drivers/media/cec/usb/pulse8/pulse8-cec.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Pulse Eight HDMI CEC driver
   4 *
   5 * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
   6 */
   7
   8/*
   9 * Notes:
  10 *
  11 * - Devices with firmware version < 2 do not store their configuration in
  12 *   EEPROM.
  13 *
  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.
  17 *
  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.
  24 *
  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.
  29 */
  30
  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>
  41
  42#include <media/cec.h>
  43
  44MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
  45MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
  46MODULE_LICENSE("GPL");
  47
  48static int debug;
  49static int persistent_config;
  50module_param(debug, int, 0644);
  51module_param(persistent_config, int, 0644);
  52MODULE_PARM_DESC(debug, "debug level (0-2)");
  53MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)");
  54
  55enum pulse8_msgcodes {
  56        MSGCODE_NOTHING = 0,
  57        MSGCODE_PING,
  58        MSGCODE_TIMEOUT_ERROR,
  59        MSGCODE_HIGH_ERROR,
  60        MSGCODE_LOW_ERROR,
  61        MSGCODE_FRAME_START,
  62        MSGCODE_FRAME_DATA,
  63        MSGCODE_RECEIVE_FAILED,
  64        MSGCODE_COMMAND_ACCEPTED,       /* 0x08 */
  65        MSGCODE_COMMAND_REJECTED,
  66        MSGCODE_SET_ACK_MASK,
  67        MSGCODE_TRANSMIT,
  68        MSGCODE_TRANSMIT_EOM,
  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,       /* Removed in FW >= 10 */
  92        MSGCODE_SET_HDMI_VERSION,
  93        MSGCODE_GET_OSD_NAME,
  94        MSGCODE_SET_OSD_NAME,
  95        MSGCODE_WRITE_EEPROM,
  96        MSGCODE_GET_ADAPTER_TYPE,       /* 0x28 */
  97        MSGCODE_SET_ACTIVE_SOURCE,
  98        MSGCODE_GET_AUTO_POWER_ON,      /* New for FW >= 10 */
  99        MSGCODE_SET_AUTO_POWER_ON,
 100
 101        MSGCODE_FRAME_EOM = 0x80,
 102        MSGCODE_FRAME_ACK = 0x40,
 103};
 104
 105static const char * const pulse8_msgnames[] = {
 106        "NOTHING",
 107        "PING",
 108        "TIMEOUT_ERROR",
 109        "HIGH_ERROR",
 110        "LOW_ERROR",
 111        "FRAME_START",
 112        "FRAME_DATA",
 113        "RECEIVE_FAILED",
 114        "COMMAND_ACCEPTED",
 115        "COMMAND_REJECTED",
 116        "SET_ACK_MASK",
 117        "TRANSMIT",
 118        "TRANSMIT_EOM",
 119        "TRANSMIT_IDLETIME",
 120        "TRANSMIT_ACK_POLARITY",
 121        "TRANSMIT_LINE_TIMEOUT",
 122        "TRANSMIT_SUCCEEDED",
 123        "TRANSMIT_FAILED_LINE",
 124        "TRANSMIT_FAILED_ACK",
 125        "TRANSMIT_FAILED_TIMEOUT_DATA",
 126        "TRANSMIT_FAILED_TIMEOUT_LINE",
 127        "FIRMWARE_VERSION",
 128        "START_BOOTLOADER",
 129        "GET_BUILDDATE",
 130        "SET_CONTROLLED",
 131        "GET_AUTO_ENABLED",
 132        "SET_AUTO_ENABLED",
 133        "GET_DEFAULT_LOGICAL_ADDRESS",
 134        "SET_DEFAULT_LOGICAL_ADDRESS",
 135        "GET_LOGICAL_ADDRESS_MASK",
 136        "SET_LOGICAL_ADDRESS_MASK",
 137        "GET_PHYSICAL_ADDRESS",
 138        "SET_PHYSICAL_ADDRESS",
 139        "GET_DEVICE_TYPE",
 140        "SET_DEVICE_TYPE",
 141        "GET_HDMI_VERSION",
 142        "SET_HDMI_VERSION",
 143        "GET_OSD_NAME",
 144        "SET_OSD_NAME",
 145        "WRITE_EEPROM",
 146        "GET_ADAPTER_TYPE",
 147        "SET_ACTIVE_SOURCE",
 148        "GET_AUTO_POWER_ON",
 149        "SET_AUTO_POWER_ON",
 150};
 151
 152static const char *pulse8_msgname(u8 cmd)
 153{
 154        static char unknown_msg[5];
 155
 156        if ((cmd & 0x3f) < ARRAY_SIZE(pulse8_msgnames))
 157                return pulse8_msgnames[cmd & 0x3f];
 158        snprintf(unknown_msg, sizeof(unknown_msg), "0x%02x", cmd);
 159        return unknown_msg;
 160}
 161
 162#define MSGSTART        0xff
 163#define MSGEND          0xfe
 164#define MSGESC          0xfd
 165#define MSGOFFSET       3
 166
 167#define DATA_SIZE 256
 168
 169#define PING_PERIOD     (15 * HZ)
 170
 171#define NUM_MSGS 8
 172
 173struct pulse8 {
 174        struct device *dev;
 175        struct serio *serio;
 176        struct cec_adapter *adap;
 177        unsigned int vers;
 178
 179        struct delayed_work ping_eeprom_work;
 180
 181        struct work_struct irq_work;
 182        struct cec_msg rx_msg[NUM_MSGS];
 183        unsigned int rx_msg_cur_idx, rx_msg_num;
 184        /* protect rx_msg_cur_idx and rx_msg_num */
 185        spinlock_t msg_lock;
 186        u8 new_rx_msg[CEC_MAX_MSG_SIZE];
 187        u8 new_rx_msg_len;
 188
 189        struct work_struct tx_work;
 190        u32 tx_done_status;
 191        u32 tx_signal_free_time;
 192        struct cec_msg tx_msg;
 193        bool tx_msg_is_bcast;
 194
 195        struct completion cmd_done;
 196        u8 data[DATA_SIZE];
 197        unsigned int len;
 198        u8 buf[DATA_SIZE];
 199        unsigned int idx;
 200        bool escape;
 201        bool started;
 202
 203        /* locks access to the adapter */
 204        struct mutex lock;
 205        bool config_pending;
 206        bool restoring_config;
 207        bool autonomous;
 208};
 209
 210static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len)
 211{
 212        int err = 0;
 213
 214        err = serio_write(serio, MSGSTART);
 215        if (err)
 216                return err;
 217        for (; !err && cmd_len; command++, cmd_len--) {
 218                if (*command >= MSGESC) {
 219                        err = serio_write(serio, MSGESC);
 220                        if (!err)
 221                                err = serio_write(serio, *command - MSGOFFSET);
 222                } else {
 223                        err = serio_write(serio, *command);
 224                }
 225        }
 226        if (!err)
 227                err = serio_write(serio, MSGEND);
 228
 229        return err;
 230}
 231
 232static int pulse8_send_and_wait_once(struct pulse8 *pulse8,
 233                                     const u8 *cmd, u8 cmd_len,
 234                                     u8 response, u8 size)
 235{
 236        int err;
 237
 238        if (debug > 1)
 239                dev_info(pulse8->dev, "transmit %s: %*ph\n",
 240                         pulse8_msgname(cmd[0]), cmd_len, cmd);
 241        init_completion(&pulse8->cmd_done);
 242
 243        err = pulse8_send(pulse8->serio, cmd, cmd_len);
 244        if (err)
 245                return err;
 246
 247        if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ))
 248                return -ETIMEDOUT;
 249        if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED &&
 250            cmd[0] != MSGCODE_SET_CONTROLLED &&
 251            cmd[0] != MSGCODE_SET_AUTO_ENABLED &&
 252            cmd[0] != MSGCODE_GET_BUILDDATE)
 253                return -ENOTTY;
 254        if (response &&
 255            ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) {
 256                dev_info(pulse8->dev, "transmit %s failed with %s\n",
 257                         pulse8_msgname(cmd[0]),
 258                         pulse8_msgname(pulse8->data[0]));
 259                return -EIO;
 260        }
 261        return 0;
 262}
 263
 264static int pulse8_send_and_wait(struct pulse8 *pulse8,
 265                                const u8 *cmd, u8 cmd_len, u8 response, u8 size)
 266{
 267        u8 cmd_sc[2];
 268        int err;
 269
 270        err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size);
 271        if (err != -ENOTTY)
 272                return err;
 273
 274        cmd_sc[0] = MSGCODE_SET_CONTROLLED;
 275        cmd_sc[1] = 1;
 276        err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2,
 277                                        MSGCODE_COMMAND_ACCEPTED, 1);
 278        if (!err)
 279                err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len,
 280                                                response, size);
 281        return err == -ENOTTY ? -EIO : err;
 282}
 283
 284static void pulse8_tx_work_handler(struct work_struct *work)
 285{
 286        struct pulse8 *pulse8 = container_of(work, struct pulse8, tx_work);
 287        struct cec_msg *msg = &pulse8->tx_msg;
 288        unsigned int i;
 289        u8 cmd[2];
 290        int err;
 291
 292        if (msg->len == 0)
 293                return;
 294
 295        mutex_lock(&pulse8->lock);
 296        cmd[0] = MSGCODE_TRANSMIT_IDLETIME;
 297        cmd[1] = pulse8->tx_signal_free_time;
 298        err = pulse8_send_and_wait(pulse8, cmd, 2,
 299                                   MSGCODE_COMMAND_ACCEPTED, 1);
 300        cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY;
 301        cmd[1] = cec_msg_is_broadcast(msg);
 302        pulse8->tx_msg_is_bcast = cec_msg_is_broadcast(msg);
 303        if (!err)
 304                err = pulse8_send_and_wait(pulse8, cmd, 2,
 305                                           MSGCODE_COMMAND_ACCEPTED, 1);
 306        cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
 307        cmd[1] = msg->msg[0];
 308        if (!err)
 309                err = pulse8_send_and_wait(pulse8, cmd, 2,
 310                                           MSGCODE_COMMAND_ACCEPTED, 1);
 311        if (!err && msg->len > 1) {
 312                for (i = 1; !err && i < msg->len; i++) {
 313                        cmd[0] = ((i == msg->len - 1)) ?
 314                                MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT;
 315                        cmd[1] = msg->msg[i];
 316                        err = pulse8_send_and_wait(pulse8, cmd, 2,
 317                                                   MSGCODE_COMMAND_ACCEPTED, 1);
 318                }
 319        }
 320        if (err && debug)
 321                dev_info(pulse8->dev, "%s(0x%02x) failed with error %d for msg %*ph\n",
 322                         pulse8_msgname(cmd[0]), cmd[1],
 323                         err, msg->len, msg->msg);
 324        msg->len = 0;
 325        mutex_unlock(&pulse8->lock);
 326        if (err)
 327                cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR);
 328}
 329
 330static void pulse8_irq_work_handler(struct work_struct *work)
 331{
 332        struct pulse8 *pulse8 =
 333                container_of(work, struct pulse8, irq_work);
 334        unsigned long flags;
 335        u32 status;
 336
 337        spin_lock_irqsave(&pulse8->msg_lock, flags);
 338        while (pulse8->rx_msg_num) {
 339                spin_unlock_irqrestore(&pulse8->msg_lock, flags);
 340                if (debug)
 341                        dev_info(pulse8->dev, "adap received %*ph\n",
 342                                 pulse8->rx_msg[pulse8->rx_msg_cur_idx].len,
 343                                 pulse8->rx_msg[pulse8->rx_msg_cur_idx].msg);
 344                cec_received_msg(pulse8->adap,
 345                                 &pulse8->rx_msg[pulse8->rx_msg_cur_idx]);
 346                spin_lock_irqsave(&pulse8->msg_lock, flags);
 347                if (pulse8->rx_msg_num)
 348                        pulse8->rx_msg_num--;
 349                pulse8->rx_msg_cur_idx =
 350                        (pulse8->rx_msg_cur_idx + 1) % NUM_MSGS;
 351        }
 352        spin_unlock_irqrestore(&pulse8->msg_lock, flags);
 353
 354        mutex_lock(&pulse8->lock);
 355        status = pulse8->tx_done_status;
 356        pulse8->tx_done_status = 0;
 357        mutex_unlock(&pulse8->lock);
 358        if (status)
 359                cec_transmit_attempt_done(pulse8->adap, status);
 360}
 361
 362static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data,
 363                                    unsigned int flags)
 364{
 365        struct pulse8 *pulse8 = serio_get_drvdata(serio);
 366        unsigned long irq_flags;
 367        unsigned int idx;
 368
 369        if (!pulse8->started && data != MSGSTART)
 370                return IRQ_HANDLED;
 371        if (data == MSGESC) {
 372                pulse8->escape = true;
 373                return IRQ_HANDLED;
 374        }
 375        if (pulse8->escape) {
 376                data += MSGOFFSET;
 377                pulse8->escape = false;
 378        } else if (data == MSGEND) {
 379                u8 msgcode = pulse8->buf[0];
 380
 381                if (debug > 1)
 382                        dev_info(pulse8->dev, "received %s: %*ph\n",
 383                                 pulse8_msgname(msgcode),
 384                                 pulse8->idx, pulse8->buf);
 385                switch (msgcode & 0x3f) {
 386                case MSGCODE_FRAME_START:
 387                        /*
 388                         * Test if we are receiving a new msg when a previous
 389                         * message is still pending.
 390                         */
 391                        if (!(msgcode & MSGCODE_FRAME_EOM)) {
 392                                pulse8->new_rx_msg_len = 1;
 393                                pulse8->new_rx_msg[0] = pulse8->buf[1];
 394                                break;
 395                        }
 396                        fallthrough;
 397                case MSGCODE_FRAME_DATA:
 398                        if (pulse8->new_rx_msg_len < CEC_MAX_MSG_SIZE)
 399                                pulse8->new_rx_msg[pulse8->new_rx_msg_len++] =
 400                                        pulse8->buf[1];
 401                        if (!(msgcode & MSGCODE_FRAME_EOM))
 402                                break;
 403
 404                        spin_lock_irqsave(&pulse8->msg_lock, irq_flags);
 405                        idx = (pulse8->rx_msg_cur_idx + pulse8->rx_msg_num) %
 406                                NUM_MSGS;
 407                        if (pulse8->rx_msg_num == NUM_MSGS) {
 408                                dev_warn(pulse8->dev,
 409                                         "message queue is full, dropping %*ph\n",
 410                                         pulse8->new_rx_msg_len,
 411                                         pulse8->new_rx_msg);
 412                                spin_unlock_irqrestore(&pulse8->msg_lock,
 413                                                       irq_flags);
 414                                pulse8->new_rx_msg_len = 0;
 415                                break;
 416                        }
 417                        pulse8->rx_msg_num++;
 418                        memcpy(pulse8->rx_msg[idx].msg, pulse8->new_rx_msg,
 419                               pulse8->new_rx_msg_len);
 420                        pulse8->rx_msg[idx].len = pulse8->new_rx_msg_len;
 421                        spin_unlock_irqrestore(&pulse8->msg_lock, irq_flags);
 422                        schedule_work(&pulse8->irq_work);
 423                        pulse8->new_rx_msg_len = 0;
 424                        break;
 425                case MSGCODE_TRANSMIT_SUCCEEDED:
 426                        WARN_ON(pulse8->tx_done_status);
 427                        pulse8->tx_done_status = CEC_TX_STATUS_OK;
 428                        schedule_work(&pulse8->irq_work);
 429                        break;
 430                case MSGCODE_TRANSMIT_FAILED_ACK:
 431                        /*
 432                         * A NACK for a broadcast message makes no sense, these
 433                         * seem to be spurious messages and are skipped.
 434                         */
 435                        if (pulse8->tx_msg_is_bcast)
 436                                break;
 437                        WARN_ON(pulse8->tx_done_status);
 438                        pulse8->tx_done_status = CEC_TX_STATUS_NACK;
 439                        schedule_work(&pulse8->irq_work);
 440                        break;
 441                case MSGCODE_TRANSMIT_FAILED_LINE:
 442                case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA:
 443                case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE:
 444                        WARN_ON(pulse8->tx_done_status);
 445                        pulse8->tx_done_status = CEC_TX_STATUS_ERROR;
 446                        schedule_work(&pulse8->irq_work);
 447                        break;
 448                case MSGCODE_HIGH_ERROR:
 449                case MSGCODE_LOW_ERROR:
 450                case MSGCODE_RECEIVE_FAILED:
 451                case MSGCODE_TIMEOUT_ERROR:
 452                        pulse8->new_rx_msg_len = 0;
 453                        break;
 454                case MSGCODE_COMMAND_ACCEPTED:
 455                case MSGCODE_COMMAND_REJECTED:
 456                default:
 457                        if (pulse8->idx == 0)
 458                                break;
 459                        memcpy(pulse8->data, pulse8->buf, pulse8->idx);
 460                        pulse8->len = pulse8->idx;
 461                        complete(&pulse8->cmd_done);
 462                        break;
 463                }
 464                pulse8->idx = 0;
 465                pulse8->started = false;
 466                return IRQ_HANDLED;
 467        } else if (data == MSGSTART) {
 468                pulse8->idx = 0;
 469                pulse8->started = true;
 470                return IRQ_HANDLED;
 471        }
 472
 473        if (pulse8->idx >= DATA_SIZE) {
 474                dev_dbg(pulse8->dev,
 475                        "throwing away %d bytes of garbage\n", pulse8->idx);
 476                pulse8->idx = 0;
 477        }
 478        pulse8->buf[pulse8->idx++] = data;
 479        return IRQ_HANDLED;
 480}
 481
 482static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable)
 483{
 484        struct pulse8 *pulse8 = cec_get_drvdata(adap);
 485        u8 cmd[16];
 486        int err;
 487
 488        mutex_lock(&pulse8->lock);
 489        cmd[0] = MSGCODE_SET_CONTROLLED;
 490        cmd[1] = enable;
 491        err = pulse8_send_and_wait(pulse8, cmd, 2,
 492                                   MSGCODE_COMMAND_ACCEPTED, 1);
 493        if (!enable) {
 494                pulse8->rx_msg_num = 0;
 495                pulse8->tx_done_status = 0;
 496        }
 497        mutex_unlock(&pulse8->lock);
 498        return enable ? err : 0;
 499}
 500
 501static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
 502{
 503        struct pulse8 *pulse8 = cec_get_drvdata(adap);
 504        u16 mask = 0;
 505        u16 pa = adap->phys_addr;
 506        u8 cmd[16];
 507        int err = 0;
 508
 509        mutex_lock(&pulse8->lock);
 510        if (log_addr != CEC_LOG_ADDR_INVALID)
 511                mask = 1 << log_addr;
 512        cmd[0] = MSGCODE_SET_ACK_MASK;
 513        cmd[1] = mask >> 8;
 514        cmd[2] = mask & 0xff;
 515        err = pulse8_send_and_wait(pulse8, cmd, 3,
 516                                   MSGCODE_COMMAND_ACCEPTED, 0);
 517        if ((err && mask != 0) || pulse8->restoring_config)
 518                goto unlock;
 519
 520        cmd[0] = MSGCODE_SET_AUTO_ENABLED;
 521        cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1;
 522        err = pulse8_send_and_wait(pulse8, cmd, 2,
 523                                   MSGCODE_COMMAND_ACCEPTED, 0);
 524        if (err)
 525                goto unlock;
 526        pulse8->autonomous = cmd[1];
 527        if (log_addr == CEC_LOG_ADDR_INVALID)
 528                goto unlock;
 529
 530        cmd[0] = MSGCODE_SET_DEVICE_TYPE;
 531        cmd[1] = adap->log_addrs.primary_device_type[0];
 532        err = pulse8_send_and_wait(pulse8, cmd, 2,
 533                                   MSGCODE_COMMAND_ACCEPTED, 0);
 534        if (err)
 535                goto unlock;
 536
 537        switch (adap->log_addrs.primary_device_type[0]) {
 538        case CEC_OP_PRIM_DEVTYPE_TV:
 539                mask = CEC_LOG_ADDR_MASK_TV;
 540                break;
 541        case CEC_OP_PRIM_DEVTYPE_RECORD:
 542                mask = CEC_LOG_ADDR_MASK_RECORD;
 543                break;
 544        case CEC_OP_PRIM_DEVTYPE_TUNER:
 545                mask = CEC_LOG_ADDR_MASK_TUNER;
 546                break;
 547        case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
 548                mask = CEC_LOG_ADDR_MASK_PLAYBACK;
 549                break;
 550        case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
 551                mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM;
 552                break;
 553        case CEC_OP_PRIM_DEVTYPE_SWITCH:
 554                mask = CEC_LOG_ADDR_MASK_UNREGISTERED;
 555                break;
 556        case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
 557                mask = CEC_LOG_ADDR_MASK_SPECIFIC;
 558                break;
 559        default:
 560                mask = 0;
 561                break;
 562        }
 563        cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK;
 564        cmd[1] = mask >> 8;
 565        cmd[2] = mask & 0xff;
 566        err = pulse8_send_and_wait(pulse8, cmd, 3,
 567                                   MSGCODE_COMMAND_ACCEPTED, 0);
 568        if (err)
 569                goto unlock;
 570
 571        cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS;
 572        cmd[1] = log_addr;
 573        err = pulse8_send_and_wait(pulse8, cmd, 2,
 574                                   MSGCODE_COMMAND_ACCEPTED, 0);
 575        if (err)
 576                goto unlock;
 577
 578        cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS;
 579        cmd[1] = pa >> 8;
 580        cmd[2] = pa & 0xff;
 581        err = pulse8_send_and_wait(pulse8, cmd, 3,
 582                                   MSGCODE_COMMAND_ACCEPTED, 0);
 583        if (err)
 584                goto unlock;
 585
 586        if (pulse8->vers < 10) {
 587                cmd[0] = MSGCODE_SET_HDMI_VERSION;
 588                cmd[1] = adap->log_addrs.cec_version;
 589                err = pulse8_send_and_wait(pulse8, cmd, 2,
 590                                           MSGCODE_COMMAND_ACCEPTED, 0);
 591                if (err)
 592                        goto unlock;
 593        }
 594
 595        if (adap->log_addrs.osd_name[0]) {
 596                size_t osd_len = strlen(adap->log_addrs.osd_name);
 597                char *osd_str = cmd + 1;
 598
 599                cmd[0] = MSGCODE_SET_OSD_NAME;
 600                strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1);
 601                if (osd_len < 4) {
 602                        memset(osd_str + osd_len, ' ', 4 - osd_len);
 603                        osd_len = 4;
 604                        osd_str[osd_len] = '\0';
 605                        strscpy(adap->log_addrs.osd_name, osd_str,
 606                                sizeof(adap->log_addrs.osd_name));
 607                }
 608                err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len,
 609                                           MSGCODE_COMMAND_ACCEPTED, 0);
 610                if (err)
 611                        goto unlock;
 612        }
 613
 614unlock:
 615        if (pulse8->restoring_config)
 616                pulse8->restoring_config = false;
 617        else
 618                pulse8->config_pending = true;
 619        mutex_unlock(&pulse8->lock);
 620        return log_addr == CEC_LOG_ADDR_INVALID ? 0 : err;
 621}
 622
 623static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
 624                                    u32 signal_free_time, struct cec_msg *msg)
 625{
 626        struct pulse8 *pulse8 = cec_get_drvdata(adap);
 627
 628        pulse8->tx_msg = *msg;
 629        if (debug)
 630                dev_info(pulse8->dev, "adap transmit %*ph\n",
 631                         msg->len, msg->msg);
 632        pulse8->tx_signal_free_time = signal_free_time;
 633        schedule_work(&pulse8->tx_work);
 634        return 0;
 635}
 636
 637static void pulse8_cec_adap_free(struct cec_adapter *adap)
 638{
 639        struct pulse8 *pulse8 = cec_get_drvdata(adap);
 640
 641        cancel_delayed_work_sync(&pulse8->ping_eeprom_work);
 642        cancel_work_sync(&pulse8->irq_work);
 643        cancel_work_sync(&pulse8->tx_work);
 644        kfree(pulse8);
 645}
 646
 647static const struct cec_adap_ops pulse8_cec_adap_ops = {
 648        .adap_enable = pulse8_cec_adap_enable,
 649        .adap_log_addr = pulse8_cec_adap_log_addr,
 650        .adap_transmit = pulse8_cec_adap_transmit,
 651        .adap_free = pulse8_cec_adap_free,
 652};
 653
 654static void pulse8_disconnect(struct serio *serio)
 655{
 656        struct pulse8 *pulse8 = serio_get_drvdata(serio);
 657
 658        cec_unregister_adapter(pulse8->adap);
 659        serio_set_drvdata(serio, NULL);
 660        serio_close(serio);
 661}
 662
 663static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
 664                        struct cec_log_addrs *log_addrs, u16 *pa)
 665{
 666        u8 *data = pulse8->data + 1;
 667        u8 cmd[2];
 668        int err;
 669        time64_t date;
 670
 671        pulse8->vers = 0;
 672
 673        cmd[0] = MSGCODE_FIRMWARE_VERSION;
 674        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
 675        if (err)
 676                return err;
 677        pulse8->vers = (data[0] << 8) | data[1];
 678        dev_info(pulse8->dev, "Firmware version %04x\n", pulse8->vers);
 679        if (pulse8->vers < 2) {
 680                *pa = CEC_PHYS_ADDR_INVALID;
 681                return 0;
 682        }
 683
 684        cmd[0] = MSGCODE_GET_BUILDDATE;
 685        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4);
 686        if (err)
 687                return err;
 688        date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
 689        dev_info(pulse8->dev, "Firmware build date %ptT\n", &date);
 690
 691        dev_dbg(pulse8->dev, "Persistent config:\n");
 692        cmd[0] = MSGCODE_GET_AUTO_ENABLED;
 693        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
 694        if (err)
 695                return err;
 696        pulse8->autonomous = data[0];
 697        dev_dbg(pulse8->dev, "Autonomous mode: %s",
 698                data[0] ? "on" : "off");
 699
 700        if (pulse8->vers >= 10) {
 701                cmd[0] = MSGCODE_GET_AUTO_POWER_ON;
 702                err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
 703                if (!err)
 704                        dev_dbg(pulse8->dev, "Auto Power On: %s",
 705                                data[0] ? "on" : "off");
 706        }
 707
 708        cmd[0] = MSGCODE_GET_DEVICE_TYPE;
 709        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
 710        if (err)
 711                return err;
 712        log_addrs->primary_device_type[0] = data[0];
 713        dev_dbg(pulse8->dev, "Primary device type: %d\n", data[0]);
 714        switch (log_addrs->primary_device_type[0]) {
 715        case CEC_OP_PRIM_DEVTYPE_TV:
 716                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV;
 717                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV;
 718                break;
 719        case CEC_OP_PRIM_DEVTYPE_RECORD:
 720                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_RECORD;
 721                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_RECORD;
 722                break;
 723        case CEC_OP_PRIM_DEVTYPE_TUNER:
 724                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_TUNER;
 725                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_TUNER;
 726                break;
 727        case CEC_OP_PRIM_DEVTYPE_PLAYBACK:
 728                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
 729                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK;
 730                break;
 731        case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM:
 732                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK;
 733                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
 734                break;
 735        case CEC_OP_PRIM_DEVTYPE_SWITCH:
 736                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
 737                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
 738                break;
 739        case CEC_OP_PRIM_DEVTYPE_PROCESSOR:
 740                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_SPECIFIC;
 741                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
 742                break;
 743        default:
 744                log_addrs->log_addr_type[0] = CEC_LOG_ADDR_TYPE_UNREGISTERED;
 745                log_addrs->all_device_types[0] = CEC_OP_ALL_DEVTYPE_SWITCH;
 746                dev_info(pulse8->dev, "Unknown Primary Device Type: %d\n",
 747                         log_addrs->primary_device_type[0]);
 748                break;
 749        }
 750
 751        cmd[0] = MSGCODE_GET_LOGICAL_ADDRESS_MASK;
 752        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 2);
 753        if (err)
 754                return err;
 755        log_addrs->log_addr_mask = (data[0] << 8) | data[1];
 756        dev_dbg(pulse8->dev, "Logical address ACK mask: %x\n",
 757                log_addrs->log_addr_mask);
 758        if (log_addrs->log_addr_mask)
 759                log_addrs->num_log_addrs = 1;
 760
 761        cmd[0] = MSGCODE_GET_PHYSICAL_ADDRESS;
 762        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
 763        if (err)
 764                return err;
 765        *pa = (data[0] << 8) | data[1];
 766        dev_dbg(pulse8->dev, "Physical address: %x.%x.%x.%x\n",
 767                cec_phys_addr_exp(*pa));
 768
 769        log_addrs->cec_version = CEC_OP_CEC_VERSION_1_4;
 770        if (pulse8->vers < 10) {
 771                cmd[0] = MSGCODE_GET_HDMI_VERSION;
 772                err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 1);
 773                if (err)
 774                        return err;
 775                log_addrs->cec_version = data[0];
 776                dev_dbg(pulse8->dev, "CEC version: %d\n", log_addrs->cec_version);
 777        }
 778
 779        cmd[0] = MSGCODE_GET_OSD_NAME;
 780        err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0);
 781        if (err)
 782                return err;
 783        strscpy(log_addrs->osd_name, data, sizeof(log_addrs->osd_name));
 784        dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name);
 785
 786        return 0;
 787}
 788
 789static int pulse8_apply_persistent_config(struct pulse8 *pulse8,
 790                                          struct cec_log_addrs *log_addrs,
 791                                          u16 pa)
 792{
 793        int err;
 794
 795        err = cec_s_log_addrs(pulse8->adap, log_addrs, false);
 796        if (err)
 797                return err;
 798
 799        cec_s_phys_addr(pulse8->adap, pa, false);
 800
 801        return 0;
 802}
 803
 804static void pulse8_ping_eeprom_work_handler(struct work_struct *work)
 805{
 806        struct pulse8 *pulse8 =
 807                container_of(work, struct pulse8, ping_eeprom_work.work);
 808        u8 cmd;
 809
 810        mutex_lock(&pulse8->lock);
 811        cmd = MSGCODE_PING;
 812        pulse8_send_and_wait(pulse8, &cmd, 1,
 813                             MSGCODE_COMMAND_ACCEPTED, 0);
 814
 815        if (pulse8->vers < 2)
 816                goto unlock;
 817
 818        if (pulse8->config_pending && persistent_config) {
 819                dev_dbg(pulse8->dev, "writing pending config to EEPROM\n");
 820                cmd = MSGCODE_WRITE_EEPROM;
 821                if (pulse8_send_and_wait(pulse8, &cmd, 1,
 822                                         MSGCODE_COMMAND_ACCEPTED, 0))
 823                        dev_info(pulse8->dev, "failed to write pending config to EEPROM\n");
 824                else
 825                        pulse8->config_pending = false;
 826        }
 827unlock:
 828        schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
 829        mutex_unlock(&pulse8->lock);
 830}
 831
 832static int pulse8_connect(struct serio *serio, struct serio_driver *drv)
 833{
 834        u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL;
 835        struct pulse8 *pulse8;
 836        int err = -ENOMEM;
 837        struct cec_log_addrs log_addrs = {};
 838        u16 pa = CEC_PHYS_ADDR_INVALID;
 839
 840        pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL);
 841
 842        if (!pulse8)
 843                return -ENOMEM;
 844
 845        pulse8->serio = serio;
 846        pulse8->adap = cec_allocate_adapter(&pulse8_cec_adap_ops, pulse8,
 847                                            dev_name(&serio->dev), caps, 1);
 848        err = PTR_ERR_OR_ZERO(pulse8->adap);
 849        if (err < 0) {
 850                kfree(pulse8);
 851                return err;
 852        }
 853
 854        pulse8->dev = &serio->dev;
 855        serio_set_drvdata(serio, pulse8);
 856        INIT_WORK(&pulse8->irq_work, pulse8_irq_work_handler);
 857        INIT_WORK(&pulse8->tx_work, pulse8_tx_work_handler);
 858        INIT_DELAYED_WORK(&pulse8->ping_eeprom_work,
 859                          pulse8_ping_eeprom_work_handler);
 860        mutex_init(&pulse8->lock);
 861        spin_lock_init(&pulse8->msg_lock);
 862        pulse8->config_pending = false;
 863
 864        err = serio_open(serio, drv);
 865        if (err)
 866                goto delete_adap;
 867
 868        err = pulse8_setup(pulse8, serio, &log_addrs, &pa);
 869        if (err)
 870                goto close_serio;
 871
 872        err = cec_register_adapter(pulse8->adap, &serio->dev);
 873        if (err < 0)
 874                goto close_serio;
 875
 876        pulse8->dev = &pulse8->adap->devnode.dev;
 877
 878        if (persistent_config && pulse8->autonomous) {
 879                err = pulse8_apply_persistent_config(pulse8, &log_addrs, pa);
 880                if (err)
 881                        goto close_serio;
 882                pulse8->restoring_config = true;
 883        }
 884
 885        schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD);
 886
 887        return 0;
 888
 889close_serio:
 890        pulse8->serio = NULL;
 891        serio_set_drvdata(serio, NULL);
 892        serio_close(serio);
 893delete_adap:
 894        cec_delete_adapter(pulse8->adap);
 895        return err;
 896}
 897
 898static const struct serio_device_id pulse8_serio_ids[] = {
 899        {
 900                .type   = SERIO_RS232,
 901                .proto  = SERIO_PULSE8_CEC,
 902                .id     = SERIO_ANY,
 903                .extra  = SERIO_ANY,
 904        },
 905        { 0 }
 906};
 907
 908MODULE_DEVICE_TABLE(serio, pulse8_serio_ids);
 909
 910static struct serio_driver pulse8_drv = {
 911        .driver         = {
 912                .name   = "pulse8-cec",
 913        },
 914        .description    = "Pulse Eight HDMI CEC driver",
 915        .id_table       = pulse8_serio_ids,
 916        .interrupt      = pulse8_interrupt,
 917        .connect        = pulse8_connect,
 918        .disconnect     = pulse8_disconnect,
 919};
 920
 921module_serio_driver(pulse8_drv);
 922