1080c646dSJean-Christophe PLAGNIOL-VILLARD /* 2080c646dSJean-Christophe PLAGNIOL-VILLARD * Basic I2C functions 3080c646dSJean-Christophe PLAGNIOL-VILLARD * 4080c646dSJean-Christophe PLAGNIOL-VILLARD * Copyright (c) 2004 Texas Instruments 5080c646dSJean-Christophe PLAGNIOL-VILLARD * 6080c646dSJean-Christophe PLAGNIOL-VILLARD * This package is free software; you can redistribute it and/or 7080c646dSJean-Christophe PLAGNIOL-VILLARD * modify it under the terms of the license found in the file 8080c646dSJean-Christophe PLAGNIOL-VILLARD * named COPYING that should have accompanied this file. 9080c646dSJean-Christophe PLAGNIOL-VILLARD * 10080c646dSJean-Christophe PLAGNIOL-VILLARD * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 11080c646dSJean-Christophe PLAGNIOL-VILLARD * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 12080c646dSJean-Christophe PLAGNIOL-VILLARD * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13080c646dSJean-Christophe PLAGNIOL-VILLARD * 14080c646dSJean-Christophe PLAGNIOL-VILLARD * Author: Jian Zhang jzhang@ti.com, Texas Instruments 15080c646dSJean-Christophe PLAGNIOL-VILLARD * 16080c646dSJean-Christophe PLAGNIOL-VILLARD * Copyright (c) 2003 Wolfgang Denk, wd@denx.de 17080c646dSJean-Christophe PLAGNIOL-VILLARD * Rewritten to fit into the current U-Boot framework 18080c646dSJean-Christophe PLAGNIOL-VILLARD * 19080c646dSJean-Christophe PLAGNIOL-VILLARD * Adapted for OMAP2420 I2C, r-woodruff2@ti.com 20080c646dSJean-Christophe PLAGNIOL-VILLARD * 21080c646dSJean-Christophe PLAGNIOL-VILLARD */ 22080c646dSJean-Christophe PLAGNIOL-VILLARD 23080c646dSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 24080c646dSJean-Christophe PLAGNIOL-VILLARD 25080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c.h> 26080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h> 27080c646dSJean-Christophe PLAGNIOL-VILLARD 28080c646dSJean-Christophe PLAGNIOL-VILLARD static void wait_for_bb (void); 29080c646dSJean-Christophe PLAGNIOL-VILLARD static u16 wait_for_pin (void); 30080c646dSJean-Christophe PLAGNIOL-VILLARD static void flush_fifo(void); 31080c646dSJean-Christophe PLAGNIOL-VILLARD 32080c646dSJean-Christophe PLAGNIOL-VILLARD void i2c_init (int speed, int slaveadd) 33080c646dSJean-Christophe PLAGNIOL-VILLARD { 34080c646dSJean-Christophe PLAGNIOL-VILLARD u16 scl; 35080c646dSJean-Christophe PLAGNIOL-VILLARD 36e23c7c95SDirk Behme writew(0x2, I2C_SYSC); /* for ES2 after soft reset */ 37080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(1000); 38e23c7c95SDirk Behme writew(0x0, I2C_SYSC); /* will probably self clear but */ 39080c646dSJean-Christophe PLAGNIOL-VILLARD 40e23c7c95SDirk Behme if (readw (I2C_CON) & I2C_CON_EN) { 41e23c7c95SDirk Behme writew (0, I2C_CON); 42080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (50000); 43080c646dSJean-Christophe PLAGNIOL-VILLARD } 44080c646dSJean-Christophe PLAGNIOL-VILLARD 458ed44d91SWolfgang Denk /* 12MHz I2C module clock */ 46e23c7c95SDirk Behme writew (0, I2C_PSC); 47080c646dSJean-Christophe PLAGNIOL-VILLARD speed = speed/1000; /* 100 or 400 */ 48080c646dSJean-Christophe PLAGNIOL-VILLARD scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */ 49e23c7c95SDirk Behme writew (scl, I2C_SCLL); 50e23c7c95SDirk Behme writew (scl, I2C_SCLH); 51080c646dSJean-Christophe PLAGNIOL-VILLARD /* own address */ 52e23c7c95SDirk Behme writew (slaveadd, I2C_OA); 53e23c7c95SDirk Behme writew (I2C_CON_EN, I2C_CON); 54080c646dSJean-Christophe PLAGNIOL-VILLARD 55080c646dSJean-Christophe PLAGNIOL-VILLARD /* have to enable intrrupts or OMAP i2c module doesn't work */ 56e23c7c95SDirk Behme writew (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | 57080c646dSJean-Christophe PLAGNIOL-VILLARD I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE); 58080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (1000); 59080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 60e23c7c95SDirk Behme writew (0xFFFF, I2C_STAT); 61e23c7c95SDirk Behme writew (0, I2C_CNT); 62080c646dSJean-Christophe PLAGNIOL-VILLARD } 63080c646dSJean-Christophe PLAGNIOL-VILLARD 64080c646dSJean-Christophe PLAGNIOL-VILLARD static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) 65080c646dSJean-Christophe PLAGNIOL-VILLARD { 66080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_error = 0; 67080c646dSJean-Christophe PLAGNIOL-VILLARD u16 status; 68080c646dSJean-Christophe PLAGNIOL-VILLARD 69080c646dSJean-Christophe PLAGNIOL-VILLARD /* wait until bus not busy */ 70080c646dSJean-Christophe PLAGNIOL-VILLARD wait_for_bb (); 71080c646dSJean-Christophe PLAGNIOL-VILLARD 72080c646dSJean-Christophe PLAGNIOL-VILLARD /* one byte only */ 73e23c7c95SDirk Behme writew (1, I2C_CNT); 74080c646dSJean-Christophe PLAGNIOL-VILLARD /* set slave address */ 75e23c7c95SDirk Behme writew (devaddr, I2C_SA); 76080c646dSJean-Christophe PLAGNIOL-VILLARD /* no stop bit needed here */ 77e23c7c95SDirk Behme writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON); 78080c646dSJean-Christophe PLAGNIOL-VILLARD 79080c646dSJean-Christophe PLAGNIOL-VILLARD status = wait_for_pin (); 80080c646dSJean-Christophe PLAGNIOL-VILLARD 81080c646dSJean-Christophe PLAGNIOL-VILLARD if (status & I2C_STAT_XRDY) { 82080c646dSJean-Christophe PLAGNIOL-VILLARD /* Important: have to use byte access */ 83e23c7c95SDirk Behme writeb (regoffset, I2C_DATA); 84080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (20000); 85e23c7c95SDirk Behme if (readw (I2C_STAT) & I2C_STAT_NACK) { 86080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_error = 1; 87080c646dSJean-Christophe PLAGNIOL-VILLARD } 88080c646dSJean-Christophe PLAGNIOL-VILLARD } else { 89080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_error = 1; 90080c646dSJean-Christophe PLAGNIOL-VILLARD } 91080c646dSJean-Christophe PLAGNIOL-VILLARD 92080c646dSJean-Christophe PLAGNIOL-VILLARD if (!i2c_error) { 93080c646dSJean-Christophe PLAGNIOL-VILLARD /* free bus, otherwise we can't use a combined transction */ 94e23c7c95SDirk Behme writew (0, I2C_CON); 95e23c7c95SDirk Behme while (readw (I2C_STAT) || (readw (I2C_CON) & I2C_CON_MST)) { 96080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (10000); 97080c646dSJean-Christophe PLAGNIOL-VILLARD /* Have to clear pending interrupt to clear I2C_STAT */ 98e23c7c95SDirk Behme writew (0xFFFF, I2C_STAT); 99080c646dSJean-Christophe PLAGNIOL-VILLARD } 100080c646dSJean-Christophe PLAGNIOL-VILLARD 101080c646dSJean-Christophe PLAGNIOL-VILLARD wait_for_bb (); 102080c646dSJean-Christophe PLAGNIOL-VILLARD /* set slave address */ 103e23c7c95SDirk Behme writew (devaddr, I2C_SA); 104080c646dSJean-Christophe PLAGNIOL-VILLARD /* read one byte from slave */ 105e23c7c95SDirk Behme writew (1, I2C_CNT); 106080c646dSJean-Christophe PLAGNIOL-VILLARD /* need stop bit here */ 107e23c7c95SDirk Behme writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, 108080c646dSJean-Christophe PLAGNIOL-VILLARD I2C_CON); 109080c646dSJean-Christophe PLAGNIOL-VILLARD 110080c646dSJean-Christophe PLAGNIOL-VILLARD status = wait_for_pin (); 111080c646dSJean-Christophe PLAGNIOL-VILLARD if (status & I2C_STAT_RRDY) { 112*7d264c1eSDirk Behme #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 113*7d264c1eSDirk Behme *value = readb (I2C_DATA); 114*7d264c1eSDirk Behme #else 115e23c7c95SDirk Behme *value = readw (I2C_DATA); 116*7d264c1eSDirk Behme #endif 117080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (20000); 118080c646dSJean-Christophe PLAGNIOL-VILLARD } else { 119080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_error = 1; 120080c646dSJean-Christophe PLAGNIOL-VILLARD } 121080c646dSJean-Christophe PLAGNIOL-VILLARD 122080c646dSJean-Christophe PLAGNIOL-VILLARD if (!i2c_error) { 123e23c7c95SDirk Behme writew (I2C_CON_EN, I2C_CON); 124e23c7c95SDirk Behme while (readw (I2C_STAT) 125e23c7c95SDirk Behme || (readw (I2C_CON) & I2C_CON_MST)) { 126080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (10000); 127e23c7c95SDirk Behme writew (0xFFFF, I2C_STAT); 128080c646dSJean-Christophe PLAGNIOL-VILLARD } 129080c646dSJean-Christophe PLAGNIOL-VILLARD } 130080c646dSJean-Christophe PLAGNIOL-VILLARD } 131080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 132e23c7c95SDirk Behme writew (0xFFFF, I2C_STAT); 133e23c7c95SDirk Behme writew (0, I2C_CNT); 134080c646dSJean-Christophe PLAGNIOL-VILLARD return i2c_error; 135080c646dSJean-Christophe PLAGNIOL-VILLARD } 136080c646dSJean-Christophe PLAGNIOL-VILLARD 137080c646dSJean-Christophe PLAGNIOL-VILLARD static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value) 138080c646dSJean-Christophe PLAGNIOL-VILLARD { 139080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_error = 0; 140080c646dSJean-Christophe PLAGNIOL-VILLARD u16 status, stat; 141080c646dSJean-Christophe PLAGNIOL-VILLARD 142080c646dSJean-Christophe PLAGNIOL-VILLARD /* wait until bus not busy */ 143080c646dSJean-Christophe PLAGNIOL-VILLARD wait_for_bb (); 144080c646dSJean-Christophe PLAGNIOL-VILLARD 145080c646dSJean-Christophe PLAGNIOL-VILLARD /* two bytes */ 146e23c7c95SDirk Behme writew (2, I2C_CNT); 147080c646dSJean-Christophe PLAGNIOL-VILLARD /* set slave address */ 148e23c7c95SDirk Behme writew (devaddr, I2C_SA); 149080c646dSJean-Christophe PLAGNIOL-VILLARD /* stop bit needed here */ 150e23c7c95SDirk Behme writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | 151080c646dSJean-Christophe PLAGNIOL-VILLARD I2C_CON_STP, I2C_CON); 152080c646dSJean-Christophe PLAGNIOL-VILLARD 153080c646dSJean-Christophe PLAGNIOL-VILLARD /* wait until state change */ 154080c646dSJean-Christophe PLAGNIOL-VILLARD status = wait_for_pin (); 155080c646dSJean-Christophe PLAGNIOL-VILLARD 156080c646dSJean-Christophe PLAGNIOL-VILLARD if (status & I2C_STAT_XRDY) { 157*7d264c1eSDirk Behme #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 158*7d264c1eSDirk Behme /* send out 1 byte */ 159*7d264c1eSDirk Behme writeb (regoffset, I2C_DATA); 160*7d264c1eSDirk Behme writew (I2C_STAT_XRDY, I2C_STAT); 161*7d264c1eSDirk Behme 162*7d264c1eSDirk Behme status = wait_for_pin (); 163*7d264c1eSDirk Behme if ((status & I2C_STAT_XRDY)) { 164*7d264c1eSDirk Behme /* send out next 1 byte */ 165*7d264c1eSDirk Behme writeb (value, I2C_DATA); 166*7d264c1eSDirk Behme writew (I2C_STAT_XRDY, I2C_STAT); 167*7d264c1eSDirk Behme } else { 168*7d264c1eSDirk Behme i2c_error = 1; 169*7d264c1eSDirk Behme } 170*7d264c1eSDirk Behme #else 171080c646dSJean-Christophe PLAGNIOL-VILLARD /* send out two bytes */ 172e23c7c95SDirk Behme writew ((value << 8) + regoffset, I2C_DATA); 173*7d264c1eSDirk Behme #endif 174080c646dSJean-Christophe PLAGNIOL-VILLARD /* must have enough delay to allow BB bit to go low */ 175080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (50000); 176e23c7c95SDirk Behme if (readw (I2C_STAT) & I2C_STAT_NACK) { 177080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_error = 1; 178080c646dSJean-Christophe PLAGNIOL-VILLARD } 179080c646dSJean-Christophe PLAGNIOL-VILLARD } else { 180080c646dSJean-Christophe PLAGNIOL-VILLARD i2c_error = 1; 181080c646dSJean-Christophe PLAGNIOL-VILLARD } 182080c646dSJean-Christophe PLAGNIOL-VILLARD 183080c646dSJean-Christophe PLAGNIOL-VILLARD if (!i2c_error) { 184080c646dSJean-Christophe PLAGNIOL-VILLARD int eout = 200; 185080c646dSJean-Christophe PLAGNIOL-VILLARD 186e23c7c95SDirk Behme writew (I2C_CON_EN, I2C_CON); 187e23c7c95SDirk Behme while ((stat = readw (I2C_STAT)) || (readw (I2C_CON) & I2C_CON_MST)) { 188080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (1000); 189080c646dSJean-Christophe PLAGNIOL-VILLARD /* have to read to clear intrrupt */ 190e23c7c95SDirk Behme writew (0xFFFF, I2C_STAT); 191080c646dSJean-Christophe PLAGNIOL-VILLARD if(--eout == 0) /* better leave with error than hang */ 192080c646dSJean-Christophe PLAGNIOL-VILLARD break; 193080c646dSJean-Christophe PLAGNIOL-VILLARD } 194080c646dSJean-Christophe PLAGNIOL-VILLARD } 195080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 196e23c7c95SDirk Behme writew (0xFFFF, I2C_STAT); 197e23c7c95SDirk Behme writew (0, I2C_CNT); 198080c646dSJean-Christophe PLAGNIOL-VILLARD return i2c_error; 199080c646dSJean-Christophe PLAGNIOL-VILLARD } 200080c646dSJean-Christophe PLAGNIOL-VILLARD 201080c646dSJean-Christophe PLAGNIOL-VILLARD static void flush_fifo(void) 202080c646dSJean-Christophe PLAGNIOL-VILLARD { u16 stat; 203080c646dSJean-Christophe PLAGNIOL-VILLARD 204080c646dSJean-Christophe PLAGNIOL-VILLARD /* note: if you try and read data when its not there or ready 205080c646dSJean-Christophe PLAGNIOL-VILLARD * you get a bus error 206080c646dSJean-Christophe PLAGNIOL-VILLARD */ 207080c646dSJean-Christophe PLAGNIOL-VILLARD while(1){ 208e23c7c95SDirk Behme stat = readw(I2C_STAT); 209080c646dSJean-Christophe PLAGNIOL-VILLARD if(stat == I2C_STAT_RRDY){ 210*7d264c1eSDirk Behme #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 211*7d264c1eSDirk Behme readb(I2C_DATA); 212*7d264c1eSDirk Behme #else 213e23c7c95SDirk Behme readw(I2C_DATA); 214*7d264c1eSDirk Behme #endif 215e23c7c95SDirk Behme writew(I2C_STAT_RRDY,I2C_STAT); 216080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(1000); 217080c646dSJean-Christophe PLAGNIOL-VILLARD }else 218080c646dSJean-Christophe PLAGNIOL-VILLARD break; 219080c646dSJean-Christophe PLAGNIOL-VILLARD } 220080c646dSJean-Christophe PLAGNIOL-VILLARD } 221080c646dSJean-Christophe PLAGNIOL-VILLARD 222080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_probe (uchar chip) 223080c646dSJean-Christophe PLAGNIOL-VILLARD { 224080c646dSJean-Christophe PLAGNIOL-VILLARD int res = 1; /* default = fail */ 225080c646dSJean-Christophe PLAGNIOL-VILLARD 226e23c7c95SDirk Behme if (chip == readw (I2C_OA)) { 227080c646dSJean-Christophe PLAGNIOL-VILLARD return res; 228080c646dSJean-Christophe PLAGNIOL-VILLARD } 229080c646dSJean-Christophe PLAGNIOL-VILLARD 230080c646dSJean-Christophe PLAGNIOL-VILLARD /* wait until bus not busy */ 231080c646dSJean-Christophe PLAGNIOL-VILLARD wait_for_bb (); 232080c646dSJean-Christophe PLAGNIOL-VILLARD 233080c646dSJean-Christophe PLAGNIOL-VILLARD /* try to read one byte */ 234e23c7c95SDirk Behme writew (1, I2C_CNT); 235080c646dSJean-Christophe PLAGNIOL-VILLARD /* set slave address */ 236e23c7c95SDirk Behme writew (chip, I2C_SA); 237080c646dSJean-Christophe PLAGNIOL-VILLARD /* stop bit needed here */ 238e23c7c95SDirk Behme writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON); 239080c646dSJean-Christophe PLAGNIOL-VILLARD /* enough delay for the NACK bit set */ 240080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (50000); 241080c646dSJean-Christophe PLAGNIOL-VILLARD 242e23c7c95SDirk Behme if (!(readw (I2C_STAT) & I2C_STAT_NACK)) { 243080c646dSJean-Christophe PLAGNIOL-VILLARD res = 0; /* success case */ 244080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 245e23c7c95SDirk Behme writew(0xFFFF, I2C_STAT); 246080c646dSJean-Christophe PLAGNIOL-VILLARD } else { 247e23c7c95SDirk Behme writew(0xFFFF, I2C_STAT); /* failue, clear sources*/ 248e23c7c95SDirk Behme writew (readw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */ 249080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(20000); 250080c646dSJean-Christophe PLAGNIOL-VILLARD wait_for_bb (); 251080c646dSJean-Christophe PLAGNIOL-VILLARD } 252080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 253e23c7c95SDirk Behme writew (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/ 254e23c7c95SDirk Behme writew(0xFFFF, I2C_STAT); 255080c646dSJean-Christophe PLAGNIOL-VILLARD return res; 256080c646dSJean-Christophe PLAGNIOL-VILLARD } 257080c646dSJean-Christophe PLAGNIOL-VILLARD 258080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) 259080c646dSJean-Christophe PLAGNIOL-VILLARD { 260080c646dSJean-Christophe PLAGNIOL-VILLARD int i; 261080c646dSJean-Christophe PLAGNIOL-VILLARD 262080c646dSJean-Christophe PLAGNIOL-VILLARD if (alen > 1) { 263080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("I2C read: addr len %d not supported\n", alen); 264080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 265080c646dSJean-Christophe PLAGNIOL-VILLARD } 266080c646dSJean-Christophe PLAGNIOL-VILLARD 267080c646dSJean-Christophe PLAGNIOL-VILLARD if (addr + len > 256) { 268080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("I2C read: address out of range\n"); 269080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 270080c646dSJean-Christophe PLAGNIOL-VILLARD } 271080c646dSJean-Christophe PLAGNIOL-VILLARD 272080c646dSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 273080c646dSJean-Christophe PLAGNIOL-VILLARD if (i2c_read_byte (chip, addr + i, &buffer[i])) { 274080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("I2C read: I/O error\n"); 2756d0f6bcfSJean-Christophe PLAGNIOL-VILLARD i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 276080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 277080c646dSJean-Christophe PLAGNIOL-VILLARD } 278080c646dSJean-Christophe PLAGNIOL-VILLARD } 279080c646dSJean-Christophe PLAGNIOL-VILLARD 280080c646dSJean-Christophe PLAGNIOL-VILLARD return 0; 281080c646dSJean-Christophe PLAGNIOL-VILLARD } 282080c646dSJean-Christophe PLAGNIOL-VILLARD 283080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) 284080c646dSJean-Christophe PLAGNIOL-VILLARD { 285080c646dSJean-Christophe PLAGNIOL-VILLARD int i; 286080c646dSJean-Christophe PLAGNIOL-VILLARD 287080c646dSJean-Christophe PLAGNIOL-VILLARD if (alen > 1) { 288080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("I2C read: addr len %d not supported\n", alen); 289080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 290080c646dSJean-Christophe PLAGNIOL-VILLARD } 291080c646dSJean-Christophe PLAGNIOL-VILLARD 292080c646dSJean-Christophe PLAGNIOL-VILLARD if (addr + len > 256) { 293080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("I2C read: address out of range\n"); 294080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 295080c646dSJean-Christophe PLAGNIOL-VILLARD } 296080c646dSJean-Christophe PLAGNIOL-VILLARD 297080c646dSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 298080c646dSJean-Christophe PLAGNIOL-VILLARD if (i2c_write_byte (chip, addr + i, buffer[i])) { 299080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("I2C read: I/O error\n"); 3006d0f6bcfSJean-Christophe PLAGNIOL-VILLARD i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 301080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 302080c646dSJean-Christophe PLAGNIOL-VILLARD } 303080c646dSJean-Christophe PLAGNIOL-VILLARD } 304080c646dSJean-Christophe PLAGNIOL-VILLARD 305080c646dSJean-Christophe PLAGNIOL-VILLARD return 0; 306080c646dSJean-Christophe PLAGNIOL-VILLARD } 307080c646dSJean-Christophe PLAGNIOL-VILLARD 308080c646dSJean-Christophe PLAGNIOL-VILLARD static void wait_for_bb (void) 309080c646dSJean-Christophe PLAGNIOL-VILLARD { 310080c646dSJean-Christophe PLAGNIOL-VILLARD int timeout = 10; 311080c646dSJean-Christophe PLAGNIOL-VILLARD u16 stat; 312080c646dSJean-Christophe PLAGNIOL-VILLARD 313e23c7c95SDirk Behme writew(0xFFFF, I2C_STAT); /* clear current interruts...*/ 314e23c7c95SDirk Behme while ((stat = readw (I2C_STAT) & I2C_STAT_BB) && timeout--) { 315e23c7c95SDirk Behme writew (stat, I2C_STAT); 316080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (50000); 317080c646dSJean-Christophe PLAGNIOL-VILLARD } 318080c646dSJean-Christophe PLAGNIOL-VILLARD 319080c646dSJean-Christophe PLAGNIOL-VILLARD if (timeout <= 0) { 320080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("timed out in wait_for_bb: I2C_STAT=%x\n", 321e23c7c95SDirk Behme readw (I2C_STAT)); 322080c646dSJean-Christophe PLAGNIOL-VILLARD } 323e23c7c95SDirk Behme writew(0xFFFF, I2C_STAT); /* clear delayed stuff*/ 324080c646dSJean-Christophe PLAGNIOL-VILLARD } 325080c646dSJean-Christophe PLAGNIOL-VILLARD 326080c646dSJean-Christophe PLAGNIOL-VILLARD static u16 wait_for_pin (void) 327080c646dSJean-Christophe PLAGNIOL-VILLARD { 328080c646dSJean-Christophe PLAGNIOL-VILLARD u16 status; 329080c646dSJean-Christophe PLAGNIOL-VILLARD int timeout = 10; 330080c646dSJean-Christophe PLAGNIOL-VILLARD 331080c646dSJean-Christophe PLAGNIOL-VILLARD do { 332080c646dSJean-Christophe PLAGNIOL-VILLARD udelay (1000); 333e23c7c95SDirk Behme status = readw (I2C_STAT); 334080c646dSJean-Christophe PLAGNIOL-VILLARD } while ( !(status & 335080c646dSJean-Christophe PLAGNIOL-VILLARD (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | 336080c646dSJean-Christophe PLAGNIOL-VILLARD I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | 337080c646dSJean-Christophe PLAGNIOL-VILLARD I2C_STAT_AL)) && timeout--); 338080c646dSJean-Christophe PLAGNIOL-VILLARD 339080c646dSJean-Christophe PLAGNIOL-VILLARD if (timeout <= 0) { 340080c646dSJean-Christophe PLAGNIOL-VILLARD printf ("timed out in wait_for_pin: I2C_STAT=%x\n", 341e23c7c95SDirk Behme readw (I2C_STAT)); 342e23c7c95SDirk Behme writew(0xFFFF, I2C_STAT); 343080c646dSJean-Christophe PLAGNIOL-VILLARD } 344080c646dSJean-Christophe PLAGNIOL-VILLARD return status; 345080c646dSJean-Christophe PLAGNIOL-VILLARD } 346