1 /* 2 * adv7511_cec.c - Analog Devices ADV7511/33 cec driver 3 * 4 * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 5 * 6 * This program is free software; you may redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 * SOFTWARE. 18 * 19 */ 20 21 #include <linux/device.h> 22 #include <linux/module.h> 23 #include <linux/of_device.h> 24 #include <linux/slab.h> 25 #include <linux/clk.h> 26 27 #include <media/cec.h> 28 29 #include "adv7511.h" 30 31 #define ADV7511_INT1_CEC_MASK \ 32 (ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | \ 33 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT | ADV7511_INT1_CEC_RX_READY1) 34 35 static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) 36 { 37 unsigned int offset = adv7511->type == ADV7533 ? 38 ADV7533_REG_CEC_OFFSET : 0; 39 unsigned int val; 40 41 if (regmap_read(adv7511->regmap_cec, 42 ADV7511_REG_CEC_TX_ENABLE + offset, &val)) 43 return; 44 45 if ((val & 0x01) == 0) 46 return; 47 48 if (tx_raw_status & ADV7511_INT1_CEC_TX_ARBIT_LOST) { 49 cec_transmit_attempt_done(adv7511->cec_adap, 50 CEC_TX_STATUS_ARB_LOST); 51 return; 52 } 53 if (tx_raw_status & ADV7511_INT1_CEC_TX_RETRY_TIMEOUT) { 54 u8 status; 55 u8 err_cnt = 0; 56 u8 nack_cnt = 0; 57 u8 low_drive_cnt = 0; 58 unsigned int cnt; 59 60 /* 61 * We set this status bit since this hardware performs 62 * retransmissions. 63 */ 64 status = CEC_TX_STATUS_MAX_RETRIES; 65 if (regmap_read(adv7511->regmap_cec, 66 ADV7511_REG_CEC_TX_LOW_DRV_CNT + offset, &cnt)) { 67 err_cnt = 1; 68 status |= CEC_TX_STATUS_ERROR; 69 } else { 70 nack_cnt = cnt & 0xf; 71 if (nack_cnt) 72 status |= CEC_TX_STATUS_NACK; 73 low_drive_cnt = cnt >> 4; 74 if (low_drive_cnt) 75 status |= CEC_TX_STATUS_LOW_DRIVE; 76 } 77 cec_transmit_done(adv7511->cec_adap, status, 78 0, nack_cnt, low_drive_cnt, err_cnt); 79 return; 80 } 81 if (tx_raw_status & ADV7511_INT1_CEC_TX_READY) { 82 cec_transmit_attempt_done(adv7511->cec_adap, CEC_TX_STATUS_OK); 83 return; 84 } 85 } 86 87 void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) 88 { 89 unsigned int offset = adv7511->type == ADV7533 ? 90 ADV7533_REG_CEC_OFFSET : 0; 91 const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY | 92 ADV7511_INT1_CEC_TX_ARBIT_LOST | 93 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT; 94 struct cec_msg msg = {}; 95 unsigned int len; 96 unsigned int val; 97 u8 i; 98 99 if (irq1 & irq_tx_mask) 100 adv_cec_tx_raw_status(adv7511, irq1); 101 102 if (!(irq1 & ADV7511_INT1_CEC_RX_READY1)) 103 return; 104 105 if (regmap_read(adv7511->regmap_cec, 106 ADV7511_REG_CEC_RX_FRAME_LEN + offset, &len)) 107 return; 108 109 msg.len = len & 0x1f; 110 111 if (msg.len > 16) 112 msg.len = 16; 113 114 if (!msg.len) 115 return; 116 117 for (i = 0; i < msg.len; i++) { 118 regmap_read(adv7511->regmap_cec, 119 i + ADV7511_REG_CEC_RX_FRAME_HDR + offset, &val); 120 msg.msg[i] = val; 121 } 122 123 /* toggle to re-enable rx 1 */ 124 regmap_write(adv7511->regmap_cec, 125 ADV7511_REG_CEC_RX_BUFFERS + offset, 1); 126 regmap_write(adv7511->regmap_cec, 127 ADV7511_REG_CEC_RX_BUFFERS + offset, 0); 128 cec_received_msg(adv7511->cec_adap, &msg); 129 } 130 131 static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) 132 { 133 struct adv7511 *adv7511 = cec_get_drvdata(adap); 134 unsigned int offset = adv7511->type == ADV7533 ? 135 ADV7533_REG_CEC_OFFSET : 0; 136 137 if (adv7511->i2c_cec == NULL) 138 return -EIO; 139 140 if (!adv7511->cec_enabled_adap && enable) { 141 /* power up cec section */ 142 regmap_update_bits(adv7511->regmap_cec, 143 ADV7511_REG_CEC_CLK_DIV + offset, 144 0x03, 0x01); 145 /* legacy mode and clear all rx buffers */ 146 regmap_write(adv7511->regmap_cec, 147 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x07); 148 regmap_write(adv7511->regmap_cec, 149 ADV7511_REG_CEC_RX_BUFFERS + offset, 0); 150 /* initially disable tx */ 151 regmap_update_bits(adv7511->regmap_cec, 152 ADV7511_REG_CEC_TX_ENABLE + offset, 1, 0); 153 /* enabled irqs: */ 154 /* tx: ready */ 155 /* tx: arbitration lost */ 156 /* tx: retry timeout */ 157 /* rx: ready 1 */ 158 regmap_update_bits(adv7511->regmap, 159 ADV7511_REG_INT_ENABLE(1), 0x3f, 160 ADV7511_INT1_CEC_MASK); 161 } else if (adv7511->cec_enabled_adap && !enable) { 162 regmap_update_bits(adv7511->regmap, 163 ADV7511_REG_INT_ENABLE(1), 0x3f, 0); 164 /* disable address mask 1-3 */ 165 regmap_update_bits(adv7511->regmap_cec, 166 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 167 0x70, 0x00); 168 /* power down cec section */ 169 regmap_update_bits(adv7511->regmap_cec, 170 ADV7511_REG_CEC_CLK_DIV + offset, 171 0x03, 0x00); 172 adv7511->cec_valid_addrs = 0; 173 } 174 adv7511->cec_enabled_adap = enable; 175 return 0; 176 } 177 178 static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) 179 { 180 struct adv7511 *adv7511 = cec_get_drvdata(adap); 181 unsigned int offset = adv7511->type == ADV7533 ? 182 ADV7533_REG_CEC_OFFSET : 0; 183 unsigned int i, free_idx = ADV7511_MAX_ADDRS; 184 185 if (!adv7511->cec_enabled_adap) 186 return addr == CEC_LOG_ADDR_INVALID ? 0 : -EIO; 187 188 if (addr == CEC_LOG_ADDR_INVALID) { 189 regmap_update_bits(adv7511->regmap_cec, 190 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 191 0x70, 0); 192 adv7511->cec_valid_addrs = 0; 193 return 0; 194 } 195 196 for (i = 0; i < ADV7511_MAX_ADDRS; i++) { 197 bool is_valid = adv7511->cec_valid_addrs & (1 << i); 198 199 if (free_idx == ADV7511_MAX_ADDRS && !is_valid) 200 free_idx = i; 201 if (is_valid && adv7511->cec_addr[i] == addr) 202 return 0; 203 } 204 if (i == ADV7511_MAX_ADDRS) { 205 i = free_idx; 206 if (i == ADV7511_MAX_ADDRS) 207 return -ENXIO; 208 } 209 adv7511->cec_addr[i] = addr; 210 adv7511->cec_valid_addrs |= 1 << i; 211 212 switch (i) { 213 case 0: 214 /* enable address mask 0 */ 215 regmap_update_bits(adv7511->regmap_cec, 216 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 217 0x10, 0x10); 218 /* set address for mask 0 */ 219 regmap_update_bits(adv7511->regmap_cec, 220 ADV7511_REG_CEC_LOG_ADDR_0_1 + offset, 221 0x0f, addr); 222 break; 223 case 1: 224 /* enable address mask 1 */ 225 regmap_update_bits(adv7511->regmap_cec, 226 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 227 0x20, 0x20); 228 /* set address for mask 1 */ 229 regmap_update_bits(adv7511->regmap_cec, 230 ADV7511_REG_CEC_LOG_ADDR_0_1 + offset, 231 0xf0, addr << 4); 232 break; 233 case 2: 234 /* enable address mask 2 */ 235 regmap_update_bits(adv7511->regmap_cec, 236 ADV7511_REG_CEC_LOG_ADDR_MASK + offset, 237 0x40, 0x40); 238 /* set address for mask 1 */ 239 regmap_update_bits(adv7511->regmap_cec, 240 ADV7511_REG_CEC_LOG_ADDR_2 + offset, 241 0x0f, addr); 242 break; 243 } 244 return 0; 245 } 246 247 static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 248 u32 signal_free_time, struct cec_msg *msg) 249 { 250 struct adv7511 *adv7511 = cec_get_drvdata(adap); 251 unsigned int offset = adv7511->type == ADV7533 ? 252 ADV7533_REG_CEC_OFFSET : 0; 253 u8 len = msg->len; 254 unsigned int i; 255 256 /* 257 * The number of retries is the number of attempts - 1, but retry 258 * at least once. It's not clear if a value of 0 is allowed, so 259 * let's do at least one retry. 260 */ 261 regmap_update_bits(adv7511->regmap_cec, 262 ADV7511_REG_CEC_TX_RETRY + offset, 263 0x70, max(1, attempts - 1) << 4); 264 265 /* blocking, clear cec tx irq status */ 266 regmap_update_bits(adv7511->regmap, ADV7511_REG_INT(1), 0x38, 0x38); 267 268 /* write data */ 269 for (i = 0; i < len; i++) 270 regmap_write(adv7511->regmap_cec, 271 i + ADV7511_REG_CEC_TX_FRAME_HDR + offset, 272 msg->msg[i]); 273 274 /* set length (data + header) */ 275 regmap_write(adv7511->regmap_cec, 276 ADV7511_REG_CEC_TX_FRAME_LEN + offset, len); 277 /* start transmit, enable tx */ 278 regmap_write(adv7511->regmap_cec, 279 ADV7511_REG_CEC_TX_ENABLE + offset, 0x01); 280 return 0; 281 } 282 283 static const struct cec_adap_ops adv7511_cec_adap_ops = { 284 .adap_enable = adv7511_cec_adap_enable, 285 .adap_log_addr = adv7511_cec_adap_log_addr, 286 .adap_transmit = adv7511_cec_adap_transmit, 287 }; 288 289 static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) 290 { 291 adv7511->cec_clk = devm_clk_get(dev, "cec"); 292 if (IS_ERR(adv7511->cec_clk)) { 293 int ret = PTR_ERR(adv7511->cec_clk); 294 295 adv7511->cec_clk = NULL; 296 return ret; 297 } 298 clk_prepare_enable(adv7511->cec_clk); 299 adv7511->cec_clk_freq = clk_get_rate(adv7511->cec_clk); 300 return 0; 301 } 302 303 int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) 304 { 305 unsigned int offset = adv7511->type == ADV7533 ? 306 ADV7533_REG_CEC_OFFSET : 0; 307 int ret = adv7511_cec_parse_dt(dev, adv7511); 308 309 if (ret) 310 goto err_cec_parse_dt; 311 312 adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops, 313 adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS); 314 if (IS_ERR(adv7511->cec_adap)) { 315 ret = PTR_ERR(adv7511->cec_adap); 316 goto err_cec_alloc; 317 } 318 319 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); 320 /* cec soft reset */ 321 regmap_write(adv7511->regmap_cec, 322 ADV7511_REG_CEC_SOFT_RESET + offset, 0x01); 323 regmap_write(adv7511->regmap_cec, 324 ADV7511_REG_CEC_SOFT_RESET + offset, 0x00); 325 326 /* legacy mode */ 327 regmap_write(adv7511->regmap_cec, 328 ADV7511_REG_CEC_RX_BUFFERS + offset, 0x00); 329 330 regmap_write(adv7511->regmap_cec, 331 ADV7511_REG_CEC_CLK_DIV + offset, 332 ((adv7511->cec_clk_freq / 750000) - 1) << 2); 333 334 ret = cec_register_adapter(adv7511->cec_adap, dev); 335 if (ret) 336 goto err_cec_register; 337 return 0; 338 339 err_cec_register: 340 cec_delete_adapter(adv7511->cec_adap); 341 adv7511->cec_adap = NULL; 342 err_cec_alloc: 343 dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n", 344 ret); 345 err_cec_parse_dt: 346 regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 347 ADV7511_CEC_CTRL_POWER_DOWN); 348 return ret == -EPROBE_DEFER ? ret : 0; 349 } 350