IIC Device(At24c02) Driver for Linux2.6.xx+ARM9
来源:互联网 发布:出售一审淘宝店铺 编辑:程序博客网 时间:2024/05/21 10:35
/* iic-dev: at24c02 256bytes(2k bits)
* From 2013-01-31 To 2013-02-02
*/
----------------------------------------------------------driver---------------------------------------------------------------
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
//begin
#include <linux/fs.h>
//error: variable `at24c02_operations' has initializer but incomplete type
//end
//begin
//czat24c02_iicdev: Unknown symbol copy_from_user
#include <asm/uaccess.h>
//end
static unsigned short ignore[] = { I2C_CLIENT_END };
static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
static int major;
static struct class *at24c02_cls;
static struct class_device *at24c02_cls_dev;
static struct i2c_client *new_client;
static struct i2c_client_address_data addr_data = {
.normal_i2c = normal_addr,
.probe = ignore,
.ignore = ignore,
};
static struct bin_attribute at24c02_attr = {
.attr = {
.name = "at24c02",
.mode = S_IRUGO,
.owner = THIS_MODULE,
},
//.size = EEPROM_SIZE,
//.read = eeprom_read,
};
static int czat24c02_attach_adapter(struct i2c_adapter *adapter);
static int czat24c02_detach_client(struct i2c_client *client);
static struct i2c_driver at24c02_driver = {
.driver = {
.name = "at24c02",
},
//.id = I2C_DRIVERID_EEPROM,
.attach_adapter = czat24c02_attach_adapter,
.detach_client = czat24c02_detach_client,
};
static ssize_t czat24c02_read (struct file *file, char __user *buffer, size_t size, loff_t *ppos)
{
printk("driver: czat24c02_read in ok\n");
if (size != 1)
printk("driver: czat24c02_read size != 1\n");
struct i2c_msg msg[2];
unsigned char val; //val[1]:addr for reading
unsigned char data;
copy_from_user(&val, buffer, 1);//get the addr for reading
printk("driver: czat24c02_read copy_from_user ok\n");
msg[0].addr = 0x50; //at24c02 address
msg[0].buf = &val;
msg[0].len = 1;
msg[0].flags = 0; //write addr
msg[1].addr = 0x50; //at24c02 address
msg[1].buf = &data;//get the data
msg[1].len = 1;
msg[1].flags = I2C_M_RD; //read addr
if((i2c_transfer(new_client->adapter, msg, 2))==2)
{
printk("driver: czat24c02_read i2c_transfer=2 ok\n");
copy_to_user(buffer,&data,1);//tell app what we got
printk("driver: czat24c02_read copy_to_user ok\n");
return 0;
}
printk("driver: czat24c02_read i2c_transfer !!!!=2\n");
return -EIO;
}
static int czat24c02_write (struct file *file, const char __user *buffer, size_t size, loff_t *ppos)
{
printk("driver: czat24c02_write in ok\n");
struct i2c_msg msg[1];
unsigned char val[2]; //val[1]:addr for writing, val[2]:data for writing
copy_from_user(val, buffer, 2);
printk("driver: czat24c02_write addr:%d, data:%d\n",val[0],val[1]);
msg[0].addr = 0x50; //at24c02 address
msg[0].buf = val;
msg[0].len = 2;
msg[0].flags = 0; //write msg
i2c_transfer(new_client->adapter, msg, 1);
return 0;
}
static int czat24c02_open(struct inode *inode, struct file *file)
{
printk("driver: czat24c02_open in ok\n");
return 0;
}
static struct file_operations at24c02_operations = {
.owner = THIS_MODULE,
.open = czat24c02_open,
.read = czat24c02_read,
.write = czat24c02_write,
};
static int czat24c02_detect(struct i2c_adapter *adapter, int address, int kind)
{
printk("driver: czat24c02_detect in ok\n");
i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
| I2C_FUNC_SMBUS_BYTE);
new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &at24c02_driver;
new_client->flags = 0;
strlcpy(new_client->name, "at24c02", I2C_NAME_SIZE);
i2c_attach_client(new_client);
sysfs_create_bin_file(&new_client->dev.kobj, &at24c02_attr);
major = register_chrdev(0, "at24c02", &at24c02_operations);
at24c02_cls = class_create(THIS_MODULE, "at24c02_cls");
at24c02_cls_dev = class_device_create(at24c02_cls, NULL, MKDEV(major,0), NULL, "at24c02_cls_dev");
return 0;
}
static int czat24c02_detach_client(struct i2c_client *client)
{
printk("driver: czat24c02_detach_client in ok\n");
int err;
sysfs_remove_bin_file(&client->dev.kobj, &at24c02_attr);
err = i2c_detach_client(client);
if (err)
return err;
kfree(i2c_get_clientdata(client));
class_device_destroy(at24c02_cls, MKDEV(major,0));
class_destroy(at24c02_cls);
unregister_chrdev(major, "at24c02");
return 0;
}
static int czat24c02_attach_adapter(struct i2c_adapter *adapter)
{
printk("driver: czat24c02_attach_adapter in ok\n");
return i2c_probe(adapter, &addr_data, czat24c02_detect);
}
static int __init czat24c02_init(void)
{
printk("driver: czat24c02_init in ok\n");
i2c_add_driver(&at24c02_driver);
return 0;
}
static void __exit czat24c02_exit(void)
{
printk("driver: czat24c02_exit in ok\n");
i2c_del_driver(&at24c02_driver);
}
module_init(czat24c02_init);
module_exit(czat24c02_exit);
MODULE_AUTHOR("chaozang(cz) <zangchao.cn@gmail.com>,copy frm my teacher:weidongshan,thanks so much!");
MODULE_LICENSE("GPL");
----------------------------------------------------test app----------------------------------------------------------
/*
* read: at24c02 addr
* write: at24c02 addr data
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
void print_usage(char *file)
{
printf(" read: %s addr\n",file);
printf("write: %s addr data\n",file);
}
//char *argv[ ] == char **argv
int main(int argc, char **argv)
{
int fd;
unsigned char buffer[2];
if((argc != 2)&&(argc != 3))
print_usage(argv[0]);
fd = open("/dev/at24c02_cls_dev",O_RDWR);
if (fd < 0)
{
printf("can't open /dev/at24c02_cls_dev\n");
return -1;
}
//if (strcmp(argv[1], "r") == 0)
if(argc == 2)
{
printf("app: argc == 2\n");
buffer[0] = strtoul(argv[1], NULL, 0);
printf("app: buffer[0] is %d\n",buffer[0]);
read(fd, buffer, 1);
printf("app: read result is:%d\n",buffer[0]);
//begin
//printf("app: read result is:%s\n",buffer[0]);
//Segmentation fault
//end
}
else if(argc == 3)
{
buffer[0] = strtoul(argv[1], NULL, 0);
buffer[1] = strtoul(argv[2], NULL, 0);
write(fd, buffer, 2);
}
else
{
print_usage(argv[0]);
return -1;
}
return 0;
}
-----------------------------------------------------------
Contact: zangchao.cn@gmail.com
- IIC Device(At24c02) Driver for Linux2.6.xx+ARM9
- LCD Driver for Linux2.6.xx+ARM9
- LCD Driver Test for Linux2.6.xx+ARM9
- Touch Screen Driver for Linux2.6.xx+ARM9
- DMA Test Driver for Linux2.6.xx+ARM9
- Sound Card(UDA1341) Driver for Linux2.6.xx+ARM9
- AT24C02 IIC读写
- TWI(IIC)使用范例AT24C02
- IIC总线操作AT24C02芯片
- linux2.6.28和linux2.6.3xx内核 的struct device 中,bus_id的改变
- ARM9的IIC
- linux2.6.xx内核代码分析
- linux2.6.xx内核代码分析
- Char Device Driver Example for Kernel 2.6
- Power Management interface for Solaris device driver
- Device Driver Development for Beginners - Reloaded
- AT24C02的Stm32模拟读写IIC程序
- IIC总线时序(结合AT24C02)
- Linux基础
- 【设计模式】2. 观察者模式
- jQuery使用load函数访问Struts2中的Action实现局部刷新和注册事件
- 熊猫烤鱿鱼
- zookeeper+dubbo+dubbo管理集群的简要配置[单机]
- IIC Device(At24c02) Driver for Linux2.6.xx+ARM9
- 美丽的花蕾灯
- 单向链表(二级指针实现)
- 单链表(一级指针实现)
- 可逆素数
- VB.net数据库编程(08):ADO.net数据访问接口
- 没有对错,你就是标准
- poj 1004 Financial Management(基础题)
- hdu1358