[U-Boot-Users] [PATCH v2 1/3] New i.MX31 SPI driver
Guennadi Liakhovetski
lg at denx.de
Thu May 8 17:59:50 CEST 2008
On Thu, 8 May 2008, Haavard Skinnemoen wrote:
> Guennadi Liakhovetski <lg at denx.de> wrote:
>
> > slave = spi_setup_slave(host, dev, hz, 0 /*| SPI_ACCESS_EXCLUSIVE */);
> > if (!slave)
> > return;
> > /* Now you MUST release the slave / host */
> > spi_xfer();
> > ...
> > spi_release();
>
> I think you should set up a slave exactly once before starting to
> communicate with it. Once you've done that, you just execute sequences
> of
>
> spi_claim_bus(slave);
> spi_xfer(slave, ...);
> /* possibly more transfers */
> spi_release_bus(slave);
>
> We could also define commonly-used "canned" sequences, like spi_w8r8()
> (write 8 bits, read 8 bits).
Ok, I see what you mean now. But then we need another function - an
opposite to spi_setup, to free any allocated RAM, etc. I thought this was
going to happen in release_bus, but after this explanation this doesn't
seem to be the case.
So, just add an spi_free(), and, as a counterpart to it, an spi_init()
might sound better than spi_setup:-)
> > And you get access to the bus if there are no exclusive users, and you get
> > exclusive access, only if there are no users currently at all.
>
> I don't see how having multiple active users on the bus at the same
> time can possibly make any sense...once you start a transfer, you
> better make sure nobody else is doing a transfer at the same time since
> you're using the same MOSI/MISO/SCK lines...
No, not "active." Multiple users having set up different slaves. But not
communicating simultaneously:-)
> > Looks like most of this API implementation is hardware independent, and
> > should go into an spi.c?
>
> Not really...what "claiming" the bus really means is highly hardware
> dependent. And SPI slave setup is mostly about decoding
> hardware-independent parameters like SCK rate and mode bits into
> hardware register values. But any convenience wrappers like spi_w8r8()
> probably belongs somewhere hardware-independent.
I thought, like (pseudocode)
static struct spi_host busses[SPI_BUSSES];
struct spi_slave *spi_init()
{
list_for_each_entry(slave, &busses[bus].slaves, list) {
if (slave->device == device)
return (struct spi_slave *)-EBUSY;
}
slave = malloc();
slave->bus = bus;
slave->device = device;
ret = busses[bus].init(slave);
if (ret) {
free(slave);
return (struct spi_slave *)ret;
}
return slave;
}
int spi_xfer()
{
list_for_each_entry(ix, &busses[bus].slaves, list) {
if (ix == slave)
break;
}
if (ix != slave)
return -EINVAL;
if (slave->bus->busy)
return -EBUSY;
return slave->bus->xfer();
}
...and so on, which is all quite hardware-independent.
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
More information about the U-Boot
mailing list