Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Driver for Amlogic Meson AO CEC Controller
0003  *
0004  * Copyright (C) 2015 Amlogic, Inc. All rights reserved
0005  * Copyright (C) 2017 BayLibre, SAS
0006  * Author: Neil Armstrong <narmstrong@baylibre.com>
0007  *
0008  * SPDX-License-Identifier: GPL-2.0+
0009  */
0010 
0011 #include <linux/bitfield.h>
0012 #include <linux/clk.h>
0013 #include <linux/device.h>
0014 #include <linux/io.h>
0015 #include <linux/delay.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/of.h>
0019 #include <linux/of_platform.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/types.h>
0022 #include <linux/interrupt.h>
0023 #include <linux/reset.h>
0024 #include <media/cec.h>
0025 #include <media/cec-notifier.h>
0026 
0027 /* CEC Registers */
0028 
0029 /*
0030  * [2:1] cntl_clk
0031  *  - 0 = Disable clk (Power-off mode)
0032  *  - 1 = Enable gated clock (Normal mode)
0033  *  - 2 = Enable free-run clk (Debug mode)
0034  */
0035 #define CEC_GEN_CNTL_REG        0x00
0036 
0037 #define CEC_GEN_CNTL_RESET      BIT(0)
0038 #define CEC_GEN_CNTL_CLK_DISABLE    0
0039 #define CEC_GEN_CNTL_CLK_ENABLE     1
0040 #define CEC_GEN_CNTL_CLK_ENABLE_DBG 2
0041 #define CEC_GEN_CNTL_CLK_CTRL_MASK  GENMASK(2, 1)
0042 
0043 /*
0044  * [7:0] cec_reg_addr
0045  * [15:8] cec_reg_wrdata
0046  * [16] cec_reg_wr
0047  *  - 0 = Read
0048  *  - 1 = Write
0049  * [23] bus free
0050  * [31:24] cec_reg_rddata
0051  */
0052 #define CEC_RW_REG          0x04
0053 
0054 #define CEC_RW_ADDR         GENMASK(7, 0)
0055 #define CEC_RW_WR_DATA          GENMASK(15, 8)
0056 #define CEC_RW_WRITE_EN         BIT(16)
0057 #define CEC_RW_BUS_BUSY         BIT(23)
0058 #define CEC_RW_RD_DATA          GENMASK(31, 24)
0059 
0060 /*
0061  * [1] tx intr
0062  * [2] rx intr
0063  */
0064 #define CEC_INTR_MASKN_REG      0x08
0065 #define CEC_INTR_CLR_REG        0x0c
0066 #define CEC_INTR_STAT_REG       0x10
0067 
0068 #define CEC_INTR_TX         BIT(1)
0069 #define CEC_INTR_RX         BIT(2)
0070 
0071 /* CEC Commands */
0072 
0073 #define CEC_TX_MSG_0_HEADER     0x00
0074 #define CEC_TX_MSG_1_OPCODE     0x01
0075 #define CEC_TX_MSG_2_OP1        0x02
0076 #define CEC_TX_MSG_3_OP2        0x03
0077 #define CEC_TX_MSG_4_OP3        0x04
0078 #define CEC_TX_MSG_5_OP4        0x05
0079 #define CEC_TX_MSG_6_OP5        0x06
0080 #define CEC_TX_MSG_7_OP6        0x07
0081 #define CEC_TX_MSG_8_OP7        0x08
0082 #define CEC_TX_MSG_9_OP8        0x09
0083 #define CEC_TX_MSG_A_OP9        0x0A
0084 #define CEC_TX_MSG_B_OP10       0x0B
0085 #define CEC_TX_MSG_C_OP11       0x0C
0086 #define CEC_TX_MSG_D_OP12       0x0D
0087 #define CEC_TX_MSG_E_OP13       0x0E
0088 #define CEC_TX_MSG_F_OP14       0x0F
0089 #define CEC_TX_MSG_LENGTH       0x10
0090 #define CEC_TX_MSG_CMD          0x11
0091 #define CEC_TX_WRITE_BUF        0x12
0092 #define CEC_TX_CLEAR_BUF        0x13
0093 #define CEC_RX_MSG_CMD          0x14
0094 #define CEC_RX_CLEAR_BUF        0x15
0095 #define CEC_LOGICAL_ADDR0       0x16
0096 #define CEC_LOGICAL_ADDR1       0x17
0097 #define CEC_LOGICAL_ADDR2       0x18
0098 #define CEC_LOGICAL_ADDR3       0x19
0099 #define CEC_LOGICAL_ADDR4       0x1A
0100 #define CEC_CLOCK_DIV_H         0x1B
0101 #define CEC_CLOCK_DIV_L         0x1C
0102 #define CEC_QUIESCENT_25MS_BIT7_0   0x20
0103 #define CEC_QUIESCENT_25MS_BIT11_8  0x21
0104 #define CEC_STARTBITMINL2H_3MS5_BIT7_0  0x22
0105 #define CEC_STARTBITMINL2H_3MS5_BIT8    0x23
0106 #define CEC_STARTBITMAXL2H_3MS9_BIT7_0  0x24
0107 #define CEC_STARTBITMAXL2H_3MS9_BIT8    0x25
0108 #define CEC_STARTBITMINH_0MS6_BIT7_0    0x26
0109 #define CEC_STARTBITMINH_0MS6_BIT8  0x27
0110 #define CEC_STARTBITMAXH_1MS0_BIT7_0    0x28
0111 #define CEC_STARTBITMAXH_1MS0_BIT8  0x29
0112 #define CEC_STARTBITMINTOT_4MS3_BIT7_0  0x2A
0113 #define CEC_STARTBITMINTOT_4MS3_BIT9_8  0x2B
0114 #define CEC_STARTBITMAXTOT_4MS7_BIT7_0  0x2C
0115 #define CEC_STARTBITMAXTOT_4MS7_BIT9_8  0x2D
0116 #define CEC_LOGIC1MINL2H_0MS4_BIT7_0    0x2E
0117 #define CEC_LOGIC1MINL2H_0MS4_BIT8  0x2F
0118 #define CEC_LOGIC1MAXL2H_0MS8_BIT7_0    0x30
0119 #define CEC_LOGIC1MAXL2H_0MS8_BIT8  0x31
0120 #define CEC_LOGIC0MINL2H_1MS3_BIT7_0    0x32
0121 #define CEC_LOGIC0MINL2H_1MS3_BIT8  0x33
0122 #define CEC_LOGIC0MAXL2H_1MS7_BIT7_0    0x34
0123 #define CEC_LOGIC0MAXL2H_1MS7_BIT8  0x35
0124 #define CEC_LOGICMINTOTAL_2MS05_BIT7_0  0x36
0125 #define CEC_LOGICMINTOTAL_2MS05_BIT9_8  0x37
0126 #define CEC_LOGICMAXHIGH_2MS8_BIT7_0    0x38
0127 #define CEC_LOGICMAXHIGH_2MS8_BIT8  0x39
0128 #define CEC_LOGICERRLOW_3MS4_BIT7_0 0x3A
0129 #define CEC_LOGICERRLOW_3MS4_BIT8   0x3B
0130 #define CEC_NOMSMPPOINT_1MS05       0x3C
0131 #define CEC_DELCNTR_LOGICERR        0x3E
0132 #define CEC_TXTIME_17MS_BIT7_0      0x40
0133 #define CEC_TXTIME_17MS_BIT10_8     0x41
0134 #define CEC_TXTIME_2BIT_BIT7_0      0x42
0135 #define CEC_TXTIME_2BIT_BIT10_8     0x43
0136 #define CEC_TXTIME_4BIT_BIT7_0      0x44
0137 #define CEC_TXTIME_4BIT_BIT10_8     0x45
0138 #define CEC_STARTBITNOML2H_3MS7_BIT7_0  0x46
0139 #define CEC_STARTBITNOML2H_3MS7_BIT8    0x47
0140 #define CEC_STARTBITNOMH_0MS8_BIT7_0    0x48
0141 #define CEC_STARTBITNOMH_0MS8_BIT8  0x49
0142 #define CEC_LOGIC1NOML2H_0MS6_BIT7_0    0x4A
0143 #define CEC_LOGIC1NOML2H_0MS6_BIT8  0x4B
0144 #define CEC_LOGIC0NOML2H_1MS5_BIT7_0    0x4C
0145 #define CEC_LOGIC0NOML2H_1MS5_BIT8  0x4D
0146 #define CEC_LOGIC1NOMH_1MS8_BIT7_0  0x4E
0147 #define CEC_LOGIC1NOMH_1MS8_BIT8    0x4F
0148 #define CEC_LOGIC0NOMH_0MS9_BIT7_0  0x50
0149 #define CEC_LOGIC0NOMH_0MS9_BIT8    0x51
0150 #define CEC_LOGICERRLOW_3MS6_BIT7_0 0x52
0151 #define CEC_LOGICERRLOW_3MS6_BIT8   0x53
0152 #define CEC_CHKCONTENTION_0MS1      0x54
0153 #define CEC_PREPARENXTBIT_0MS05_BIT7_0  0x56
0154 #define CEC_PREPARENXTBIT_0MS05_BIT8    0x57
0155 #define CEC_NOMSMPACKPOINT_0MS45    0x58
0156 #define CEC_ACK0NOML2H_1MS5_BIT7_0  0x5A
0157 #define CEC_ACK0NOML2H_1MS5_BIT8    0x5B
0158 #define CEC_BUGFIX_DISABLE_0        0x60
0159 #define CEC_BUGFIX_DISABLE_1        0x61
0160 #define CEC_RX_MSG_0_HEADER     0x80
0161 #define CEC_RX_MSG_1_OPCODE     0x81
0162 #define CEC_RX_MSG_2_OP1        0x82
0163 #define CEC_RX_MSG_3_OP2        0x83
0164 #define CEC_RX_MSG_4_OP3        0x84
0165 #define CEC_RX_MSG_5_OP4        0x85
0166 #define CEC_RX_MSG_6_OP5        0x86
0167 #define CEC_RX_MSG_7_OP6        0x87
0168 #define CEC_RX_MSG_8_OP7        0x88
0169 #define CEC_RX_MSG_9_OP8        0x89
0170 #define CEC_RX_MSG_A_OP9        0x8A
0171 #define CEC_RX_MSG_B_OP10       0x8B
0172 #define CEC_RX_MSG_C_OP11       0x8C
0173 #define CEC_RX_MSG_D_OP12       0x8D
0174 #define CEC_RX_MSG_E_OP13       0x8E
0175 #define CEC_RX_MSG_F_OP14       0x8F
0176 #define CEC_RX_MSG_LENGTH       0x90
0177 #define CEC_RX_MSG_STATUS       0x91
0178 #define CEC_RX_NUM_MSG          0x92
0179 #define CEC_TX_MSG_STATUS       0x93
0180 #define CEC_TX_NUM_MSG          0x94
0181 
0182 
0183 /* CEC_TX_MSG_CMD definition */
0184 #define TX_NO_OP    0  /* No transaction */
0185 #define TX_REQ_CURRENT  1  /* Transmit earliest message in buffer */
0186 #define TX_ABORT    2  /* Abort transmitting earliest message */
0187 #define TX_REQ_NEXT 3  /* Overwrite earliest msg, transmit next */
0188 
0189 /* tx_msg_status definition */
0190 #define TX_IDLE     0  /* No transaction */
0191 #define TX_BUSY     1  /* Transmitter is busy */
0192 #define TX_DONE     2  /* Message successfully transmitted */
0193 #define TX_ERROR    3  /* Message transmitted with error */
0194 
0195 /* rx_msg_cmd */
0196 #define RX_NO_OP    0  /* No transaction */
0197 #define RX_ACK_CURRENT  1  /* Read earliest message in buffer */
0198 #define RX_DISABLE  2  /* Disable receiving latest message */
0199 #define RX_ACK_NEXT 3  /* Clear earliest msg, read next */
0200 
0201 /* rx_msg_status */
0202 #define RX_IDLE     0  /* No transaction */
0203 #define RX_BUSY     1  /* Receiver is busy */
0204 #define RX_DONE     2  /* Message has been received successfully */
0205 #define RX_ERROR    3  /* Message has been received with error */
0206 
0207 /* RX_CLEAR_BUF options */
0208 #define CLEAR_START 1
0209 #define CLEAR_STOP  0
0210 
0211 /* CEC_LOGICAL_ADDRx options */
0212 #define LOGICAL_ADDR_MASK   0xf
0213 #define LOGICAL_ADDR_VALID  BIT(4)
0214 #define LOGICAL_ADDR_DISABLE    0
0215 
0216 #define CEC_CLK_RATE        32768
0217 
0218 struct meson_ao_cec_device {
0219     struct platform_device      *pdev;
0220     void __iomem            *base;
0221     struct clk          *core;
0222     spinlock_t          cec_reg_lock;
0223     struct cec_notifier     *notify;
0224     struct cec_adapter      *adap;
0225     struct cec_msg          rx_msg;
0226 };
0227 
0228 #define writel_bits_relaxed(mask, val, addr) \
0229     writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
0230 
0231 static inline int meson_ao_cec_wait_busy(struct meson_ao_cec_device *ao_cec)
0232 {
0233     ktime_t timeout = ktime_add_us(ktime_get(), 5000);
0234 
0235     while (readl_relaxed(ao_cec->base + CEC_RW_REG) & CEC_RW_BUS_BUSY) {
0236         if (ktime_compare(ktime_get(), timeout) > 0)
0237             return -ETIMEDOUT;
0238     }
0239 
0240     return 0;
0241 }
0242 
0243 static void meson_ao_cec_read(struct meson_ao_cec_device *ao_cec,
0244                  unsigned long address, u8 *data,
0245                  int *res)
0246 {
0247     unsigned long flags;
0248     u32 reg = FIELD_PREP(CEC_RW_ADDR, address);
0249     int ret = 0;
0250 
0251     if (res && *res)
0252         return;
0253 
0254     spin_lock_irqsave(&ao_cec->cec_reg_lock, flags);
0255 
0256     ret = meson_ao_cec_wait_busy(ao_cec);
0257     if (ret)
0258         goto read_out;
0259 
0260     writel_relaxed(reg, ao_cec->base + CEC_RW_REG);
0261 
0262     ret = meson_ao_cec_wait_busy(ao_cec);
0263     if (ret)
0264         goto read_out;
0265 
0266     *data = FIELD_GET(CEC_RW_RD_DATA,
0267               readl_relaxed(ao_cec->base + CEC_RW_REG));
0268 
0269 read_out:
0270     spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags);
0271 
0272     if (res)
0273         *res = ret;
0274 }
0275 
0276 static void meson_ao_cec_write(struct meson_ao_cec_device *ao_cec,
0277                    unsigned long address, u8 data,
0278                    int *res)
0279 {
0280     unsigned long flags;
0281     u32 reg = FIELD_PREP(CEC_RW_ADDR, address) |
0282           FIELD_PREP(CEC_RW_WR_DATA, data) |
0283           CEC_RW_WRITE_EN;
0284     int ret = 0;
0285 
0286     if (res && *res)
0287         return;
0288 
0289     spin_lock_irqsave(&ao_cec->cec_reg_lock, flags);
0290 
0291     ret = meson_ao_cec_wait_busy(ao_cec);
0292     if (ret)
0293         goto write_out;
0294 
0295     writel_relaxed(reg, ao_cec->base + CEC_RW_REG);
0296 
0297 write_out:
0298     spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags);
0299 
0300     if (res)
0301         *res = ret;
0302 }
0303 
0304 static inline void meson_ao_cec_irq_setup(struct meson_ao_cec_device *ao_cec,
0305                       bool enable)
0306 {
0307     u32 cfg = CEC_INTR_TX | CEC_INTR_RX;
0308 
0309     writel_bits_relaxed(cfg, enable ? cfg : 0,
0310                 ao_cec->base + CEC_INTR_MASKN_REG);
0311 }
0312 
0313 static inline int meson_ao_cec_clear(struct meson_ao_cec_device *ao_cec)
0314 {
0315     int ret = 0;
0316 
0317     meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_DISABLE, &ret);
0318     meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
0319     meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 1, &ret);
0320     meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 1, &ret);
0321     if (ret)
0322         return ret;
0323 
0324     udelay(100);
0325 
0326     meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, 0, &ret);
0327     meson_ao_cec_write(ao_cec, CEC_TX_CLEAR_BUF, 0, &ret);
0328     if (ret)
0329         return ret;
0330 
0331     udelay(100);
0332 
0333     meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret);
0334     meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret);
0335 
0336     return ret;
0337 }
0338 
0339 static int meson_ao_cec_arbit_bit_time_set(struct meson_ao_cec_device *ao_cec,
0340                        unsigned int bit_set,
0341                        unsigned int time_set)
0342 {
0343     int ret = 0;
0344 
0345     switch (bit_set) {
0346     case CEC_SIGNAL_FREE_TIME_RETRY:
0347         meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT7_0,
0348                    time_set & 0xff, &ret);
0349         meson_ao_cec_write(ao_cec, CEC_TXTIME_4BIT_BIT10_8,
0350                    (time_set >> 8) & 0x7, &ret);
0351         break;
0352 
0353     case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
0354         meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT7_0,
0355                    time_set & 0xff, &ret);
0356         meson_ao_cec_write(ao_cec, CEC_TXTIME_2BIT_BIT10_8,
0357                    (time_set >> 8) & 0x7, &ret);
0358         break;
0359 
0360     case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
0361         meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT7_0,
0362                    time_set & 0xff, &ret);
0363         meson_ao_cec_write(ao_cec, CEC_TXTIME_17MS_BIT10_8,
0364                    (time_set >> 8) & 0x7, &ret);
0365         break;
0366     }
0367 
0368     return ret;
0369 }
0370 
0371 static irqreturn_t meson_ao_cec_irq(int irq, void *data)
0372 {
0373     struct meson_ao_cec_device *ao_cec = data;
0374     u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG);
0375 
0376     if (stat)
0377         return IRQ_WAKE_THREAD;
0378 
0379     return IRQ_NONE;
0380 }
0381 
0382 static void meson_ao_cec_irq_tx(struct meson_ao_cec_device *ao_cec)
0383 {
0384     unsigned long tx_status = 0;
0385     u8 stat;
0386     int ret = 0;
0387 
0388     meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &stat, &ret);
0389     if (ret)
0390         goto tx_reg_err;
0391 
0392     switch (stat) {
0393     case TX_DONE:
0394         tx_status = CEC_TX_STATUS_OK;
0395         break;
0396 
0397     case TX_BUSY:
0398         tx_status = CEC_TX_STATUS_ARB_LOST;
0399         break;
0400 
0401     case TX_IDLE:
0402         tx_status = CEC_TX_STATUS_LOW_DRIVE;
0403         break;
0404 
0405     case TX_ERROR:
0406     default:
0407         tx_status = CEC_TX_STATUS_NACK;
0408         break;
0409     }
0410 
0411     /* Clear Interruption */
0412     writel_relaxed(CEC_INTR_TX, ao_cec->base + CEC_INTR_CLR_REG);
0413 
0414     /* Stop TX */
0415     meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_NO_OP, &ret);
0416     if (ret)
0417         goto tx_reg_err;
0418 
0419     cec_transmit_attempt_done(ao_cec->adap, tx_status);
0420     return;
0421 
0422 tx_reg_err:
0423     cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR);
0424 }
0425 
0426 static void meson_ao_cec_irq_rx(struct meson_ao_cec_device *ao_cec)
0427 {
0428     int i, ret = 0;
0429     u8 reg;
0430 
0431     meson_ao_cec_read(ao_cec, CEC_RX_MSG_STATUS, &reg, &ret);
0432     if (reg != RX_DONE)
0433         goto rx_out;
0434 
0435     meson_ao_cec_read(ao_cec, CEC_RX_NUM_MSG, &reg, &ret);
0436     if (reg != 1)
0437         goto rx_out;
0438 
0439     meson_ao_cec_read(ao_cec, CEC_RX_MSG_LENGTH, &reg, &ret);
0440 
0441     ao_cec->rx_msg.len = reg + 1;
0442     if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE)
0443         ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE;
0444 
0445     for (i = 0; i < ao_cec->rx_msg.len; i++) {
0446         u8 byte;
0447 
0448         meson_ao_cec_read(ao_cec, CEC_RX_MSG_0_HEADER + i, &byte, &ret);
0449 
0450         ao_cec->rx_msg.msg[i] = byte;
0451     }
0452 
0453     if (ret)
0454         goto rx_out;
0455 
0456     cec_received_msg(ao_cec->adap, &ao_cec->rx_msg);
0457 
0458 rx_out:
0459     /* Clear Interruption */
0460     writel_relaxed(CEC_INTR_RX, ao_cec->base + CEC_INTR_CLR_REG);
0461 
0462     /* Ack RX message */
0463     meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_ACK_CURRENT, &ret);
0464     meson_ao_cec_write(ao_cec, CEC_RX_MSG_CMD, RX_NO_OP, &ret);
0465 
0466     /* Clear RX buffer */
0467     meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_START, &ret);
0468     meson_ao_cec_write(ao_cec, CEC_RX_CLEAR_BUF, CLEAR_STOP, &ret);
0469 }
0470 
0471 static irqreturn_t meson_ao_cec_irq_thread(int irq, void *data)
0472 {
0473     struct meson_ao_cec_device *ao_cec = data;
0474     u32 stat = readl_relaxed(ao_cec->base + CEC_INTR_STAT_REG);
0475 
0476     if (stat & CEC_INTR_TX)
0477         meson_ao_cec_irq_tx(ao_cec);
0478 
0479     meson_ao_cec_irq_rx(ao_cec);
0480 
0481     return IRQ_HANDLED;
0482 }
0483 
0484 static int meson_ao_cec_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
0485 {
0486     struct meson_ao_cec_device *ao_cec = adap->priv;
0487     int ret = 0;
0488 
0489     meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
0490                LOGICAL_ADDR_DISABLE, &ret);
0491     if (ret)
0492         return ret;
0493 
0494     ret = meson_ao_cec_clear(ao_cec);
0495     if (ret)
0496         return ret;
0497 
0498     if (logical_addr == CEC_LOG_ADDR_INVALID)
0499         return 0;
0500 
0501     meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
0502                logical_addr & LOGICAL_ADDR_MASK, &ret);
0503     if (ret)
0504         return ret;
0505 
0506     udelay(100);
0507 
0508     meson_ao_cec_write(ao_cec, CEC_LOGICAL_ADDR0,
0509                (logical_addr & LOGICAL_ADDR_MASK) |
0510                LOGICAL_ADDR_VALID, &ret);
0511 
0512     return ret;
0513 }
0514 
0515 static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts,
0516                  u32 signal_free_time, struct cec_msg *msg)
0517 {
0518     struct meson_ao_cec_device *ao_cec = adap->priv;
0519     int i, ret = 0;
0520     u8 reg;
0521 
0522     meson_ao_cec_read(ao_cec, CEC_TX_MSG_STATUS, &reg, &ret);
0523     if (ret)
0524         return ret;
0525 
0526     if (reg == TX_BUSY) {
0527         dev_dbg(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
0528             __func__);
0529         meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
0530     }
0531 
0532     for (i = 0; i < msg->len; i++) {
0533         meson_ao_cec_write(ao_cec, CEC_TX_MSG_0_HEADER + i,
0534                    msg->msg[i], &ret);
0535     }
0536 
0537     meson_ao_cec_write(ao_cec, CEC_TX_MSG_LENGTH, msg->len - 1, &ret);
0538     meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_REQ_CURRENT, &ret);
0539 
0540     return ret;
0541 }
0542 
0543 static int meson_ao_cec_adap_enable(struct cec_adapter *adap, bool enable)
0544 {
0545     struct meson_ao_cec_device *ao_cec = adap->priv;
0546     int ret;
0547 
0548     meson_ao_cec_irq_setup(ao_cec, false);
0549 
0550     writel_bits_relaxed(CEC_GEN_CNTL_RESET, CEC_GEN_CNTL_RESET,
0551                 ao_cec->base + CEC_GEN_CNTL_REG);
0552 
0553     if (!enable)
0554         return 0;
0555 
0556     /* Enable gated clock (Normal mode). */
0557     writel_bits_relaxed(CEC_GEN_CNTL_CLK_CTRL_MASK,
0558                 FIELD_PREP(CEC_GEN_CNTL_CLK_CTRL_MASK,
0559                        CEC_GEN_CNTL_CLK_ENABLE),
0560                 ao_cec->base + CEC_GEN_CNTL_REG);
0561 
0562     udelay(100);
0563 
0564     /* Release Reset */
0565     writel_bits_relaxed(CEC_GEN_CNTL_RESET, 0,
0566                 ao_cec->base + CEC_GEN_CNTL_REG);
0567 
0568     /* Clear buffers */
0569     ret = meson_ao_cec_clear(ao_cec);
0570     if (ret)
0571         return ret;
0572 
0573     /* CEC arbitration 3/5/7 bit time set. */
0574     ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
0575                     CEC_SIGNAL_FREE_TIME_RETRY,
0576                     0x118);
0577     if (ret)
0578         return ret;
0579     ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
0580                     CEC_SIGNAL_FREE_TIME_NEW_INITIATOR,
0581                     0x000);
0582     if (ret)
0583         return ret;
0584     ret = meson_ao_cec_arbit_bit_time_set(ao_cec,
0585                     CEC_SIGNAL_FREE_TIME_NEXT_XFER,
0586                     0x2aa);
0587     if (ret)
0588         return ret;
0589 
0590     meson_ao_cec_irq_setup(ao_cec, true);
0591 
0592     return 0;
0593 }
0594 
0595 static const struct cec_adap_ops meson_ao_cec_ops = {
0596     .adap_enable = meson_ao_cec_adap_enable,
0597     .adap_log_addr = meson_ao_cec_set_log_addr,
0598     .adap_transmit = meson_ao_cec_transmit,
0599 };
0600 
0601 static int meson_ao_cec_probe(struct platform_device *pdev)
0602 {
0603     struct meson_ao_cec_device *ao_cec;
0604     struct device *hdmi_dev;
0605     int ret, irq;
0606 
0607     hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
0608 
0609     if (IS_ERR(hdmi_dev))
0610         return PTR_ERR(hdmi_dev);
0611 
0612     ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL);
0613     if (!ao_cec)
0614         return -ENOMEM;
0615 
0616     spin_lock_init(&ao_cec->cec_reg_lock);
0617 
0618     ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec,
0619                         "meson_ao_cec",
0620                         CEC_CAP_DEFAULTS |
0621                         CEC_CAP_CONNECTOR_INFO,
0622                         1); /* Use 1 for now */
0623     if (IS_ERR(ao_cec->adap))
0624         return PTR_ERR(ao_cec->adap);
0625 
0626     ao_cec->adap->owner = THIS_MODULE;
0627 
0628     ao_cec->base = devm_platform_ioremap_resource(pdev, 0);
0629     if (IS_ERR(ao_cec->base)) {
0630         ret = PTR_ERR(ao_cec->base);
0631         goto out_probe_adapter;
0632     }
0633 
0634     irq = platform_get_irq(pdev, 0);
0635     ret = devm_request_threaded_irq(&pdev->dev, irq,
0636                     meson_ao_cec_irq,
0637                     meson_ao_cec_irq_thread,
0638                     0, NULL, ao_cec);
0639     if (ret) {
0640         dev_err(&pdev->dev, "irq request failed\n");
0641         goto out_probe_adapter;
0642     }
0643 
0644     ao_cec->core = devm_clk_get(&pdev->dev, "core");
0645     if (IS_ERR(ao_cec->core)) {
0646         dev_err(&pdev->dev, "core clock request failed\n");
0647         ret = PTR_ERR(ao_cec->core);
0648         goto out_probe_adapter;
0649     }
0650 
0651     ret = clk_prepare_enable(ao_cec->core);
0652     if (ret) {
0653         dev_err(&pdev->dev, "core clock enable failed\n");
0654         goto out_probe_adapter;
0655     }
0656 
0657     ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
0658     if (ret) {
0659         dev_err(&pdev->dev, "core clock set rate failed\n");
0660         goto out_probe_clk;
0661     }
0662 
0663     device_reset_optional(&pdev->dev);
0664 
0665     ao_cec->pdev = pdev;
0666     platform_set_drvdata(pdev, ao_cec);
0667 
0668     ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
0669                             ao_cec->adap);
0670     if (!ao_cec->notify) {
0671         ret = -ENOMEM;
0672         goto out_probe_clk;
0673     }
0674 
0675     ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
0676     if (ret < 0)
0677         goto out_probe_notify;
0678 
0679     /* Setup Hardware */
0680     writel_relaxed(CEC_GEN_CNTL_RESET,
0681                ao_cec->base + CEC_GEN_CNTL_REG);
0682 
0683     return 0;
0684 
0685 out_probe_notify:
0686     cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
0687 
0688 out_probe_clk:
0689     clk_disable_unprepare(ao_cec->core);
0690 
0691 out_probe_adapter:
0692     cec_delete_adapter(ao_cec->adap);
0693 
0694     dev_err(&pdev->dev, "CEC controller registration failed\n");
0695 
0696     return ret;
0697 }
0698 
0699 static int meson_ao_cec_remove(struct platform_device *pdev)
0700 {
0701     struct meson_ao_cec_device *ao_cec = platform_get_drvdata(pdev);
0702 
0703     clk_disable_unprepare(ao_cec->core);
0704 
0705     cec_notifier_cec_adap_unregister(ao_cec->notify, ao_cec->adap);
0706     cec_unregister_adapter(ao_cec->adap);
0707 
0708     return 0;
0709 }
0710 
0711 static const struct of_device_id meson_ao_cec_of_match[] = {
0712     { .compatible = "amlogic,meson-gx-ao-cec", },
0713     { /* sentinel */ }
0714 };
0715 MODULE_DEVICE_TABLE(of, meson_ao_cec_of_match);
0716 
0717 static struct platform_driver meson_ao_cec_driver = {
0718     .probe   = meson_ao_cec_probe,
0719     .remove  = meson_ao_cec_remove,
0720     .driver  = {
0721         .name = "meson-ao-cec",
0722         .of_match_table = of_match_ptr(meson_ao_cec_of_match),
0723     },
0724 };
0725 
0726 module_platform_driver(meson_ao_cec_driver);
0727 
0728 MODULE_DESCRIPTION("Meson AO CEC Controller driver");
0729 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
0730 MODULE_LICENSE("GPL");