I2C总线驱动
//
#define ADXL345_ADDR 0x53
//寄存器地址
#define ADXL345_REG_DEVID 0x00 // Device ID //read data =0xE5
#define ADXL345_REG_BW_RATE 0x2C // Data rate and power mode control
#define ADXL345_REG_POWER_CTL 0x2D // Power-saving features control
#define ADXL345_REG_DATA_FORMAT 0x31 // Data format control
#define ADXL345_REG_DATAX0 0x32 // X-axis data 0
#define ADXL345_REG_DATAX1 0x33 // X-axis data 1
#define ADXL345_REG_DATAY0 0x34 // Y-axis data 0
#define ADXL345_REG_DATAY1 0x35 // Y-axis data 1
#define ADXL345_REG_DATAZ0 0x36 // Z-axis data 0
#define ADXL345_REG_DATAZ1 0x37 // Z-axis data 1
struct adxl345_drvdata{
//set private data
struct i2c_client *client;
struct timer_list timer;//timer
struct work_struct wq;//work queue
};
u8 readbuf[20];
enum adxl345_type {
adxl345,
adxl345a
};
static const unsigned short normal_i2c[] = {
0x2c, 0x2d, 0x2e, I2C_CLIENT_END
};
static const struct i2c_device_id adxl345_id[] = {
{"wbw717_Adx345", adxl345},
{"adxl345a", adxl345a},
{},
};
static const struct of_device_id adxl345_of_match[] = {
{.compatible = "wbw717_Adx345"},
{}
};
static int adxl345_read_regs(struct i2c_client *client,u8 reg,void *val,int len)
{
int ret=0;
struct i2c_msg m[2];
m[0].addr = ADXL345_ADDR;
m[0].flags = 0;
m[0].buf = ®
m[0].len = 1;
m[1].addr = ADXL345_ADDR;
m[1].flags = I2C_M_RD;
m[1].buf = val;
m[1].len = len;
ret = i2c_transfer(client->adapter,m,2);
printk("read res= %d\r\n",ret);
if (ret < 0)
return ret;
else if (ret != ARRAY_SIZE(m))
return -EIO;
return ret;
}
static int adxl345_remove(struct i2c_client *client)
{
int i, err;
printk("adxl345_remove\r\n");
return 0;
}
static int
adxl345_probe(struct i2c_client *client)
{
int ret = 0;
struct adxl345_drvdata *ddata;
printk("%s called\n",__func__);
//malloc memory
ddata = (struct adxl345_drvdata*)kzalloc(sizeof(struct adxl345_drvdata),
GFP_KERNEL);
if(!ddata){
printk(KERN_ERR"failed to malloc for driver data\n");
ret = -ENOMEM;
goto ERR_MALLOC_DRVDATA;
}
ddata->client = client;
//set client as private data for transmit ddata to other functions
i2c_set_clientdata(client,ddata);
adxl345_read_regs(client,ADXL345_REG_DEVID,readbuf,1);
printk("adxl345_probe23==%x\r\n",readbuf[0]);
return 0;
ERR_MALLOC_DRVDATA:
return ret;
return 0;
}
static int adxl345_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
int i, err;
printk("adxl345_detect\r\n");
return 0;
}
static struct i2c_driver adxl345_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adxl345",
.of_match_table = adxl345_of_match,
},
.probe_new = adxl345_probe,
.remove = adxl345_remove,
};
static struct task_struct *key_kthread;
static int adxl345_driver_init(void)
{
int err;
printk("%s %d\r\n", __FILE__, __LINE__);
err = i2c_add_driver(&adxl345_driver);
if (err)
printk("driver error\r\n");
return err;
}
static void adxl345_driver_exit(void)
{
// kthread_stop(key_kthread);
printk("led dirver exit!!!\r\n");
// device_destroy(led_class, MKDEV(major, 0));
// platform_driver_unregister(&led_driver);
// class_destroy(led_class);
i2c_del_driver(&adxl345_driver);
}
module_init(adxl345_driver_init);
module_exit(adxl345_driver_exit);
MODULE_LICENSE("GPL"); //声明模块拥有开源许可
设备树中添加adxl345 节点,挂在到I2C 1 口下.
&i2c0if {
clock-frequency = <100000>;
};
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
clock-frequency = <100000>;
wbw717_Adx345@53 {
compatible = "wbw717_Adx345";
reg = <0x53>;
status = "okay";
};
};
&i2c2 {
clock-frequency = <100000>;
};
硬件接口:
3.3V PWR <>ADXl345 VDD
GND <>ADXl345 GND
I2C1 SDA<>ADXl345 SDA
I2C1 SCL<>ADXl345 SCL