1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2011
4 * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com
5 */
6
7 #include <common.h>
8 #include <i2c.h>
9 #include <asm/io.h>
10 #include <linux/ctype.h>
11 #include "../common/common.h"
12
i2c_write_start_seq(void)13 static void i2c_write_start_seq(void)
14 {
15 struct fsl_i2c_base *base;
16 base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +
17 CONFIG_SYS_I2C_OFFSET);
18 udelay(DELAY_ABORT_SEQ);
19 out_8(&base->cr, (I2C_CR_MEN | I2C_CR_MSTA));
20 udelay(DELAY_ABORT_SEQ);
21 out_8(&base->cr, (I2C_CR_MEN));
22 }
23
i2c_make_abort(void)24 int i2c_make_abort(void)
25 {
26 struct fsl_i2c_base *base;
27 base = (struct fsl_i2c_base *)(CONFIG_SYS_IMMR +
28 CONFIG_SYS_I2C_OFFSET);
29 uchar last;
30 int nbr_read = 0;
31 int i = 0;
32 int ret = 0;
33
34 /* wait after each operation to finsh with a delay */
35 out_8(&base->cr, (I2C_CR_MSTA));
36 udelay(DELAY_ABORT_SEQ);
37 out_8(&base->cr, (I2C_CR_MEN | I2C_CR_MSTA));
38 udelay(DELAY_ABORT_SEQ);
39 in_8(&base->dr);
40 udelay(DELAY_ABORT_SEQ);
41 last = in_8(&base->dr);
42 nbr_read++;
43
44 /*
45 * do read until the last bit is 1, but stop if the full eeprom is
46 * read.
47 */
48 while (((last & 0x01) != 0x01) &&
49 (nbr_read < CONFIG_SYS_IVM_EEPROM_MAX_LEN)) {
50 udelay(DELAY_ABORT_SEQ);
51 last = in_8(&base->dr);
52 nbr_read++;
53 }
54 if ((last & 0x01) != 0x01)
55 ret = -2;
56 if ((last != 0xff) || (nbr_read > 1))
57 printf("[INFO] i2c abort after %d bytes (0x%02x)\n",
58 nbr_read, last);
59 udelay(DELAY_ABORT_SEQ);
60 out_8(&base->cr, (I2C_CR_MEN));
61 udelay(DELAY_ABORT_SEQ);
62 /* clear status reg */
63 out_8(&base->sr, 0);
64
65 for (i = 0; i < 5; i++)
66 i2c_write_start_seq();
67 if (ret != 0)
68 printf("[ERROR] i2c abort failed after %d bytes (0x%02x)\n",
69 nbr_read, last);
70
71 return ret;
72 }
73