Example #1
0
bool
spi_controller_highspeed_mode(sdioh_info_t *sd, bool hsmode)
{
	spih_info_t *si = (spih_info_t *)sd->controller;
	osl_t *osh = si->osh;
	spih_regs_t *regs = si->regs;

	if (si->rev >= 10) {
		if (hsmode) {
			SPIPCI_ORREG(osh, &regs->spih_ext, 0x10);
		} else {
			SPIPCI_ANDREG(osh, &regs->spih_ext, ~0x10);
		}
	}

	return TRUE;
}
Example #2
0
void
spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen)
{
	spih_info_t *si = (spih_info_t *)sd->controller;
	osl_t *osh = si->osh;
	spih_regs_t *regs = si->regs;
	uint32 count;
	uint32 spi_data_out;
	uint32 spi_data_in;
	bool yield;

	sd_trace(("%s: enter\n", __FUNCTION__));

	if (bcmpcispi_dump) {
		printf("SENDRECV(len=%d)\n", msglen);
		hexdump(" OUT: ", msg_out, msglen);
	}

#ifdef BCMSDYIELD
	
	yield = ((msglen > 500) && (si->rev >= 8));
#else
	yield = FALSE;
#endif 

	ASSERT(msglen % 4 == 0);


	SPIPCI_ANDREG(osh, &regs->spih_gpio_data, ~SPIH_CS);	

	for (count = 0; count < (uint32)msglen/4; count++) {
		spi_data_out = ((uint32)((uint32 *)msg_out)[count]);
		SPIPCI_WREG(osh, &regs->spih_data, spi_data_out);
	}

#ifdef BCMSDYIELD
	if (yield) {
		
		SPIPCI_WREG(osh, &regs->spih_int_status, SPIH_WFIFO_INTR);
		SPIPCI_RREG(osh, &regs->spih_int_status);

		
		sd->intmask |= SPIH_WFIFO_INTR;
		sd->got_hcint = FALSE;
		SPIPCI_WREG(osh, &regs->spih_int_mask, sd->intmask);

	}
#endif 

	
	SPIPCI_ANDREG(osh, &regs->spih_gpio_data, ~0x00000020);	

	if (yield) {
		ASSERT((SPIPCI_RREG(sd->osh, &regs->spih_stat) & SPIH_WFEMPTY) == 0);
	}

	spi_waitbits(sd, yield);
	SPIPCI_ORREG(osh, &regs->spih_gpio_data, 0x00000020);	

	for (count = 0; count < (uint32)msglen/4; count++) {
		spi_data_in = SPIPCI_RREG(osh, &regs->spih_data);
		((uint32 *)msg_in)[count] = spi_data_in;
	}

	
	SPIPCI_ORREG(osh, &regs->spih_gpio_data, SPIH_CS);

	if (bcmpcispi_dump) {
		hexdump(" IN : ", msg_in, msglen);
	}
}
Example #3
0
/* Send/Receive an SPI Packet */
void
spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen)
{
	spih_info_t *si = (spih_info_t *)sd->controller;
	osl_t *osh = si->osh;
	spih_regs_t *regs = si->regs;
	uint32 count;
	uint32 spi_data_out;
	uint32 spi_data_in;
	bool yield;

	sd_trace(("%s: enter\n", __FUNCTION__));

	if (bcmpcispi_dump) {
		printf("SENDRECV(len=%d)\n", msglen);
		hexdump(" OUT: ", msg_out, msglen);
	}

#ifdef BCMSDYIELD
	/* Only yield the CPU and wait for interrupt on Rev 8 and newer FPGA images. */
	yield = ((msglen > 500) && (si->rev >= 8));
#else
	yield = FALSE;
#endif /* BCMSDYIELD */

	ASSERT(msglen % 4 == 0);

	SPIPCI_ANDREG(osh, &regs->spih_gpio_data, ~SPIH_CS);	/* Set GPIO CS# Low (asserted) */

	for (count = 0; count < (uint32)msglen/4; count++) {
		spi_data_out = ((uint32)((uint32 *)msg_out)[count]);
		SPIPCI_WREG(osh, &regs->spih_data, spi_data_out);
	}

#ifdef BCMSDYIELD
	if (yield) {
		/* Ack the interrupt in the interrupt controller */
		SPIPCI_WREG(osh, &regs->spih_int_status, SPIH_WFIFO_INTR);
		SPIPCI_RREG(osh, &regs->spih_int_status);

		/* Enable the FIFO Empty Interrupt */
		sd->intmask |= SPIH_WFIFO_INTR;
		sd->got_hcint = FALSE;
		SPIPCI_WREG(osh, &regs->spih_int_mask, sd->intmask);

	}
#endif /* BCMSDYIELD */

	/* Wait for write fifo to empty... */
	SPIPCI_ANDREG(osh, &regs->spih_gpio_data, ~0x00000020);	/* Set GPIO 5 Low */

	if (yield) {
		ASSERT((SPIPCI_RREG(sd->osh, &regs->spih_stat) & SPIH_WFEMPTY) == 0);
	}

	spi_waitbits(sd, yield);
	SPIPCI_ORREG(osh, &regs->spih_gpio_data, 0x00000020);	/* Set GPIO 5 High (de-asserted) */

	for (count = 0; count < (uint32)msglen/4; count++) {
		spi_data_in = SPIPCI_RREG(osh, &regs->spih_data);
		((uint32 *)msg_in)[count] = spi_data_in;
	}

	/* Set GPIO CS# High (de-asserted) */
	SPIPCI_ORREG(osh, &regs->spih_gpio_data, SPIH_CS);

	if (bcmpcispi_dump) {
		hexdump(" IN : ", msg_in, msglen);
	}
}