示例#1
0
/*----------------------------------------------------------------------*/
static void eeprom_get_status_reg(u8 *status) 
{
	spi_chip_select(ENABLE);
	spi_write(RDSR_CMD);
	*status = spi_read();		
	spi_chip_select(DISABLE);
}
示例#2
0
/*----------------------------------------------------------------------*/
static u8 spi_eeprom_read(u16 address, u16 nbytes, u8 *dest)
{
	u8	status;
	u16	cnt = 0;
	int i = 0;

	do {
		i++;
		eeprom_get_status_reg(&status);		
	}
	while((status & (1<<RDY)) && (i < max_ee_busy_loop));

	if (i == max_ee_busy_loop)
		return (status);

	/* eeprom ready */
	if (!(status & (1<<RDY))) {	
		spi_chip_select(ENABLE);
		/* read op */
		spi_write(READ_CMD);
		spi_write((u8)(address >> 8));		/* MSB byte First */
		spi_write((u8)(address & 0x00FF));	/* LSB byte */

		while (cnt < nbytes) {
			*(dest++) = spi_read();
			cnt++;
		}
		status = 0;
		/* deassert cs */
		spi_chip_select(DISABLE);
	} 
示例#3
0
static int cadence_spi_set_speed(struct udevice *bus, uint hz)
{
	struct cadence_spi_platdata *plat = bus->platdata;
	struct cadence_spi_priv *priv = dev_get_priv(bus);
	int err;

	/* Disable QSPI */
	cadence_qspi_apb_controller_disable(priv->regbase);

	cadence_spi_write_speed(bus, hz);

	/* Calibration required for different SCLK speed or chip select */
	if (priv->qspi_calibrated_hz != plat->max_hz ||
	    priv->qspi_calibrated_cs != spi_chip_select(bus)) {
		err = spi_calibration(bus);
		if (err)
			return err;
	}

	/* Enable QSPI */
	cadence_qspi_apb_controller_enable(priv->regbase);

	debug("%s: speed=%d\n", __func__, hz);

	return 0;
}
示例#4
0
/*----------------------------------------------------------------------*/
static void spi_master_init(void)
{
	/* try to reset again from Reset Control Register */
	u32 val = RT2880_REG(RT2880_RSTCTRL_REG);
	val |= RSTCTRL_SPI_RESET;
	RT2880_REG(RT2880_RSTCTRL_REG) = val;

	val = val & ~(RSTCTRL_SPI_RESET);
	RT2880_REG(RT2880_RSTCTRL_REG) = val;
	udelay(500);

#if defined(RALINK_VITESSE_SWITCH_CONNECT_SPI_CS1)
	/* config ARB and set the low or high active correctly according to the device */
	RT2880_REG(RT2880_SPI_ARB_REG) = SPIARB_ARB_EN | (SPIARB_SPI1_ACTIVE_MODE <<1) | SPIARB_SPI0_ACTIVE_MODE;
        RT2880_REG(RT2880_SPI0_CTL_REG) = (~SPIARB_SPI0_ACTIVE_MODE)&0x1;     //disable first
        RT2880_REG(RT2880_SPI1_CTL_REG) = (~SPIARB_SPI1_ACTIVE_MODE)&0x1;     //disable first
#endif
	RT2880_REG(RT2880_SPICFG_REG) = SPICFG_MSBFIRST | SPICFG_RXCLKEDGE_FALLING | SPICFG_TXCLKEDGE_FALLING | CFG_CLK_DIV;
	spi_chip_select(DISABLE);

#ifdef DBG
/*        printf("SPICFG = %08x\n", RT2880_REG(RT2880_SPICFG_REG));*/
/*        printf("is busy %d\n", IS_BUSY);*/
	if (IS_BUSY) printf("spi_master_init: is busy\n");
#endif		 	
}
示例#5
0
文件: spi_drv.c 项目: jhbsz/LC4
/*----------------------------------------------------------------------*/
void spi_master_init(void)
{
    int i;
    u32* spireg = spi_register[spich];

    /* reset spi block */
    RT2880_REG(RT2880_RSTCTRL_REG) |= RSTCTRL_SPI_RESET;
    RT2880_REG(RT2880_RSTCTRL_REG) &= ~(RSTCTRL_SPI_RESET);
    /* udelay(500); */
    for ( i = 0; i < 1000; i++);

#if defined(CONFIG_RALINK_VITESSE_SWITCH_CONNECT_SPI_CS1)||defined(CONFIG_RALINK_SLIC_CONNECT_SPI_CS1)
    /* config ARB and set the low or high active correctly according to the device */
    RT2880_REG(RT2880_SPI_ARB_REG) = SPIARB_ARB_EN|(SPIARB_SPI1_ACTIVE_MODE<<1)| SPIARB_SPI0_ACTIVE_MODE;
    RT2880_REG(RT2880_SPI1_CTL_REG) = (~SPIARB_SPI1_ACTIVE_MODE)&0x1;     //disable first
#endif
    RT2880_REG(RT2880_SPI0_CTL_REG) = (~SPIARB_SPI0_ACTIVE_MODE)&0x1;     //disable first

    RT2880_REG(spireg[SPICFG]) = SPICFG_MSBFIRST
                                 | SPICFG_RXCLKEDGE_FALLING
                                 | SPICFG_TXCLKEDGE_FALLING
                                 | SPICFG_SPICLK_DIV128 ;
    spi_chip_select(DISABLE);

#ifdef DBG
    printk("SPICFG = %08x\n", RT2880_REG(RT2880_SPICFG_REG));
    printk("is busy %d\n", IS_BUSY);
#endif
}
示例#6
0
/*----------------------------------------------------------------------*/
void spi_master_init(void)
{
	int i;
	
	spi_device = 0;
#if defined(CONFIG_RALINK_MULTISPI)	
	RT2880_REG(RT2880_SPIARB_REG) |= 0x80000000; 
#endif	
	/* reset spi block */
	RT2880_REG(RT2880_RSTCTRL_REG) |= RSTCTRL_SPI_RESET;
	RT2880_REG(RT2880_RSTCTRL_REG) &= ~(RSTCTRL_SPI_RESET);
	/* udelay(500); */
	for ( i = 0; i < 1000; i++);
	

	RT2880_REG(RT2880_SPICFG_REG) = SPICFG_MSBFIRST | 
									SPICFG_RXCLKEDGE_FALLING |
									SPICFG_TXCLKEDGE_FALLING |
									SPICFG_SPICLK_DIV128;	

	spi_chip_select(DISABLE);

#ifdef DBG
	printk("SPICFG = %08x\n", RT2880_REG(RT2880_SPICFG_REG));
	printk("is busy %d\n", IS_BUSY);
#endif		 	
}
示例#7
0
unsigned char spi_btransfer(const unsigned char data)
{
	spi_chip_select();
  
  //Start new transmission
  SPDR = data;
  
  // wait until finished
  while(!(SPSR & (1 << SPIF)));
  
  spi_chip_release();
  
  return SPDR;
}
示例#8
0
/*----------------------------------------------------------------------*/
void spi_master_init(void)
{
	int i;
	u32* spireg = spi_register[spich];

#if 0 
	/* remove it, cos' reset will impact spi0 and spi1
		spi reset already did on ./drivers/mtd/ralink/ralink_spi.c
		this place should not be reset again, it will clear spi#0 for spi flash configuration
	*/
	
	/* reset spi block */
	RT2880_REG(RT2880_RSTCTRL_REG) |= RSTCTRL_SPI_RESET;
	RT2880_REG(RT2880_RSTCTRL_REG) &= ~(RSTCTRL_SPI_RESET);
#endif
	/* udelay(500); */
	for ( i = 0; i < 1000; i++);

#if defined(CONFIG_RALINK_VITESSE_SWITCH_CONNECT_SPI_CS1)||defined(CONFIG_RALINK_SLIC_CONNECT_SPI_CS1)
	/* config ARB and set the low or high active correctly according to the device */
	RT2880_REG(RT2880_SPI_ARB_REG) = SPIARB_ARB_EN|(SPIARB_SPI1_ACTIVE_MODE<<1)| SPIARB_SPI0_ACTIVE_MODE;
#if defined(CONFIG_RALINK_MT7620)
	if (spich > 0) 
	    RT2880_REG(RT2880_SPI_ARB_REG) |= SPIARB_CS1CTL;
#endif
	RT2880_REG(RT2880_SPI1_CTL_REG) = (~SPIARB_SPI1_ACTIVE_MODE)&0x1;     //disable first
#endif
	RT2880_REG(RT2880_SPI0_CTL_REG) = (~SPIARB_SPI0_ACTIVE_MODE)&0x1;     //disable first

	RT2880_REG(spireg[SPICFG]) = SPICFG_MSBFIRST
								| SPICFG_RXCLKEDGE_FALLING
								| SPICFG_TXCLKEDGE_FALLING
								| SPICFG_SPICLK_DIV128 ;
	spi_chip_select(DISABLE);

#ifdef DBG
	printk("SPICFG = %08x\n", RT2880_REG(RT2880_SPICFG_REG));
	printk("is busy %d\n", IS_BUSY);
#endif		 	
}
示例#9
0
unsigned short spi_wtransfer(const unsigned short data)
{
	unsigned char data_lo = (unsigned char)data;
	unsigned char data_hi = (unsigned char)(data >> 8);
	
	spi_chip_select();
	
	SPDR = data_hi;
	
	while(!(SPSR & (1 << SPIF)));
	
	data_hi = SPDR;
	
	SPDR = data_lo;
	
	while(!(SPSR & (1 << SPIF)));
	
	data_lo = SPDR;
	
	spi_chip_release();
	
	return (data_hi << 8) | (data_lo);
}
示例#10
0
static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen,
			    const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = slave->parent;
	struct sandbox_state *state = state_get_current();
	struct dm_spi_emul_ops *ops;
	struct udevice *emul;
	uint bytes = bitlen / 8, i;
	int ret;
	u8 *tx = (void *)dout, *rx = din;
	uint busnum, cs;

	if (bitlen == 0)
		return 0;

	/* we can only do 8 bit transfers */
	if (bitlen % 8) {
		printf("sandbox_spi: xfer: invalid bitlen size %u; needs to be 8bit\n",
		       bitlen);
		return -EINVAL;
	}

	busnum = bus->seq;
	cs = spi_chip_select(slave);
	if (busnum >= CONFIG_SANDBOX_SPI_MAX_BUS ||
	    cs >= CONFIG_SANDBOX_SPI_MAX_CS) {
		printf("%s: busnum=%u, cs=%u: out of range\n", __func__,
		       busnum, cs);
		return -ENOENT;
	}
	ret = sandbox_spi_get_emul(state, bus, slave, &emul);
	if (ret) {
		printf("%s: busnum=%u, cs=%u: no emulation available (err=%d)\n",
		       __func__, busnum, cs, ret);
		return -ENOENT;
	}
	ret = device_probe(emul);
	if (ret)
		return ret;

	/* make sure rx/tx buffers are full so clients can assume */
	if (!tx) {
		debug("sandbox_spi: xfer: auto-allocating tx scratch buffer\n");
		tx = malloc(bytes);
		if (!tx) {
			debug("sandbox_spi: Out of memory\n");
			return -ENOMEM;
		}
	}
	if (!rx) {
		debug("sandbox_spi: xfer: auto-allocating rx scratch buffer\n");
		rx = malloc(bytes);
		if (!rx) {
			debug("sandbox_spi: Out of memory\n");
			return -ENOMEM;
		}
	}

	ops = spi_emul_get_ops(emul);
	ret = ops->xfer(emul, bitlen, dout, din, flags);

	debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:",
	      ret, ret ? "bad" : "good");
	for (i = 0; i < bytes; ++i)
		debug(" %u:%02x", i, rx[i]);
	debug("\n");

	if (tx != dout)
		free(tx);
	if (rx != din)
		free(rx);

	return ret;
}
示例#11
0
/* Calibration sequence to determine the read data capture delay register */
static int spi_calibration(struct udevice *bus)
{
	struct cadence_spi_platdata *plat = bus->platdata;
	struct cadence_spi_priv *priv = dev_get_priv(bus);
	void *base = priv->regbase;
	u8 opcode_rdid = 0x9F;
	unsigned int idcode = 0, temp = 0;
	int err = 0, i, range_lo = -1, range_hi = -1;

	/* start with slowest clock (1 MHz) */
	cadence_spi_write_speed(bus, 1000000);

	/* configure the read data capture delay register to 0 */
	cadence_qspi_apb_readdata_capture(base, 1, 0);

	/* Enable QSPI */
	cadence_qspi_apb_controller_enable(base);

	/* read the ID which will be our golden value */
	err = cadence_qspi_apb_command_read(base, 1, &opcode_rdid,
		3, (u8 *)&idcode);
	if (err) {
		puts("SF: Calibration failed (read)\n");
		return err;
	}

	/* use back the intended clock and find low range */
	cadence_spi_write_speed(bus, plat->max_hz);
	for (i = 0; i < CQSPI_READ_CAPTURE_MAX_DELAY; i++) {
		/* Disable QSPI */
		cadence_qspi_apb_controller_disable(base);

		/* reconfigure the read data capture delay register */
		cadence_qspi_apb_readdata_capture(base, 1, i);

		/* Enable back QSPI */
		cadence_qspi_apb_controller_enable(base);

		/* issue a RDID to get the ID value */
		err = cadence_qspi_apb_command_read(base, 1, &opcode_rdid,
			3, (u8 *)&temp);
		if (err) {
			puts("SF: Calibration failed (read)\n");
			return err;
		}

		/* search for range lo */
		if (range_lo == -1 && temp == idcode) {
			range_lo = i;
			continue;
		}

		/* search for range hi */
		if (range_lo != -1 && temp != idcode) {
			range_hi = i - 1;
			break;
		}
		range_hi = i;
	}

	if (range_lo == -1) {
		puts("SF: Calibration failed (low range)\n");
		return err;
	}

	/* Disable QSPI for subsequent initialization */
	cadence_qspi_apb_controller_disable(base);

	/* configure the final value for read data capture delay register */
	cadence_qspi_apb_readdata_capture(base, 1, (range_hi + range_lo) / 2);
	debug("SF: Read data capture delay calibrated to %i (%i - %i)\n",
	      (range_hi + range_lo) / 2, range_lo, range_hi);

	/* just to ensure we do once only when speed or chip select change */
	priv->qspi_calibrated_hz = plat->max_hz;
	priv->qspi_calibrated_cs = spi_chip_select(bus);

	return 0;
}
示例#12
0
static int cadence_spi_xfer(struct udevice *dev, unsigned int bitlen,
			    const void *dout, void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct cadence_spi_platdata *plat = bus->platdata;
	struct cadence_spi_priv *priv = dev_get_priv(bus);
	void *base = priv->regbase;
	u8 *cmd_buf = priv->cmd_buf;
	size_t data_bytes;
	int err = 0;
	u32 mode = CQSPI_STIG_WRITE;

	if (flags & SPI_XFER_BEGIN) {
		/* copy command to local buffer */
		priv->cmd_len = bitlen / 8;
		memcpy(cmd_buf, dout, priv->cmd_len);
	}

	if (flags == (SPI_XFER_BEGIN | SPI_XFER_END)) {
		/* if start and end bit are set, the data bytes is 0. */
		data_bytes = 0;
	} else {
		data_bytes = bitlen / 8;
	}
	debug("%s: len=%d [bytes]\n", __func__, data_bytes);

	/* Set Chip select */
	cadence_qspi_apb_chipselect(base, spi_chip_select(dev),
				    CONFIG_CQSPI_DECODER);

	if ((flags & SPI_XFER_END) || (flags == 0)) {
		if (priv->cmd_len == 0) {
			printf("QSPI: Error, command is empty.\n");
			return -1;
		}

		if (din && data_bytes) {
			/* read */
			/* Use STIG if no address. */
			if (!CQSPI_IS_ADDR(priv->cmd_len))
				mode = CQSPI_STIG_READ;
			else
				mode = CQSPI_INDIRECT_READ;
		} else if (dout && !(flags & SPI_XFER_BEGIN)) {
			/* write */
			if (!CQSPI_IS_ADDR(priv->cmd_len))
				mode = CQSPI_STIG_WRITE;
			else
				mode = CQSPI_INDIRECT_WRITE;
		}

		switch (mode) {
		case CQSPI_STIG_READ:
			err = cadence_qspi_apb_command_read(
				base, priv->cmd_len, cmd_buf,
				data_bytes, din);

		break;
		case CQSPI_STIG_WRITE:
			err = cadence_qspi_apb_command_write(base,
				priv->cmd_len, cmd_buf,
				data_bytes, dout);
		break;
		case CQSPI_INDIRECT_READ:
			err = cadence_qspi_apb_indirect_read_setup(plat,
				priv->cmd_len, cmd_buf);
			if (!err) {
				err = cadence_qspi_apb_indirect_read_execute
				(plat, data_bytes, din);
			}
		break;
		case CQSPI_INDIRECT_WRITE:
			err = cadence_qspi_apb_indirect_write_setup
				(plat, priv->cmd_len, cmd_buf);
			if (!err) {
				err = cadence_qspi_apb_indirect_write_execute
				(plat, data_bytes, dout);
			}
		break;
		default:
			err = -1;
			break;
		}

		if (flags & SPI_XFER_END) {
			/* clear command buffer */
			memset(cmd_buf, 0, sizeof(priv->cmd_buf));
			priv->cmd_len = 0;
		}
	}

	return err;
}
示例#13
0
static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen,
			    const void *data_out, void *data_in,
			    unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct tegra30_spi_priv *priv = dev_get_priv(bus);
	struct spi_regs *regs = priv->regs;
	u32 reg, tmpdout, tmpdin = 0;
	const u8 *dout = data_out;
	u8 *din = data_in;
	int num_bytes;
	int ret;

	debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
	      __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
	if (bitlen % 8)
		return -1;
	num_bytes = bitlen / 8;

	ret = 0;

	reg = readl(&regs->status);
	writel(reg, &regs->status);	/* Clear all SPI events via R/W */
	debug("%s entry: STATUS = %08x\n", __func__, reg);

	reg = readl(&regs->status2);
	writel(reg, &regs->status2);	/* Clear all STATUS2 events via R/W */
	debug("%s entry: STATUS2 = %08x\n", __func__, reg);

	debug("%s entry: COMMAND = %08x\n", __func__, readl(&regs->command));

	clrsetbits_le32(&regs->command2, SLINK_CMD2_SS_EN_MASK,
			SLINK_CMD2_TXEN | SLINK_CMD2_RXEN |
			(spi_chip_select(dev) << SLINK_CMD2_SS_EN_SHIFT));
	debug("%s entry: COMMAND2 = %08x\n", __func__, readl(&regs->command2));

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(dev);

	/* handle data in 32-bit chunks */
	while (num_bytes > 0) {
		int bytes;
		int is_read = 0;
		int tm, i;

		tmpdout = 0;
		bytes = (num_bytes > 4) ?  4 : num_bytes;

		if (dout != NULL) {
			for (i = 0; i < bytes; ++i)
				tmpdout = (tmpdout << 8) | dout[i];
			dout += bytes;
		}

		num_bytes -= bytes;

		clrsetbits_le32(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
				bytes * 8 - 1);
		writel(tmpdout, &regs->tx_fifo);
		setbits_le32(&regs->command, SLINK_CMD_GO);

		/*
		 * Wait for SPI transmit FIFO to empty, or to time out.
		 * The RX FIFO status will be read and cleared last
		 */
		for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) {
			u32 status;

			status = readl(&regs->status);

			/* We can exit when we've had both RX and TX activity */
			if (is_read && (status & SLINK_STAT_TXF_EMPTY))
				break;

			if ((status & (SLINK_STAT_BSY | SLINK_STAT_RDY)) !=
					SLINK_STAT_RDY)
				tm++;

			else if (!(status & SLINK_STAT_RXF_EMPTY)) {
				tmpdin = readl(&regs->rx_fifo);
				is_read = 1;

				/* swap bytes read in */
				if (din != NULL) {
					for (i = bytes - 1; i >= 0; --i) {
						din[i] = tmpdin & 0xff;
						tmpdin >>= 8;
					}
					din += bytes;
				}
			}
		}

		if (tm >= SPI_TIMEOUT)
			ret = tm;

		/* clear ACK RDY, etc. bits */
		writel(readl(&regs->status), &regs->status);
	}