Beispiel #1
0
/**
 * Write bytes to slave device
 * 
 * @param self
 * @param args Tuple with data to write
 * @return none
 */
static PyObject* py_write(PyObject *self, PyObject* args){

    PyObject *tx_list;
    PyObject *item = 0;
    uint8_t tx_len = 0;

    /* Parse arguments */
    if(!PyArg_ParseTuple(args, "O!", &PyList_Type, &tx_list)){
        return NULL;
    }

    /* Get length of list */
    tx_len = PyList_Size(tx_list);

    /* Allocate memory for output buffer */
    uint8_t *tx_buffer = (uint8_t *)malloc(tx_len * sizeof(uint8_t));
    memset(tx_buffer, 0, sizeof(uint8_t));

    /* Populate output buffer */
    int i;
    for(i = 0; i < tx_len; i++){
        item = PyList_GetItem(tx_list, i);
        tx_buffer[i] = (uint8_t)PyInt_AsLong(item);
    }

    /* Send data */
    if(spi_write(fd, tx_buffer, tx_len) < 0){
        return PyErr_SetFromErrno(PyExc_IOError);
    }

    /* Do cleanup */
    free(tx_buffer);

    //Py_DECREF(item);
    Py_DECREF(tx_list);
    
    Py_RETURN_NONE;
}
Beispiel #2
0
/*
 * ad7816 data access by SPI
 */
static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data)
{
	struct spi_device *spi_dev = chip->spi_dev;
	int ret = 0;

	gpio_set_value(chip->rdwr_pin, 1);
	gpio_set_value(chip->rdwr_pin, 0);
	ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id));
	if (ret < 0) {
		dev_err(&spi_dev->dev, "SPI channel setting error\n");
		return ret;
	}
	gpio_set_value(chip->rdwr_pin, 1);


	if (chip->mode == AD7816_PD) { /* operating mode 2 */
		gpio_set_value(chip->convert_pin, 1);
		gpio_set_value(chip->convert_pin, 0);
	} else { /* operating mode 1 */
		gpio_set_value(chip->convert_pin, 0);
		gpio_set_value(chip->convert_pin, 1);
	}

	while (gpio_get_value(chip->busy_pin))
		cpu_relax();

	gpio_set_value(chip->rdwr_pin, 0);
	gpio_set_value(chip->rdwr_pin, 1);
	ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
	if (ret < 0) {
		dev_err(&spi_dev->dev, "SPI data read error\n");
		return ret;
	}

	*data = be16_to_cpu(*data);

	return ret;
}
Beispiel #3
0
static int trf7970a_transmit(struct trf7970a *trf, struct sk_buff *skb,
		unsigned int len)
{
	unsigned int timeout;
	int ret;

	print_hex_dump_debug("trf7970a tx data: ", DUMP_PREFIX_NONE,
			16, 1, skb->data, len, false);

	ret = spi_write(trf->spi, skb->data, len);
	if (ret) {
		dev_err(trf->dev, "%s - Can't send tx data: %d\n", __func__,
				ret);
		return ret;
	}

	skb_pull(skb, len);

	if (skb->len > 0) {
		trf->state = TRF7970A_ST_WAIT_FOR_TX_FIFO;
		timeout = TRF7970A_WAIT_FOR_FIFO_DRAIN_TIMEOUT;
	} else {
		if (trf->issue_eof) {
			trf->state = TRF7970A_ST_WAIT_TO_ISSUE_EOF;
			timeout = TRF7970A_WAIT_TO_ISSUE_ISO15693_EOF;
		} else {
			trf->state = TRF7970A_ST_WAIT_FOR_RX_DATA;
			timeout = trf->timeout;
		}
	}

	dev_dbg(trf->dev, "Setting timeout for %d ms, state: %d\n", timeout,
			trf->state);

	schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));

	return 0;
}
Beispiel #4
0
void writeData(uint8_t d)
{
	if (!g_HWSPI)
	{
		bbData(d);
		return;
	}
	memory_barrier();
	gpio_set(PIN_DC);
	gpio_clear(24);
	memory_barrier();
	pack.command = 0x100 | d;	// LoSSI 9-bit Parameter mode
	spi_start(0);				// Start SPI transfer to CS0 destination
	// Bypass spi_write function here
	//while (!HW.SPI0.CS.B.TXD); // ensure no reads
	//HW.SPI0.FIFO = pack.command;
	spi_write(d);
	spi_flush();
	memory_barrier();
	gpio_set(24);
	memory_barrier();
	//printf("Data:%.2X \n",pack.command);
}
Beispiel #5
0
static int sst25l_erase_sector(struct sst25l_flash *flash, uint32_t offset)
{
	unsigned char command[4];
	int err;

	err = sst25l_write_enable(flash, 1);
	if (err)
		return err;

	command[0] = SST25L_CMD_SECTOR_ERASE;
	command[1] = offset >> 16;
	command[2] = offset >> 8;
	command[3] = offset;
	err = spi_write(flash->spi, command, 4);
	if (err)
		return err;

	err = sst25l_wait_till_ready(flash);
	if (err)
		return err;

	return sst25l_write_enable(flash, 0);
}
Beispiel #6
0
int mmcsd_write_block(long long address, long size, int *data) {
	int r1;
	long i;

	mmcsd_select();
	r1 = 0xFF;
	r1 = mmcsd_write_single_block(address);

	if (r1) {
		mmcsd_deselect();
		return r1;
	}

	spi_write(DUMMY_BYTE);
	spi_write(DATA_START_TOKEN);

	for (i = 0; i < MMCSD_MAX_BLOCK_SIZE; ++i) {
		if (size) {
			spi_write(data[i]);
			size--;
		} else
			spi_write(0);
	}

	r1 = 0;
	spi_write(DUMMY_BYTE);
	spi_write(DUMMY_BYTE);
	r1 = mmcsd_get_r1();

	if (r1 & 0x0A) {
		return r1;
	}

	while (!input(MMC_DI))
		spi_write(DUMMY_BYTE);

	mmcsd_deselect();

	return 0;
}
static int sd_start_command(struct sd_host *host, struct sd_command *cmd)
{
	int retval = 0;

	/* select the card by driving CS low */
	spi_cs_low(host);

	/* send the command through the MOSI line */
	spi_write(host, cmd, sizeof(*cmd));

	/*
	 * Wait for the card response.
	 * Card responses come in the MISO line and have the most significant
	 * bit cleared.
	 */
	retval = spi_wait_for_resp(host, 0x00, 0x80, MMC_SPI_N_CR);

	if (retval > 0 && !(retval & 0x01) && cmd->cmd != 0x40)
		DBG("command = %d, response = 0x%02x\n", cmd->cmd & ~0x40,
		    retval);

	return retval;
}
/*
 * Erase one sector of flash memory at offset ``offset'' which is any
 * address within the sector which should be erased.
 *
 * Returns 0 if successful, non-zero otherwise.
 */
static int erase_sector(struct m25p *flash, u32 offset)
{
	DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB at 0x%08x\n",
			flash->spi->dev.bus_id, __FUNCTION__,
			flash->mtd.erasesize / 1024, offset);

	/* Wait until finished previous write command. */
	if (wait_till_ready(flash))
		return 1;

	/* Send write enable, then erase commands. */
	write_enable(flash);

	/* Set up command buffer. */
	flash->command[0] = flash->erase_opcode;
	flash->command[1] = offset >> 16;
	flash->command[2] = offset >> 8;
	flash->command[3] = offset;

	spi_write(flash->spi, flash->command, sizeof(flash->command));

	return 0;
}
Beispiel #9
0
static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
			    unsigned int value)
{
	u8 *cache = codec->reg_cache;
	struct spi_device *spi = codec->control_data;

	if (reg >= codec->driver->reg_cache_size)
		return -EINVAL;

	/* only write to the hardware if value has changed */
	if (cache[reg] != value) {
		u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };

		if (spi_write(spi, tmp, sizeof(tmp))) {
			dev_err(&spi->dev, "SPI write failed\n");
			return -EIO;
		}

		cache[reg] = value;
	}

	return 0;
}
Beispiel #10
0
// get module version
void bfin_get_module_version(ModuleVersion* vers) {
#if 1
#else
  u16 x;
  
  app_pause();
  // command
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, MSG_GET_MODULE_VERSION_COM);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);

  // major
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_read(BFIN_SPI, &x);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  vers->maj = x;
  // minor
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_read(BFIN_SPI, &x);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  vers->min = x;
  // rev
  vers->rev = 0;
  // rev high
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_read(BFIN_SPI, &x);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  vers->rev |= ((x << 8) & 0xff00);
    // rev low
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_read(BFIN_SPI, &x);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  vers->rev |= (x & 0x00ff);

  app_resume();
#endif
}
Beispiel #11
0
static ssize_t p61_dev_write(struct file *filp, const char *buf, size_t count,
                             loff_t *offset)
{
    int ret = -1;
    struct p61_dev *p61_dev;
    unsigned char tx_buffer[MAX_BUFFER_SIZE];

    P61_DBG_MSG(KERN_ALERT "p61_dev_write -Enter count %zu\n", count);

    p61_dev = filp->private_data;

    mutex_lock(&p61_dev->write_mutex);
    if (count > MAX_BUFFER_SIZE)
        count = MAX_BUFFER_SIZE;

    memset(&tx_buffer[0], 0, sizeof(tx_buffer));
    if (copy_from_user(&tx_buffer[0], &buf[0], count))
    {
        P61_ERR_MSG("%s : failed to copy from user space\n", __func__);
        mutex_unlock(&p61_dev->write_mutex);
        return -EFAULT;
    }
    /* Write data */
    ret = spi_write(p61_dev->spi, &tx_buffer[0], count);
    if (ret < 0)
    {
        ret = -EIO;
    }
    else
    {
        ret = count;
    }

    mutex_unlock(&p61_dev->write_mutex);
    P61_DBG_MSG(KERN_ALERT "p61_dev_write ret %d- Exit \n", ret);
    return ret;
}
Beispiel #12
0
static sint8 spi_rw(uint8 *pu8Mosi, uint8 *pu8Miso, uint16 u16Sz)
{
	uint8 u8Dummy = 0;
	uint8 u8SkipMosi = 0, u8SkipMiso = 0;
	uint16_t txd_data = 0;
	uint16_t rxd_data = 0;
	uint8_t uc_pcs;

	if (!pu8Mosi) {
		pu8Mosi = &u8Dummy;
		u8SkipMosi = 1;
	}
	else if(!pu8Miso) {
		pu8Miso = &u8Dummy;
		u8SkipMiso = 1;
	}
	else {
		return M2M_ERR_BUS_FAIL;
	}

	while (u16Sz) {
		txd_data = *pu8Mosi;
		spi_write(CONF_WINC_SPI, txd_data, 0, 0);

		/* Read SPI master data register. */
		spi_read(CONF_WINC_SPI, &rxd_data, &uc_pcs);
		*pu8Miso = rxd_data;

		u16Sz--;
		if (!u8SkipMiso)
			pu8Miso++;
		if (!u8SkipMosi)
			pu8Mosi++;
	}

	return M2M_SUCCESS;
}
Beispiel #13
0
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
#if	(FB_OLED && FB_IIC_OLED)
	if(cmd)
			{
   IIC_Start();
   Write_IIC_Byte(0x78);			//D/C#=0; R/W#=0
   Write_IIC_Byte(0x40);			//write data
   Write_IIC_Byte(dat);
   IIC_Stop();
		}
	else {
		IIC_Start();
   Write_IIC_Byte(0x78);            //Slave address,SA0=0
   Write_IIC_Byte(0x00);			//write command
   Write_IIC_Byte(dat); 
   IIC_Stop();
		
	}
#endif
#if	(FB_OLED && FB_SPI_OLED)
		//uint8_t i;
	uint8_t buffer[1];
	buffer[0] = dat;	
	if(cmd)
	  OLED_DC_Set();
	else 
	  OLED_DC_Clr();		  
	OLED_CS_Clr();
	spi_write(QN_SPI1, buffer, 1, oled_write_done);
	delay(100);
			 		  
	OLED_CS_Set();
	OLED_DC_Set();  
#endif

}
Beispiel #14
0
/* Primitive bulk write support for soc-cache.  The data pointed to by
 * `data' needs to already be in the form the hardware expects
 * including any leading register specific data.  Any data written
 * through this function will not go through the cache as it only
 * handles writing to volatile or out of bounds registers.
 */
static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg,
				     const void *data, size_t len)
{
	int ret;

	/* To ensure that we don't get out of sync with the cache, check
	 * whether the base register is volatile or if we've directly asked
	 * to bypass the cache.  Out of bounds registers are considered
	 * volatile.
	 */
	if (!codec->cache_bypass
	    && !snd_soc_codec_volatile_register(codec, reg)
	    && reg < codec->driver->reg_cache_size)
		return -EINVAL;

	switch (codec->control_type) {
#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
	case SND_SOC_I2C:
		ret = i2c_master_send(to_i2c_client(codec->dev), data, len);
		break;
#endif
#if defined(CONFIG_SPI_MASTER)
	case SND_SOC_SPI:
		ret = spi_write(to_spi_device(codec->dev), data, len);
		break;
#endif
	default:
		BUG();
	}

	if (ret == len)
		return 0;
	if (ret < 0)
		return ret;
	else
		return -EIO;
}
static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
			     const char *buffer, size_t count) {
	struct spi_device *spi = to_spi_device(dev);
	struct pcf2123_sysfs_reg *r;
	u8 txbuf[2];
	unsigned long reg;
	unsigned long val;

	int ret;

	r = container_of(attr, struct pcf2123_sysfs_reg, attr);

	if (strict_strtoul(r->name, 16, &reg)
		|| strict_strtoul(buffer, 10, &val))
		return -EINVAL;

	txbuf[0] = PCF2123_WRITE | reg;
	txbuf[1] = val;
	ret = spi_write(spi, txbuf, sizeof(txbuf));
	if (ret < 0)
		return -EIO;
	pcf2123_delay_trec();
	return count;
}
Beispiel #16
0
static rt_size_t sd_mmc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
	rt_uint32_t count = size;
	rt_uint32_t sector = sd_mmc_partition.offset + pos;

	while (count)
	{
		if (sd_mmc_spi_read_open_PDCA(sector))
		{
			pdca_load_channel(PDCA_CHANNEL_SPI_RX, buffer, MMC_SECTOR_SIZE);
			pdca_load_channel(PDCA_CHANNEL_SPI_TX, (void *) dummy, MMC_SECTOR_SIZE);

			spi_write(SD_MMC_SPI, 0xFF);

			pdca_channel_rx->cr = AVR32_PDCA_TEN_MASK;
			pdca_channel_tx->cr = AVR32_PDCA_TEN_MASK;

			while (!(pdca_channel_rx->isr & AVR32_PDCA_ISR_TRC_MASK));

			sd_mmc_spi_read_close_PDCA();

			pdca_channel_rx->cr = AVR32_PDCA_TDIS_MASK;
			pdca_channel_tx->cr = AVR32_PDCA_TDIS_MASK;

			count--;
			buffer += MMC_SECTOR_SIZE;
		}
		else
		{
			rt_kprintf("Unable to initiate SD/MMC read command.\n");
			return 0;
		}
	}

	return size;
}
Beispiel #17
0
/**
 * @brief   Accepts data that can be fitted in single page boundary (for EEPROM)
 *          or can be placed in write buffer (for FRAM)
 */
size_t Mtd25::bus_write(const uint8_t *txdata, size_t len, uint32_t offset) {
  msg_t status;

  osalDbgCheck(this->writebuf_size >= cfg.pagesize + cfg.addr_len + 1);
  osalDbgAssert((offset + len) <= capacity(), "Transaction out of device bounds");

  this->acquire();

  /* fill preamble */
  if (4 == cfg.addr_len)
    writebuf[0] = S25_CMD_4PP;
  else
    writebuf[0] = S25_CMD_PP;
  addr2buf(&writebuf[1], offset, cfg.addr_len);

  status = spi_write(txdata, len, writebuf, 1+cfg.addr_len);

  this->release();

  if (MSG_OK == status)
    return len;
  else
    return 0;
}
Beispiel #18
0
static int adc128_adc_conversion(struct adc128 *adc, u8 channel)
{
	int ret;

	mutex_lock(&adc->lock);

	adc->buffer[0] = channel << 3;
	adc->buffer[1] = 0;

	ret = spi_write(adc->spi, &adc->buffer, 2);
	if (ret < 0) {
		mutex_unlock(&adc->lock);
		return ret;
	}

	ret = spi_read(adc->spi, &adc->buffer, 2);

	mutex_unlock(&adc->lock);

	if (ret < 0)
		return ret;

	return ((adc->buffer[0] << 8 | adc->buffer[1]) & 0xFFF);
}
Beispiel #19
0
void writeCommand(uint8_t c)
{
	if (!g_HWSPI)
	{
		bbCmd(c);
		return;
	}
	memory_barrier();
	gpio_clear(PIN_DC);
	gpio_clear(24);
	memory_barrier();

	pack.command = 0x000 | c;	// LoSSI 9-bit Command mode
	spi_start(0);		// Start SPI transfer to CS0 destination
	// Bypass spi_write function here
	//while (!HW.SPI0.CS.B.TXD); // ensure no reads
	//HW.SPI0.FIFO = pack.command;
	spi_write(c) ;
	spi_flush();
	memory_barrier();
	gpio_set(24);
	memory_barrier();
	printf("Command:%.2X ",pack.command);
}
void main()
{

   char dato=0;
   int16 lectura=0;

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
//CONFIGURACIÓN BUS SPI-------------------------------------------------------------
 setup_spi(spi_master | spi_l_to_h | spi_clk_div_16);//Vamos a trabajar como maestro|que funciona en activo alto
 //lcd_init();
 set_adc_channel(0);
 
 while(true)
 {
  set_adc_channel(0);
  delay_ms(200);
  lectura=read_adc();
  spi_write(lectura);//Escribir lo que haya en el pin A0
  //lcd_gotoxy(1,1);
  //printf(lcd_putc," %Ld   ",lectura);
 // delay_ms(200);
 }
}
Beispiel #21
0
//void bfin_set_param(u8 idx, f32 x ) {
void bfin_set_param(u8 idx, fix16_t x ) {

  static ParamValue pval;
  pval.asInt = (s32)x;

  print_dbg("\r\n bfin_set_param, idx: ");
  print_dbg_ulong(idx);

  print_dbg(", val: 0x");
  print_dbg_hex((u32)x);

  //  app_pause();

  // command
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, MSG_SET_PARAM_COM);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  //idx
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, idx);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  //val0
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, pval.asByte[0]);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  // val1
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, pval.asByte[1]);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  //val2
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, pval.asByte[2]);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);
  //val3
  spi_selectChip(BFIN_SPI, BFIN_SPI_NPCS);
  spi_write(BFIN_SPI, pval.asByte[3]);
  spi_unselectChip(BFIN_SPI, BFIN_SPI_NPCS);

  //  app_resume();
}
Beispiel #22
0
int mmcsd_send_cmd(int cmd, long long arg, short g_CRC_enabled) {
	int packet[6];

	packet[0] = cmd | 0x40;
	packet[1] = make8(arg, 3);
	packet[2] = make8(arg, 2);
	packet[3] = make8(arg, 1);
	packet[4] = make8(arg, 0);

	if (g_CRC_enabled)
		packet[5] = mmcsd_crc7(packet, 5);
	else
		packet[5] = DUMMY_BYTE;

	spi_write(packet[0]);
	spi_write(packet[1]);
	spi_write(packet[2]);
	spi_write(packet[3]);
	spi_write(packet[4]);
	spi_write(packet[5]);

	return 0;
}
Beispiel #23
0
UBYTE flash_buf_read(UDWORD address)
{
	UBYTE buff_addr;
	UDWORD page;
	
	//make address correct
	buff_addr=MAKE8(address,0);
	page=address & FLASH_MAX_PAGES; 
	page=page<<1;
	//addr=addr | buff_addr;
	
	//read page into buffer
	//transfer main memory into buffer #1
	FLASH_CS(0);
	spi_write(0xD4);
	spi_write(0);
	spi_write(0);
	spi_write(buff_addr);
	spi_write(0);
	buff_addr=spi_write(0);
	FLASH_CS(1);	
	return buff_addr;
}
Beispiel #24
0
/*******************************************************************************
*	WRITE DATA FROM EEPROM
*	***** ARGUMENTS *****
*	/param reasAdd:		EEEPROM address where it is wanted to start writing
*	/param data:		Pointer of a byte vector variable in where data to be sent is
*	/param dataSize:	Size of the vector variable pointed by "data" pointer
*
*	***** FUNCTIONALITY *****
*	writeData() writes a frame of 0-137071 data, the start address is specified in "readAdd" argument,
*	then the function will store as many data as specified by sizeData in EEPROM and will store it
*	in the variable pointed by "data" pointer argument.
*
*	IMPORTANT: there's not knowledge about the limit of data it's allowed to be read in a frame
*******************************************************************************/
 void EEPROM_writeData(uint8_t *writeAdd, uint8_t *data, uint8_t dataSize){
	unsigned short r_data = 0;
	unsigned char r_pcs;
	 
	_EEPROM_wren();
	spi_write(SPI, WRITE, spi_get_pcs(3),  0);
	while((spi_read_status(SPI) & SPI_SR_RDRF) == 0);
	spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs);
	
	
	/**************** SENDING ADDRESS ************************/ 
	spi_write(SPI, writeAdd[2], spi_get_pcs(3),  0);
	while((spi_read_status(SPI) & SPI_SR_RDRF) == 0);
	spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs);
	 
	spi_write(SPI, writeAdd[1], spi_get_pcs(3),  0);
	while((spi_read_status(SPI) & SPI_SR_RDRF) == 0);
	spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs);
	 
	spi_write(SPI, writeAdd[0], spi_get_pcs(3),  0);
	while((spi_read_status(SPI) & SPI_SR_RDRF) == 0);
	spi_read(SPI, (uint16_t*) &r_data, (uint8_t*) &r_pcs);	
	

	/**************** SENDING DATA ************************/
	for(int i = 0; i<dataSize-1; i++){
		spi_write(SPI, *data, spi_get_pcs(3),  0);					// It receive data in "data" and it's a pointer
		while((spi_read_status(SPI) & SPI_SR_RDRF) == 0);
		spi_read(SPI, (uint16_t*) r_data, (uint8_t*) &r_pcs);
		data++;
	}
	spi_write(SPI, *data, spi_get_pcs(3),  1);						// The las byte must toggle CS
	spi_read(SPI, (uint16_t*) r_data, (uint8_t*) &r_pcs);
	
	while( EEPROM_getWriteInProcess() );							// Deberíamos hacer esto aquí pa evitarle el complique al usuario
}
int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
{
	st->tx[0] = SCA3000_WRITE_REG(address);
	st->tx[1] = val;
	return spi_write(st->us, st->tx, 2);
}
Beispiel #26
0
/*! \brief Writes the \a ctrl control word.
 */
static void aic23b_write_control_word(aic23b_ctrl_t ctrl)
{
#if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_TWI
  int twi_status;
  aic23b_ctrl_t my_ctrl = ctrl;
  twi_package_t twi_package =
  {
    .chip         = AIC23B_TWI_ADDRESS,
    .addr_length  = 0,
    .buffer       = &my_ctrl,
    .length       = sizeof(my_ctrl)
  };
  do
  {
     twi_status=twi_master_write(AIC23B_TWI, &twi_package);
  }
  while( twi_status != TWI_SUCCESS );
#elif AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
  spi_selectChip(AIC23B_SPI, AIC23B_SPI_NPCS);
  spi_write(AIC23B_SPI, *(uint16_t *)&ctrl);
  spi_unselectChip(AIC23B_SPI, AIC23B_SPI_NPCS);
#endif
}


/*! \name Low-Level Interface
 */
//! @{

void aic23b_configure_freq(int master_clock_hz, int sample_rate_hz)
{
  aic23b_src_t src;

  src.data    = AIC23B_DEFAULT(AIC23B_SRC);
  src.clkout  = 0;
  src.clkin   = 0;

  switch (master_clock_hz)
  {
   case 12000000:
    src.usb     = 1;
    if (sample_rate_hz < (8000 + 8021) / 2)
    { // 8000 Hz
      src.sr    = 0x3;
      src.bosr  = 0;
    }
    else if (sample_rate_hz < (8021 + 32000) / 2)
    { // 8021 Hz
      src.sr    = 0xB;
      src.bosr  = 1;
    }
    else if (sample_rate_hz < (32000 + 44100) / 2)
    { // 32000 Hz
      src.sr    = 0x6;
      src.bosr  = 0;
    }
    else if (sample_rate_hz < (44100 + 48000) / 2)
    { // 44100 Hz
      src.sr    = 0x8;
      src.bosr  = 1;
    }
    else if (sample_rate_hz < (48000 + 88200) / 2)
    { // 48000 Hz
      src.sr    = 0x0;
      src.bosr  = 0;
    }
    else if (sample_rate_hz < (88200 + 96000) / 2)
    { // 88200 Hz
      src.sr    = 0xF;
      src.bosr  = 1;
    }
    else
    { // 96000 Hz
      src.sr    = 0x7;
      src.bosr  = 0;
    }
    break;
  case 11289600:
    src.usb     = 0;
    if (sample_rate_hz < (8021 + 22050) / 2)
    { // 8021 Hz
      src.sr    = 0xB;
      src.bosr  = 0;
    }
    else if (sample_rate_hz < (22050 + 88200) / 2)
    { // 22050, 44100 and 48000 Hz
      src.sr    = 0x8;
      src.bosr  = 0;
    }
    else
    { // 88200 Hz
      src.sr    = 0xF;
      src.bosr  = 0;
    }
    break;
  case 18432000:
    src.usb   = 0;
    src.sr    = 0;
    src.bosr  = 1;
    break;
  default:
    //Not supported
    return;
  }

  aic23b_write_reg(AIC23B_SRC, src.data);
}
/*
 * initialize the chip
 */
static int __devinit pontis_init(ice1712_t *ice)
{
	static unsigned short wm_inits[] = {
		/* These come first to reduce init pop noise */
		WM_ADC_MUX,	0x00c0,	/* ADC mute */
		WM_DAC_MUTE,	0x0001,	/* DAC softmute */
		WM_DAC_CTRL1,	0x0000,	/* DAC mute */

		WM_POWERDOWN,	0x0008,	/* All power-up except HP */
		WM_RESET,	0x0000,	/* reset */
	};
	static unsigned short wm_inits2[] = {
		WM_MASTER_CTRL,	0x0022,	/* 256fs, slave mode */
		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */
		WM_OUT_MUX,	0x0001,	/* OUT DAC */
		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */
		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */
		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */
		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */
		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */
		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */
		// WM_DAC_MASTER,	0x0100,	/* DAC master muted */
		WM_PHASE_SWAP,	0x0000,	/* phase normal */
		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
#if 0
		WM_ALC_CTRL1,	0x007b,	/* */
		WM_ALC_CTRL2,	0x0000,	/* */
		WM_ALC_CTRL3,	0x0000,	/* */
		WM_NOISE_GATE,	0x0000,	/* */
#endif
		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
	};
	static unsigned char cs_inits[] = {
		0x04,	0x80,	/* RUN, RXP0 */
		0x05,	0x05,	/* slave, 24bit */
		0x01,	0x00,
		0x02,	0x00,
		0x03,	0x00,
	};
	unsigned int i;

	ice->vt1720 = 1;
	ice->num_total_dacs = 2;
	ice->num_total_adcs = 2;

	/* to remeber the register values */
	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
	if (! ice->akm)
		return -ENOMEM;
	ice->akm_codecs = 1;

	/* HACK - use this as the SPDIF source.
	 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
	 */
	ice->gpio.saved[0] = 0;

	/* initialize WM8776 codec */
	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
		wm_put(ice, wm_inits[i], wm_inits[i+1]);
	schedule_timeout_uninterruptible(1);
	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);

	/* initialize CS8416 codec */
	/* assert PRST#; MT05 bit 7 */
	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
	mdelay(5);
	/* deassert PRST# */
	outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));

	for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
		spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);

	return 0;
}
/*! \brief Initializes SD/MMC resources: GPIO, SPI and SD/MMC.
 */
static void sd_mmc_resources_init(void)
{
  // GPIO pins used for SD/MMC interface
  static const gpio_map_t SD_MMC_SPI_GPIO_MAP =
  {
    {SD_MMC_SPI_SCK_PIN,  SD_MMC_SPI_SCK_FUNCTION },  // SPI Clock.
    {SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION},  // MISO.
    {SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION},  // MOSI.
    {SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION}   // Chip Select NPCS.
  };

  // SPI options.
  spi_options_t spiOptions =
  {
    .reg          = SD_MMC_SPI_NPCS,
    .baudrate     = SD_MMC_SPI_MASTER_SPEED,  // Defined in conf_sd_mmc_spi.h.
    .bits         = SD_MMC_SPI_BITS,          // Defined in conf_sd_mmc_spi.h.
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 1,
    .spi_mode     = 0,
    .modfdis      = 1
  };

  // Assign I/Os to SPI.
  gpio_enable_module(SD_MMC_SPI_GPIO_MAP,
                     sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));

  // Initialize as master.
  spi_initMaster(SD_MMC_SPI, &spiOptions);

  // Set SPI selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(SD_MMC_SPI, 0, 0, 0);

  // Enable SPI module.
  spi_enable(SD_MMC_SPI);

  // Initialize SD/MMC driver with SPI clock (PBA).
  sd_mmc_spi_init(spiOptions, PBA_HZ);
}


/*! \brief Initialize PDCA (Peripheral DMA Controller A) resources for the SPI transfer and start a dummy transfer
 */
void local_pdca_init(void)
{
  // this PDCA channel is used for data reception from the SPI
  pdca_channel_options_t pdca_options_SPI_RX ={ // pdca channel options

    .addr = ram_buffer,
    // memory address. We take here the address of the string dummy_data. This string is located in the file dummy.h

    .size = 512,                              // transfer counter: here the size of the string
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_RX,        // select peripheral ID - data are on reception from SPI1 RX line
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // this channel is used to activate the clock of the SPI by sending a dummy variables
  pdca_channel_options_t pdca_options_SPI_TX ={ // pdca channel options

    .addr = (void *)&dummy_data,              // memory address.
                                              // We take here the address of the string dummy_data.
                                              // This string is located in the file dummy.h
    .size = 512,                              // transfer counter: here the size of the string
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_TX,        // select peripheral ID - data are on reception from SPI1 RX line
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // Init PDCA transmission channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_TX, &pdca_options_SPI_TX);

  // Init PDCA Reception channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_RX, &pdca_options_SPI_RX);

  //! \brief Enable pdca transfer interrupt when completed
  INTC_register_interrupt(&pdca_int_handler, AVR32_PDCA_IRQ_0, AVR32_INTC_INT1);  // pdca_channel_spi1_RX = 0

}


/*! \brief Main function. Execution starts here.
 */
int main(void)
{
  int i, j;


  // Switch the main clock to the external oscillator 0
  pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

  // Initialize debug RS232 with PBA clock
  init_dbg_rs232(PBA_HZ);

  //start test
  print_dbg("\r\nInit SD/MMC Driver");
  print_dbg("\r\nInsert SD/MMC...");

  // Initialize Interrupt Controller
  INTC_init_interrupts();

  // Initialize SD/MMC driver resources: GPIO, SPI and SD/MMC.
  sd_mmc_resources_init();

  // Wait for a card to be inserted
  while (!sd_mmc_spi_mem_check());
  print_dbg("\r\nCard detected!");

  // Read Card capacity
  sd_mmc_spi_get_capacity();
  print_dbg("Capacity = ");
  print_dbg_ulong(capacity >> 20);
  print_dbg(" MBytes");

  // Enable all interrupts.
  Enable_global_interrupt();

  // Initialize PDCA controller before starting a transfer
  local_pdca_init();

  // Read the first sectors number 1, 2, 3 of the card
  for(j = 1; j <= 3; j++)
  {
    // Configure the PDCA channel: the address of memory ram_buffer to receive the data at sector address j
    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_RX,
                     &ram_buffer,
                     512);

    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_TX,
                     (void *)&dummy_data,
                     512); //send dummy to activate the clock

    end_of_transfer = false;
    // open sector number j
    if(sd_mmc_spi_read_open_PDCA (j))
    {
      print_dbg("\r\nFirst 512 Bytes of Transfer number ");
      print_dbg_ulong(j);
      print_dbg(" :\r\n");

      spi_write(SD_MMC_SPI,0xFF); // Write a first dummy data to synchronize transfer
      pdca_enable_interrupt_transfer_complete(AVR32_PDCA_CHANNEL_SPI_RX);
      pdca_channelrx =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_RX); // get the correct PDCA channel pointer
      pdca_channeltx =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_TX); // get the correct PDCA channel pointer
      pdca_channelrx->cr = AVR32_PDCA_TEN_MASK; // Enable RX PDCA transfer first
      pdca_channeltx->cr = AVR32_PDCA_TEN_MASK; // and TX PDCA transfer

      while(!end_of_transfer);

      // Display the first 2O bytes of the ram_buffer content
      for( i = 0; i < 20; i++)
      {
        print_dbg_char_hex( (U8)(*(ram_buffer + i)));
      }
    }
    else
    {
      print_dbg("\r\n! Unable to open memory \r\n");
    }
  }
  print_dbg("\r\nEnd of the example.\r\n");

  while (1);
}
Beispiel #29
0
/*
 * Handle our "Vendor Extension" commands on endpoint 0.
 * If we handle this one, return non-zero.
 */
unsigned char
app_vendor_cmd (void)
{
  OEE = 0x0f;
  IOE = 0x04;  IOE = 0x01;  // pulse two I/O pins

  if (bRequestType == VRT_VENDOR_IN){

    /////////////////////////////////
    //    handle the IN requests
    /////////////////////////////////

    switch (bRequest){

    case VRQ_GET_STATUS:
      switch (wIndexL){

      case GS_TX_UNDERRUN:
	EP0BUF[0] = g_tx_underrun;
	g_tx_underrun = 0;
	EP0BCH = 0;
	EP0BCL = 1;
	break;

      case GS_RX_OVERRUN:
	EP0BUF[0] = g_rx_overrun;
	g_rx_overrun = 0;
	EP0BCH = 0;
	EP0BCL = 1;
	break;

      default:
	return 0;
      }
      break;

    case VRQ_I2C_READ:
      if (!i2c_read (wValueL, EP0BUF, wLengthL))
	return 0;

      EP0BCH = 0;
      EP0BCL = wLengthL;
      break;

    case VRQ_SPI_READ:
      if (!spi_read (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, wLengthL))
	return 0;

      EP0BCH = 0;
      EP0BCL = wLengthL;
      break;

    case VRQ_JTAG_RW:
      *EP0BUF = fpga_rxtx(wValueL);
      EP0BCH = 0;
      EP0BCL = 1;
      break;

    default:
      return 0;
    }
  }

  else if (bRequestType == VRT_VENDOR_OUT){

    /////////////////////////////////
    //    handle the OUT requests
    /////////////////////////////////

    switch (bRequest){

    case VRQ_SET_LED:
      switch (wIndexL){
      case 0:
	set_led_0 (wValueL);
	break;

      case 1:
	set_led_1 (wValueL);
	break;

      default:
	return 0;
      }
      break;

    case VRQ_FPGA_LOAD:
      switch (wIndexL){			// sub-command
      case FL_BEGIN:
	return fpga_load_begin ();

      case FL_XFER:
	get_ep0_data ();
	return fpga_load_xfer (EP0BUF, EP0BCL);

      case FL_END:
	return fpga_load_end ();

      case FL_END_SHUTDOWN:
	return fpga_load_end_shutdown ();

      case FL_TX:
	get_ep0_data ();
	return fpga_tx (EP0BUF);

      case FL_INIT:
	initialize_jtag();
	return 1;

      default:
	return 0;
      }
      break;


    case VRQ_FPGA_SET_RESET:
      fpga_set_reset (wValueL);
      break;

    case VRQ_FPGA_SET_TX_ENABLE:
      fpga_set_tx_enable (wValueL);
      break;

    case VRQ_FPGA_SET_RX_ENABLE:
      fpga_set_rx_enable (wValueL);
      break;

    case VRQ_FPGA_SET_TX_RESET:
      fpga_set_tx_reset (wValueL);
      break;

    case VRQ_FPGA_SET_RX_RESET:
      fpga_set_rx_reset (wValueL);
      break;

    case VRQ_I2C_WRITE:
      get_ep0_data ();
      if (!i2c_write (wValueL, EP0BUF, EP0BCL))
	return 0;
      break;

    case VRQ_SPI_WRITE:
      get_ep0_data ();
      if (!spi_write (wValueH, wValueL, wIndexH, wIndexL, EP0BUF, EP0BCL))
	return 0;
      break;

    default:
      return 0;
    }

  }
  else
    return 0;    // invalid bRequestType

  return 1;
}
Beispiel #30
0
/* When we cat /sys/bus/spi/devices/spi0.0/looptest this will be triggered */
static ssize_t dummy_looptest(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct spi_device *spi = to_spi_device(dev);
	struct dummy *p_dummy = dev_get_drvdata(&spi->dev);

	/*
	 * WARNING! Do not dereference the chip-specific data in any normal
	 * driver for a chip. It is usually STATIC and shall not be read
	 * or written to. Your chip driver should NOT depend on fields in this
	 * struct, this is just used here to alter the behaviour of the chip
	 * in order to perform tests.
	 */
	struct pl022_config_chip *chip_info = spi->controller_data;
	int status;
	u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD,
			0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05,
			0xF0, 0x0D};
	u8 rxbuf[14];
	u8 *bigtxbuf_virtual;
	u8 *bigrxbuf_virtual;

	if (mutex_lock_interruptible(&p_dummy->lock))
		return -ERESTARTSYS;

	bigtxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL);
	if (bigtxbuf_virtual == NULL) {
		status = -ENOMEM;
		goto out;
	}
	bigrxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL);

	/* Fill TXBUF with some happy pattern */
	memset(bigtxbuf_virtual, 0xAA, DMA_TEST_SIZE);

	/*
	 * Force chip to 8 bit mode
	 * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
	 */
	chip_info->data_size = SSP_DATA_BITS_8;
	/* You should NOT DO THIS EITHER */
	spi->master->setup(spi);

	/* Now run the tests for 8bit mode */
	pr_info("Simple test 1: write 0xAA byte, read back garbage byte "
		"in 8bit mode\n");
	status = spi_w8r8(spi, 0xAA);
	if (status < 0)
		pr_warning("Siple test 1: FAILURE: spi_write_then_read "
			   "failed with status %d\n", status);
	else
		pr_info("Simple test 1: SUCCESS!\n");

	pr_info("Simple test 2: write 8 bytes, read back 8 bytes garbage "
		"in 8bit mode (full FIFO)\n");
	status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
	if (status < 0)
		pr_warning("Simple test 2: FAILURE: spi_write_then_read() "
			   "failed with status %d\n", status);
	else
		pr_info("Simple test 2: SUCCESS!\n");

	pr_info("Simple test 3: write 14 bytes, read back 14 bytes garbage "
		"in 8bit mode (see if we overflow FIFO)\n");
	status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
	if (status < 0)
		pr_warning("Simple test 3: FAILURE: failed with status %d "
			   "(probably FIFO overrun)\n", status);
	else
		pr_info("Simple test 3: SUCCESS!\n");

	pr_info("Simple test 4: write 8 bytes with spi_write(), read 8 "
		"bytes garbage with spi_read() in 8bit mode\n");
	status = spi_write(spi, &txbuf[0], 8);
	if (status < 0)
		pr_warning("Simple test 4 step 1: FAILURE: spi_write() "
			   "failed with status %d\n", status);
	else
		pr_info("Simple test 4 step 1: SUCCESS!\n");
	status = spi_read(spi, &rxbuf[0], 8);
	if (status < 0)
		pr_warning("Simple test 4 step 2: FAILURE: spi_read() "
			   "failed with status %d\n", status);
	else
		pr_info("Simple test 4 step 2: SUCCESS!\n");

	pr_info("Simple test 5: write 14 bytes with spi_write(), read "
		"14 bytes garbage with spi_read() in 8bit mode\n");
	status = spi_write(spi, &txbuf[0], 14);
	if (status < 0)
		pr_warning("Simple test 5 step 1: FAILURE: spi_write() "
			   "failed with status %d (probably FIFO overrun)\n",
			   status);
	else
		pr_info("Simple test 5 step 1: SUCCESS!\n");
	status = spi_read(spi, &rxbuf[0], 14);
	if (status < 0)
		pr_warning("Simple test 5 step 2: FAILURE: spi_read() "
			   "failed with status %d (probably FIFO overrun)\n",
			   status);
	else
		pr_info("Simple test 5: SUCCESS!\n");

	pr_info("Simple test 6: write %d bytes with spi_write(), "
		"read %d bytes garbage with spi_read() in 8bit mode\n",
		DMA_TEST_SIZE, DMA_TEST_SIZE);
	status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
	if (status < 0)
		pr_warning("Simple test 6 step 1: FAILURE: spi_write() "
			   "failed with status %d (probably FIFO overrun)\n",
			   status);
	else
		pr_info("Simple test 6 step 1: SUCCESS!\n");
	status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
	if (status < 0)
		pr_warning("Simple test 6 step 2: FAILURE: spi_read() "
			   "failed with status %d (probably FIFO overrun)\n",
			   status);
	else
		pr_info("Simple test 6: SUCCESS!\n");


	/*
	 * Force chip to 16 bit mode
	 * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
	 */
	chip_info->data_size = SSP_DATA_BITS_16;
	/* You should NOT DO THIS EITHER */
	spi->master->setup(spi);

	pr_info("Simple test 7: write 0xAA byte, read back garbage byte "
		"in 16bit bus mode\n");
	status = spi_w8r8(spi, 0xAA);
	if (status == -EIO)
		pr_info("Simple test 7: SUCCESS! (expected failure with "
			"status EIO)\n");
	else if (status < 0)
		pr_warning("Siple test 7: FAILURE: spi_write_then_read "
			   "failed with status %d\n", status);
	else
		pr_warning("Siple test 7: FAILURE: spi_write_then_read "
			   "succeeded but it was expected to fail!\n");

	pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage "
		"in 16bit mode (full FIFO)\n");
	status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
	if (status < 0)
		pr_warning("Simple test 8: FAILURE: spi_write_then_read() "
			   "failed with status %d\n", status);
	else
		pr_info("Simple test 8: SUCCESS!\n");

	pr_info("Simple test 9: write 14 bytes, read back 14 bytes garbage "
		"in 16bit mode (see if we overflow FIFO)\n");
	status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
	if (status < 0)
		pr_warning("Simple test 9: FAILURE: failed with status %d "
			   "(probably FIFO overrun)\n", status);
	else
		pr_info("Simple test 9: SUCCESS!\n");

	pr_info("Simple test 10: write %d bytes with spi_write(), "
	       "read %d bytes garbage with spi_read() in 16bit mode\n",
	       DMA_TEST_SIZE, DMA_TEST_SIZE);
	status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
	if (status < 0)
		pr_warning("Simple test 10 step 1: FAILURE: spi_write() "
			   "failed with status %d (probably FIFO overrun)\n",
			   status);
	else
		pr_info("Simple test 10 step 1: SUCCESS!\n");

	status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
	if (status < 0)
		pr_warning("Simple test 10 step 2: FAILURE: spi_read() "
			   "failed with status %d (probably FIFO overrun)\n",
			   status);
	else
		pr_info("Simple test 10: SUCCESS!\n");

	status = sprintf(buf, "loop test complete\n");
	kfree(bigrxbuf_virtual);
	kfree(bigtxbuf_virtual);
 out:
	mutex_unlock(&p_dummy->lock);
	return status;
}