1 /* 2 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com> 3 * Copyright (C) 2017 Jonathan Liu <net147@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of 8 * the License, or (at your option) any later version. 9 */ 10 11 #include <linux/clk.h> 12 #include <linux/i2c.h> 13 #include <linux/iopoll.h> 14 15 #include "sun4i_hdmi.h" 16 17 #define SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK ( \ 18 SUN4I_HDMI_DDC_INT_STATUS_ILLEGAL_FIFO_OPERATION | \ 19 SUN4I_HDMI_DDC_INT_STATUS_DDC_RX_FIFO_UNDERFLOW | \ 20 SUN4I_HDMI_DDC_INT_STATUS_DDC_TX_FIFO_OVERFLOW | \ 21 SUN4I_HDMI_DDC_INT_STATUS_ARBITRATION_ERROR | \ 22 SUN4I_HDMI_DDC_INT_STATUS_ACK_ERROR | \ 23 SUN4I_HDMI_DDC_INT_STATUS_BUS_ERROR \ 24 ) 25 26 /* FIFO request bit is set when FIFO level is above RX_THRESHOLD during read */ 27 #define RX_THRESHOLD SUN4I_HDMI_DDC_FIFO_CTRL_RX_THRES_MAX 28 29 static int fifo_transfer(struct sun4i_hdmi *hdmi, u8 *buf, int len, bool read) 30 { 31 /* 32 * 1 byte takes 9 clock cycles (8 bits + 1 ACK) = 90 us for 100 kHz 33 * clock. As clock rate is fixed, just round it up to 100 us. 34 */ 35 const unsigned long byte_time_ns = 100; 36 const u32 mask = SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK | 37 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST | 38 SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE; 39 u32 reg; 40 /* 41 * If threshold is inclusive, then the FIFO may only have 42 * RX_THRESHOLD number of bytes, instead of RX_THRESHOLD + 1. 43 */ 44 int read_len = RX_THRESHOLD + 45 (hdmi->variant->ddc_fifo_thres_incl ? 0 : 1); 46 47 /* 48 * Limit transfer length by FIFO threshold or FIFO size. 49 * For TX the threshold is for an empty FIFO. 50 */ 51 len = min_t(int, len, read ? read_len : SUN4I_HDMI_DDC_FIFO_SIZE); 52 53 /* Wait until error, FIFO request bit set or transfer complete */ 54 if (regmap_field_read_poll_timeout(hdmi->field_ddc_int_status, reg, 55 reg & mask, len * byte_time_ns, 56 100000)) 57 return -ETIMEDOUT; 58 59 if (reg & SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK) 60 return -EIO; 61 62 if (read) 63 readsb(hdmi->base + hdmi->variant->ddc_fifo_reg, buf, len); 64 else 65 writesb(hdmi->base + hdmi->variant->ddc_fifo_reg, buf, len); 66 67 /* Clear FIFO request bit by forcing a write to that bit */ 68 regmap_field_force_write(hdmi->field_ddc_int_status, 69 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST); 70 71 return len; 72 } 73 74 static int xfer_msg(struct sun4i_hdmi *hdmi, struct i2c_msg *msg) 75 { 76 int i, len; 77 u32 reg; 78 79 /* Set FIFO direction */ 80 if (hdmi->variant->ddc_fifo_has_dir) { 81 reg = readl(hdmi->base + SUN4I_HDMI_DDC_CTRL_REG); 82 reg &= ~SUN4I_HDMI_DDC_CTRL_FIFO_DIR_MASK; 83 reg |= (msg->flags & I2C_M_RD) ? 84 SUN4I_HDMI_DDC_CTRL_FIFO_DIR_READ : 85 SUN4I_HDMI_DDC_CTRL_FIFO_DIR_WRITE; 86 writel(reg, hdmi->base + SUN4I_HDMI_DDC_CTRL_REG); 87 } 88 89 /* Clear address register (not cleared by soft reset) */ 90 regmap_field_write(hdmi->field_ddc_addr_reg, 0); 91 92 /* Set I2C address */ 93 regmap_field_write(hdmi->field_ddc_slave_addr, msg->addr); 94 95 /* 96 * Set FIFO RX/TX thresholds and clear FIFO 97 * 98 * If threshold is inclusive, we can set the TX threshold to 99 * 0 instead of 1. 100 */ 101 regmap_field_write(hdmi->field_ddc_fifo_tx_thres, 102 hdmi->variant->ddc_fifo_thres_incl ? 0 : 1); 103 regmap_field_write(hdmi->field_ddc_fifo_rx_thres, RX_THRESHOLD); 104 regmap_field_write(hdmi->field_ddc_fifo_clear, 1); 105 if (regmap_field_read_poll_timeout(hdmi->field_ddc_fifo_clear, 106 reg, !reg, 100, 2000)) 107 return -EIO; 108 109 /* Set transfer length */ 110 regmap_field_write(hdmi->field_ddc_byte_count, msg->len); 111 112 /* Set command */ 113 regmap_field_write(hdmi->field_ddc_cmd, 114 msg->flags & I2C_M_RD ? 115 SUN4I_HDMI_DDC_CMD_IMPLICIT_READ : 116 SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE); 117 118 /* Clear interrupt status bits by forcing a write */ 119 regmap_field_force_write(hdmi->field_ddc_int_status, 120 SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK | 121 SUN4I_HDMI_DDC_INT_STATUS_FIFO_REQUEST | 122 SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE); 123 124 /* Start command */ 125 regmap_field_write(hdmi->field_ddc_start, 1); 126 127 /* Transfer bytes */ 128 for (i = 0; i < msg->len; i += len) { 129 len = fifo_transfer(hdmi, msg->buf + i, msg->len - i, 130 msg->flags & I2C_M_RD); 131 if (len <= 0) 132 return len; 133 } 134 135 /* Wait for command to finish */ 136 if (regmap_field_read_poll_timeout(hdmi->field_ddc_start, 137 reg, !reg, 100, 100000)) 138 return -EIO; 139 140 /* Check for errors */ 141 regmap_field_read(hdmi->field_ddc_int_status, ®); 142 if ((reg & SUN4I_HDMI_DDC_INT_STATUS_ERROR_MASK) || 143 !(reg & SUN4I_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE)) { 144 return -EIO; 145 } 146 147 return 0; 148 } 149 150 static int sun4i_hdmi_i2c_xfer(struct i2c_adapter *adap, 151 struct i2c_msg *msgs, int num) 152 { 153 struct sun4i_hdmi *hdmi = i2c_get_adapdata(adap); 154 u32 reg; 155 int err, i, ret = num; 156 157 for (i = 0; i < num; i++) { 158 if (!msgs[i].len) 159 return -EINVAL; 160 if (msgs[i].len > SUN4I_HDMI_DDC_BYTE_COUNT_MAX) 161 return -EINVAL; 162 } 163 164 /* DDC clock needs to be enabled for the module to work */ 165 clk_prepare_enable(hdmi->ddc_clk); 166 clk_set_rate(hdmi->ddc_clk, 100000); 167 168 /* Reset I2C controller */ 169 regmap_field_write(hdmi->field_ddc_en, 1); 170 regmap_field_write(hdmi->field_ddc_reset, 1); 171 if (regmap_field_read_poll_timeout(hdmi->field_ddc_reset, 172 reg, !reg, 100, 2000)) { 173 clk_disable_unprepare(hdmi->ddc_clk); 174 return -EIO; 175 } 176 177 regmap_field_write(hdmi->field_ddc_sck_en, 1); 178 regmap_field_write(hdmi->field_ddc_sda_en, 1); 179 180 for (i = 0; i < num; i++) { 181 err = xfer_msg(hdmi, &msgs[i]); 182 if (err) { 183 ret = err; 184 break; 185 } 186 } 187 188 clk_disable_unprepare(hdmi->ddc_clk); 189 return ret; 190 } 191 192 static u32 sun4i_hdmi_i2c_func(struct i2c_adapter *adap) 193 { 194 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 195 } 196 197 static const struct i2c_algorithm sun4i_hdmi_i2c_algorithm = { 198 .master_xfer = sun4i_hdmi_i2c_xfer, 199 .functionality = sun4i_hdmi_i2c_func, 200 }; 201 202 static int sun4i_hdmi_init_regmap_fields(struct sun4i_hdmi *hdmi) 203 { 204 hdmi->field_ddc_en = 205 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 206 hdmi->variant->field_ddc_en); 207 if (IS_ERR(hdmi->field_ddc_en)) 208 return PTR_ERR(hdmi->field_ddc_en); 209 210 hdmi->field_ddc_start = 211 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 212 hdmi->variant->field_ddc_start); 213 if (IS_ERR(hdmi->field_ddc_start)) 214 return PTR_ERR(hdmi->field_ddc_start); 215 216 hdmi->field_ddc_reset = 217 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 218 hdmi->variant->field_ddc_reset); 219 if (IS_ERR(hdmi->field_ddc_reset)) 220 return PTR_ERR(hdmi->field_ddc_reset); 221 222 hdmi->field_ddc_addr_reg = 223 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 224 hdmi->variant->field_ddc_addr_reg); 225 if (IS_ERR(hdmi->field_ddc_addr_reg)) 226 return PTR_ERR(hdmi->field_ddc_addr_reg); 227 228 hdmi->field_ddc_slave_addr = 229 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 230 hdmi->variant->field_ddc_slave_addr); 231 if (IS_ERR(hdmi->field_ddc_slave_addr)) 232 return PTR_ERR(hdmi->field_ddc_slave_addr); 233 234 hdmi->field_ddc_int_mask = 235 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 236 hdmi->variant->field_ddc_int_mask); 237 if (IS_ERR(hdmi->field_ddc_int_mask)) 238 return PTR_ERR(hdmi->field_ddc_int_mask); 239 240 hdmi->field_ddc_int_status = 241 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 242 hdmi->variant->field_ddc_int_status); 243 if (IS_ERR(hdmi->field_ddc_int_status)) 244 return PTR_ERR(hdmi->field_ddc_int_status); 245 246 hdmi->field_ddc_fifo_clear = 247 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 248 hdmi->variant->field_ddc_fifo_clear); 249 if (IS_ERR(hdmi->field_ddc_fifo_clear)) 250 return PTR_ERR(hdmi->field_ddc_fifo_clear); 251 252 hdmi->field_ddc_fifo_rx_thres = 253 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 254 hdmi->variant->field_ddc_fifo_rx_thres); 255 if (IS_ERR(hdmi->field_ddc_fifo_rx_thres)) 256 return PTR_ERR(hdmi->field_ddc_fifo_rx_thres); 257 258 hdmi->field_ddc_fifo_tx_thres = 259 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 260 hdmi->variant->field_ddc_fifo_tx_thres); 261 if (IS_ERR(hdmi->field_ddc_fifo_tx_thres)) 262 return PTR_ERR(hdmi->field_ddc_fifo_tx_thres); 263 264 hdmi->field_ddc_byte_count = 265 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 266 hdmi->variant->field_ddc_byte_count); 267 if (IS_ERR(hdmi->field_ddc_byte_count)) 268 return PTR_ERR(hdmi->field_ddc_byte_count); 269 270 hdmi->field_ddc_cmd = 271 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 272 hdmi->variant->field_ddc_cmd); 273 if (IS_ERR(hdmi->field_ddc_cmd)) 274 return PTR_ERR(hdmi->field_ddc_cmd); 275 276 hdmi->field_ddc_sda_en = 277 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 278 hdmi->variant->field_ddc_sda_en); 279 if (IS_ERR(hdmi->field_ddc_sda_en)) 280 return PTR_ERR(hdmi->field_ddc_sda_en); 281 282 hdmi->field_ddc_sck_en = 283 devm_regmap_field_alloc(hdmi->dev, hdmi->regmap, 284 hdmi->variant->field_ddc_sck_en); 285 if (IS_ERR(hdmi->field_ddc_sck_en)) 286 return PTR_ERR(hdmi->field_ddc_sck_en); 287 288 return 0; 289 } 290 291 int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi) 292 { 293 struct i2c_adapter *adap; 294 int ret = 0; 295 296 ret = sun4i_ddc_create(hdmi, hdmi->ddc_parent_clk); 297 if (ret) 298 return ret; 299 300 ret = sun4i_hdmi_init_regmap_fields(hdmi); 301 if (ret) 302 return ret; 303 304 adap = devm_kzalloc(dev, sizeof(*adap), GFP_KERNEL); 305 if (!adap) 306 return -ENOMEM; 307 308 adap->owner = THIS_MODULE; 309 adap->class = I2C_CLASS_DDC; 310 adap->algo = &sun4i_hdmi_i2c_algorithm; 311 strlcpy(adap->name, "sun4i_hdmi_i2c adapter", sizeof(adap->name)); 312 i2c_set_adapdata(adap, hdmi); 313 314 ret = i2c_add_adapter(adap); 315 if (ret) 316 return ret; 317 318 hdmi->i2c = adap; 319 320 return ret; 321 } 322