📄 spi.c
字号:
temp &= ~(0xff << 8);
temp |= (0x55 << 8);
outl(temp, PINSEL0);
} if (num == 1)
{
temp = inl(PINSEL1);
PinSel1Save = temp & (0xff << 2);
temp &= ~(0xff << 2);
temp |= (0xaa << 2);
outl(temp, PINSEL1);
}
sema_init(&(SpiDevices[num].sem), 1);
SpiDevices[num].BaseAddr = num * (S1PCR - S0PCR) + S0PCR;
outl(8, SpiDevices[num].BaseAddr + S0PCCR - S0PCR);
inl(SpiDevices[num].BaseAddr + S0PSR - S0PCR); outl(1 << 5, SpiDevices[num].BaseAddr + S0PCR - S0PCR);
filp->private_data = &SpiDevices[num];
local_irq_restore(flag);
} SpiDevices[num].usage++;
MOD_INC_USE_COUNT; return 0; /* success */} /*********************************************************************************************************
** Function name: spi_release
** Descriptions: release device
** Input:inode: information of device
** filp: pointer of file
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-4-29
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int spi_release(struct inode *inode, struct file *filp) { unsigned long flag; int num; u32 temp;
num = MINOR(inode->i_rdev); if (num >= MAX_SPI) { return -ENODEV; }
MOD_DEC_USE_COUNT; SpiDevices[num].usage--;
if (SpiDevices[num].usage == 0)
{
local_irq_save(flag);
if (num == 0)
{
temp = inl(PINSEL0);
temp &= ~(0xff << 8);
temp |= PinSel0Save;
outl(temp, PINSEL0);
} if (num == 1)
{
temp = inl(PINSEL1);
temp &= ~(0xff << 2);
temp |= PinSel1Save;
outl(temp, PINSEL1);
} local_irq_restore(flag);
}
return(0); } /*********************************************************************************************************
** Function name: spi_ioctl
** Descriptions: IO control function
** Input:inode: information of device
** filp: pointer of file
** cmd: command
** arg: additive parameter
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-4-29
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int spi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){
int num; u32 temp;
Spi_Dev *dep;
num = MINOR(inode->i_rdev); if (num >= MAX_SPI) { return -ENODEV; }
if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC) { return -ENOTTY; } if (_IOC_NR(cmd) >= SPI_MAXNR) { return -ENOTTY; }
dep = filp->private_data;
switch(cmd) { case SPI_SET_CLKDIV:
if (arg < 8)
{
arg = 8;
}
arg++;
arg &= ~1;
outl(arg, dep->BaseAddr + S0PCCR - S0PCR); break; case SPI_SET_CPHA_FIRST:
temp = inl(dep->BaseAddr + S0PCR - S0PCR);
temp &= ~(1 << 3);
outl(temp, dep->BaseAddr + S0PCR - S0PCR);
break;
case SPI_SET_CPHA_SECOND:
temp = inl(dep->BaseAddr + S0PCR - S0PCR);
temp |= (1 << 3);
outl(temp, dep->BaseAddr + S0PCR - S0PCR);
break;
case SPI_SET_CPOL_LOW:
temp = inl(dep->BaseAddr + S0PCR - S0PCR);
temp |= (1 << 4);
outl(temp, dep->BaseAddr + S0PCR - S0PCR);
break;
case SPI_SET_CPOL_HIGHT:
temp = inl(dep->BaseAddr + S0PCR - S0PCR);
temp &= ~(1 << 4);
outl(temp, dep->BaseAddr + S0PCR - S0PCR);
break;
case SPI_SET_LSBF_BIT0:
temp = inl(dep->BaseAddr + S0PCR - S0PCR);
temp |= (1 << 6);
outl(temp, dep->BaseAddr + S0PCR - S0PCR);
break;
case SPI_SET_LSBF_BIT7:
temp = inl(dep->BaseAddr + S0PCR - S0PCR);
temp &= ~(1 << 6);
outl(temp, dep->BaseAddr + S0PCR - S0PCR);
break;
case SPI_WR_DATA:
if (!access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)))
{
return -EFAULT; }
if (!access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)))
{
return -EFAULT; }
get_user(temp, (u8 *)arg);
outl(temp, dep->BaseAddr + S0PDR - S0PCR);
while (1)
{
temp = inl(dep->BaseAddr + S0PSR - S0PCR);
if ((temp & (1 << 7)) != 0)
{
break;
}
if (temp != 0)
{
return -EIO;
}
}
temp = inl(dep->BaseAddr + S0PDR - S0PCR);
put_user(temp, (u8 *)arg); break;
case SPI_START:
if (down_interruptible(&dep->sem))
{
return -ERESTARTSYS;
} break; case SPI_END:
up(&dep->sem);
break; default: return -ENOTTY; break; } return 0;}
/*********************************************************************************************************
** Function name: spi_init
** Descriptions: init driver
** Input:none
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-4-29
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int spi_init(void){ int result;
result = register_chrdev(MAJOR_NR, DEVICE_NAME, &spi_fops); if (result < 0) { printk(KERN_ERR DEVICE_NAME ": Unable to get major %d\n", MAJOR_NR ); return(result); }
if (MAJOR_NR == 0) { MAJOR_NR = result; /* dynamic */ }
printk(KERN_INFO DEVICE_NAME ": init OK\n"); return(0); }/*********************************************************************************************************
** Function name: spi_cleanup
** Descriptions: exit driver
** Input:none
** Output none
** Created by: Chenmingji
** Created Date: 2005-4-29
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void spi_cleanup(void){
unregister_chrdev(MAJOR_NR, DEVICE_NAME);}/*********************************************************************************************************** End Of File********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -