adv7511_cec.c (10597B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * adv7511_cec.c - Analog Devices ADV7511/33 cec driver 4 * 5 * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 6 */ 7 8#include <linux/device.h> 9#include <linux/module.h> 10#include <linux/of_device.h> 11#include <linux/slab.h> 12#include <linux/clk.h> 13 14#include <media/cec.h> 15 16#include "adv7511.h" 17 18#define ADV7511_INT1_CEC_MASK \ 19 (ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | \ 20 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT | ADV7511_INT1_CEC_RX_READY1 | \ 21 ADV7511_INT1_CEC_RX_READY2 | ADV7511_INT1_CEC_RX_READY3) 22 23static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) 24{ 25 unsigned int offset = adv7511->reg_cec_offset; 26 unsigned int val; 27 28 if (regmap_read(adv7511->regmap_cec, 29 ADV7511_REG_CEC_TX_ENABLE + offset, &val)) 30 return; 31 32 if ((val & 0x01) == 0) 33 return; 34 35 if (tx_raw_status & ADV7511_INT1_CEC_TX_ARBIT_LOST) { 36 cec_transmit_attempt_done(adv7511->cec_adap, 37 CEC_TX_STATUS_ARB_LOST); 38 return; 39 } 40 if (tx_raw_status & ADV7511_INT1_CEC_TX_RETRY_TIMEOUT) { 41 u8 status; 42 u8 err_cnt = 0; 43 u8 nack_cnt = 0; 44 u8 low_drive_cnt = 0; 45 unsigned int cnt; 46 47 /* 48 * We set this status bit since this hardware performs 49 * retransmissions. 50 */ 51 status = CEC_TX_STATUS_MAX_RETRIES; 52 if (regmap_read(adv7511->regmap_cec, 53 ADV7511_REG_CEC_TX_LOW_DRV_CNT + offset, &cnt)) { 54 err_cnt = 1; 55 status |= CEC_TX_STATUS_ERROR; 56 } else { 57 nack_cnt = cnt & 0xf; 58 if (nack_cnt) 59 status |= CEC_TX_STATUS_NACK; 60 low_drive_cnt = cnt >> 4; 61 if (low_drive_cnt) 62 status |= CEC_TX_STATUS_LOW_DRIVE; 63 } 64 cec_transmit_done(adv7511->cec_adap, status, 65 0, nack_cnt, low_drive_cnt, err_cnt); 66 return; 67 } 68 if (tx_raw_status & ADV7511_INT1_CEC_TX_READY) { 69 cec_transmit_attempt_done(adv7511->cec_adap, CEC_TX_STATUS_OK); 70 return; 71 } 72} 73 74static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) 75{ 76 unsigned int offset = adv7511->reg_cec_offset; 77 struct cec_msg msg = {}; 78 unsigned int len; 79 unsigned int val; 80 u8 i; 81 82 if (regmap_read(adv7511->regmap_cec, 83 ADV7511_REG_CEC_RX_FRAME_LEN[rx_buf] + offset, &len)) 84 return; 85 86 msg.len = len & 0x1f; 87 88 if (msg.len > 16) 89 msg.len = 16; 90 91 if (!msg.len) 92 return; 93 94 for (i = 0; i < msg.len; i++) { 95 regmap_read(adv7511->regmap_cec, 96 i + ADV7511_REG_CEC_RX_FRAME_HDR[rx_buf] + offset, 97 &val); 98 msg.msg[i] = val; 99 } 100 101 /* Toggle RX Ready Clear bit to re-enable this RX buffer */ 102 regmap_update_bits(adv7511->regmap_cec, 103 ADV7511_REG_CEC_RX_BUFFERS + offset, BIT(rx_buf), 104 BIT(rx_buf)); 105 regmap_update_bits(adv7511->regmap_cec, 106 ADV7511_REG_CEC_RX_BUFFERS + offset, BIT(rx_buf), 0); 107 108 cec_received_msg(adv7511->cec_adap, &msg); 109} 110 111void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) 112{ 113 unsigned int offset = adv7511->reg_cec_offset; 114 const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY | 115 ADV7511_INT1_CEC_TX_ARBIT_LOST | 116 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT; 117 const u32 irq_rx_mask = ADV7511_INT1_CEC_RX_READY1 | 118 ADV7511_INT1_CEC_RX_READY2 | 119 ADV7511_INT1_CEC_RX_READY3; 120 unsigned int rx_status; 121 int rx_order[3] = { -1, -1, -1 }; 122 int i; 123 124 if (irq1 & irq_tx_mask) 125 adv_cec_tx_raw_status(adv7511, irq1); 126 127 if (!(irq1 & irq_rx_mask)) 128 return; 129 130 if (regmap_read(adv7511->regmap_cec, 131 ADV7511_REG_CEC_RX_STATUS + offset, &rx_status)) 132 return; 133 134 /* 135 * ADV7511_REG_CEC_RX_STATUS[5:0] contains the reception order of RX 136 * buffers 0, 1, and 2 in bits [1:0], [3:2], and [5:4] respectively. 137 * The values are to be interpreted as follows: 138 * 139 * 0 = buffer unused 140 * 1 = buffer contains oldest received frame (if applicable) 141 * 2 = buffer contains second oldest received frame (if applicable) 142 * 3 = buffer contains third oldest received frame (if applicable) 143 * 144 * Fill rx_order with the sequence of RX buffer indices to 145 * read from in order, where -1 indicates that there are no 146 * more buffers to process. 147 */ 148 for (i = 0; i < 3; i++) { 149 unsigned int timestamp = (rx_status >> (2 * i)) & 0x3; 150 151 if (timestamp) 152 rx_order[timestamp - 1] = i; 153 } 154 155 /* Read CEC RX buffers in the appropriate order as prescribed above */ 156 for (i = 0; i < 3; i++) { 157 int rx_buf = rx_order[i]; 158 159 if (rx_buf < 0) 160 break; 161 162 adv7511_cec_rx(adv7511, rx_buf); 163 } 164} 165 166static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) 167{ 168 struct adv7511 *adv7511 = cec_get_drvdata(adap); 169 unsigned int offset = adv7511->reg_cec_offset; 170 171 if (adv7511->i2c_cec == NULL) 172 return -EIO; 173 174 if (!adv7511->cec_enabled_adap && enable) { 175 /* power up cec section */ 176 regmap_update_bits(adv7511->regmap_cec, 177 ADV7511_REG_CEC_CLK_DIV + offset, 178 0x03, 0x01); 179 /* non-legacy mode and clear all rx buffers */ 180 regmap_write(adv7511->regmap_cec, 181 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x0f); 182 regmap_write(adv7511->regmap_cec, 183 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x08); 184 /* initially disable tx */ 185 regmap_update_bits(adv7511->regmap_cec, 186 ADV7511_REG_CEC_TX_ENABLE + offset, 1, 0); 187 /* enabled irqs: */ 188 /* tx: ready */ 189 /* tx: arbitration lost */ 190 /* tx: retry timeout */ 191 /* rx: ready 1-3 */ 192 regmap_update_bits(adv7511->regmap, 193 ADV7511_REG_INT_ENABLE(1), 0x3f, 194 ADV7511_INT1_CEC_MASK); 195 } else if (adv7511->cec_enabled_adap && !enable) { 196 regmap_update_bits(adv7511->regmap, 197 ADV7511_REG_INT_ENABLE(1), 0x3f, 0); 198 /* disable address mask 1-3 */ 199 regmap_update_bits(adv7511->regmap_cec, 200 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 201 0x70, 0x00); 202 /* power down cec section */ 203 regmap_update_bits(adv7511->regmap_cec, 204 ADV7511_REG_CEC_CLK_DIV + offset, 205 0x03, 0x00); 206 adv7511->cec_valid_addrs = 0; 207 } 208 adv7511->cec_enabled_adap = enable; 209 return 0; 210} 211 212static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) 213{ 214 struct adv7511 *adv7511 = cec_get_drvdata(adap); 215 unsigned int offset = adv7511->reg_cec_offset; 216 unsigned int i, free_idx = ADV7511_MAX_ADDRS; 217 218 if (!adv7511->cec_enabled_adap) 219 return addr == CEC_LOG_ADDR_INVALID ? 0 : -EIO; 220 221 if (addr == CEC_LOG_ADDR_INVALID) { 222 regmap_update_bits(adv7511->regmap_cec, 223 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 224 0x70, 0); 225 adv7511->cec_valid_addrs = 0; 226 return 0; 227 } 228 229 for (i = 0; i < ADV7511_MAX_ADDRS; i++) { 230 bool is_valid = adv7511->cec_valid_addrs & (1 << i); 231 232 if (free_idx == ADV7511_MAX_ADDRS && !is_valid) 233 free_idx = i; 234 if (is_valid && adv7511->cec_addr[i] == addr) 235 return 0; 236 } 237 if (i == ADV7511_MAX_ADDRS) { 238 i = free_idx; 239 if (i == ADV7511_MAX_ADDRS) 240 return -ENXIO; 241 } 242 adv7511->cec_addr[i] = addr; 243 adv7511->cec_valid_addrs |= 1 << i; 244 245 switch (i) { 246 case 0: 247 /* enable address mask 0 */ 248 regmap_update_bits(adv7511->regmap_cec, 249 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 250 0x10, 0x10); 251 /* set address for mask 0 */ 252 regmap_update_bits(adv7511->regmap_cec, 253 ADV7511_REG_CEC_LOG_ADDR_0_1 + offset, 254 0x0f, addr); 255 break; 256 case 1: 257 /* enable address mask 1 */ 258 regmap_update_bits(adv7511->regmap_cec, 259 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 260 0x20, 0x20); 261 /* set address for mask 1 */ 262 regmap_update_bits(adv7511->regmap_cec, 263 ADV7511_REG_CEC_LOG_ADDR_0_1 + offset, 264 0xf0, addr << 4); 265 break; 266 case 2: 267 /* enable address mask 2 */ 268 regmap_update_bits(adv7511->regmap_cec, 269 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 270 0x40, 0x40); 271 /* set address for mask 1 */ 272 regmap_update_bits(adv7511->regmap_cec, 273 ADV7511_REG_CEC_LOG_ADDR_2 + offset, 274 0x0f, addr); 275 break; 276 } 277 return 0; 278} 279 280static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 281 u32 signal_free_time, struct cec_msg *msg) 282{ 283 struct adv7511 *adv7511 = cec_get_drvdata(adap); 284 unsigned int offset = adv7511->reg_cec_offset; 285 u8 len = msg->len; 286 unsigned int i; 287 288 /* 289 * The number of retries is the number of attempts - 1, but retry 290 * at least once. It's not clear if a value of 0 is allowed, so 291 * let's do at least one retry. 292 */ 293 regmap_update_bits(adv7511->regmap_cec, 294 ADV7511_REG_CEC_TX_RETRY + offset, 295 0x70, max(1, attempts - 1) << 4); 296 297 /* blocking, clear cec tx irq status */ 298 regmap_update_bits(adv7511->regmap, ADV7511_REG_INT(1), 0x38, 0x38); 299 300 /* write data */ 301 for (i = 0; i < len; i++) 302 regmap_write(adv7511->regmap_cec, 303 i + ADV7511_REG_CEC_TX_FRAME_HDR + offset, 304 msg->msg[i]); 305 306 /* set length (data + header) */ 307 regmap_write(adv7511->regmap_cec, 308 ADV7511_REG_CEC_TX_FRAME_LEN + offset, len); 309 /* start transmit, enable tx */ 310 regmap_write(adv7511->regmap_cec, 311 ADV7511_REG_CEC_TX_ENABLE + offset, 0x01); 312 return 0; 313} 314 315static const struct cec_adap_ops adv7511_cec_adap_ops = { 316 .adap_enable = adv7511_cec_adap_enable, 317 .adap_log_addr = adv7511_cec_adap_log_addr, 318 .adap_transmit = adv7511_cec_adap_transmit, 319}; 320 321static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) 322{ 323 adv7511->cec_clk = devm_clk_get(dev, "cec"); 324 if (IS_ERR(adv7511->cec_clk)) { 325 int ret = PTR_ERR(adv7511->cec_clk); 326 327 adv7511->cec_clk = NULL; 328 return ret; 329 } 330 clk_prepare_enable(adv7511->cec_clk); 331 adv7511->cec_clk_freq = clk_get_rate(adv7511->cec_clk); 332 return 0; 333} 334 335int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) 336{ 337 unsigned int offset = adv7511->reg_cec_offset; 338 int ret = adv7511_cec_parse_dt(dev, adv7511); 339 340 if (ret) 341 goto err_cec_parse_dt; 342 343 adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops, 344 adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS); 345 if (IS_ERR(adv7511->cec_adap)) { 346 ret = PTR_ERR(adv7511->cec_adap); 347 goto err_cec_alloc; 348 } 349 350 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); 351 /* cec soft reset */ 352 regmap_write(adv7511->regmap_cec, 353 ADV7511_REG_CEC_SOFT_RESET + offset, 0x01); 354 regmap_write(adv7511->regmap_cec, 355 ADV7511_REG_CEC_SOFT_RESET + offset, 0x00); 356 357 /* non-legacy mode - use all three RX buffers */ 358 regmap_write(adv7511->regmap_cec, 359 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x08); 360 361 regmap_write(adv7511->regmap_cec, 362 ADV7511_REG_CEC_CLK_DIV + offset, 363 ((adv7511->cec_clk_freq / 750000) - 1) << 2); 364 365 ret = cec_register_adapter(adv7511->cec_adap, dev); 366 if (ret) 367 goto err_cec_register; 368 return 0; 369 370err_cec_register: 371 cec_delete_adapter(adv7511->cec_adap); 372 adv7511->cec_adap = NULL; 373err_cec_alloc: 374 dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n", 375 ret); 376err_cec_parse_dt: 377 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 378 ADV7511_CEC_CTRL_POWER_DOWN); 379 return ret == -EPROBE_DEFER ? ret : 0; 380}