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; }
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]; }
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; }
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; }
/** * 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; }
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; }
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; }
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; }
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); }
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; }
/* * 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; }
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; }
/** * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/** * 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; }