Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: jz4780: Add i2c bus controller driver for Ingenic JZ4780

Adds the i2c bus controller driver for the Ingenic JZ4780 SoC.

Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Zubair Lutfullah Kakakhel and committed by
Wolfram Sang
ba92222e 3b10db23

+877
+35
Documentation/devicetree/bindings/i2c/i2c-jz4780.txt
··· 1 + * Ingenic JZ4780 I2C Bus controller 2 + 3 + Required properties: 4 + - compatible: should be "ingenic,jz4780-i2c" 5 + - reg: Should contain the address & size of the I2C controller registers. 6 + - interrupts: Should specify the interrupt provided by parent. 7 + - clocks: Should contain a single clock specifier for the JZ4780 I2C clock. 8 + - clock-frequency: desired I2C bus clock frequency in Hz. 9 + 10 + Recommended properties: 11 + - pinctrl-names: should be "default"; 12 + - pinctrl-0: phandle to pinctrl function 13 + 14 + Optional properties: 15 + - interrupt-parent: Should be the phandle of the interrupt controller that 16 + delivers interrupts to the I2C block. 17 + 18 + Example 19 + 20 + / { 21 + i2c4: i2c4@0x10054000 { 22 + compatible = "ingenic,jz4780-i2c"; 23 + reg = <0x10054000 0x1000>; 24 + 25 + interrupt-parent = <&intc>; 26 + interrupts = <56>; 27 + 28 + clocks = <&cgu JZ4780_CLK_SMB4>; 29 + clock-frequency = <100000>; 30 + pinctrl-names = "default"; 31 + pinctrl-0 = <&pins_i2c4_data>; 32 + 33 + }; 34 + }; 35 +
+9
drivers/i2c/busses/Kconfig
··· 583 583 This driver can also be built as a module. If so, the module 584 584 will be called i2c-iop3xx. 585 585 586 + config I2C_JZ4780 587 + tristate "JZ4780 I2C controller interface support" 588 + depends on MACH_JZ4780 || COMPILE_TEST 589 + help 590 + If you say yes to this option, support will be included for the 591 + Ingenic JZ4780 I2C controller. 592 + 593 + If you don't know what to do here, say N. 594 + 586 595 config I2C_KEMPLD 587 596 tristate "Kontron COM I2C Controller" 588 597 depends on MFD_KEMPLD
+1
drivers/i2c/busses/Makefile
··· 56 56 obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o 57 57 obj-$(CONFIG_I2C_IMX) += i2c-imx.o 58 58 obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o 59 + obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o 59 60 obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o 60 61 obj-$(CONFIG_I2C_MESON) += i2c-meson.o 61 62 obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
+832
drivers/i2c/busses/i2c-jz4780.c
··· 1 + /* 2 + * Ingenic JZ4780 I2C bus driver 3 + * 4 + * Copyright (C) 2006 - 2009 Ingenic Semiconductor Inc. 5 + * Copyright (C) 2015 Imagination Technologies 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/bitops.h> 19 + #include <linux/clk.h> 20 + #include <linux/completion.h> 21 + #include <linux/delay.h> 22 + #include <linux/errno.h> 23 + #include <linux/i2c.h> 24 + #include <linux/init.h> 25 + #include <linux/interrupt.h> 26 + #include <linux/kernel.h> 27 + #include <linux/module.h> 28 + #include <linux/platform_device.h> 29 + #include <linux/sched.h> 30 + #include <linux/slab.h> 31 + #include <linux/time.h> 32 + 33 + #define JZ4780_I2C_CTRL 0x00 34 + #define JZ4780_I2C_TAR 0x04 35 + #define JZ4780_I2C_SAR 0x08 36 + #define JZ4780_I2C_DC 0x10 37 + #define JZ4780_I2C_SHCNT 0x14 38 + #define JZ4780_I2C_SLCNT 0x18 39 + #define JZ4780_I2C_FHCNT 0x1C 40 + #define JZ4780_I2C_FLCNT 0x20 41 + #define JZ4780_I2C_INTST 0x2C 42 + #define JZ4780_I2C_INTM 0x30 43 + #define JZ4780_I2C_RXTL 0x38 44 + #define JZ4780_I2C_TXTL 0x3C 45 + #define JZ4780_I2C_CINTR 0x40 46 + #define JZ4780_I2C_CRXUF 0x44 47 + #define JZ4780_I2C_CRXOF 0x48 48 + #define JZ4780_I2C_CTXOF 0x4C 49 + #define JZ4780_I2C_CRXREQ 0x50 50 + #define JZ4780_I2C_CTXABRT 0x54 51 + #define JZ4780_I2C_CRXDONE 0x58 52 + #define JZ4780_I2C_CACT 0x5C 53 + #define JZ4780_I2C_CSTP 0x60 54 + #define JZ4780_I2C_CSTT 0x64 55 + #define JZ4780_I2C_CGC 0x68 56 + #define JZ4780_I2C_ENB 0x6C 57 + #define JZ4780_I2C_STA 0x70 58 + #define JZ4780_I2C_TXABRT 0x80 59 + #define JZ4780_I2C_DMACR 0x88 60 + #define JZ4780_I2C_DMATDLR 0x8C 61 + #define JZ4780_I2C_DMARDLR 0x90 62 + #define JZ4780_I2C_SDASU 0x94 63 + #define JZ4780_I2C_ACKGC 0x98 64 + #define JZ4780_I2C_ENSTA 0x9C 65 + #define JZ4780_I2C_SDAHD 0xD0 66 + 67 + #define JZ4780_I2C_CTRL_STPHLD BIT(7) 68 + #define JZ4780_I2C_CTRL_SLVDIS BIT(6) 69 + #define JZ4780_I2C_CTRL_REST BIT(5) 70 + #define JZ4780_I2C_CTRL_MATP BIT(4) 71 + #define JZ4780_I2C_CTRL_SATP BIT(3) 72 + #define JZ4780_I2C_CTRL_SPDF BIT(2) 73 + #define JZ4780_I2C_CTRL_SPDS BIT(1) 74 + #define JZ4780_I2C_CTRL_MD BIT(0) 75 + 76 + #define JZ4780_I2C_STA_SLVACT BIT(6) 77 + #define JZ4780_I2C_STA_MSTACT BIT(5) 78 + #define JZ4780_I2C_STA_RFF BIT(4) 79 + #define JZ4780_I2C_STA_RFNE BIT(3) 80 + #define JZ4780_I2C_STA_TFE BIT(2) 81 + #define JZ4780_I2C_STA_TFNF BIT(1) 82 + #define JZ4780_I2C_STA_ACT BIT(0) 83 + 84 + static const char * const jz4780_i2c_abrt_src[] = { 85 + "ABRT_7B_ADDR_NOACK", 86 + "ABRT_10ADDR1_NOACK", 87 + "ABRT_10ADDR2_NOACK", 88 + "ABRT_XDATA_NOACK", 89 + "ABRT_GCALL_NOACK", 90 + "ABRT_GCALL_READ", 91 + "ABRT_HS_ACKD", 92 + "SBYTE_ACKDET", 93 + "ABRT_HS_NORSTRT", 94 + "SBYTE_NORSTRT", 95 + "ABRT_10B_RD_NORSTRT", 96 + "ABRT_MASTER_DIS", 97 + "ARB_LOST", 98 + "SLVFLUSH_TXFIFO", 99 + "SLV_ARBLOST", 100 + "SLVRD_INTX", 101 + }; 102 + 103 + #define JZ4780_I2C_INTST_IGC BIT(11) 104 + #define JZ4780_I2C_INTST_ISTT BIT(10) 105 + #define JZ4780_I2C_INTST_ISTP BIT(9) 106 + #define JZ4780_I2C_INTST_IACT BIT(8) 107 + #define JZ4780_I2C_INTST_RXDN BIT(7) 108 + #define JZ4780_I2C_INTST_TXABT BIT(6) 109 + #define JZ4780_I2C_INTST_RDREQ BIT(5) 110 + #define JZ4780_I2C_INTST_TXEMP BIT(4) 111 + #define JZ4780_I2C_INTST_TXOF BIT(3) 112 + #define JZ4780_I2C_INTST_RXFL BIT(2) 113 + #define JZ4780_I2C_INTST_RXOF BIT(1) 114 + #define JZ4780_I2C_INTST_RXUF BIT(0) 115 + 116 + #define JZ4780_I2C_INTM_MIGC BIT(11) 117 + #define JZ4780_I2C_INTM_MISTT BIT(10) 118 + #define JZ4780_I2C_INTM_MISTP BIT(9) 119 + #define JZ4780_I2C_INTM_MIACT BIT(8) 120 + #define JZ4780_I2C_INTM_MRXDN BIT(7) 121 + #define JZ4780_I2C_INTM_MTXABT BIT(6) 122 + #define JZ4780_I2C_INTM_MRDREQ BIT(5) 123 + #define JZ4780_I2C_INTM_MTXEMP BIT(4) 124 + #define JZ4780_I2C_INTM_MTXOF BIT(3) 125 + #define JZ4780_I2C_INTM_MRXFL BIT(2) 126 + #define JZ4780_I2C_INTM_MRXOF BIT(1) 127 + #define JZ4780_I2C_INTM_MRXUF BIT(0) 128 + 129 + #define JZ4780_I2C_DC_READ BIT(8) 130 + 131 + #define JZ4780_I2C_SDAHD_HDENB BIT(8) 132 + 133 + #define JZ4780_I2C_ENB_I2C BIT(0) 134 + 135 + #define JZ4780_I2CSHCNT_ADJUST(n) (((n) - 8) < 6 ? 6 : ((n) - 8)) 136 + #define JZ4780_I2CSLCNT_ADJUST(n) (((n) - 1) < 8 ? 8 : ((n) - 1)) 137 + #define JZ4780_I2CFHCNT_ADJUST(n) (((n) - 8) < 6 ? 6 : ((n) - 8)) 138 + #define JZ4780_I2CFLCNT_ADJUST(n) (((n) - 1) < 8 ? 8 : ((n) - 1)) 139 + 140 + #define JZ4780_I2C_FIFO_LEN 16 141 + #define TX_LEVEL 3 142 + #define RX_LEVEL (JZ4780_I2C_FIFO_LEN - TX_LEVEL - 1) 143 + 144 + #define JZ4780_I2C_TIMEOUT 300 145 + 146 + #define BUFSIZE 200 147 + 148 + struct jz4780_i2c { 149 + void __iomem *iomem; 150 + int irq; 151 + struct clk *clk; 152 + struct i2c_adapter adap; 153 + 154 + /* lock to protect rbuf and wbuf between xfer_rd/wr and irq handler */ 155 + spinlock_t lock; 156 + 157 + /* beginning of lock scope */ 158 + unsigned char *rbuf; 159 + int rd_total_len; 160 + int rd_data_xfered; 161 + int rd_cmd_xfered; 162 + 163 + unsigned char *wbuf; 164 + int wt_len; 165 + 166 + int is_write; 167 + int stop_hold; 168 + int speed; 169 + 170 + int data_buf[BUFSIZE]; 171 + int cmd_buf[BUFSIZE]; 172 + int cmd; 173 + 174 + /* end of lock scope */ 175 + struct completion trans_waitq; 176 + }; 177 + 178 + static inline unsigned short jz4780_i2c_readw(struct jz4780_i2c *i2c, 179 + unsigned long offset) 180 + { 181 + return readw(i2c->iomem + offset); 182 + } 183 + 184 + static inline void jz4780_i2c_writew(struct jz4780_i2c *i2c, 185 + unsigned long offset, unsigned short val) 186 + { 187 + writew(val, i2c->iomem + offset); 188 + } 189 + 190 + static int jz4780_i2c_disable(struct jz4780_i2c *i2c) 191 + { 192 + unsigned short regval; 193 + unsigned long loops = 5; 194 + 195 + jz4780_i2c_writew(i2c, JZ4780_I2C_ENB, 0); 196 + 197 + do { 198 + regval = jz4780_i2c_readw(i2c, JZ4780_I2C_ENSTA); 199 + if (!(regval & JZ4780_I2C_ENB_I2C)) 200 + return 0; 201 + 202 + usleep_range(5000, 15000); 203 + } while (--loops); 204 + 205 + dev_err(&i2c->adap.dev, "disable failed: ENSTA=0x%04x\n", regval); 206 + return -ETIMEDOUT; 207 + } 208 + 209 + static int jz4780_i2c_enable(struct jz4780_i2c *i2c) 210 + { 211 + unsigned short regval; 212 + unsigned long loops = 5; 213 + 214 + jz4780_i2c_writew(i2c, JZ4780_I2C_ENB, 1); 215 + 216 + do { 217 + regval = jz4780_i2c_readw(i2c, JZ4780_I2C_ENSTA); 218 + if (regval & JZ4780_I2C_ENB_I2C) 219 + return 0; 220 + 221 + usleep_range(5000, 15000); 222 + } while (--loops); 223 + 224 + dev_err(&i2c->adap.dev, "enable failed: ENSTA=0x%04x\n", regval); 225 + return -ETIMEDOUT; 226 + } 227 + 228 + static int jz4780_i2c_set_target(struct jz4780_i2c *i2c, unsigned char address) 229 + { 230 + unsigned short regval; 231 + unsigned long loops = 5; 232 + 233 + do { 234 + regval = jz4780_i2c_readw(i2c, JZ4780_I2C_STA); 235 + if ((regval & JZ4780_I2C_STA_TFE) && 236 + !(regval & JZ4780_I2C_STA_MSTACT)) 237 + break; 238 + 239 + usleep_range(5000, 15000); 240 + } while (--loops); 241 + 242 + if (loops) { 243 + jz4780_i2c_writew(i2c, JZ4780_I2C_TAR, address); 244 + return 0; 245 + } 246 + 247 + dev_err(&i2c->adap.dev, 248 + "set device to address 0x%02x failed, STA=0x%04x\n", 249 + address, regval); 250 + 251 + return -ENXIO; 252 + } 253 + 254 + static int jz4780_i2c_set_speed(struct jz4780_i2c *i2c) 255 + { 256 + int dev_clk_khz = clk_get_rate(i2c->clk) / 1000; 257 + int cnt_high = 0; /* HIGH period count of the SCL clock */ 258 + int cnt_low = 0; /* LOW period count of the SCL clock */ 259 + int cnt_period = 0; /* period count of the SCL clock */ 260 + int setup_time = 0; 261 + int hold_time = 0; 262 + unsigned short tmp = 0; 263 + int i2c_clk = i2c->speed; 264 + 265 + if (jz4780_i2c_disable(i2c)) 266 + dev_dbg(&i2c->adap.dev, "i2c not disabled\n"); 267 + 268 + /* 269 + * 1 JZ4780_I2C cycle equals to cnt_period PCLK(i2c_clk) 270 + * standard mode, min LOW and HIGH period are 4700 ns and 4000 ns 271 + * fast mode, min LOW and HIGH period are 1300 ns and 600 ns 272 + */ 273 + cnt_period = dev_clk_khz / i2c_clk; 274 + 275 + if (i2c_clk <= 100) 276 + cnt_high = (cnt_period * 4000) / (4700 + 4000); 277 + else 278 + cnt_high = (cnt_period * 600) / (1300 + 600); 279 + 280 + cnt_low = cnt_period - cnt_high; 281 + 282 + /* 283 + * NOTE: JZ4780_I2C_CTRL_REST can't set when i2c enabled, because 284 + * normal read are 2 messages, we cannot disable i2c controller 285 + * between these two messages, this means that we must always set 286 + * JZ4780_I2C_CTRL_REST when init JZ4780_I2C_CTRL 287 + * 288 + */ 289 + if (i2c_clk <= 100) { 290 + tmp = JZ4780_I2C_CTRL_SPDS | JZ4780_I2C_CTRL_REST 291 + | JZ4780_I2C_CTRL_SLVDIS | JZ4780_I2C_CTRL_MD; 292 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 293 + 294 + jz4780_i2c_writew(i2c, JZ4780_I2C_SHCNT, 295 + JZ4780_I2CSHCNT_ADJUST(cnt_high)); 296 + jz4780_i2c_writew(i2c, JZ4780_I2C_SLCNT, 297 + JZ4780_I2CSLCNT_ADJUST(cnt_low)); 298 + } else { 299 + tmp = JZ4780_I2C_CTRL_SPDF | JZ4780_I2C_CTRL_REST 300 + | JZ4780_I2C_CTRL_SLVDIS | JZ4780_I2C_CTRL_MD; 301 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 302 + 303 + jz4780_i2c_writew(i2c, JZ4780_I2C_FHCNT, 304 + JZ4780_I2CFHCNT_ADJUST(cnt_high)); 305 + jz4780_i2c_writew(i2c, JZ4780_I2C_FLCNT, 306 + JZ4780_I2CFLCNT_ADJUST(cnt_low)); 307 + } 308 + 309 + /* 310 + * a i2c device must internally provide a hold time at least 300ns 311 + * tHD:DAT 312 + * Standard Mode: min=300ns, max=3450ns 313 + * Fast Mode: min=0ns, max=900ns 314 + * tSU:DAT 315 + * Standard Mode: min=250ns, max=infinite 316 + * Fast Mode: min=100(250ns is recommended), max=infinite 317 + * 318 + * 1i2c_clk = 10^6 / dev_clk_khz 319 + * on FPGA, dev_clk_khz = 12000, so 1i2c_clk = 1000/12 = 83ns 320 + * on Pisces(1008M), dev_clk_khz=126000, so 1i2c_clk = 1000 / 126 = 8ns 321 + * 322 + * The actual hold time is (SDAHD + 1) * (i2c_clk period). 323 + * 324 + * Length of setup time calculated using (SDASU - 1) * (ic_clk_period) 325 + * 326 + */ 327 + if (i2c_clk <= 100) { /* standard mode */ 328 + setup_time = 300; 329 + hold_time = 400; 330 + } else { 331 + setup_time = 450; 332 + hold_time = 450; 333 + } 334 + 335 + hold_time = ((hold_time * dev_clk_khz) / 1000000) - 1; 336 + setup_time = ((setup_time * dev_clk_khz) / 1000000) + 1; 337 + 338 + if (setup_time > 255) 339 + setup_time = 255; 340 + 341 + if (setup_time <= 0) 342 + setup_time = 1; 343 + 344 + jz4780_i2c_writew(i2c, JZ4780_I2C_SDASU, setup_time); 345 + 346 + if (hold_time > 255) 347 + hold_time = 255; 348 + 349 + if (hold_time >= 0) { 350 + /*i2c hold time enable */ 351 + hold_time |= JZ4780_I2C_SDAHD_HDENB; 352 + jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, hold_time); 353 + } else { 354 + /* disable hold time */ 355 + jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, 0); 356 + } 357 + 358 + return 0; 359 + } 360 + 361 + static int jz4780_i2c_cleanup(struct jz4780_i2c *i2c) 362 + { 363 + int ret; 364 + unsigned long flags; 365 + unsigned short tmp; 366 + 367 + spin_lock_irqsave(&i2c->lock, flags); 368 + 369 + /* can send stop now if need */ 370 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL); 371 + tmp &= ~JZ4780_I2C_CTRL_STPHLD; 372 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 373 + 374 + /* disable all interrupts first */ 375 + jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0); 376 + 377 + /* then clear all interrupts */ 378 + jz4780_i2c_readw(i2c, JZ4780_I2C_CTXABRT); 379 + jz4780_i2c_readw(i2c, JZ4780_I2C_CINTR); 380 + 381 + /* then disable the controller */ 382 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL); 383 + tmp &= ~JZ4780_I2C_ENB_I2C; 384 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 385 + udelay(10); 386 + tmp |= JZ4780_I2C_ENB_I2C; 387 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 388 + 389 + spin_unlock_irqrestore(&i2c->lock, flags); 390 + 391 + ret = jz4780_i2c_disable(i2c); 392 + if (ret) 393 + dev_err(&i2c->adap.dev, 394 + "unable to disable device during cleanup!\n"); 395 + 396 + if (unlikely(jz4780_i2c_readw(i2c, JZ4780_I2C_INTM) 397 + & jz4780_i2c_readw(i2c, JZ4780_I2C_INTST))) 398 + dev_err(&i2c->adap.dev, 399 + "device has interrupts after a complete cleanup!\n"); 400 + 401 + return ret; 402 + } 403 + 404 + static int jz4780_i2c_prepare(struct jz4780_i2c *i2c) 405 + { 406 + jz4780_i2c_set_speed(i2c); 407 + return jz4780_i2c_enable(i2c); 408 + } 409 + 410 + static void jz4780_i2c_send_rcmd(struct jz4780_i2c *i2c, int cmd_count) 411 + { 412 + int i; 413 + 414 + for (i = 0; i < cmd_count; i++) 415 + jz4780_i2c_writew(i2c, JZ4780_I2C_DC, JZ4780_I2C_DC_READ); 416 + } 417 + 418 + static void jz4780_i2c_trans_done(struct jz4780_i2c *i2c) 419 + { 420 + jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0); 421 + complete(&i2c->trans_waitq); 422 + } 423 + 424 + static irqreturn_t jz4780_i2c_irq(int irqno, void *dev_id) 425 + { 426 + unsigned short tmp; 427 + unsigned short intst; 428 + unsigned short intmsk; 429 + struct jz4780_i2c *i2c = dev_id; 430 + unsigned long flags; 431 + 432 + spin_lock_irqsave(&i2c->lock, flags); 433 + intmsk = jz4780_i2c_readw(i2c, JZ4780_I2C_INTM); 434 + intst = jz4780_i2c_readw(i2c, JZ4780_I2C_INTST); 435 + 436 + intst &= intmsk; 437 + 438 + if (intst & JZ4780_I2C_INTST_TXABT) { 439 + jz4780_i2c_trans_done(i2c); 440 + goto done; 441 + } 442 + 443 + if (intst & JZ4780_I2C_INTST_RXOF) { 444 + dev_dbg(&i2c->adap.dev, "received fifo overflow!\n"); 445 + jz4780_i2c_trans_done(i2c); 446 + goto done; 447 + } 448 + 449 + /* 450 + * When reading, always drain RX FIFO before we send more Read 451 + * Commands to avoid fifo overrun 452 + */ 453 + if (i2c->is_write == 0) { 454 + int rd_left; 455 + 456 + while ((jz4780_i2c_readw(i2c, JZ4780_I2C_STA) 457 + & JZ4780_I2C_STA_RFNE)) { 458 + *(i2c->rbuf++) = jz4780_i2c_readw(i2c, JZ4780_I2C_DC) 459 + & 0xff; 460 + i2c->rd_data_xfered++; 461 + if (i2c->rd_data_xfered == i2c->rd_total_len) { 462 + jz4780_i2c_trans_done(i2c); 463 + goto done; 464 + } 465 + } 466 + 467 + rd_left = i2c->rd_total_len - i2c->rd_data_xfered; 468 + 469 + if (rd_left <= JZ4780_I2C_FIFO_LEN) 470 + jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, rd_left - 1); 471 + } 472 + 473 + if (intst & JZ4780_I2C_INTST_TXEMP) { 474 + if (i2c->is_write == 0) { 475 + int cmd_left = i2c->rd_total_len - i2c->rd_cmd_xfered; 476 + int max_send = (JZ4780_I2C_FIFO_LEN - 1) 477 + - (i2c->rd_cmd_xfered 478 + - i2c->rd_data_xfered); 479 + int cmd_to_send = min(cmd_left, max_send); 480 + 481 + if (i2c->rd_cmd_xfered != 0) 482 + cmd_to_send = min(cmd_to_send, 483 + JZ4780_I2C_FIFO_LEN 484 + - TX_LEVEL - 1); 485 + 486 + if (cmd_to_send) { 487 + jz4780_i2c_send_rcmd(i2c, cmd_to_send); 488 + i2c->rd_cmd_xfered += cmd_to_send; 489 + } 490 + 491 + cmd_left = i2c->rd_total_len - i2c->rd_cmd_xfered; 492 + if (cmd_left == 0) { 493 + intmsk = jz4780_i2c_readw(i2c, JZ4780_I2C_INTM); 494 + intmsk &= ~JZ4780_I2C_INTM_MTXEMP; 495 + jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, intmsk); 496 + 497 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL); 498 + tmp &= ~JZ4780_I2C_CTRL_STPHLD; 499 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 500 + } 501 + } else { 502 + unsigned short data; 503 + unsigned short i2c_sta; 504 + 505 + i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA); 506 + 507 + while ((i2c_sta & JZ4780_I2C_STA_TFNF) && 508 + (i2c->wt_len > 0)) { 509 + i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA); 510 + data = *i2c->wbuf; 511 + data &= ~JZ4780_I2C_DC_READ; 512 + jz4780_i2c_writew(i2c, JZ4780_I2C_DC, 513 + data); 514 + i2c->wbuf++; 515 + i2c->wt_len--; 516 + } 517 + 518 + if (i2c->wt_len == 0) { 519 + if (!i2c->stop_hold) { 520 + tmp = jz4780_i2c_readw(i2c, 521 + JZ4780_I2C_CTRL); 522 + tmp &= ~JZ4780_I2C_CTRL_STPHLD; 523 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, 524 + tmp); 525 + } 526 + 527 + jz4780_i2c_trans_done(i2c); 528 + goto done; 529 + } 530 + } 531 + } 532 + 533 + done: 534 + spin_unlock_irqrestore(&i2c->lock, flags); 535 + return IRQ_HANDLED; 536 + } 537 + 538 + static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src) 539 + { 540 + int i; 541 + 542 + dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src); 543 + dev_err(&i2c->adap.dev, "device addr=%x\n", 544 + jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)); 545 + dev_err(&i2c->adap.dev, "send cmd count:%d %d\n", 546 + i2c->cmd, i2c->cmd_buf[i2c->cmd]); 547 + dev_err(&i2c->adap.dev, "receive data count:%d %d\n", 548 + i2c->cmd, i2c->data_buf[i2c->cmd]); 549 + 550 + for (i = 0; i < 16; i++) { 551 + if (src & BIT(i)) 552 + dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n", 553 + i, jz4780_i2c_abrt_src[i]); 554 + } 555 + } 556 + 557 + static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c, 558 + unsigned char *buf, int len, int cnt, 559 + int idx) 560 + { 561 + int ret = 0; 562 + long timeout; 563 + int wait_time = JZ4780_I2C_TIMEOUT * (len + 5); 564 + unsigned short tmp; 565 + unsigned long flags; 566 + 567 + memset(buf, 0, len); 568 + 569 + spin_lock_irqsave(&i2c->lock, flags); 570 + 571 + i2c->stop_hold = 0; 572 + i2c->is_write = 0; 573 + i2c->rbuf = buf; 574 + i2c->rd_total_len = len; 575 + i2c->rd_data_xfered = 0; 576 + i2c->rd_cmd_xfered = 0; 577 + 578 + if (len <= JZ4780_I2C_FIFO_LEN) 579 + jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, len - 1); 580 + else 581 + jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, RX_LEVEL); 582 + 583 + jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, TX_LEVEL); 584 + 585 + jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 586 + JZ4780_I2C_INTM_MRXFL | JZ4780_I2C_INTM_MTXEMP 587 + | JZ4780_I2C_INTM_MTXABT | JZ4780_I2C_INTM_MRXOF); 588 + 589 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL); 590 + tmp |= JZ4780_I2C_CTRL_STPHLD; 591 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 592 + 593 + spin_unlock_irqrestore(&i2c->lock, flags); 594 + 595 + timeout = wait_for_completion_timeout(&i2c->trans_waitq, 596 + msecs_to_jiffies(wait_time)); 597 + 598 + if (!timeout) { 599 + dev_err(&i2c->adap.dev, "irq read timeout\n"); 600 + dev_dbg(&i2c->adap.dev, "send cmd count:%d %d\n", 601 + i2c->cmd, i2c->cmd_buf[i2c->cmd]); 602 + dev_dbg(&i2c->adap.dev, "receive data count:%d %d\n", 603 + i2c->cmd, i2c->data_buf[i2c->cmd]); 604 + ret = -EIO; 605 + } 606 + 607 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_TXABRT); 608 + if (tmp) { 609 + jz4780_i2c_txabrt(i2c, tmp); 610 + ret = -EIO; 611 + } 612 + 613 + return ret; 614 + } 615 + 616 + static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c, 617 + unsigned char *buf, int len, 618 + int cnt, int idx) 619 + { 620 + int ret = 0; 621 + int wait_time = JZ4780_I2C_TIMEOUT * (len + 5); 622 + long timeout; 623 + unsigned short tmp; 624 + unsigned long flags; 625 + 626 + spin_lock_irqsave(&i2c->lock, flags); 627 + 628 + if (idx < (cnt - 1)) 629 + i2c->stop_hold = 1; 630 + else 631 + i2c->stop_hold = 0; 632 + 633 + i2c->is_write = 1; 634 + i2c->wbuf = buf; 635 + i2c->wt_len = len; 636 + 637 + jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, TX_LEVEL); 638 + 639 + jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, JZ4780_I2C_INTM_MTXEMP 640 + | JZ4780_I2C_INTM_MTXABT); 641 + 642 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL); 643 + tmp |= JZ4780_I2C_CTRL_STPHLD; 644 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 645 + 646 + spin_unlock_irqrestore(&i2c->lock, flags); 647 + 648 + timeout = wait_for_completion_timeout(&i2c->trans_waitq, 649 + msecs_to_jiffies(wait_time)); 650 + if (timeout && !i2c->stop_hold) { 651 + unsigned short i2c_sta; 652 + int write_in_process; 653 + 654 + timeout = JZ4780_I2C_TIMEOUT * 100; 655 + for (; timeout > 0; timeout--) { 656 + i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA); 657 + 658 + write_in_process = (i2c_sta & JZ4780_I2C_STA_MSTACT) || 659 + !(i2c_sta & JZ4780_I2C_STA_TFE); 660 + if (!write_in_process) 661 + break; 662 + udelay(10); 663 + } 664 + } 665 + 666 + if (!timeout) { 667 + dev_err(&i2c->adap.dev, "write wait timeout\n"); 668 + ret = -EIO; 669 + } 670 + 671 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_TXABRT); 672 + if (tmp) { 673 + jz4780_i2c_txabrt(i2c, tmp); 674 + ret = -EIO; 675 + } 676 + 677 + return ret; 678 + } 679 + 680 + static int jz4780_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, 681 + int count) 682 + { 683 + int i = -EIO; 684 + int ret = 0; 685 + struct jz4780_i2c *i2c = adap->algo_data; 686 + 687 + ret = jz4780_i2c_prepare(i2c); 688 + if (ret) { 689 + dev_err(&i2c->adap.dev, "I2C prepare failed\n"); 690 + goto out; 691 + } 692 + 693 + if (msg->addr != jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)) { 694 + ret = jz4780_i2c_set_target(i2c, msg->addr); 695 + if (ret) 696 + goto out; 697 + } 698 + for (i = 0; i < count; i++, msg++) { 699 + if (msg->flags & I2C_M_RD) 700 + ret = jz4780_i2c_xfer_read(i2c, msg->buf, msg->len, 701 + count, i); 702 + else 703 + ret = jz4780_i2c_xfer_write(i2c, msg->buf, msg->len, 704 + count, i); 705 + 706 + if (ret) 707 + goto out; 708 + } 709 + 710 + ret = i; 711 + 712 + out: 713 + jz4780_i2c_cleanup(i2c); 714 + return ret; 715 + } 716 + 717 + static u32 jz4780_i2c_functionality(struct i2c_adapter *adap) 718 + { 719 + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 720 + } 721 + 722 + static const struct i2c_algorithm jz4780_i2c_algorithm = { 723 + .master_xfer = jz4780_i2c_xfer, 724 + .functionality = jz4780_i2c_functionality, 725 + }; 726 + 727 + static const struct of_device_id jz4780_i2c_of_matches[] = { 728 + { .compatible = "ingenic,jz4780-i2c", }, 729 + { /* sentinel */ } 730 + }; 731 + 732 + static int jz4780_i2c_probe(struct platform_device *pdev) 733 + { 734 + int ret = 0; 735 + unsigned int clk_freq = 0; 736 + unsigned short tmp; 737 + struct resource *r; 738 + struct jz4780_i2c *i2c; 739 + 740 + i2c = devm_kzalloc(&pdev->dev, sizeof(struct jz4780_i2c), GFP_KERNEL); 741 + if (!i2c) 742 + return -ENOMEM; 743 + 744 + i2c->adap.owner = THIS_MODULE; 745 + i2c->adap.algo = &jz4780_i2c_algorithm; 746 + i2c->adap.algo_data = i2c; 747 + i2c->adap.retries = 5; 748 + i2c->adap.dev.parent = &pdev->dev; 749 + i2c->adap.dev.of_node = pdev->dev.of_node; 750 + sprintf(i2c->adap.name, "%s", pdev->name); 751 + 752 + init_completion(&i2c->trans_waitq); 753 + spin_lock_init(&i2c->lock); 754 + 755 + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 756 + i2c->iomem = devm_ioremap_resource(&pdev->dev, r); 757 + if (IS_ERR(i2c->iomem)) 758 + return PTR_ERR(i2c->iomem); 759 + 760 + platform_set_drvdata(pdev, i2c); 761 + 762 + i2c->clk = devm_clk_get(&pdev->dev, NULL); 763 + if (IS_ERR(i2c->clk)) 764 + return PTR_ERR(i2c->clk); 765 + 766 + clk_prepare_enable(i2c->clk); 767 + 768 + if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", 769 + &clk_freq)) { 770 + dev_err(&pdev->dev, "clock-frequency not specified in DT"); 771 + return clk_freq; 772 + } 773 + 774 + i2c->speed = clk_freq / 1000; 775 + jz4780_i2c_set_speed(i2c); 776 + 777 + dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed); 778 + 779 + tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL); 780 + tmp &= ~JZ4780_I2C_CTRL_STPHLD; 781 + jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp); 782 + 783 + jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0x0); 784 + 785 + i2c->cmd = 0; 786 + memset(i2c->cmd_buf, 0, BUFSIZE); 787 + memset(i2c->data_buf, 0, BUFSIZE); 788 + 789 + i2c->irq = platform_get_irq(pdev, 0); 790 + ret = devm_request_irq(&pdev->dev, i2c->irq, jz4780_i2c_irq, 0, 791 + dev_name(&pdev->dev), i2c); 792 + if (ret) { 793 + ret = -ENODEV; 794 + goto err; 795 + } 796 + 797 + ret = i2c_add_adapter(&i2c->adap); 798 + if (ret < 0) { 799 + dev_err(&pdev->dev, "Failed to add bus\n"); 800 + goto err; 801 + } 802 + 803 + return 0; 804 + 805 + err: 806 + clk_disable_unprepare(i2c->clk); 807 + return ret; 808 + } 809 + 810 + static int jz4780_i2c_remove(struct platform_device *pdev) 811 + { 812 + struct jz4780_i2c *i2c = platform_get_drvdata(pdev); 813 + 814 + clk_disable_unprepare(i2c->clk); 815 + i2c_del_adapter(&i2c->adap); 816 + return 0; 817 + } 818 + 819 + static struct platform_driver jz4780_i2c_driver = { 820 + .probe = jz4780_i2c_probe, 821 + .remove = jz4780_i2c_remove, 822 + .driver = { 823 + .name = "jz4780-i2c", 824 + .of_match_table = of_match_ptr(jz4780_i2c_of_matches), 825 + }, 826 + }; 827 + 828 + module_platform_driver(jz4780_i2c_driver); 829 + 830 + MODULE_LICENSE("GPL"); 831 + MODULE_AUTHOR("ztyan<ztyan@ingenic.cn>"); 832 + MODULE_DESCRIPTION("i2c driver for JZ4780 SoCs");