drivers/spi/spi-lm70llp.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-lm70llp.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-lm70llp.c
Extension
.c
Size
8554 bytes
Lines
328
Domain
Driver Families
Bucket
drivers/spi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct spi_lm70llp {
	struct spi_bitbang	bitbang;
	struct parport		*port;
	struct pardevice	*pd;
	struct spi_device	*spidev_lm70;
	struct spi_board_info	info;
	//struct device		*dev;
};

/* REVISIT : ugly global ; provides "exclusive open" facility */
static struct spi_lm70llp *lm70llp;

/*-------------------------------------------------------------------*/

static inline struct spi_lm70llp *spidev_to_pp(struct spi_device *spi)
{
	return spi->controller_data;
}

/*---------------------- LM70 LLP eval board-specific inlines follow */

/* NOTE:  we don't actually need to reread the output values, since they'll
 * still be what we wrote before.  Plus, going through parport builds in
 * a ~1ms/operation delay; these SPI transfers could easily be faster.
 */

static inline void deassertCS(struct spi_lm70llp *pp)
{
	u8 data = parport_read_data(pp->port);

	data &= ~0x80;		/* pull D7/SI-out low while de-asserted */
	parport_write_data(pp->port, data | nCS);
}

static inline void assertCS(struct spi_lm70llp *pp)
{
	u8 data = parport_read_data(pp->port);

	data |= 0x80;		/* pull D7/SI-out high so lm70 drives SO-in */
	parport_write_data(pp->port, data & ~nCS);
}

static inline void clkHigh(struct spi_lm70llp *pp)
{
	u8 data = parport_read_data(pp->port);

	parport_write_data(pp->port, data | SCLK);
}

static inline void clkLow(struct spi_lm70llp *pp)
{
	u8 data = parport_read_data(pp->port);

	parport_write_data(pp->port, data & ~SCLK);
}

/*------------------------- SPI-LM70-specific inlines ----------------------*/

static inline void spidelay(unsigned d)
{
	udelay(d);
}

static inline void setsck(struct spi_device *s, int is_on)
{
	struct spi_lm70llp *pp = spidev_to_pp(s);

	if (is_on)
		clkHigh(pp);
	else
		clkLow(pp);
}

static inline void setmosi(struct spi_device *s, int is_on)
{
	/* FIXME update D7 ... this way we can put the chip
	 * into shutdown mode and read the manufacturer ID,
	 * but we can't put it back into operational mode.
	 */
}

/*
 * getmiso:
 * Why do we return 0 when the SIO line is high and vice-versa?
 * The fact is, the lm70 eval board from NS (which this driver drives),
 * is wired in just such a way : when the lm70's SIO goes high, a transistor
 * switches it to low reflecting this on the parport (pin 13), and vice-versa.
 */
static inline int getmiso(struct spi_device *s)
{

Annotation

Implementation Notes