1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014 MediaTek Inc. 4 * Author: Jie Qiu <jie.qiu@mediatek.com> 5 */ 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/i2c.h> 9 #include <linux/time.h> 10 #include <linux/delay.h> 11 #include <linux/errno.h> 12 #include <linux/err.h> 13 #include <linux/platform_device.h> 14 #include <linux/clk.h> 15 #include <linux/slab.h> 16 #include <linux/io.h> 17 #include <linux/iopoll.h> 18 #include <linux/of_address.h> 19 #include <linux/of_irq.h> 20 #include <linux/of_platform.h> 21 22 #define SIF1_CLOK (288) 23 #define DDC_DDCMCTL0 (0x0) 24 #define DDCM_ODRAIN BIT(31) 25 #define DDCM_CLK_DIV_OFFSET (16) 26 #define DDCM_CLK_DIV_MASK (0xfff << 16) 27 #define DDCM_CS_STATUS BIT(4) 28 #define DDCM_SCL_STATE BIT(3) 29 #define DDCM_SDA_STATE BIT(2) 30 #define DDCM_SM0EN BIT(1) 31 #define DDCM_SCL_STRECH BIT(0) 32 #define DDC_DDCMCTL1 (0x4) 33 #define DDCM_ACK_OFFSET (16) 34 #define DDCM_ACK_MASK (0xff << 16) 35 #define DDCM_PGLEN_OFFSET (8) 36 #define DDCM_PGLEN_MASK (0x7 << 8) 37 #define DDCM_SIF_MODE_OFFSET (4) 38 #define DDCM_SIF_MODE_MASK (0x7 << 4) 39 #define DDCM_START (0x1) 40 #define DDCM_WRITE_DATA (0x2) 41 #define DDCM_STOP (0x3) 42 #define DDCM_READ_DATA_NO_ACK (0x4) 43 #define DDCM_READ_DATA_ACK (0x5) 44 #define DDCM_TRI BIT(0) 45 #define DDC_DDCMD0 (0x8) 46 #define DDCM_DATA3 (0xff << 24) 47 #define DDCM_DATA2 (0xff << 16) 48 #define DDCM_DATA1 (0xff << 8) 49 #define DDCM_DATA0 (0xff << 0) 50 #define DDC_DDCMD1 (0xc) 51 #define DDCM_DATA7 (0xff << 24) 52 #define DDCM_DATA6 (0xff << 16) 53 #define DDCM_DATA5 (0xff << 8) 54 #define DDCM_DATA4 (0xff << 0) 55 56 struct mtk_hdmi_ddc { 57 struct i2c_adapter adap; 58 struct clk *clk; 59 void __iomem *regs; 60 }; 61 62 static inline void sif_set_bit(struct mtk_hdmi_ddc *ddc, unsigned int offset, 63 unsigned int val) 64 { 65 writel(readl(ddc->regs + offset) | val, ddc->regs + offset); 66 } 67 68 static inline void sif_clr_bit(struct mtk_hdmi_ddc *ddc, unsigned int offset, 69 unsigned int val) 70 { 71 writel(readl(ddc->regs + offset) & ~val, ddc->regs + offset); 72 } 73 74 static inline bool sif_bit_is_set(struct mtk_hdmi_ddc *ddc, unsigned int offset, 75 unsigned int val) 76 { 77 return (readl(ddc->regs + offset) & val) == val; 78 } 79 80 static inline void sif_write_mask(struct mtk_hdmi_ddc *ddc, unsigned int offset, 81 unsigned int mask, unsigned int shift, 82 unsigned int val) 83 { 84 unsigned int tmp; 85 86 tmp = readl(ddc->regs + offset); 87 tmp &= ~mask; 88 tmp |= (val << shift) & mask; 89 writel(tmp, ddc->regs + offset); 90 } 91 92 static inline unsigned int sif_read_mask(struct mtk_hdmi_ddc *ddc, 93 unsigned int offset, unsigned int mask, 94 unsigned int shift) 95 { 96 return (readl(ddc->regs + offset) & mask) >> shift; 97 } 98 99 static void ddcm_trigger_mode(struct mtk_hdmi_ddc *ddc, int mode) 100 { 101 u32 val; 102 103 sif_write_mask(ddc, DDC_DDCMCTL1, DDCM_SIF_MODE_MASK, 104 DDCM_SIF_MODE_OFFSET, mode); 105 sif_set_bit(ddc, DDC_DDCMCTL1, DDCM_TRI); 106 readl_poll_timeout(ddc->regs + DDC_DDCMCTL1, val, 107 (val & DDCM_TRI) != DDCM_TRI, 4, 20000); 108 } 109 110 static int mtk_hdmi_ddc_read_msg(struct mtk_hdmi_ddc *ddc, struct i2c_msg *msg) 111 { 112 struct device *dev = ddc->adap.dev.parent; 113 u32 remain_count, ack_count, ack_final, read_count, temp_count; 114 u32 index = 0; 115 u32 ack; 116 int i; 117 118 ddcm_trigger_mode(ddc, DDCM_START); 119 sif_write_mask(ddc, DDC_DDCMD0, 0xff, 0, (msg->addr << 1) | 0x01); 120 sif_write_mask(ddc, DDC_DDCMCTL1, DDCM_PGLEN_MASK, DDCM_PGLEN_OFFSET, 121 0x00); 122 ddcm_trigger_mode(ddc, DDCM_WRITE_DATA); 123 ack = sif_read_mask(ddc, DDC_DDCMCTL1, DDCM_ACK_MASK, DDCM_ACK_OFFSET); 124 dev_dbg(dev, "ack = 0x%x\n", ack); 125 if (ack != 0x01) { 126 dev_err(dev, "i2c ack err!\n"); 127 return -ENXIO; 128 } 129 130 remain_count = msg->len; 131 ack_count = (msg->len - 1) / 8; 132 ack_final = 0; 133 134 while (remain_count > 0) { 135 if (ack_count > 0) { 136 read_count = 8; 137 ack_final = 0; 138 ack_count--; 139 } else { 140 read_count = remain_count; 141 ack_final = 1; 142 } 143 144 sif_write_mask(ddc, DDC_DDCMCTL1, DDCM_PGLEN_MASK, 145 DDCM_PGLEN_OFFSET, read_count - 1); 146 ddcm_trigger_mode(ddc, (ack_final == 1) ? 147 DDCM_READ_DATA_NO_ACK : 148 DDCM_READ_DATA_ACK); 149 150 ack = sif_read_mask(ddc, DDC_DDCMCTL1, DDCM_ACK_MASK, 151 DDCM_ACK_OFFSET); 152 temp_count = 0; 153 while (((ack & (1 << temp_count)) != 0) && (temp_count < 8)) 154 temp_count++; 155 if (((ack_final == 1) && (temp_count != (read_count - 1))) || 156 ((ack_final == 0) && (temp_count != read_count))) { 157 dev_err(dev, "Address NACK! ACK(0x%x)\n", ack); 158 break; 159 } 160 161 for (i = read_count; i >= 1; i--) { 162 int shift; 163 int offset; 164 165 if (i > 4) { 166 offset = DDC_DDCMD1; 167 shift = (i - 5) * 8; 168 } else { 169 offset = DDC_DDCMD0; 170 shift = (i - 1) * 8; 171 } 172 173 msg->buf[index + i - 1] = sif_read_mask(ddc, offset, 174 0xff << shift, 175 shift); 176 } 177 178 remain_count -= read_count; 179 index += read_count; 180 } 181 182 return 0; 183 } 184 185 static int mtk_hdmi_ddc_write_msg(struct mtk_hdmi_ddc *ddc, struct i2c_msg *msg) 186 { 187 struct device *dev = ddc->adap.dev.parent; 188 u32 ack; 189 190 ddcm_trigger_mode(ddc, DDCM_START); 191 sif_write_mask(ddc, DDC_DDCMD0, DDCM_DATA0, 0, msg->addr << 1); 192 sif_write_mask(ddc, DDC_DDCMD0, DDCM_DATA1, 8, msg->buf[0]); 193 sif_write_mask(ddc, DDC_DDCMCTL1, DDCM_PGLEN_MASK, DDCM_PGLEN_OFFSET, 194 0x1); 195 ddcm_trigger_mode(ddc, DDCM_WRITE_DATA); 196 197 ack = sif_read_mask(ddc, DDC_DDCMCTL1, DDCM_ACK_MASK, DDCM_ACK_OFFSET); 198 dev_dbg(dev, "ack = %d\n", ack); 199 200 if (ack != 0x03) { 201 dev_err(dev, "i2c ack err!\n"); 202 return -EIO; 203 } 204 205 return 0; 206 } 207 208 static int mtk_hdmi_ddc_xfer(struct i2c_adapter *adapter, 209 struct i2c_msg *msgs, int num) 210 { 211 struct mtk_hdmi_ddc *ddc = adapter->algo_data; 212 struct device *dev = adapter->dev.parent; 213 int ret; 214 int i; 215 216 if (!ddc) { 217 dev_err(dev, "invalid arguments\n"); 218 return -EINVAL; 219 } 220 221 sif_set_bit(ddc, DDC_DDCMCTL0, DDCM_SCL_STRECH); 222 sif_set_bit(ddc, DDC_DDCMCTL0, DDCM_SM0EN); 223 sif_clr_bit(ddc, DDC_DDCMCTL0, DDCM_ODRAIN); 224 225 if (sif_bit_is_set(ddc, DDC_DDCMCTL1, DDCM_TRI)) { 226 dev_err(dev, "ddc line is busy!\n"); 227 return -EBUSY; 228 } 229 230 sif_write_mask(ddc, DDC_DDCMCTL0, DDCM_CLK_DIV_MASK, 231 DDCM_CLK_DIV_OFFSET, SIF1_CLOK); 232 233 for (i = 0; i < num; i++) { 234 struct i2c_msg *msg = &msgs[i]; 235 236 dev_dbg(dev, "i2c msg, adr:0x%x, flags:%d, len :0x%x\n", 237 msg->addr, msg->flags, msg->len); 238 239 if (msg->flags & I2C_M_RD) 240 ret = mtk_hdmi_ddc_read_msg(ddc, msg); 241 else 242 ret = mtk_hdmi_ddc_write_msg(ddc, msg); 243 if (ret < 0) 244 goto xfer_end; 245 } 246 247 ddcm_trigger_mode(ddc, DDCM_STOP); 248 249 return i; 250 251 xfer_end: 252 ddcm_trigger_mode(ddc, DDCM_STOP); 253 dev_err(dev, "ddc failed!\n"); 254 return ret; 255 } 256 257 static u32 mtk_hdmi_ddc_func(struct i2c_adapter *adapter) 258 { 259 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 260 } 261 262 static const struct i2c_algorithm mtk_hdmi_ddc_algorithm = { 263 .master_xfer = mtk_hdmi_ddc_xfer, 264 .functionality = mtk_hdmi_ddc_func, 265 }; 266 267 static int mtk_hdmi_ddc_probe(struct platform_device *pdev) 268 { 269 struct device *dev = &pdev->dev; 270 struct mtk_hdmi_ddc *ddc; 271 struct resource *mem; 272 int ret; 273 274 ddc = devm_kzalloc(dev, sizeof(struct mtk_hdmi_ddc), GFP_KERNEL); 275 if (!ddc) 276 return -ENOMEM; 277 278 ddc->clk = devm_clk_get(dev, "ddc-i2c"); 279 if (IS_ERR(ddc->clk)) { 280 dev_err(dev, "get ddc_clk failed: %p ,\n", ddc->clk); 281 return PTR_ERR(ddc->clk); 282 } 283 284 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 285 ddc->regs = devm_ioremap_resource(&pdev->dev, mem); 286 if (IS_ERR(ddc->regs)) 287 return PTR_ERR(ddc->regs); 288 289 ret = clk_prepare_enable(ddc->clk); 290 if (ret) { 291 dev_err(dev, "enable ddc clk failed!\n"); 292 return ret; 293 } 294 295 strlcpy(ddc->adap.name, "mediatek-hdmi-ddc", sizeof(ddc->adap.name)); 296 ddc->adap.owner = THIS_MODULE; 297 ddc->adap.class = I2C_CLASS_DDC; 298 ddc->adap.algo = &mtk_hdmi_ddc_algorithm; 299 ddc->adap.retries = 3; 300 ddc->adap.dev.of_node = dev->of_node; 301 ddc->adap.algo_data = ddc; 302 ddc->adap.dev.parent = &pdev->dev; 303 304 ret = i2c_add_adapter(&ddc->adap); 305 if (ret < 0) { 306 dev_err(dev, "failed to add bus to i2c core\n"); 307 goto err_clk_disable; 308 } 309 310 platform_set_drvdata(pdev, ddc); 311 312 dev_dbg(dev, "ddc->adap: %p\n", &ddc->adap); 313 dev_dbg(dev, "ddc->clk: %p\n", ddc->clk); 314 dev_dbg(dev, "physical adr: %pa, end: %pa\n", &mem->start, 315 &mem->end); 316 317 return 0; 318 319 err_clk_disable: 320 clk_disable_unprepare(ddc->clk); 321 return ret; 322 } 323 324 static int mtk_hdmi_ddc_remove(struct platform_device *pdev) 325 { 326 struct mtk_hdmi_ddc *ddc = platform_get_drvdata(pdev); 327 328 i2c_del_adapter(&ddc->adap); 329 clk_disable_unprepare(ddc->clk); 330 331 return 0; 332 } 333 334 static const struct of_device_id mtk_hdmi_ddc_match[] = { 335 { .compatible = "mediatek,mt8173-hdmi-ddc", }, 336 {}, 337 }; 338 339 struct platform_driver mtk_hdmi_ddc_driver = { 340 .probe = mtk_hdmi_ddc_probe, 341 .remove = mtk_hdmi_ddc_remove, 342 .driver = { 343 .name = "mediatek-hdmi-ddc", 344 .of_match_table = mtk_hdmi_ddc_match, 345 }, 346 }; 347 348 MODULE_AUTHOR("Jie Qiu <jie.qiu@mediatek.com>"); 349 MODULE_DESCRIPTION("MediaTek HDMI DDC Driver"); 350 MODULE_LICENSE("GPL v2"); 351