/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (c) 2007 Will Robertson * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "cpu.h" #include "spi-imx31.h" #include "debug.h" #include "kernel.h" /* This is all based on communicating with the MC13783 PMU which is on * CSPI2 with the chip select at 0. The LCD controller resides on * CSPI3 cs1, but we have no idea how to communicate to it */ void spi_init(void) { CSPI_CONREG2 |= (2 << 20); // Burst will be triggered at SPI_RDY low CSPI_CONREG2 |= (2 << 16); // Clock = IPG_CLK/16 - we want about 20mhz CSPI_CONREG2 |= (31 << 8); // All 32 bits are to be transferred CSPI_CONREG2 |= (1 << 3); // Start burst on TXFIFO write. CSPI_CONREG2 |= (1 << 1); // Master mode. CSPI_CONREG2 |= 1; // Enable CSPI2; } static int spi_transfer(int address, long data, long* buffer, bool read) { unsigned long packet = 0; if(!read) { /* Set the appropriate bit in the packet to indicate a write */ packet |= (1<<31); } /* Set the address of the packet */ packet |= (address << 25); /* Ensure data only occupies 24 bits, then mash the data into the packet */ data &= ~(DATAMASK); packet |= data; /* Wait for some room in TXFIFO */ while(CSPI_STATREG2 & (1<<2)); /* Send the packet */ CSPI_TXDATA2 = packet; /* Poll the XCH bit to wait for the end of the transfer, with * a one second timeout */ int newtick = current_tick + HZ; while((CSPI_CONREG2 & (1<<2)) && (current_tick < newtick)); if(newtick > current_tick) { *buffer = CSPI_RXDATA2; return 0; } else { /* Indicate the fact that the transfer timed out */ return -1; } } void spi_send(int address, unsigned long data) { long dummy; if(spi_transfer(address, data, &dummy, false)) { DEBUGF("SPI Send timed out"); } } void spi_read(int address, unsigned long* buffer) { if(spi_transfer(address, 0, buffer, true)) { DEBUGF("SPI read timed out"); } }