linux spi驱动测试,linux spi驱动开发学习-----spidev.c和spi test app

static void bitbang_work(struct work_struct *work)

{

struct spi_bitbang    *bitbang =

container_of(work, struct spi_bitbang, work);

unsigned long        flags;

int            do_setup = -1;

int            (*setup_transfer)(struct spi_device *,

struct spi_transfer *);

setup_transfer = bitbang->setup_transfer;

spin_lock_irqsave(&bitbang->lock, flags);

bitbang->busy = 1;

while (!list_empty(&bitbang->queue)) {

struct spi_message    *m;

struct spi_device    *spi;

unsigned        nsecs;

struct spi_transfer    *t = NULL;

unsigned        tmp;

unsigned        cs_change;

int            status;

m = container_of(bitbang->queue.next, struct spi_message,

queue);

list_del_init(&m->queue);

spin_unlock_irqrestore(&bitbang->lock, flags);

/* FIXME this is made-up ... the correct value is known to

* word-at-a-time bitbang code, and presumably chipselect()

* should enforce these requirements too?

*/

nsecs = 100;

spi = m->spi;

tmp = 0;

cs_change = 1;

status = 0;

list_for_each_entry (t, &m->transfers, transfer_list) {

/* override speed or wordsize? */

if (t->speed_hz || t->bits_per_word)

do_setup = 1;

/* init (-1) or override (1) transfer params */

if (do_setup != 0) {

if (!setup_transfer) {

status = -ENOPROTOOPT;

break;

}

status = setup_transfer(spi, t);

if (status

break;

}

/* set up default clock polarity, and activate chip;

* this implicitly updates clock and spi modes as

* previously recorded for this device via setup().

* (and also deselects any other chip that might be

* selected ...)

*/

if (cs_change) {

bitbang->chipselect(spi, BITBANG_CS_ACTIVE);

ndelay(nsecs);

}

cs_change = t->cs_change;

if (!t->tx_buf && !t->rx_buf && t->len) {

status = -EINVAL;

break;

}

/* transfer data. the lower level code handles any

* new dma mappings it needs. our caller always gave

* us dma-safe buffers.

*/

if (t->len) {

/* REVISIT dma API still needs a designated

* DMA_ADDR_INVALID; ~0 might be better.

*/

if (!m->is_dma_mapped)

t->rx_dma = t->tx_dma = 0;

status = bitbang->txrx_bufs(spi, t);

}

if (status > 0)

m->actual_length += status;

if (status != t->len) {

/* always report some kind of error */

if (status >= 0)

status = -EREMOTEIO;

break;

}

status = 0;

/* protocol tweaks before next transfer */

if (t->delay_usecs)

udelay(t->delay_usecs);

if (!cs_change)

continue;

if (t->transfer_list.next == &m->transfers)

break;

/* sometimes a short mid-message deselect of the chip

* may be needed to terminate a mode or command

*/

ndelay(nsecs);

bitbang->chipselect(spi, BITBANG_CS_INACTIVE);

ndelay(nsecs);

}

m->status = status;

m->complete(m->context);

/* restore speed and wordsize if it was overridden */

if (do_setup == 1)

setup_transfer(spi, NULL);

do_setup = 0;

/* normally deactivate chipselect ... unless no error and

* cs_change has hinted that the next message will probably

* be for this chip too.

*/

if (!(status == 0 && cs_change)) {

ndelay(nsecs);

bitbang->chipselect(spi, BITBANG_CS_INACTIVE);

ndelay(nsecs);

}

spin_lock_irqsave(&bitbang->lock, flags);

}

bitbang->busy = 0;

spin_unlock_irqrestore(&bitbang->lock, flags);

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值