本文整理汇总了C++中spi_message_add_tail函数的典型用法代码示例。如果您正苦于以下问题:C++ spi_message_add_tail函数的具体用法?C++ spi_message_add_tail怎么用?C++ spi_message_add_tail使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了spi_message_add_tail函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: max6902_get_reg
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;
}
开发者ID:xf739645524,项目名称:kernel-rhel5,代码行数:36,代码来源:rtc-max6902.c
示例2: max3110_write_then_read
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;
}
开发者ID:macbury,项目名称:linux-2.6,代码行数:24,代码来源:mrst_max3110.c
示例3: ab4500_read
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];
}
开发者ID:A2109devs,项目名称:lenovo_a2109a_kernel,代码行数:24,代码来源:ab4500-core.c
示例4: mc13783_reg_read
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;
}
开发者ID:Aaroneke,项目名称:galaxy-2636,代码行数:36,代码来源:mc13783-core.c
示例5: ili922x_read_status
/**
* 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;
}
开发者ID:AnadoluPanteri,项目名称:kernel-plus-harmattan,代码行数:41,代码来源:ili922x.c
示例6: linux_spi_write
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;
}
开发者ID:faijurrahman,项目名称:driver,代码行数:36,代码来源:linux_wlan_spi.c
示例7: adis16240_read_ring_data
/**
* 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;
}
开发者ID:3sOx,项目名称:asuswrt-merlin,代码行数:41,代码来源:adis16240_ring.c
示例8: kxr94_spi_write
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;
}
开发者ID:kzlin129,项目名称:tt-gpl,代码行数:24,代码来源:kxr94_adc.c
示例9: fc8050_spi_write_then_read
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;
}
开发者ID:samno1607,项目名称:LG-P920-Stock-Gingerbread-Kernel,代码行数:24,代码来源:fc8050_spi.c
示例10: linux_spi_read
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;
}
开发者ID:globalgang,项目名称:driver,代码行数:36,代码来源:linux_wlan_spi.c
示例11: sca3000_write_reg
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;
}
开发者ID:12rafael,项目名称:jellytimekernel,代码行数:75,代码来源:sca3000_core.c
示例12: wl12xx_spi_init
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);
}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:75,代码来源:spi.c
示例13: dataflash_erase
/*
* 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),
//.........这里部分代码省略.........
开发者ID:AdrianHuang,项目名称:linux-3.8.13,代码行数:101,代码来源:mtd_dataflash.c
示例14: wm0010_stage2_load
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;
}
开发者ID:ReneNyffenegger,项目名称:linux,代码行数:73,代码来源:wm0010.c
示例15: spi_mem_exec_op
/**
* 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;
}
开发者ID:woodsts,项目名称:barebox,代码行数:80,代码来源:spi-mem.c
示例16: m25p80_erase
//.........这里部分代码省略.........
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;
开发者ID:jameshilliard,项目名称:stblinux-2.6.18-7.1,代码行数:66,代码来源:m25p80.c
示例17: dataflash_erase
/*
* 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;
}
开发者ID:Reggi3,项目名称:mini210s-barebox,代码行数:81,代码来源:mtd_dataflash.c
示例18: dataflash_write
/*
* 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);
//.........这里部分代码省略.........
开发者ID:Reggi3,项目名称:mini210s-barebox,代码行数:101,代码来源:mtd_dataflash.c
示例19: stm32fwu_spi_write
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;
}
开发者ID:moonlightly,项目名称:android_kernel_samsung_ms013g,代码行数:73,代码来源:ssp_firmware.c
示例20: ade7758_configure_ring
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;
}
开发者ID:AD5GB,项目名称:kernel_n5_3.10-experimental,代码行数:65,代码来源:ade7758_ring.c
注:本文中的spi_message_add_tail函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论