int gpio_i2c_readX_KeyPad_Fix( int Grp, unsigned char Dev, void (*Func[2])(void)) { int rxdata; I2C_LOCK(Grp); if(Func[0]) { (*Func[0])(); } i2c_start_bit(Grp); i2c_send_byte(Grp, (unsigned char)(Dev) | 1); i2c_receive_ack(Grp); rxdata = i2c_receive_byte(Grp); i2c_receive_ack(Grp); i2c_stop_bit(Grp); if(Func[1]) { (*Func[1])(); } I2C_UNLOCK(Grp); return (unsigned char)rxdata; }
int gpio_i2c_readX(int Grp, unsigned char devaddress, unsigned char address) { int rxdata; I2C_LOCK(Grp); i2c_start_bit(Grp); i2c_send_byte(Grp, (unsigned char)(devaddress)); i2c_receive_ack(Grp); i2c_send_byte(Grp, address); i2c_receive_ack(Grp); i2c_start_bit(Grp); i2c_send_byte(Grp, (unsigned char)(devaddress) | 1); i2c_receive_ack(Grp); rxdata = i2c_receive_byte(Grp); i2c_stop_bit(Grp); I2C_UNLOCK(Grp); return (unsigned char)rxdata; }
int gpio_i2c_wr_arr(int Grp, unsigned char dev, unsigned char rarr[], int rsize, unsigned char darr[], int dsize) { int i; I2C_LOCK(Grp); i2c_start_bit(Grp); i2c_send_byte(Grp, dev); i2c_receive_ack(Grp); for(i = 0; i < rsize; i ++) { i2c_send_byte(Grp, rarr[i]); i2c_receive_ack(Grp); } if(dsize > 0) { for(i = 0; i < dsize-1; i ++) { i2c_send_byte(Grp, darr[i]); i2c_receive_ack(Grp); } i2c_send_byte(Grp, darr[i]); } i2c_stop_bit(Grp); I2C_UNLOCK(Grp); return 0; }
int gpio_i2c_probeX(int Grp, unsigned char devaddress) { int ret; I2C_LOCK(Grp); i2c_start_bit(Grp); i2c_send_byte(Grp, (unsigned char)(devaddress)); ret = i2c_receive_ack(Grp); i2c_stop_bit(Grp); I2C_UNLOCK(Grp); return ret; }
int gpio_i2c_write(unsigned char devaddress, unsigned char address, unsigned char data) { int Grp = 0; I2C_LOCK(Grp); i2c_start_bit(Grp); i2c_send_byte(Grp, (unsigned char)(devaddress)); i2c_receive_ack(Grp); i2c_send_byte(Grp, address); i2c_receive_ack(Grp); i2c_send_byte(Grp, data); i2c_stop_bit(Grp); I2C_UNLOCK(Grp); return 0 ; }
STATIC int pd63000_write(int unit, int devno, uint16 addr, uint8* data, uint32 len) { int rv = SOC_E_NONE; uint8 saddr = soc_i2c_addr(unit, devno); uint8 *ptr; uint32 i; if (!data) { return SOC_E_PARAM; } assert((PD63000_CTN == len)); I2C_LOCK(unit); if ((rv = soc_i2c_start(unit, SOC_I2C_TX_ADDR(saddr))) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "i2c%d: soc_i2c_pd63000_write: " "failed to generate start.\n"), unit)); I2C_UNLOCK(unit); return rv; } ptr = data; for (i = 0; i < len; i++, ptr++) { if ((rv = soc_i2c_write_one_byte(unit, *ptr) ) < 0 ) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "i2c%d: soc_i2c_pd63000_write: " "failed to send byte %d.\n"), unit, i )); break; } soc_i2c_device(unit, devno)->tbyte++; } soc_i2c_stop(unit); I2C_UNLOCK(unit); return rv; }
int gpio_i2c_writeX_KeyPad_Fix( int Grp, unsigned char Dev, unsigned char rarr[], int rsize, unsigned char darr[], int dsize, void (*Func[2])(void)) { int i; I2C_LOCK(Grp); if(Func[0]) { (*Func[0])(); } i2c_start_bit(Grp); i2c_send_byte(Grp, Dev); i2c_receive_ack(Grp); for(i = 0; i < rsize; i ++) { i2c_send_byte(Grp, rarr[i]); i2c_receive_ack(Grp); } for(i = 0; i < dsize; i ++) { i2c_send_byte(Grp, darr[i]); i2c_receive_ack(Grp); } i2c_stop_bit(Grp); if(Func[1]) { (*Func[1])(); } I2C_UNLOCK(Grp); return 0; }
/* * Function: pcie_write * Purpose: Write len bytes of data, return the number of bytes written. * Uses PAGE mode to write up to 32 bytes at a time between address * stages for maximum performance. * * Parameters: * unit - StrataSwitch device number or I2C bus number * devno - chip device id * addr - PCIE memory address to write to * data - address of data buffer to write from * len - number of bytes to write * * Returns: * SOC_E_NONE -- no error encountered * SOC_E_TIMEOUT - chip timeout or data error * * * Notes: * Uses page mode to write in 32-byte chunks, when an address * which does not begin on a page boundary is provided, the write * operation handles unaligned accesses by breaking up the write * into one write which is not page aligned, and the remainder as * page aligned accesses. * */ STATIC int pcie_write(int unit, int devno, uint16 addr, uint8* data, uint32 len) { int rv = SOC_E_NONE; uint8 *ptr; uint16 a0; uint32 b, numpages, cpage, nbytes, tbytes, caddr; i2c_bus_addr_t bus_addr; /* User must have data to write */ if ( ! data || len <= 0 ) return SOC_E_PARAM; I2C_LOCK(unit); /* Use PAGE mode */ caddr = addr; numpages = len / PCIE_PAGE_SIZE + (len % PCIE_PAGE_SIZE > 0); ptr = data; tbytes = soc_i2c_device(unit, devno)->tbyte++; bus_addr = SOC_I2C_TX_ADDR(soc_i2c_addr(unit, devno)); LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write: addr=0x%x data=%p len=%d npages=%d\n"), caddr, (void *)data, (int)len, numpages)); /* Loop over every page in buffer .. */ for(cpage = 0; cpage < numpages; cpage++){ /* Address not page aligned, D'Oh, can't write a full page. */ if( (caddr % PCIE_PAGE_SIZE) != 0){ nbytes = PCIE_PAGE_SIZE - (caddr % PCIE_PAGE_SIZE); len -= nbytes; } else { /* Address is page aligned, calculate bytes to write */ if ( len <= PCIE_PAGE_SIZE ) { /* Less than a page to write */ nbytes = len; } else { /* Wammo, full page write */ nbytes = PCIE_PAGE_SIZE; len -= nbytes; } } /* Construct device address bytes */ a0 = (uint16) (caddr & 0xFFff); /* Generate Start, for Write address */ if( (rv = soc_i2c_start(unit, bus_addr)) < 0){ LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write(%d,%d,%x,%d,%d): " "failed to gen start\n"), unit, devno, caddr, *data, len)); I2C_UNLOCK(unit); return rv; } LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write: unit=%d cpage=%d START on page_addr=0x%x" " nbytes=%d\n"), unit, cpage, ((a0 >> 8) & 0xFF) , nbytes)); if( (rv = soc_i2c_write_one_byte(unit, ((a0 >> 8) & 0xFF))) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write(%d,%d,%x,%p,%d): " "failed to send a0 byte.\n"), unit, devno, addr, (void *)data, len)); goto error; } LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write: unit=%d cpage=%d START on page_addr=0x%x" " nbytes=%d\n"), unit, cpage, ((a0) & 0xFF) , nbytes)); if( (rv = soc_i2c_write_one_byte(unit, a0 & 0xFF)) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write(%d,%d,%04x,%x,%p,%d): " "failed to send a0 byte.\n"), unit, devno, addr, a0, (void *)data, len)); goto error; } /* Send up to PAGE_SIZE data bytes, wait for ACK */ for ( b = 0; b < nbytes; b++, ptr++, caddr++ ) { if ( (rv = soc_i2c_write_one_byte(unit, *ptr)) < 0){ LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write(%d,%d,%d,%d,%d): " "tx data byte error\n"), unit, devno, caddr, (uint32)*ptr, b)); goto error; } LOG_VERBOSE(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_write(u=%d,id=%d,page=%d " "caddr=%d,data=0x%x,idx=%d)\n"), unit, devno, cpage, caddr, (uint8)*ptr, b)); soc_i2c_device(unit, devno)->tbyte++; } /* Send STOP, also what we do on an error to free bus.. */ error: soc_i2c_stop(unit); /* Acknowledge polling: When the chip enters it's * own internal write-cycle, it falls off the I2C bus * and does not ACK a start/address phase; hence, we * attempt addressing the chip until it responds, at * which point the internal write cycle has finished. */ rv = pcie_ack_poll(unit, bus_addr); LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_ack_poll: " "%d address cycles for wr latency.\n"), rv)); rv = (rv > 0 ? SOC_E_NONE: SOC_E_TIMEOUT); } I2C_UNLOCK(unit); return rv < 0 ? rv : soc_i2c_device(unit, devno)->tbyte - tbytes - 1 ; }
/* * Function: pcie_read * * Purpose: Read len bytes of data into buffer, update len with total * amount read. * * Parameters: * unit - StrataSwitch device number or I2C bus number * devno - chip device id * addr - PCIE memory address to read from * data - address of data buffer to read into * len - address containing number of bytes read into data buffer (updated * with number of bytes read on completion). * * Returns: data bufffer filled in with data from address, number of * bytes read is updated in len field. Status code: * * SOC_E_NONE -- no error encounter * SOC_E_TIMEOUT - chip timeout or data error * * Notes: * Currently uses random address byte read to initiate the read; if * more than one byte of data is requested at the current address, a * sequential read operation is performed. */ STATIC int pcie_read(int unit, int devno, uint16 addr, uint8* data, uint32 *len) { int rv = SOC_E_NONE; uint8 saddr_r, saddr_w; uint16 a0; uint32 nbytes = 0; /* Valid address, memory and size must be provided */ if ( ! len || ! data ) return SOC_E_PARAM; I2C_LOCK(unit); saddr_r = SOC_I2C_RX_ADDR(soc_i2c_addr(unit, devno)); saddr_w = SOC_I2C_TX_ADDR(soc_i2c_addr(unit, devno)); a0 = (uint16) (addr & 0xFFff); LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_read: addr=0x%x (a0=0x%x) len=%d\n"), addr, a0, (int)*len)); /* First, we put out the address which we would like to * read at using the SOC_I2C_TX_ADDR (saddr_w) */ if ( (rv = soc_i2c_start(unit, saddr_w)) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_read(%d,%d,%x,%p,%d): " "failed to generate start.\n"), unit, devno, addr, (void *)data, *len)); I2C_UNLOCK(unit); return rv; } LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_read(%d,%d,%x,%p,%d): " "to send a0 byte.\n"), unit, devno, addr, (void *)data, *len)); if( (rv = soc_i2c_write_one_byte(unit, ((a0 >> 8) & 0xFF))) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_read(%d,%d,%x,%p,%d): " "failed to send a0 byte.\n"), unit, devno, addr, (void *)data, *len)); goto error; } if( (rv = soc_i2c_write_one_byte(unit, a0 & 0xFF)) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_read(%d,%d,%04x,%x,%p,%d): " "failed to send a0 byte.\n"), unit, devno, addr, a0, (void *)data, *len)); goto error; } /* Now, we have sent the first and second word addresses, * we then issue a repeated start condition, followed by * the device's read address (note: saddr_r) */ if( (rv = soc_i2c_rep_start(unit, saddr_r)) < 0) { LOG_INFO(BSL_LS_SOC_I2C, (BSL_META_U(unit, "pcie_read(%d,%d,%x,%p,%d): " "failed to generate rep start.\n"), unit, devno, addr, (void *)data, *len)); goto error; } nbytes = *len; if ( (rv = soc_i2c_read_bytes(unit, data, (int *)&nbytes, 0) ) < 0 ) { goto error; } *len = nbytes; error: soc_i2c_stop(unit); I2C_UNLOCK(unit); return rv ; }