⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_txx9.c

📁 linux-2.6.15.6
💻 C
字号:
/* * linux/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c * Copyright (C) 2000-2001 Toshiba Corporation * * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the * terms of the GNU General Public License version 2. This program is * licensed "as is" without any warranty of any kind, whether express * or implied. * * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */#include <linux/init.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/interrupt.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/spinlock.h>#include <linux/wait.h>#include <asm/tx4938/spi.h>#include <asm/tx4938/tx4938.h>static int (*txx9_spi_cs_func)(int chipid, int on);static DEFINE_SPINLOCK(txx9_spi_lock);extern unsigned int txx9_gbus_clock;#define SPI_FIFO_SIZE	4void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)){	txx9_spi_cs_func = cs_func;	/* enter config mode */	tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;}static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs){	/* disable rx intr */	tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;	wake_up(&txx9_spi_wait);}static struct irqaction txx9_spi_action = {	txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,};void __init txx9_spi_irqinit(int irc_irq){	setup_irq(irc_irq, &txx9_spi_action);}int txx9_spi_io(int chipid, struct spi_dev_desc *desc,		unsigned char **inbufs, unsigned int *incounts,		unsigned char **outbufs, unsigned int *outcounts,		int cansleep){	unsigned int incount, outcount;	unsigned char *inp, *outp;	int ret;	unsigned long flags;	spin_lock_irqsave(&txx9_spi_lock, flags);	if ((tx4938_spiptr->mcr & TXx9_SPMCR_OPMODE) == TXx9_SPMCR_ACTIVE) {		spin_unlock_irqrestore(&txx9_spi_lock, flags);		return -EBUSY;	}	/* enter config mode */	tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;	tx4938_spiptr->cr0 =		(desc->byteorder ? TXx9_SPCR0_SBOS : 0) |		(desc->polarity ? TXx9_SPCR0_SPOL : 0) |		(desc->phase ? TXx9_SPCR0_SPHA : 0) |		0x08;	tx4938_spiptr->cr1 =		(((TXX9_IMCLK + desc->baud) / (2 * desc->baud) - 1) << 8) |		0x08 /* 8 bit only */;	/* enter active mode */	tx4938_spiptr->mcr = TXx9_SPMCR_ACTIVE;	spin_unlock_irqrestore(&txx9_spi_lock, flags);	/* CS ON */	if ((ret = txx9_spi_cs_func(chipid, 1)) < 0) {		spin_unlock_irqrestore(&txx9_spi_lock, flags);		return ret;	}	udelay(desc->tcss);	/* do scatter IO */	inp = inbufs ? *inbufs : NULL;	outp = outbufs ? *outbufs : NULL;	incount = 0;	outcount = 0;	while (1) {		unsigned char data;		unsigned int count;		int i;		if (!incount) {			incount = incounts ? *incounts++ : 0;			inp = (incount && inbufs) ? *inbufs++ : NULL;		}		if (!outcount) {			outcount = outcounts ? *outcounts++ : 0;			outp = (outcount && outbufs) ? *outbufs++ : NULL;		}		if (!inp && !outp)			break;		count = SPI_FIFO_SIZE;		if (incount)			count = min(count, incount);		if (outcount)			count = min(count, outcount);		/* now tx must be idle... */		while (!(tx4938_spiptr->sr & TXx9_SPSR_SIDLE))			;		tx4938_spiptr->cr0 =			(tx4938_spiptr->cr0 & ~TXx9_SPCR0_RXIFL_MASK) |			((count - 1) << 12);		if (cansleep) {			/* enable rx intr */			tx4938_spiptr->cr0 |= TXx9_SPCR0_RBSIE;		}		/* send */		for (i = 0; i < count; i++)			tx4938_spiptr->dr = inp ? *inp++ : 0;		/* wait all rx data */		if (cansleep) {			wait_event(txx9_spi_wait,				   tx4938_spiptr->sr & TXx9_SPSR_SRRDY);		} else {			while (!(tx4938_spiptr->sr & TXx9_SPSR_RBSI))				;		}		/* receive */		for (i = 0; i < count; i++) {			data = tx4938_spiptr->dr;			if (outp)				*outp++ = data;		}		if (incount)			incount -= count;		if (outcount)			outcount -= count;	}	/* CS OFF */	udelay(desc->tcsh);	txx9_spi_cs_func(chipid, 0);	udelay(desc->tcsr);	spin_lock_irqsave(&txx9_spi_lock, flags);	/* enter config mode */	tx4938_spiptr->mcr = TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR;	spin_unlock_irqrestore(&txx9_spi_lock, flags);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -