示例#1
0
static int max6902_get_reg(struct device *dev, unsigned char address,
				unsigned char *data)
{
	struct spi_device *spi = to_spi_device(dev);
	struct max6902 *chip = dev_get_drvdata(dev);
	struct spi_message message;
	struct spi_transfer xfer;
	int status;

	if (!data)
		return -EINVAL;

	/* Build our spi message */
	spi_message_init(&message);
	memset(&xfer, 0, sizeof(xfer));
	xfer.len = 2;
	/* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */
	xfer.tx_buf = chip->tx_buf;
	xfer.rx_buf = chip->rx_buf;

	/* Set MSB to indicate read */
	chip->tx_buf[0] = address | 0x80;

	spi_message_add_tail(&xfer, &message);

	/* do the i/o */
	status = spi_sync(spi, &message);
	if (status == 0)
		status = message.status;
	else
		return status;

	*data = chip->rx_buf[1];

	return status;
}
示例#2
0
static int max3110_write_then_read(struct uart_max3110 *max,
		const void *txbuf, void *rxbuf, unsigned len, int always_fast)
{
	struct spi_device *spi = max->spi;
	struct spi_message	message;
	struct spi_transfer	x;
	int ret;

	spi_message_init(&message);
	memset(&x, 0, sizeof x);
	x.len = len;
	x.tx_buf = txbuf;
	x.rx_buf = rxbuf;
	spi_message_add_tail(&x, &message);

	if (always_fast)
		x.speed_hz = spi->max_speed_hz;
	else if (max->baud)
		x.speed_hz = max->baud;

	/* Do the i/o */
	ret = spi_sync(spi, &message);
	return ret;
}
int ab4500_read(struct ab4500 *ab4500, unsigned char block,
		unsigned long addr)
{
	struct spi_transfer xfer;
	struct spi_message	msg;
	unsigned long spi_data =
		1 << 23 | block << 18 | addr << 10;

	mutex_lock(&ab4500->lock);
	ab4500->tx_buf[0] = spi_data;
	ab4500->rx_buf[0] = 0;

	xfer.tx_buf	= ab4500->tx_buf;
	xfer.rx_buf 	= ab4500->rx_buf;
	xfer.len	= sizeof(unsigned long);

	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	spi_sync(ab4500->spi, &msg);
	mutex_unlock(&ab4500->lock);

	return  ab4500->rx_buf[0];
}
示例#4
0
int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val)
{
	struct spi_transfer t;
	struct spi_message m;
	int ret;

	BUG_ON(!mutex_is_locked(&mc13783->lock));

	if (offset > MC13783_NUMREGS)
		return -EINVAL;

	*val = offset << MC13783_REGOFFSET_SHIFT;

	memset(&t, 0, sizeof(t));

	t.tx_buf = val;
	t.rx_buf = val;
	t.len = sizeof(u32);

	spi_message_init(&m);
	spi_message_add_tail(&t, &m);

	ret = spi_sync(mc13783->spidev, &m);

	/* error in message.status implies error return from spi_sync */
	BUG_ON(!ret && m.status);

	if (ret)
		return ret;

	*val &= 0xffffff;

	dev_vdbg(&mc13783->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val);

	return 0;
}
/**
 * ili922x_read_status - read status register from display
 * @spi: spi device
 * @rs:  output value
 */
static int ili922x_read_status(struct spi_device *spi, u16 *rs)
{
	struct spi_message msg;
	struct spi_transfer xfer;
	unsigned char tbuf[CMD_BUFSIZE];
	unsigned char rbuf[CMD_BUFSIZE];
	int ret, i;

	memset(&xfer, 0, sizeof(struct spi_transfer));
	spi_message_init(&msg);
	xfer.tx_buf = tbuf;
	xfer.rx_buf = rbuf;
	xfer.cs_change = 1;
	CHECK_FREQ_REG(spi, &xfer);

	tbuf[0] = set_tx_byte(START_BYTE(ili922x_id, START_RS_INDEX,
					 START_RW_READ));
	/*
	 * we need 4-byte xfer here due to invalid dummy byte
	 * received after start byte
	 */
	for (i = 1; i < 4; i++)
		tbuf[i] = set_tx_byte(0);	/* dummy */

	xfer.bits_per_word = 8;
	xfer.len = 4;
	spi_message_add_tail(&xfer, &msg);
	ret = spi_sync(spi, &msg);
	if (ret < 0) {
		dev_dbg(&spi->dev, "Error sending SPI message 0x%x", ret);
		return ret;
	}

	*rs = (rbuf[2] << 8) + rbuf[3];
	return 0;
}
示例#6
0
int linux_spi_write(uint8_t *b, uint32_t len)
{
	int ret;
	struct spi_message msg;

	if (len > 0 && NULL != b) {
		struct spi_transfer tr = {
			.tx_buf = b,
			.len = len,
			.speed_hz = SPEED,
			.delay_usecs = 0,
		};
		char *r_buffer = kzalloc(len, GFP_KERNEL);

		if (!r_buffer)
			return 0;	/* TODO: it should be return -ENOMEM */

		tr.rx_buf = r_buffer;
		PRINT_D(BUS_DBG, "Request writing %d bytes\n", len);

		spi_message_init(&msg);
		spi_message_add_tail(&tr, &msg);
		ret = spi_sync(wilc_spi_dev, &msg);
		if (ret < 0)
			PRINT_ER("SPI transaction failed\n");

		kfree(r_buffer);
	} else {
		PRINT_ER("can't write data due to NULL buffer or zero length\n");
		ret = -1;
	}

	(ret < 0) ? (ret = 0) : (ret = 1);

	return ret;
}
示例#7
0
/**
 * adis16240_read_ring_data() read data registers which will be placed into ring
 * @dev: device associated with child of actual device (iio_dev or iio_trig)
 * @rx: somewhere to pass back the value read
 **/
static int adis16240_read_ring_data(struct device *dev, u8 *rx)
{
	struct spi_message msg;
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
	struct spi_transfer xfers[ADIS16240_OUTPUTS + 1];
	int ret;
	int i;

	mutex_lock(&st->buf_lock);

	spi_message_init(&msg);

	memset(xfers, 0, sizeof(xfers));
	for (i = 0; i <= ADIS16240_OUTPUTS; i++) {
		xfers[i].bits_per_word = 8;
		xfers[i].cs_change = 1;
		xfers[i].len = 2;
		xfers[i].delay_usecs = 30;
		xfers[i].tx_buf = st->tx + 2 * i;
		st->tx[2 * i]
			= ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i);
		st->tx[2 * i + 1] = 0;
		if (i >= 1)
			xfers[i].rx_buf = rx + 2 * (i - 1);
		spi_message_add_tail(&xfers[i], &msg);
	}

	ret = spi_sync(st->us, &msg);
	if (ret)
		dev_err(&st->us->dev, "problem when burst reading");

	mutex_unlock(&st->buf_lock);

	return ret;
}
示例#8
0
int kxr94_spi_write( struct spi_device *spi_dev, unsigned char addr, unsigned char data )
{
	unsigned char			tx_buf[2]={addr, data};
	struct spi_message		msg;
	struct spi_transfer		transfer;
	int				retval;

	/* Prepare the data. */
	memset( &msg, 0, sizeof( msg ) );
	memset( &transfer, 0, sizeof( transfer ) );
	spi_message_init( &msg );

	/* Prepare the address cycle. */
	transfer.tx_buf=tx_buf;
	transfer.len=sizeof( tx_buf );
	transfer.delay_usecs=80;
	spi_message_add_tail( &transfer, &msg );

	/* Finalize and transmit. */
	msg.spi=spi_dev;
	msg.is_dma_mapped=0;
	retval=spi_sync( spi_dev, &msg );
	return retval;
}
int fc8050_spi_write_then_read(struct spi_device *spi, fci_u8 *txbuf, fci_u16 tx_length, fci_u8 *rxbuf, fci_u16 rx_length)
{
	fci_s32 res;
	
	struct spi_message	message;
	struct spi_transfer	x;

	spi_message_init(&message);
	memset(&x, 0, sizeof x);

	spi_message_add_tail(&x, &message);
	
	memcpy(data_buf, txbuf, tx_length);
	
	x.tx_buf=data_buf;
	x.rx_buf=data_buf;
	x.len = tx_length + rx_length;
	
	res = spi_sync(spi, &message);

	memcpy(rxbuf, x.rx_buf + tx_length, rx_length);

	return res;
}
示例#10
0
int linux_spi_read(unsigned char*rb, unsigned long rlen){

	int ret;
	
		if(rlen > 0){
				struct spi_message msg;
				struct spi_transfer tr = {
				//		.tx_buf = t_buffer,
						.rx_buf = rb,
						.len = rlen,
						.speed_hz = SPEED,
						.delay_usecs = 0,
						
				};
				char *t_buffer = (char*) kzalloc(rlen, GFP_KERNEL);
				if(! t_buffer){
					PRINT_ER("Failed to allocate memory for t_buffer\n");
				}
				tr.tx_buf = t_buffer;			

				spi_message_init(&msg);
				spi_message_add_tail(&tr,&msg);
				ret = spi_sync(atwilc_spi_dev,&msg);
				if(ret < 0){
					PRINT_ER("SPI transaction failed\n");
				}
				kfree(t_buffer);
			}else{
					PRINT_ER("can't read data with the following length: %ld\n",rlen);
					ret = -1;
				}
		/* change return value to match ATWILC interface */
		(ret<0)? (ret = 0):(ret = 1);
	
	return ret;
}
示例#11
0
int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
{
	struct spi_transfer xfer = {
		.bits_per_word = 8,
		.len = 2,
		.cs_change = 1,
		.tx_buf = st->tx,
	};
	struct spi_message msg;

	st->tx[0] = SCA3000_WRITE_REG(address);
	st->tx[1] = val;
	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	return spi_sync(st->us, &msg);
}

int sca3000_read_data(struct sca3000_state *st,
		      uint8_t reg_address_high,
		      u8 **rx_p,
		      int len)
{
	int ret;
	struct spi_message msg;
	struct spi_transfer xfer = {
		.bits_per_word = 8,
		.len = len + 1,
		.cs_change = 1,
		.tx_buf = st->tx,
	};

	*rx_p = kmalloc(len + 1, GFP_KERNEL);
	if (*rx_p == NULL) {
		ret = -ENOMEM;
		goto error_ret;
	}
	xfer.rx_buf = *rx_p;
	st->tx[0] = SCA3000_READ_REG(reg_address_high);
	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	ret = spi_sync(st->us, &msg);

	if (ret) {
		dev_err(get_device(&st->us->dev), "problem reading register");
		goto error_free_rx;
	}

	return 0;
error_free_rx:
	kfree(*rx_p);
error_ret:
	return ret;

}
/**
 * sca3000_reg_lock_on() test if the ctrl register lock is on
 *
 * Lock must be held.
 **/
static int sca3000_reg_lock_on(struct sca3000_state *st)
{
	u8 *rx;
	int ret;

	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);

	if (ret < 0)
		return ret;
	ret = !(rx[1] & SCA3000_LOCKED);
	kfree(rx);

	return ret;
}
示例#12
0
文件: spi.c 项目: AlexShiLucky/linux
static void wl12xx_spi_init(struct device *child)
{
	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
	struct spi_transfer t;
	struct spi_message m;
	struct spi_device *spi = to_spi_device(glue->dev);
	u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);

	if (!cmd) {
		dev_err(child->parent,
			"could not allocate cmd for spi init\n");
		return;
	}

	memset(&t, 0, sizeof(t));
	spi_message_init(&m);

	/*
	 * Set WSPI_INIT_COMMAND
	 * the data is being send from the MSB to LSB
	 */
	cmd[0] = 0xff;
	cmd[1] = 0xff;
	cmd[2] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
	cmd[3] = 0;
	cmd[4] = 0;
	cmd[5] = HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
	cmd[5] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;

	cmd[6] = WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
		| WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;

	if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
		cmd[6] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
	else
		cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY;

	cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END;

	/*
	 * The above is the logical order; it must actually be stored
	 * in the buffer byte-swapped.
	 */
	__swab32s((u32 *)cmd);
	__swab32s((u32 *)cmd+1);

	t.tx_buf = cmd;
	t.len = WSPI_INIT_CMD_LEN;
	spi_message_add_tail(&t, &m);

	spi_sync(to_spi_device(glue->dev), &m);

	/* Send extra clocks with inverted CS (high). this is required
	 * by the wilink family in order to successfully enter WSPI mode.
	 */
	spi->mode ^= SPI_CS_HIGH;
	memset(&m, 0, sizeof(m));
	spi_message_init(&m);

	cmd[0] = 0xff;
	cmd[1] = 0xff;
	cmd[2] = 0xff;
	cmd[3] = 0xff;
	__swab32s((u32 *)cmd);

	t.tx_buf = cmd;
	t.len = 4;
	spi_message_add_tail(&t, &m);

	spi_sync(to_spi_device(glue->dev), &m);

	/* Restore chip select configration to normal */
	spi->mode ^= SPI_CS_HIGH;
	kfree(cmd);
}
示例#13
0
static ssize_t sq_spi_download_write(struct file *file, const char __user *data,
                                     size_t len, loff_t *ppos)
{
    int err = 0;
    //char *p;
    struct spi_message msg;
    struct spi_transfer xfer;
    //char buf[128];
    char *buf;

    buf = kmalloc(len,GFP_KERNEL);
    if(!buf) {
        return -ENOMEM;
    }


    if(copy_from_user(buf,data,len)) {
        return -EFAULT;
    }

    SPI_DOWNLOAD_DBG(" write len=0x%x =>",len);

#if (SPI_CTRL_GPIO_EN == 1 )
    do {
#endif

        /*
        i=0;
        while(1) {
        	sq_gpio_set_low(TST_GPIO_G,1<<i);
        	sq_gpio_set_high(TST_GPIO_G,1<<i);
        	i++;
        	if(i>0x07)
        		i=0;
        }
        */



#if 0
        i=1;
        while(i--)
        {

            sq_gpio_set_low(TST_GPIO_G,DL_PROGB);
            udelay(20);
            sq_gpio_set_high(TST_GPIO_G,DL_PROGB);
            /*
            sq_gpio_set_low(TST_GPIO_G,DL_RST);
            udelay(20);
            sq_gpio_set_high(TST_GPIO_G,DL_RST);


            sq_gpio_set_low(TST_GPIO_G,DL_INITB);
            udelay(20);
            sq_gpio_set_high(TST_GPIO_G,DL_INITB);


            sq_gpio_set_low(TST_GPIO_G,DL_DONE);
            udelay(20);
            sq_gpio_set_high(TST_GPIO_G,DL_DONE);
            */

            //sq_gpio_in(TST_GPIO_G,DL_INITB);
            //sq_gpio_in(TST_GPIO_G,DL_DONE);
            //sq_spi_download_write_rst();

        }
#endif


        /*
        	c = len;
        	p = data;
        	while(c--) {
        	printk("%c",*p++);
        	}
        	printk("\n");
        */


#if 1
        spi_message_init(&msg);
        memset(&xfer, 0, sizeof(struct spi_transfer));

        //SPI_DOWNLOAD_DBG(" bits_per_word= %d",msg.spi->bits_per_word);
        xfer.tx_buf = buf;



//	xfer.tx_buf = tx_buf;
        xfer.len = SET_TX_RX_LEN(len, 0);
        spi_message_add_tail(&xfer, &msg);
#if (SPI_CTRL_GPIO_EN == 1 )
        sq_spi_download_write_before();
#endif

        err = spi_sync(sq_spi_download_device, &msg);


#if (SPI_CTRL_GPIO_EN == 1 )
        //sq_spi_download_write_chk();

    } while (sq_spi_download_write_chk() != 0 );
#endif
#endif

    kfree(buf);

//	SPI_DOWNLOAD_DBG(" <============== sq_spi_download_write end ===============>");
    return 0;

}
示例#14
0
/*
 * Erase pages of flash.
 */
static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct dataflash	*priv = mtd->priv;
	struct spi_device	*spi = priv->spi;
	struct spi_transfer	x = { .tx_dma = 0, };
	struct spi_message	msg;
	unsigned		blocksize = priv->page_size << 3;
	uint8_t			*command;
	uint32_t		rem;

	pr_debug("%s: erase addr=0x%llx len 0x%llx\n",
	      dev_name(&spi->dev), (long long)instr->addr,
	      (long long)instr->len);

	div_u64_rem(instr->len, priv->page_size, &rem);
	if (rem)
		return -EINVAL;
	div_u64_rem(instr->addr, priv->page_size, &rem);
	if (rem)
		return -EINVAL;

	spi_message_init(&msg);

	x.tx_buf = command = priv->command;
	x.len = 4;
	spi_message_add_tail(&x, &msg);

	mutex_lock(&priv->lock);
	while (instr->len > 0) {
		unsigned int	pageaddr;
		int		status;
		int		do_block;

		/* Calculate flash page address; use block erase (for speed) if
		 * we're at a block boundary and need to erase the whole block.
		 */
		pageaddr = div_u64(instr->addr, priv->page_size);
		do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize;
		pageaddr = pageaddr << priv->page_offset;

		command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
		command[1] = (uint8_t)(pageaddr >> 16);
		command[2] = (uint8_t)(pageaddr >> 8);
		command[3] = 0;

		pr_debug("ERASE %s: (%x) %x %x %x [%i]\n",
			do_block ? "block" : "page",
			command[0], command[1], command[2], command[3],
			pageaddr);

		status = spi_sync(spi, &msg);
		(void) dataflash_waitready(spi);

		if (status < 0) {
			printk(KERN_ERR "%s: erase %x, err %d\n",
				dev_name(&spi->dev), pageaddr, status);
			/* REVISIT:  can retry instr->retries times; or
			 * giveup and instr->fail_addr = instr->addr;
			 */
			continue;
		}

		if (do_block) {
			instr->addr += blocksize;
			instr->len -= blocksize;
		} else {
			instr->addr += priv->page_size;
			instr->len -= priv->page_size;
		}
	}
	mutex_unlock(&priv->lock);

	/* Inform MTD subsystem that erase is complete */
	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return 0;
}

/*
 * Read from the DataFlash device.
 *   from   : Start offset in flash device
 *   len    : Amount to read
 *   retlen : About of data actually read
 *   buf    : Buffer containing the data
 */
static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
			       size_t *retlen, u_char *buf)
{
	struct dataflash	*priv = mtd->priv;
	struct spi_transfer	x[2] = { { .tx_dma = 0, }, };
	struct spi_message	msg;
	unsigned int		addr;
	uint8_t			*command;
	int			status;

	pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev),
			(unsigned)from, (unsigned)(from + len));

	/* Calculate flash page/byte address */
	addr = (((unsigned)from / priv->page_size) << priv->page_offset)
		+ ((unsigned)from % priv->page_size);

	command = priv->command;

	pr_debug("READ: (%x) %x %x %x\n",
		command[0], command[1], command[2], command[3]);

	spi_message_init(&msg);

	x[0].tx_buf = command;
	x[0].len = 8;
	spi_message_add_tail(&x[0], &msg);

	x[1].rx_buf = buf;
	x[1].len = len;
	spi_message_add_tail(&x[1], &msg);

	mutex_lock(&priv->lock);

	/* Continuous read, max clock = f(car) which may be less than
	 * the peak rate available.  Some chips support commands with
	 * fewer "don't care" bytes.  Both buffers stay unchanged.
	 */
	command[0] = OP_READ_CONTINUOUS;
	command[1] = (uint8_t)(addr >> 16);
	command[2] = (uint8_t)(addr >> 8);
	command[3] = (uint8_t)(addr >> 0);
	/* plus 4 "don't care" bytes */

	status = spi_sync(priv->spi, &msg);
	mutex_unlock(&priv->lock);

	if (status >= 0) {
		*retlen = msg.actual_length - 8;
		status = 0;
	} else
		pr_debug("%s: read %x..%x --> %d\n",
			dev_name(&priv->spi->dev),
			(unsigned)from, (unsigned)(from + len),
			status);
	return status;
}
示例#15
0
static int wm0010_stage2_load(struct snd_soc_codec *codec)
{
	struct spi_device *spi = to_spi_device(codec->dev);
	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
	const struct firmware *fw;
	struct spi_message m;
	struct spi_transfer t;
	u32 *img;
	u8 *out;
	int i;
	int ret = 0;

	ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
			ret);
		return ret;
	}

	dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);

	/* Copy to local buffer first as vmalloc causes problems for dma */
	img = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
	if (!img) {
		ret = -ENOMEM;
		goto abort2;
	}

	out = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
	if (!out) {
		ret = -ENOMEM;
		goto abort1;
	}

	memcpy(img, &fw->data[0], fw->size);

	spi_message_init(&m);
	memset(&t, 0, sizeof(t));
	t.rx_buf = out;
	t.tx_buf = img;
	t.len = fw->size;
	t.bits_per_word = 8;
	t.speed_hz = wm0010->sysclk / 10;
	spi_message_add_tail(&t, &m);

	dev_dbg(codec->dev, "Starting initial download at %dHz\n",
		t.speed_hz);

	ret = spi_sync(spi, &m);
	if (ret != 0) {
		dev_err(codec->dev, "Initial download failed: %d\n", ret);
		goto abort;
	}

	/* Look for errors from the boot ROM */
	for (i = 0; i < fw->size; i++) {
		if (out[i] != 0x55) {
			dev_err(codec->dev, "Boot ROM error: %x in %d\n",
				out[i], i);
			wm0010_mark_boot_failure(wm0010);
			ret = -EBUSY;
			goto abort;
		}
	}
abort:
	kfree(out);
abort1:
	kfree(img);
abort2:
	release_firmware(fw);

	return ret;
}
示例#16
0
文件: spi-mem.c 项目: woodsts/barebox
/**
 * spi_mem_exec_op() - Execute a memory operation
 * @mem: the SPI memory
 * @op: the memory operation to execute
 *
 * Executes a memory operation.
 *
 * This function first checks that @op is supported and then tries to execute
 * it.
 *
 * Return: 0 in case of success, a negative error code otherwise.
 */
int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
	unsigned int tmpbufsize, xferpos = 0, totalxferlen = 0;
	struct spi_controller *ctlr = mem->spi->controller;
	struct spi_transfer xfers[4] = { };
	struct spi_message msg;
	u8 *tmpbuf;
	int ret;

	ret = spi_mem_check_op(op);
	if (ret)
		return ret;

	if (!spi_mem_internal_supports_op(mem, op))
		return -ENOTSUPP;

	if (ctlr->mem_ops) {
		ret = spi_mem_access_start(mem);
		if (ret)
			return ret;

		ret = ctlr->mem_ops->exec_op(mem, op);

		spi_mem_access_end(mem);

		/*
		 * Some controllers only optimize specific paths (typically the
		 * read path) and expect the core to use the regular SPI
		 * interface in other cases.
		 */
		if (!ret || ret != -ENOTSUPP)
			return ret;
	}

	tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes +
		     op->dummy.nbytes;

	/*
	 * Allocate a buffer to transmit the CMD, ADDR cycles with kmalloc() so
	 * we're guaranteed that this buffer is DMA-able, as required by the
	 * SPI layer.
	 */
	tmpbuf = kzalloc(tmpbufsize, GFP_KERNEL);
	if (!tmpbuf)
		return -ENOMEM;

	spi_message_init(&msg);

	tmpbuf[0] = op->cmd.opcode;
	xfers[xferpos].tx_buf = tmpbuf;
	xfers[xferpos].len = sizeof(op->cmd.opcode);
	spi_message_add_tail(&xfers[xferpos], &msg);
	xferpos++;
	totalxferlen++;

	if (op->addr.nbytes) {
		int i;

		for (i = 0; i < op->addr.nbytes; i++)
			tmpbuf[i + 1] = op->addr.val >>
					(8 * (op->addr.nbytes - i - 1));

		xfers[xferpos].tx_buf = tmpbuf + 1;
		xfers[xferpos].len = op->addr.nbytes;
		spi_message_add_tail(&xfers[xferpos], &msg);
		xferpos++;
		totalxferlen += op->addr.nbytes;
	}
示例#17
0
/*
 * Erase an address range on the flash chip.  The address range may extend
 * one or more erase sectors.  Return an error is there is a problem erasing.
 */
static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct m25p *flash = mtd_to_m25p(mtd);
	u32 addr,len;
	uint64_t tmpdiv;
	int rem, rem1;

	DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
			flash->spi->dev.bus_id, __FUNCTION__, "at",
			(u32)instr->addr, instr->len);

	/* sanity checks */
	if (instr->addr + instr->len > device_size(&(flash->mtd)))
		return -EINVAL;
	tmpdiv = (uint64_t) instr->addr;
 	rem = do_div(tmpdiv, mtd->erasesize);
	tmpdiv = (uint64_t) instr->len;
	rem1 = do_div(tmpdiv, mtd->erasesize);
	if (rem != 0 || rem1 != 0) {
		return -EINVAL;
	}

	addr = instr->addr;
	len = instr->len;

	mutex_lock(&flash->lock);

	/* REVISIT in some cases we could speed up erasing large regions
	 * by using OPCODE_SE instead of OPCODE_BE_4K
	 */

	/* now erase those sectors */
	while (len) {
#ifdef CONFIG_MIPS_BRCM97XXX
		/* BSPI remaps each 4MB segment */
		if (erase_sector(flash, (addr + 0x400000) & 0xffffff)) {
#else
		if (erase_sector(flash, addr)) {
#endif
			instr->state = MTD_ERASE_FAILED;
			mutex_unlock(&flash->lock);
			return -EIO;
		}

		addr += mtd->erasesize;
		len -= mtd->erasesize;
	}

	mutex_unlock(&flash->lock);

	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return 0;
}

/*
 * Read an address range from the flash chip.  The address range
 * may be any size provided it is within the physical boundaries.
 */
static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
	size_t *retlen, u_char *buf)
{
	struct m25p *flash = mtd_to_m25p(mtd);
	struct spi_transfer t[2];
	struct spi_message m;
	size_t total_len = len;

	DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
			flash->spi->dev.bus_id, __FUNCTION__, "from",
			(u32)from, len);

	/* sanity checks */
	if (!len)
		return 0;

	if (from + len > device_size(&(flash->mtd)))
		return -EINVAL;

	if (retlen)
		*retlen = 0;

	total_len = len;
	while(total_len) {
		len = total_len;

#if 0 //defined(BRCM_SPI_SS_WAR)
	/*
	 * For testing purposes only - read 12 bytes at a time:
	 *
	 * 3548a0 MSPI has a 12-byte limit (PR42350).
	 * MSPI emulated via BSPI has no such limit.
	 * In production BSPI is always used because it is much faster.
	 */
		if(len > 12)
			len = 12;
#endif
#ifdef CONFIG_MIPS_BRCM97XXX
		/* don't cross a 4MB boundary due to remapping */
		len = min(len, (0x400000 - ((u32)from & 0x3fffff)));
#endif
		spi_message_init(&m);
		memset(t, 0, (sizeof t));

		t[0].tx_buf = flash->command;
		t[0].len = sizeof(flash->command);
		spi_message_add_tail(&t[0], &m);

		t[1].rx_buf = buf;
		t[1].len = len;
		spi_message_add_tail(&t[1], &m);

		/* Byte count starts at zero. */

		mutex_lock(&flash->lock);

		/* Wait till previous write/erase is done. */
		if (wait_till_ready(flash)) {
			/* REVISIT status return?? */
			mutex_unlock(&flash->lock);
			return 1;
		}

		/* FIXME switch to OPCODE_FAST_READ.  It's required for higher
		 * clocks; and at this writing, every chip this driver handles
		 * supports that opcode.
		 */

		/* Set up the write data buffer. */
		flash->command[0] = OPCODE_READ;
#ifdef CONFIG_MIPS_BRCM97XXX
		/* BSPI remaps each 4MB segment */
		flash->command[1] = ((from >> 16) + 0x40) & 0xff;
#else
		flash->command[1] = from >> 16;
#endif
		flash->command[2] = from >> 8;
		flash->command[3] = from;

		spi_sync(flash->spi, &m);

		*retlen += m.actual_length - sizeof(flash->command);

		mutex_unlock(&flash->lock);

		from += len;
		buf += len;
		total_len -= len;
	}

	return 0;
}

/*
 * Write an address range to the flash chip.  Data must be written in
 * FLASH_PAGESIZE chunks.  The address range may be any size provided
 * it is within the physical boundaries.
 */
static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
	size_t *retlen, const u_char *buf)
{
	struct m25p *flash = mtd_to_m25p(mtd);
	u32 page_offset, page_size;
	struct spi_transfer t[2];
	struct spi_message m;

	DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n",
			flash->spi->dev.bus_id, __FUNCTION__, "to",
			(u32)to, len);

	if (retlen)
		*retlen = 0;

	/* sanity checks */
	if (!len)
		return(0);

	if (to + len > device_size(&(flash->mtd)))
		return -EINVAL;
#ifdef BRCM_SPI_SS_WAR
	if(len > 12)
		return -EIO;
#endif

	spi_message_init(&m);
	memset(t, 0, (sizeof t));

	t[0].tx_buf = flash->command;
	t[0].len = sizeof(flash->command);
	spi_message_add_tail(&t[0], &m);

	t[1].tx_buf = buf;
	spi_message_add_tail(&t[1], &m);

	mutex_lock(&flash->lock);

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

	write_enable(flash);

	/* Set up the opcode in the write buffer. */
	flash->command[0] = OPCODE_PP;
#ifdef CONFIG_MIPS_BRCM97XXX
	/* BSPI remaps each 4MB segment */
	flash->command[1] = ((to >> 16) + 0x40) & 0xff;
#else
	flash->command[1] = to >> 16;
#endif
	flash->command[2] = to >> 8;
	flash->command[3] = to;

	/* what page do we start with? */
	page_offset = to % FLASH_PAGESIZE;

	/* do all the bytes fit onto one page? */
	if (page_offset + len <= FLASH_PAGESIZE) {
		t[1].len = len;

		spi_sync(flash->spi, &m);

		*retlen = m.actual_length - sizeof(flash->command);
	} else {
		u32 i;

		/* the size of data remaining on the first page */
		page_size = FLASH_PAGESIZE - page_offset;

		t[1].len = page_size;
		spi_sync(flash->spi, &m);

		*retlen = m.actual_length - sizeof(flash->command);

		/* write everything in PAGESIZE chunks */
		for (i = page_size; i < len; i += page_size) {
			page_size = len - i;
			if (page_size > FLASH_PAGESIZE)
				page_size = FLASH_PAGESIZE;

			/* write the next page to flash */
#ifdef CONFIG_MIPS_BRCM97XXX
			/* BSPI remaps each 4MB segment */
			flash->command[1] = (((to + i) >> 16) + 0x40) & 0xff;
#else
			flash->command[1] = (to + i) >> 16;
#endif
			flash->command[2] = (to + i) >> 8;
			flash->command[3] = (to + i);

			t[1].tx_buf = buf + i;
			t[1].len = page_size;

			wait_till_ready(flash);

			write_enable(flash);

			spi_sync(flash->spi, &m);

			if (retlen)
				*retlen += m.actual_length
					- sizeof(flash->command);
		}
	}

	mutex_unlock(&flash->lock);

	return 0;
}


/****************************************************************************/

/*
 * SPI device driver setup and teardown
 */

struct flash_info {
	char		*name;

	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
	 * a high byte of zero plus three data bytes: the manufacturer id,
	 * then a two byte device id.
	 */
	u32		jedec_id;

	/* The size listed here is what works with OPCODE_SE, which isn't
	 * necessarily called a "sector" by the vendor.
	 */
	unsigned	sector_size;
	u16		n_sectors;

	u16		flags;
#define	SECT_4K		0x01		/* OPCODE_BE_4K works uniformly */
};


/* NOTE: double check command sets and memory organization when you add
 * more flash chips.  This current list focusses on newer chips, which
 * have been converging on command sets which including JEDEC ID.
 */
static struct flash_info __devinitdata m25p_data [] = {

	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
	{ "at25fs010",  0x1f6601, 32 * 1024, 4, SECT_4K, },
	{ "at25fs040",  0x1f6604, 64 * 1024, 8, SECT_4K, },

	{ "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },

	{ "at26f004",   0x1f0400, 64 * 1024, 8, SECT_4K, },
	{ "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
	{ "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
	{ "at26df321",  0x1f4701, 64 * 1024, 64, SECT_4K, },

	/* Spansion -- single (large) sector size only, at least
	 * for the chips listed here (without boot sectors).
	 */
	{ "s25sl004a", 0x010212, 64 * 1024, 8, },
	{ "s25sl008a", 0x010213, 64 * 1024, 16, },
	{ "s25sl016a", 0x010214, 64 * 1024, 32, },
	{ "s25sl032a", 0x010215, 64 * 1024, 64, },
	{ "s25sl064a", 0x010216, 64 * 1024, 128, },
#ifdef CONFIG_MIPS_BRCM97XXX
	{ "s25fl128p", 0x012018, 64 * 1024, 256, },
#endif

	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
	{ "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
	{ "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
	{ "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
	{ "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },

	/* ST Microelectronics -- newer production may have feature updates */
	{ "m25p05",  0x202010,  32 * 1024, 2, },
	{ "m25p10",  0x202011,  32 * 1024, 4, },
	{ "m25p20",  0x202012,  64 * 1024, 4, },
	{ "m25p40",  0x202013,  64 * 1024, 8, },
#ifndef CONFIG_MIPS_BRCM97XXX
	/* ID 0 is detected when there's nothing on the bus */
	{ "m25p80",         0,  64 * 1024, 16, },
#endif
	{ "m25p16",  0x202015,  64 * 1024, 32, },
	{ "m25p32",  0x202016,  64 * 1024, 64, },
	{ "m25p64",  0x202017,  64 * 1024, 128, },
	{ "m25p128", 0x202018, 256 * 1024, 64, },

	{ "m45pe80", 0x204014,  64 * 1024, 16, },
	{ "m45pe16", 0x204015,  64 * 1024, 32, },

	{ "m25pe80", 0x208014,  64 * 1024, 16, },
	{ "m25pe16", 0x208015,  64 * 1024, 32, SECT_4K, },

	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
	{ "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
	{ "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
	{ "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
	{ "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
	{ "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
	{ "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
	{ "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
};

static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
{
	int			tmp;
	u8			code = OPCODE_RDID;
	u8			id[3];
	u32			jedec;
	struct flash_info	*info;

	/* JEDEC also defines an optional "extended device information"
	 * string for after vendor-specific data, after the three bytes
	 * we use here.  Supporting some chips might require using it.
	 */
	tmp = spi_write_then_read(spi, &code, 1, id, 3);
	if (tmp < 0) {
		DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
			spi->dev.bus_id, tmp);
		return NULL;
	}
	jedec = id[0];
	jedec = jedec << 8;
	jedec |= id[1];
	jedec = jedec << 8;
	jedec |= id[2];

	for (tmp = 0, info = m25p_data;
			tmp < ARRAY_SIZE(m25p_data);
			tmp++, info++) {
		if (info->jedec_id == jedec)
			return info;
	}
	dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
	return NULL;
}
示例#18
0
/*
 * Erase pages of flash.
 */
static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	struct dataflash	*priv = mtd->priv;
	struct spi_device	*spi = priv->spi;
	struct spi_transfer	x;
	struct spi_message	msg;
	unsigned		blocksize = priv->page_size << 3;
	uint8_t			*command;
	uint32_t		rem;

	pr_debug("%s: erase addr=0x%llx len 0x%llx\n",
	      dev_name(&spi->dev), (long long)instr->addr,
	      (long long)instr->len);

	div_u64_rem(instr->len, priv->page_size, &rem);
	if (rem)
		return -EINVAL;
	div_u64_rem(instr->addr, priv->page_size, &rem);
	if (rem)
		return -EINVAL;

	spi_message_init(&msg);

	memset(&x, 0, sizeof(x));

	x.tx_buf = command = priv->command;
	x.len = 4;
	spi_message_add_tail(&x, &msg);

	while (instr->len > 0) {
		unsigned int	pageaddr;
		int		status;
		int		do_block;

		/* Calculate flash page address; use block erase (for speed) if
		 * we're at a block boundary and need to erase the whole block.
		 */
		pageaddr = div_u64(instr->addr, priv->page_size);
		do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize;
		pageaddr = pageaddr << priv->page_offset;

		command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
		command[1] = (uint8_t)(pageaddr >> 16);
		command[2] = (uint8_t)(pageaddr >> 8);
		command[3] = 0;

		pr_debug("ERASE %s: (%x) %x %x %x [%i]\n",
			do_block ? "block" : "page",
			command[0], command[1], command[2], command[3],
			pageaddr);

		status = spi_sync(spi, &msg);
		(void) dataflash_waitready(spi);

		if (status < 0) {
			printk(KERN_ERR "%s: erase %x, err %d\n",
				dev_name(&spi->dev), pageaddr, status);
			/* REVISIT:  can retry instr->retries times; or
			 * giveup and instr->fail_addr = instr->addr;
			 */
			continue;
		}

		if (do_block) {
			instr->addr += blocksize;
			instr->len -= blocksize;
		} else {
			instr->addr += priv->page_size;
			instr->len -= priv->page_size;
		}
	}

	/* Inform MTD subsystem that erase is complete */
	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	return 0;
}
示例#19
0
/*
 * Write to the DataFlash device.
 *   to     : Start offset in flash device
 *   len    : Amount to write
 *   retlen : Amount of data actually written
 *   buf    : Buffer containing the data
 */
static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
				size_t * retlen, const u_char * buf)
{
	struct dataflash	*priv = mtd->priv;
	struct spi_device	*spi = priv->spi;
	struct spi_transfer	x[2];
	struct spi_message	msg;
	unsigned int		pageaddr, addr, offset, writelen;
	size_t			remaining = len;
	u_char			*writebuf = (u_char *) buf;
	int			status = -EINVAL;
	uint8_t			*command;

	pr_debug("%s: write 0x%x..0x%x\n",
		dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len));

	spi_message_init(&msg);

	memset(&x[0], 0, sizeof(struct spi_transfer) * 2);

	x[0].tx_buf = command = priv->command;
	x[0].len = 4;
	spi_message_add_tail(&x[0], &msg);

	pageaddr = ((unsigned)to / priv->page_size);
	offset = ((unsigned)to % priv->page_size);
	if (offset + len > priv->page_size)
		writelen = priv->page_size - offset;
	else
		writelen = len;

	while (remaining > 0) {
		pr_debug("write @ %i:%i len=%i\n",
			pageaddr, offset, writelen);

		/* REVISIT:
		 * (a) each page in a sector must be rewritten at least
		 *     once every 10K sibling erase/program operations.
		 * (b) for pages that are already erased, we could
		 *     use WRITE+MWRITE not PROGRAM for ~30% speedup.
		 * (c) WRITE to buffer could be done while waiting for
		 *     a previous MWRITE/MWERASE to complete ...
		 * (d) error handling here seems to be mostly missing.
		 *
		 * Two persistent bits per page, plus a per-sector counter,
		 * could support (a) and (b) ... we might consider using
		 * the second half of sector zero, which is just one block,
		 * to track that state.  (On AT91, that sector should also
		 * support boot-from-DataFlash.)
		 */

		addr = pageaddr << priv->page_offset;

		/* (1) Maybe transfer partial page to Buffer1 */
		if (writelen != priv->page_size) {
			command[0] = OP_TRANSFER_BUF1;
			command[1] = (addr & 0x00FF0000) >> 16;
			command[2] = (addr & 0x0000FF00) >> 8;
			command[3] = 0;

			pr_debug("TRANSFER: (%x) %x %x %x\n",
				command[0], command[1], command[2], command[3]);

			status = spi_sync(spi, &msg);
			if (status < 0)
				pr_debug("%s: xfer %u -> %d\n",
					dev_name(&spi->dev), addr, status);

			(void) dataflash_waitready(priv->spi);
		}

		/* (2) Program full page via Buffer1 */
		addr += offset;
		command[0] = OP_PROGRAM_VIA_BUF1;
		command[1] = (addr & 0x00FF0000) >> 16;
		command[2] = (addr & 0x0000FF00) >> 8;
		command[3] = (addr & 0x000000FF);

		pr_debug("PROGRAM: (%x) %x %x %x\n",
			command[0], command[1], command[2], command[3]);

		x[1].tx_buf = writebuf;
		x[1].len = writelen;
		spi_message_add_tail(x + 1, &msg);
		status = spi_sync(spi, &msg);
		spi_transfer_del(x + 1);
		if (status < 0)
			pr_debug("%s: pgm %u/%u -> %d\n",
				dev_name(&spi->dev), addr, writelen, status);

		(void) dataflash_waitready(priv->spi);


#ifdef CONFIG_MTD_DATAFLASH_WRITE_VERIFY

		/* (3) Compare to Buffer1 */
		addr = pageaddr << priv->page_offset;
		command[0] = OP_COMPARE_BUF1;
		command[1] = (addr & 0x00FF0000) >> 16;
		command[2] = (addr & 0x0000FF00) >> 8;
		command[3] = 0;

		pr_debug("COMPARE: (%x) %x %x %x\n",
			command[0], command[1], command[2], command[3]);

		status = spi_sync(spi, &msg);
		if (status < 0)
			pr_debug("%s: compare %u -> %d\n",
				dev_name(&spi->dev), addr, status);

		status = dataflash_waitready(priv->spi);

		/* Check result of the compare operation */
		if (status & (1 << 6)) {
			printk(KERN_ERR "%s: compare page %u, err %d\n",
				dev_name(&spi->dev), pageaddr, status);
			remaining = 0;
			status = -EIO;
			break;
		} else
			status = 0;

#endif	/* CONFIG_MTD_DATAFLASH_WRITE_VERIFY */

		remaining = remaining - writelen;
		pageaddr++;
		offset = 0;
		writebuf += writelen;
		*retlen += writelen;

		if (remaining > priv->page_size)
			writelen = priv->page_size;
		else
			writelen = remaining;
	}
static int stm32fwu_spi_write(struct spi_device *spi,
	const u8 *buffer, ssize_t len)
{
	int ret;
	u8 rx_buf[STM_MAX_BUFFER_SIZE] = {0,};
	struct spi_message m;
#if BYTETOBYTE_USED
	struct spi_transfer t[STM_MAX_BUFFER_SIZE];
	memset(t, 0, STM_MAX_BUFFER_SIZE * sizeof(struct spi_transfer));
	int i;
#else
	struct spi_transfer	t = {
		.tx_buf		= buffer,
		.rx_buf		= rx_buf,
		.len		= len,
		.bits_per_word = 8,
	};
#endif
	spi_message_init(&m);
#if BYTETOBYTE_USED
	for (i = 0; i < len; i++) {
		t[i].tx_buf = &buffer[i];
		t[i].rx_buf = &rx_buf[i];
		t[i].len = 1;
		t[i].bits_per_word = 8;
		t[i].delay_usecs = BYTE_DELAY_WRITE;
		spi_message_add_tail(&t[i], &m);
	}
#else
	spi_message_add_tail(&t, &m);
#endif
	ret = spi_sync(spi, &m);

	if (ret < 0) {
		pr_err("[SSP] Error in %d spi_write()\n", ret);
		return ret;
	}

	return len;
}

static int send_addr(struct spi_device *spi, u32 fw_addr, int send_short)
{
	int res;
	int i = send_short;
	int len = SEND_ADDR_LEN - send_short;
	u8 header[SEND_ADDR_LEN];
	struct stm32fwu_spi_cmd dummy_cmd;
	dummy_cmd.timeout = DEF_ACKROOF_NUMBER;
	pr_debug("[SSP]%s\n", __func__);


	header[0] = (u8)((fw_addr >> 24) & 0xFF);
	header[1] = (u8)((fw_addr >> 16) & 0xFF);
	header[2] = (u8)((fw_addr >> 8) & 0xFF);
	header[3] = (u8)(fw_addr & 0xFF);
	header[4] = header[0] ^ header[1] ^ header[2] ^ header[3];

	res = stm32fwu_spi_write(spi, &header[i], len);

	if (res <  len) {
		pr_err("[SSP] Error in sending address. Res  %d\n", res);
		return ((res > 0) ? -EIO : res);
	}

	res = stm32fwu_spi_wait_for_ack(spi, &dummy_cmd, BL_ACK);
	if (res != BL_ACK) {
		pr_err("[SSP] send_addr(): rcv_ack returned 0x%x\n",
			res);
		return res;
	}
	return 0;
}
int ade7758_configure_ring(struct iio_dev *indio_dev)
{
	struct ade7758_state *st = iio_priv(indio_dev);
	int ret = 0;

	indio_dev->buffer = iio_kfifo_allocate(indio_dev);
	if (!indio_dev->buffer) {
		ret = -ENOMEM;
		return ret;
	}

	indio_dev->setup_ops = &ade7758_ring_setup_ops;

	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
						 &ade7758_trigger_handler,
						 0,
						 indio_dev,
						 "ade7759_consumer%d",
						 indio_dev->id);
	if (indio_dev->pollfunc == NULL) {
		ret = -ENOMEM;
		goto error_iio_kfifo_free;
	}

	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;

	st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
	st->tx_buf[1] = 0;
	st->tx_buf[2] = 0;
	st->tx_buf[3] = 0;
	st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
	st->tx_buf[5] = 0;
	st->tx_buf[6] = 0;
	st->tx_buf[7] = 0;

	/* build spi ring message */
	st->ring_xfer[0].tx_buf = &st->tx_buf[0];
	st->ring_xfer[0].len = 1;
	st->ring_xfer[0].bits_per_word = 8;
	st->ring_xfer[0].delay_usecs = 4;
	st->ring_xfer[1].rx_buf = &st->rx_buf[1];
	st->ring_xfer[1].len = 3;
	st->ring_xfer[1].bits_per_word = 8;
	st->ring_xfer[1].cs_change = 1;

	st->ring_xfer[2].tx_buf = &st->tx_buf[4];
	st->ring_xfer[2].len = 1;
	st->ring_xfer[2].bits_per_word = 8;
	st->ring_xfer[2].delay_usecs = 1;
	st->ring_xfer[3].rx_buf = &st->rx_buf[5];
	st->ring_xfer[3].len = 3;
	st->ring_xfer[3].bits_per_word = 8;

	spi_message_init(&st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
	spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);

	return 0;

error_iio_kfifo_free:
	iio_kfifo_free(indio_dev->buffer);
	return ret;
}
示例#22
0
int tdmb_fc8050_spi_write_read(uint8* tx_data, int tx_length, uint8 *rx_data, int rx_length)
{
	int rc;

	struct spi_transfer	t = {
			.tx_buf		= tx_data,
			.rx_buf		= rx_data,
			.len		= tx_length+rx_length,
		};

	struct spi_message	m;	

	if (fc8050_ctrl_info.spi_ptr == NULL)
	{
		printk("tdmb_fc8050_spi_write_read error txdata=0x%x, length=%d\n", (unsigned int)tx_data, tx_length+rx_length);
	}

	mutex_lock(&fc8050_ctrl_info.mutex);

	spi_message_init(&m);
	spi_message_add_tail(&t, &m);
	rc = spi_sync(fc8050_ctrl_info.spi_ptr, &m);

	if ( rc < 0 )
	{
		printk("tdmb_fc8050_spi_read_burst result(%d), actual_len=%d\n",rc, m.actual_length);
	}

	mutex_unlock(&fc8050_ctrl_info.mutex);

	return TRUE;
}

#ifdef FEATURE_DMB_USE_WORKQUEUE
static irqreturn_t broadcast_tdmb_spi_isr(int irq, void *handle)
{
	struct tdmb_fc8050_ctrl_blk* fc8050_info_p;
	unsigned long flag;

	fc8050_info_p = (struct tdmb_fc8050_ctrl_blk *)handle;	
	if ( fc8050_info_p && fc8050_info_p->TdmbPowerOnState )
	{
		if (fc8050_info_p->spi_irq_status)
		{			
			printk("######### spi read function is so late skip #########\n");			
			return IRQ_HANDLED;
		}		
//		printk("***** broadcast_tdmb_spi_isr coming *******\n");

		spin_lock_irqsave(&fc8050_info_p->spin_lock, flag);
		queue_work(fc8050_info_p->spi_wq, &fc8050_info_p->spi_work);
		spin_unlock_irqrestore(&fc8050_info_p->spin_lock, flag);    
	}
	else
	{
		printk("broadcast_tdmb_spi_isr is called, but device is off state\n");
	}

	return IRQ_HANDLED; 
}

static void broacast_tdmb_spi_work(struct work_struct *tdmb_work)
{
	struct tdmb_fc8050_ctrl_blk *pTdmbWorkData;

	pTdmbWorkData = container_of(tdmb_work, struct tdmb_fc8050_ctrl_blk, spi_work);
	if ( pTdmbWorkData )
	{
		fc8050_isr_control(0);
		pTdmbWorkData->spi_irq_status = TRUE;
		broadcast_drv_if_isr();
		pTdmbWorkData->spi_irq_status = FALSE;
		fc8050_isr_control(1);
	}
	else
	{
		printk("~~~~~~~broadcast_tdmb_spi_work call but pTdmbworkData is NULL ~~~~~~~\n");
	}
}
#else
static irqreturn_t broadcast_tdmb_spi_event_handler(int irq, void *handle)
{	
	struct tdmb_fc8050_ctrl_blk* fc8050_info_p;

	fc8050_info_p = (struct tdmb_fc8050_ctrl_blk *)handle;	
	if ( fc8050_info_p && fc8050_info_p->TdmbPowerOnState )
	{
		if (fc8050_info_p->spi_irq_status)
		{			
			printk("######### spi read function is so late skip #########\n");			
			return IRQ_HANDLED;
		}		

		fc8050_isr_control(0);
		fc8050_info_p->spi_irq_status = TRUE;
		broadcast_drv_if_isr();
		fc8050_info_p->spi_irq_status = FALSE;
		fc8050_isr_control(1);
	}
	else
	{
		printk("broadcast_tdmb_spi_isr is called, but device is off state\n");
	}

	return IRQ_HANDLED;
} 
#endif


static int broadcast_tdmb_fc8050_probe(struct spi_device *spi)
{
	int rc;

#ifdef ANTENNA_SWITCHING
	struct pm_gpio GPIO11_CFG = {
				.direction      = PM_GPIO_DIR_OUT,
				.pull           = PM_GPIO_PULL_NO,
				.function       = PM_GPIO_FUNC_NORMAL,
				.vin_sel        = 2,
				.inv_int_pol    = 0,	
				};
	struct pm_gpio GPIO12_CFG = {
				.direction      = PM_GPIO_DIR_OUT,
				.pull           = PM_GPIO_PULL_NO,
				.function       = PM_GPIO_FUNC_NORMAL,
				.vin_sel        = 2,
				.inv_int_pol    = 0,			
				};	
#endif  /* ANTENNA_SWITCHING */

	fc8050_ctrl_info.TdmbPowerOnState = FALSE;
	
	fc8050_ctrl_info.spi_ptr 				= spi;
	fc8050_ctrl_info.spi_ptr->mode 			= SPI_MODE_0;
	fc8050_ctrl_info.spi_ptr->bits_per_word 	= 8;
	fc8050_ctrl_info.spi_ptr->max_speed_hz 	= ( 24000*1000 );
	rc = spi_setup(spi);

	printk("broadcast_tdmb_fc8050_probe spi_setup=%d\n", rc);

	BBM_HOSTIF_SELECT(NULL, 1);

#ifdef FEATURE_DMB_USE_WORKQUEUE
	INIT_WORK(&fc8050_ctrl_info.spi_work, broacast_tdmb_spi_work);
	fc8050_ctrl_info.spi_wq = create_singlethread_workqueue("tdmb_spi_wq");
	if(fc8050_ctrl_info.spi_wq == NULL){
		printk("Failed to setup tdmb spi workqueue \n");

		return -ENOMEM;
	}
#endif

	gpio_request(DMB_RESET_N, "DMB_RESET_N");
	gpio_request(DMB_EN, "DMB_EN");
	gpio_request(DMB_INT_N, "DMB_INT_N");
	//gpio_direction_output(DMB_RESET_N, false);      
	//gpio_direction_output(DMB_EN, false);               
	//gpio_direction_output(DMB_INT_N, false);           

#ifdef ANTENNA_SWITCHING
	pm8xxx_gpio_config(DMB_ANT_SEL_P_EAR, &GPIO11_CFG);
	pm8xxx_gpio_config(DMB_ANT_SEL_N_INNER, &GPIO12_CFG);

	gpio_set_value_cansleep(DMB_ANT_SEL_P_EAR, 1);
	gpio_set_value_cansleep(DMB_ANT_SEL_N_INNER, 0);
#endif  /* ANTENNA_SWITCHING */

#ifdef FEATURE_DMB_USE_WORKQUEUE
	rc = request_irq(spi->irq, broadcast_tdmb_spi_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, 
	                   spi->dev.driver->name, &fc8050_ctrl_info);
#else
	rc = request_threaded_irq(spi->irq, NULL, broadcast_tdmb_spi_event_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING,
	                      spi->dev.driver->name, &fc8050_ctrl_info);
#endif
	printk("broadcast_tdmb_fc8050_probe request_irq=%d\n", rc);


	tdmb_fc8050_interrupt_lock();

	mutex_init(&fc8050_ctrl_info.mutex);

	wake_lock_init(&fc8050_ctrl_info.wake_lock,  WAKE_LOCK_SUSPEND, dev_name(&spi->dev));		
	spin_lock_init(&fc8050_ctrl_info.spin_lock);

#ifdef PM_QOS
	pm_qos_add_request(&fc8050_ctrl_info.pm_req_list, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
#endif  /* PM_QOS */

	printk("broadcast_fc8050_probe End\n");

	return rc;
}

static int broadcast_tdmb_fc8050_remove(struct spi_device *spi)
{
	printk("broadcast_tdmb_fc8050_remove \n");

#ifdef FEATURE_DMB_USE_WORKQUEUE
	if (fc8050_ctrl_info.spi_wq)
	{
		flush_workqueue(fc8050_ctrl_info.spi_wq);
		destroy_workqueue(fc8050_ctrl_info.spi_wq);
	}
#endif
	free_irq(spi->irq, &fc8050_ctrl_info);

	mutex_destroy(&fc8050_ctrl_info.mutex);

	wake_lock_destroy(&fc8050_ctrl_info.wake_lock);

#ifdef PM_QOS
	pm_qos_remove_request(&fc8050_ctrl_info.pm_req_list);
#endif  /* PM_QOS */

	memset((unsigned char*)&fc8050_ctrl_info, 0x0, sizeof(struct tdmb_fc8050_ctrl_blk));

	return 0;
}

static int broadcast_tdmb_fc8050_suspend(struct spi_device *spi, pm_message_t mesg)
{
	printk("broadcast_tdmb_fc8050_suspend \n");
	return 0;
}
示例#23
0
static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
{
	struct spi_device *spi = to_spi_device(codec->dev);
	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
	struct list_head xfer_list;
	struct wm0010_boot_xfer *xfer;
	int ret;
	struct completion done;
	const struct firmware *fw;
	const struct dfw_binrec *rec;
	const struct dfw_inforec *inforec;
	u64 *img;
	u8 *out, dsp;
	u32 len, offset;

	INIT_LIST_HEAD(&xfer_list);

	ret = request_firmware(&fw, name, codec->dev);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to request application(%s): %d\n",
			name, ret);
		return ret;
	}

	rec = (const struct dfw_binrec *)fw->data;
	inforec = (const struct dfw_inforec *)rec->data;
	offset = 0;
	dsp = inforec->dsp_target;
	wm0010->boot_failed = false;
	if (WARN_ON(!list_empty(&xfer_list)))
		return -EINVAL;
	init_completion(&done);

	/* First record should be INFO */
	if (rec->command != DFW_CMD_INFO) {
		dev_err(codec->dev, "First record not INFO\r\n");
		ret = -EINVAL;
		goto abort;
	}

	if (inforec->info_version != INFO_VERSION) {
		dev_err(codec->dev,
			"Unsupported version (%02d) of INFO record\r\n",
			inforec->info_version);
		ret = -EINVAL;
		goto abort;
	}

	dev_dbg(codec->dev, "Version v%02d INFO record found\r\n",
		inforec->info_version);

	/* Check it's a DSP file */
	if (dsp != DEVICE_ID_WM0010) {
		dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
		ret = -EINVAL;
		goto abort;
	}

	/* Skip the info record as we don't need to send it */
	offset += ((rec->length) + 8);
	rec = (void *)&rec->data[rec->length];

	while (offset < fw->size) {
		dev_dbg(codec->dev,
			"Packet: command %d, data length = 0x%x\r\n",
			rec->command, rec->length);
		len = rec->length + 8;

		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
		if (!xfer) {
			ret = -ENOMEM;
			goto abort;
		}

		xfer->codec = codec;
		list_add_tail(&xfer->list, &xfer_list);

		out = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!out) {
			ret = -ENOMEM;
			goto abort1;
		}
		xfer->t.rx_buf = out;

		img = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!img) {
			ret = -ENOMEM;
			goto abort1;
		}
		xfer->t.tx_buf = img;

		byte_swap_64((u64 *)&rec->command, img, len);

		spi_message_init(&xfer->m);
		xfer->m.complete = wm0010_boot_xfer_complete;
		xfer->m.context = xfer;
		xfer->t.len = len;
		xfer->t.bits_per_word = 8;

		if (!wm0010->pll_running) {
			xfer->t.speed_hz = wm0010->sysclk / 6;
		} else {
			xfer->t.speed_hz = wm0010->max_spi_freq;

			if (wm0010->board_max_spi_speed &&
			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
					xfer->t.speed_hz = wm0010->board_max_spi_speed;
		}

		/* Store max usable spi frequency for later use */
		wm0010->max_spi_freq = xfer->t.speed_hz;

		spi_message_add_tail(&xfer->t, &xfer->m);

		offset += ((rec->length) + 8);
		rec = (void *)&rec->data[rec->length];

		if (offset >= fw->size) {
			dev_dbg(codec->dev, "All transfers scheduled\n");
			xfer->done = &done;
		}

		ret = spi_async(spi, &xfer->m);
		if (ret != 0) {
			dev_err(codec->dev, "Write failed: %d\n", ret);
			goto abort1;
		}

		if (wm0010->boot_failed) {
			dev_dbg(codec->dev, "Boot fail!\n");
			ret = -EINVAL;
			goto abort1;
		}
	}

	wait_for_completion(&done);

	ret = 0;

abort1:
	while (!list_empty(&xfer_list)) {
		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
					list);
		kfree(xfer->t.rx_buf);
		kfree(xfer->t.tx_buf);
		list_del(&xfer->list);
		kfree(xfer);
	}

abort:
	release_firmware(fw);
	return ret;
}
static int aic3254_config_ex(CODEC_SPI_CMD *cmds, int size)
{
	int i = 0;
	int ret = -EINVAL;
	struct spi_transfer *spi_t_cmds = NULL;
	struct spi_message m;
	unsigned char *buffer = NULL;
	unsigned char *ptr = NULL;

	if (!codec_dev) {
		pr_aud_err("%s: no spi device\n", __func__);
		return -EFAULT;
	}

	if (cmds == NULL || size == 0) {
		pr_aud_err("%s: invalid spi parameters\n", __func__);
		return -EINVAL;
	} else {
		/* pr_info("%s: size = %d", __func__, size); */
	}

	spi_t_cmds = (struct spi_transfer *) kmalloc(size*sizeof(struct spi_transfer), GFP_KERNEL);
	if (spi_t_cmds == NULL) {
		pr_aud_err("%s: kmalloc spi transfer struct fail\n", __func__);
		goto error;
	} else
		memset(spi_t_cmds, 0, size*sizeof(struct spi_transfer));

	buffer = (unsigned char *) kmalloc(size * 2 * sizeof(unsigned char), GFP_KERNEL);
	if (buffer == NULL) {
		pr_aud_err("%s: kmalloc buffer fail\n", __func__);
		goto error;
	} else
		memset(buffer, 0, size*sizeof(CODEC_SPI_CMD)*sizeof(unsigned char));

	if (ctl_ops->spibus_enable)
		ctl_ops->spibus_enable(1);

	spi_message_init(&m);
	for (i = 0, ptr = buffer; i < size; i++, ptr += 2) {
		ptr[0] = cmds[i].reg << 1;
		ptr[1] = cmds[i].data;

		spi_t_cmds[i].tx_buf = ptr;
		spi_t_cmds[i].len = 2;
		spi_message_add_tail(&spi_t_cmds[i], &m);
	}
	codec_dev->bits_per_word = 16;
	ret = spi_sync(codec_dev, &m);

	if (ctl_ops->spibus_enable)
		ctl_ops->spibus_enable(0);

error:
	if (buffer)
		kfree(buffer);

	if (spi_t_cmds)
		kfree(spi_t_cmds);
	return ret;
}
示例#25
0
static int wm0010_boot(struct snd_soc_codec *codec)
{
	struct spi_device *spi = to_spi_device(codec->dev);
	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
	unsigned long flags;
	int ret;
	struct spi_message m;
	struct spi_transfer t;
	struct dfw_pllrec pll_rec;
	u32 *p, len;
	u64 *img_swap;
	u8 *out;
	int i;

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	if (wm0010->state != WM0010_POWER_OFF)
		dev_warn(wm0010->dev, "DSP already powered up!\n");
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	if (wm0010->sysclk > 26000000) {
		dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
		ret = -ECANCELED;
		goto err;
	}

	mutex_lock(&wm0010->lock);
	wm0010->pll_running = false;

	dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);

	ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
				    wm0010->core_supplies);
	if (ret != 0) {
		dev_err(&spi->dev, "Failed to enable core supplies: %d\n",
			ret);
		mutex_unlock(&wm0010->lock);
		goto err;
	}

	ret = regulator_enable(wm0010->dbvdd);
	if (ret != 0) {
		dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret);
		goto err_core;
	}

	/* Release reset */
	gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value);
	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_OUT_OF_RESET;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	if (!wait_for_completion_timeout(&wm0010->boot_completion,
					 msecs_to_jiffies(20)))
		dev_err(codec->dev, "Failed to get interrupt from DSP\n");

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_BOOTROM;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	ret = wm0010_stage2_load(codec);
	if (ret)
		goto abort;

	if (!wait_for_completion_timeout(&wm0010->boot_completion,
					 msecs_to_jiffies(20)))
		dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_STAGE2;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	/* Only initialise PLL if max_spi_freq initialised */
	if (wm0010->max_spi_freq) {

		/* Initialise a PLL record */
		memset(&pll_rec, 0, sizeof(pll_rec));
		pll_rec.command = DFW_CMD_PLL;
		pll_rec.length = (sizeof(pll_rec) - 8);

		/* On wm0010 only the CLKCTRL1 value is used */
		pll_rec.clkctrl1 = wm0010->pll_clkctrl1;

		ret = -ENOMEM;
		len = pll_rec.length + 8;
		out = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!out)
			goto abort;

		img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA);
		if (!img_swap)
			goto abort_out;

		/* We need to re-order for 0010 */
		byte_swap_64((u64 *)&pll_rec, img_swap, len);

		spi_message_init(&m);
		memset(&t, 0, sizeof(t));
		t.rx_buf = out;
		t.tx_buf = img_swap;
		t.len = len;
		t.bits_per_word = 8;
		t.speed_hz = wm0010->sysclk / 6;
		spi_message_add_tail(&t, &m);

		ret = spi_sync(spi, &m);
		if (ret) {
			dev_err(codec->dev, "First PLL write failed: %d\n", ret);
			goto abort_swap;
		}

		/* Use a second send of the message to get the return status */
		ret = spi_sync(spi, &m);
		if (ret) {
			dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
			goto abort_swap;
		}

		p = (u32 *)out;

		/* Look for PLL active code from the DSP */
		for (i = 0; i < len / 4; i++) {
			if (*p == 0x0e00ed0f) {
				dev_dbg(codec->dev, "PLL packet received\n");
				wm0010->pll_running = true;
				break;
			}
			p++;
		}

		kfree(img_swap);
		kfree(out);
	} else
		dev_dbg(codec->dev, "Not enabling DSP PLL.");

	ret = wm0010_firmware_load("wm0010.dfw", codec);

	if (ret != 0)
		goto abort;

	spin_lock_irqsave(&wm0010->irq_lock, flags);
	wm0010->state = WM0010_FIRMWARE;
	spin_unlock_irqrestore(&wm0010->irq_lock, flags);

	mutex_unlock(&wm0010->lock);

	return 0;

abort_swap:
	kfree(img_swap);
abort_out:
	kfree(out);
abort:
	/* Put the chip back into reset */
	wm0010_halt(codec);
	mutex_unlock(&wm0010->lock);
	return ret;

err_core:
	mutex_unlock(&wm0010->lock);
	regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
			       wm0010->core_supplies);
err:
	return ret;
}
示例#26
0
文件: fbtft-io.c 项目: rm-hull/fbtft
int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len)
{
	int ret;
	u8 txbuf[32] = { 0, };
	struct spi_transfer	t = {
			.speed_hz = 2000000,
			.rx_buf		= buf,
			.len		= len,
		};
	struct spi_message	m;

	if (!par->spi) {
		dev_err(par->info->device, "%s: par->spi is unexpectedly NULL\n", __func__);
		return -ENODEV;
	}

	if (par->startbyte) {
		if (len > 32) {
			dev_err(par->info->device, "%s: len=%d can't be larger than 32 when using 'startbyte'\n", __func__, len);
			return -EINVAL;
		}
		txbuf[0] = par->startbyte | 0x3;
		t.tx_buf = txbuf;
		fbtft_dev_dbg_hex(DEBUG_READ, par, par->info->device, u8, txbuf, len, "%s(len=%d) txbuf => ", __func__, len);
	}

	spi_message_init(&m);
	spi_message_add_tail(&t, &m);
	ret = spi_sync(par->spi, &m);
	fbtft_dev_dbg_hex(DEBUG_READ, par, par->info->device, u8, buf, len, "%s(len=%d) buf <= ", __func__, len);

	return ret;
}
EXPORT_SYMBOL(fbtft_read_spi);


#ifdef CONFIG_ARCH_BCM2708

/*  Raspberry Pi  -  writing directly to the registers is 40-50% faster than optimized use of gpiolib  */

#define GPIOSET(no, ishigh)	{ if (ishigh) set|=(1<<no); else reset|=(1<<no); } while(0)

int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
{
	unsigned int set=0;
	unsigned int reset=0;
	u8 data;

	fbtft_dev_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, "%s(len=%d): ", __func__, len);

	while (len--) {
		data = *(u8 *) buf;
		buf++;

		/* Set data */
		GPIOSET(par->gpio.db[0], (data&0x01));
		GPIOSET(par->gpio.db[1], (data&0x02));
		GPIOSET(par->gpio.db[2], (data&0x04));
		GPIOSET(par->gpio.db[3], (data&0x08));
		GPIOSET(par->gpio.db[4], (data&0x10));
		GPIOSET(par->gpio.db[5], (data&0x20));
		GPIOSET(par->gpio.db[6], (data&0x40));
		GPIOSET(par->gpio.db[7], (data&0x80));
		writel(set, __io_address(GPIO_BASE+0x1C));
		writel(reset, __io_address(GPIO_BASE+0x28));

		//Pulse /WR low
		writel((1<<par->gpio.wr),  __io_address(GPIO_BASE+0x28));
		writel(0,  __io_address(GPIO_BASE+0x28)); //used as a delay
		writel((1<<par->gpio.wr),  __io_address(GPIO_BASE+0x1C));

		set = 0;
		reset = 0;
	}

	return 0;
}
示例#27
0
static int ak4182_read12_ser(struct device *dev, unsigned command)
{
	struct spi_device	*spi = to_spi_device(dev);
	struct ak4182		*ts = dev_get_drvdata(dev);
	struct ser_req		*req = kzalloc(sizeof *req, GFP_KERNEL);
	int			status;
	int			sample;
	int			use_internal;

	if (!req)
		return -ENOMEM;

	spi_message_init(&req->msg);

	/* FIXME boards with ak4182 might use external vref instead ... */
	use_internal = (ts->model == 4182);

	/* maybe turn on internal vREF, and let it settle */
	if (use_internal) {
		req->ref_on = REF_ON;
		req->xfer[0].tx_buf = &req->ref_on;
		req->xfer[0].len = 1;
		spi_message_add_tail(&req->xfer[0], &req->msg);

		req->xfer[1].rx_buf = &req->scratch;
		req->xfer[1].len = 2;

		/* for 1uF, settle for 800 usec; no cap, 100 usec.  */
		req->xfer[1].delay_usecs = ts->vref_delay_usecs;
		spi_message_add_tail(&req->xfer[1], &req->msg);
	}

	/* take sample */
	req->command = (u8) command;
	req->xfer[2].tx_buf = &req->command;
	req->xfer[2].len = 1;
	spi_message_add_tail(&req->xfer[2], &req->msg);
	req->xfer[3].rx_buf = &req->sample;
	
	req->xfer[3].len = 2;
	spi_message_add_tail(&req->xfer[3], &req->msg);

	/* REVISIT:  take a few more samples, and compare ... */

	/* converter in low power mode & enable PENIRQ */
	req->ref_off = PWRDOWN;
	req->xfer[4].tx_buf = &req->ref_off;
	req->xfer[4].len = 1;
	spi_message_add_tail(&req->xfer[4], &req->msg);

	req->xfer[5].rx_buf = &req->scratch;
	req->xfer[5].len = 2;
	CS_CHANGE(req->xfer[5]);
	spi_message_add_tail(&req->xfer[5], &req->msg);

	ts->irq_disabled = 1;
	disable_irq(spi->irq);
	status = spi_sync(spi, &req->msg);
	ts->irq_disabled = 0;
	enable_irq(spi->irq);

	if (req->msg.status)
		status = req->msg.status;

	/* on-wire is a must-ignore bit, a BE12 value, then padding */
	sample = be16_to_cpu(req->sample);
	sample = sample >> 3;
	sample &= 0x0fff;

	kfree(req);
	return status ? status : sample;
}
示例#28
0
static int ad7298_probe(struct spi_device *spi)
{
	struct ad7298_platform_data *pdata = spi->dev.platform_data;
	struct ad7298_state *st;
	struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
	int ret;

	if (indio_dev == NULL)
		return -ENOMEM;

	st = iio_priv(indio_dev);

	if (pdata && pdata->ext_ref)
		st->ext_ref = AD7298_EXTREF;

	if (st->ext_ref) {
		st->reg = regulator_get(&spi->dev, "vref");
		if (IS_ERR(st->reg)) {
			ret = PTR_ERR(st->reg);
			goto error_free;
		}
		ret = regulator_enable(st->reg);
		if (ret)
			goto error_put_reg;
	}

	spi_set_drvdata(spi, indio_dev);

	st->spi = spi;

	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->dev.parent = &spi->dev;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = ad7298_channels;
	indio_dev->num_channels = ARRAY_SIZE(ad7298_channels);
	indio_dev->info = &ad7298_info;

	/* Setup default message */

	st->scan_single_xfer[0].tx_buf = &st->tx_buf[0];
	st->scan_single_xfer[0].len = 2;
	st->scan_single_xfer[0].cs_change = 1;
	st->scan_single_xfer[1].tx_buf = &st->tx_buf[1];
	st->scan_single_xfer[1].len = 2;
	st->scan_single_xfer[1].cs_change = 1;
	st->scan_single_xfer[2].rx_buf = &st->rx_buf[0];
	st->scan_single_xfer[2].len = 2;

	spi_message_init(&st->scan_single_msg);
	spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
	spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
	spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg);

	ret = iio_triggered_buffer_setup(indio_dev, NULL,
			&ad7298_trigger_handler, NULL);
	if (ret)
		goto error_disable_reg;

	ret = iio_device_register(indio_dev);
	if (ret)
		goto error_cleanup_ring;

	return 0;

error_cleanup_ring:
	iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
	if (st->ext_ref)
		regulator_disable(st->reg);
error_put_reg:
	if (st->ext_ref)
		regulator_put(st->reg);
error_free:
	iio_device_free(indio_dev);

	return ret;
}
示例#29
0
static int __must_check wl12xx_spi_raw_read(struct device *child, int addr,
					    void *buf, size_t len, bool fixed)
{
	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
	struct wl1271 *wl = dev_get_drvdata(child);
	struct spi_transfer t[2];
	struct spi_message m;
	u32 *busy_buf;
	u32 *cmd;
	u32 chunk_len;

	while (len > 0) {
		chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);

		cmd = &wl->buffer_cmd;
		busy_buf = wl->buffer_busyword;

		*cmd = 0;
		*cmd |= WSPI_CMD_READ;
		*cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
			WSPI_CMD_BYTE_LENGTH;
		*cmd |= addr & WSPI_CMD_BYTE_ADDR;

		if (fixed)
			*cmd |= WSPI_CMD_FIXED;

		spi_message_init(&m);
		memset(t, 0, sizeof(t));

		t[0].tx_buf = cmd;
		t[0].len = 4;
		t[0].cs_change = true;
		spi_message_add_tail(&t[0], &m);

		/* Busy and non busy words read */
		t[1].rx_buf = busy_buf;
		t[1].len = WL1271_BUSY_WORD_LEN;
		t[1].cs_change = true;
		spi_message_add_tail(&t[1], &m);

		spi_sync(to_spi_device(glue->dev), &m);

		if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
		    wl12xx_spi_read_busy(child)) {
			memset(buf, 0, chunk_len);
			return 0;
		}

		spi_message_init(&m);
		memset(t, 0, sizeof(t));

		t[0].rx_buf = buf;
		t[0].len = chunk_len;
		t[0].cs_change = true;
		spi_message_add_tail(&t[0], &m);

		spi_sync(to_spi_device(glue->dev), &m);

		if (!fixed)
			addr += chunk_len;
		buf += chunk_len;
		len -= chunk_len;
	}

	return 0;
}
示例#30
0
/**
 * spi_mem_exec_op() - Execute a memory operation
 * @slave: the SPI device
 * @op: the memory operation to execute
 *
 * Executes a memory operation.
 *
 * This function first checks that @op is supported and then tries to execute
 * it.
 *
 * Return: 0 in case of success, a negative error code otherwise.
 */
int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
{
	struct udevice *bus = slave->dev->parent;
	struct dm_spi_ops *ops = spi_get_ops(bus);
	unsigned int pos = 0;
	const u8 *tx_buf = NULL;
	u8 *rx_buf = NULL;
	u8 *op_buf;
	int op_len;
	u32 flag;
	int ret;
	int i;

	if (!spi_mem_supports_op(slave, op))
		return -ENOTSUPP;

	if (ops->mem_ops) {
#ifndef __UBOOT__
		/*
		 * Flush the message queue before executing our SPI memory
		 * operation to prevent preemption of regular SPI transfers.
		 */
		spi_flush_queue(ctlr);

		if (ctlr->auto_runtime_pm) {
			ret = pm_runtime_get_sync(ctlr->dev.parent);
			if (ret < 0) {
				dev_err(&ctlr->dev,
					"Failed to power device: %d\n",
					ret);
				return ret;
			}
		}

		mutex_lock(&ctlr->bus_lock_mutex);
		mutex_lock(&ctlr->io_mutex);
#endif
		ret = ops->mem_ops->exec_op(slave, op);
#ifndef __UBOOT__
		mutex_unlock(&ctlr->io_mutex);
		mutex_unlock(&ctlr->bus_lock_mutex);

		if (ctlr->auto_runtime_pm)
			pm_runtime_put(ctlr->dev.parent);
#endif

		/*
		 * Some controllers only optimize specific paths (typically the
		 * read path) and expect the core to use the regular SPI
		 * interface in other cases.
		 */
		if (!ret || ret != -ENOTSUPP)
			return ret;
	}

#ifndef __UBOOT__
	tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes +
		     op->dummy.nbytes;

	/*
	 * Allocate a buffer to transmit the CMD, ADDR cycles with kmalloc() so
	 * we're guaranteed that this buffer is DMA-able, as required by the
	 * SPI layer.
	 */
	tmpbuf = kzalloc(tmpbufsize, GFP_KERNEL | GFP_DMA);
	if (!tmpbuf)
		return -ENOMEM;

	spi_message_init(&msg);

	tmpbuf[0] = op->cmd.opcode;
	xfers[xferpos].tx_buf = tmpbuf;
	xfers[xferpos].len = sizeof(op->cmd.opcode);
	xfers[xferpos].tx_nbits = op->cmd.buswidth;
	spi_message_add_tail(&xfers[xferpos], &msg);
	xferpos++;
	totalxferlen++;

	if (op->addr.nbytes) {
		int i;

		for (i = 0; i < op->addr.nbytes; i++)
			tmpbuf[i + 1] = op->addr.val >>
					(8 * (op->addr.nbytes - i - 1));

		xfers[xferpos].tx_buf = tmpbuf + 1;
		xfers[xferpos].len = op->addr.nbytes;
		xfers[xferpos].tx_nbits = op->addr.buswidth;
		spi_message_add_tail(&xfers[xferpos], &msg);
		xferpos++;
		totalxferlen += op->addr.nbytes;
	}