Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96710
  • 博文数量: 54
  • 博客积分: 1920
  • 博客等级: 上尉
  • 技术积分: 480
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-08 13:46
文章分类

全部博文(54)

文章存档

2011年(1)

2010年(8)

2009年(45)

我的朋友

分类: LINUX

2009-05-11 15:09:29


(stranger)
08-07-14 20:45
[求助]SPI设备驱动问题?  

我在做一个s3c2410+linux-2.6.18平台上通过spi总线方式接入的fpga芯片驱动时遇到问题,有SPI驱动开发经验的朋友指点一下.

在内核配置时候选择了 Samsung S3C24XX series SPI,按照论坛上以前帖子上的做法,然后在arch/arm/mach-s3c2410/的devs.c文件中加入下列信息:

/* add by jiarubin*/
static struct spi_board_info s3c2410_spi_board[] = {
[0] = {
.modalias = "spi_fpga",
.platform_data =NULL,
.chip_select = 1,
.max_speed_hz = 500*1000,
},
};


struct s3c2410_spi_info s3c2410_spi_platdata = {
.pin_cs = S3C2410_GPE7,
.board_info = s3c2410_spi_board,
.board_size = ARRAY_SIZE(s3c2410_spi_board),
};
/* end add */
struct platform_device s3c_device_spi0 = {
.name = "s3c2410-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_spi0_resource),
.resource = s3c_spi0_resource,
.dev = {
.dma_mask = &s3c_device_spi0_dmamask,
.coherent_dma_mask = 0xffffffffUL,
.platform_data =&s3c2410_spi_platdata/*add by jiarubin*/
}
};

最后将我自己编译出来的ko文件成功加载上以后,从/sys/下的bus/和devices/都能找到自己fpga设备和驱动,但是在应用程序中调用write()函数访问时报错,我的驱动代码如下,请高手帮我分析一下,谢谢!

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#include

#include "spi_fpga.h"

struct spi_fpga{

struct spi_device *spi;

/* data buffers */
unsigned char *tx;
unsigned char *rx;

struct semaphore lock;
};

struct spi_device *new_device;
struct spi_fpga *fpga_dev;
unsigned char register_address=0;

void config_gpio(void)
{
s3c2410_gpio_cfgpin(SPI_FPGA_RST,S3C2410_GPIO_OUTPUT);
}

static int spi_fpga_probe(struct spi_device *spi)
{
struct spi_board_info *data;
struct spi_fpga *fpga;

data=kzalloc(sizeof(struct spi_board_info), SLAB_KERNEL);
if (!data)
return -ENOMEM;
data->platform_data = spi->dev.platform_data;
if (!data->platform_data) {
dev_dbg(&spi->dev, "no platform data?\n");
return -ENODEV;
}

fpga = kzalloc(sizeof(struct spi_fpga), SLAB_KERNEL);
if (!fpga)
return -ENOMEM;

fpga->spi = spi;
new_device=fpga->spi;
fpga_dev=fpga;
init_MUTEX(&fpga->lock);
dev_set_drvdata(&spi->dev, fpga);
fpga_dev=dev_get_drvdata(&spi->dev);
return 0;
}

static int spi_fpga_remove(struct spi_device *spi)
{
struct spi_fpga *pfpga = dev_get_drvdata(&spi->dev);
kfree(pfpga);
return 0;
}

static ssize_t spi_fpga_write(struct file *file, const char * buffer, size_t count, loff_t *ppos)
{
struct spi_transfer t[2];
struct spi_message m;
unsigned char *buf,ret;

//down(&fpga_write_sem);
buf=kmalloc(count,GFP_KERNEL);
if (buf== NULL)
return - ENOMEM;

memset(buf,0,count);
ret = copy_from_user(buf, buffer, count);
if(ret != 0)
{
kfree(buf);
return -EFAULT;
}

spi_message_init(&m);
memset(t, 0, (sizeof t));

t[0].tx_buf = ®ister_address;
t[0].len = sizeof(register_address);
spi_message_add_tail(&t[0], &m);

t[1].tx_buf = buf;
t[1].len = count;
spi_message_add_tail(&t[1], &m);

//up(&fpga_write_sem);

return spi_sync(new_device, &m);
}


static ssize_t spi_fpga_read(struct file * file, const char * buffer, size_t count, loff_t *ppos)
{
struct spi_transfer t[2];
struct spi_message m;
unsigned char *buf,ret;

//down(&fpga_read_sem);
buf=kmalloc(count,GFP_KERNEL);
if (buf== NULL)
return - ENOMEM;
memset(buf,0,count);
spi_message_init(&m);
memset(t, 0, (sizeof t));

t[0].tx_buf = ®ister_address;
t[0].len = sizeof(register_address);
spi_message_add_tail(&t[0], &m);

t[1].rx_buf = buf;
t[1].len = count;
spi_message_add_tail(&t[1], &m);
ret=copy_to_user(buffer, buf, count);
if(ret != 0)
{
kfree(buf);
return -EFAULT;
}
//up(&fpga_read_sem);

return spi_sync(new_device, &m);
}


static struct spi_driver spi_fpga_driver = {
.driver = {
.name = "spi_fpga",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = spi_fpga_probe,
.remove = __devexit_p(spi_fpga_remove),

};

static int spi_fpga_open(struct inode * inode, struct file * filp)
{
return 0;
}

static int spi_fpga_release(struct inode * inode, struct file * filp)
{
return 0;
}

static loff_t spi_fpga_llseek (struct file *filp, loff_t off, int whence)
{
switch(whence)
{
case SEEK_SET:
register_address= off;
break;

case SEEK_CUR:
register_address = register_address+ off;
break;

default: /* can't happen */
return -EINVAL;
}

return register_address;
}

void spi_fpga_highreset(void)
{
s3c2410_gpio_setpin(SPI_FPGA_RST, 1 );
msleep(10);
}

void spi_fpga_lowreset(void)
{
s3c2410_gpio_setpin(SPI_FPGA_RST, 0 );
msleep(10);
}


/*to user*/
static struct file_operations spi_fpga_fops = {
.owner = THIS_MODULE,
.open = spi_fpga_open,
.write = spi_fpga_write,
.read = spi_fpga_read,
.llseek = spi_fpga_llseek,
.release = spi_fpga_release,
};


static int __init spi_fpga_init(void)
{
unsigned int result;
result = register_chrdev(DS3_FPGA_MAJOR, DEVICE_NAME, &spi_fpga_fops);
if (result < 0)
{
printk(KERN_ERR DEVICE_NAME ": Unable to get major %d\n", DS3_FPGA_MAJOR);
return(result);
}

config_gpio();
spi_fpga_lowreset();
spi_fpga_highreset();
spi_fpga_lowreset();

printk(KERN_ERR DEVICE_NAME ": init OK\n");
return spi_register_driver(&spi_fpga_driver);
}

static void __exit spi_fpga_exit(void)
{
spi_unregister_driver(&spi_fpga_driver);
unregister_chrdev(DS3_FPGA_MAJOR, DEVICE_NAME);
}

module_init(spi_fpga_init);
module_exit(spi_fpga_exit);

MODULE_DESCRIPTION("spi fpga driver");
MODULE_LICENSE("GPL");

谢谢各位关注,问题已经解决.简单说一下,之前贴的加在devs.c里的板极信息

struct spi_board_info s3c2410_spi_board[] = {
[0] = {
.modalias = "spi_fpga",
//.bus_num =0,
.chip_select = S3C2410_GPE7,
.max_speed_hz = 1*1000*1000,
},
};

这里最重要的是modalias,务必和设备驱动的设备名一致.因为在下面已经把platform_data =&s3c2410_spi_platdata分给spi0,这里的bus_num就没必要赋了.

struct s3c2410_spi_info s3c2410_spi_platdata = {
.pin_cs = S3C2410_GPE7,
.board_info = s3c2410_spi_board,
.board_size = ARRAY_SIZE(s3c2410_spi_board),
};


static u64 s3c_device_spi0_dmamask = 0xffffffffUL;

struct platform_device s3c_device_spi0 = {
.name = "s3c2410-spi",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_spi0_resource),
.resource = s3c_spi0_resource,
.dev = {
.dma_mask = &s3c_device_spi0_dmamask,
.coherent_dma_mask = 0xffffffffUL,
.platform_data =&s3c2410_spi_platdata
}
};

文章选项: 打印


(old hand)
08-07-29 11:44
Re: [求助]SPI设备驱动问题? 新 []  

有浅在风险啊,改一下,牢靠一些


static int spi_fpga_probe(struct spi_device *spi)
{
struct spi_board_info *data;
struct spi_fpga *fpga;

data=kzalloc(sizeof(struct spi_board_info), SLAB_KERNEL);
if (!data)
return -ENOMEM;
data->platform_data = spi->dev.platform_data;
if (!data->platform_data) {
dev_dbg(&spi->dev, "no platform data?\n");
return -ENODEV;
}

fpga = kzalloc(sizeof(struct spi_fpga), SLAB_KERNEL);
if (!fpga)
return -ENOMEM;

fpga->spi = spi;
new_device=fpga->spi;
fpga_dev=fpga;
init_MUTEX(&fpga->lock);
dev_set_drvdata(&spi->dev, fpga);
fpga_dev=dev_get_drvdata(&spi->dev);
return 0;
}

 

阅读(1197) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~