Home | History | Annotate | Download | only in km83xx
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2011
      4  * Holger Brunck, Keymile GmbH Hannover, holger.brunck (at) 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 
     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 
     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