#include "linux/printk.h"
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/i2c.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
/***************************************************************
文件名 : aht10i2c.c
作者 : 1997AURORA
版本 : V1.0
描述 : aht10 I2C驱动程序
其他 : 无
日志 : 初版V1.0 2021/8/8 1997AURORA创建
***************************************************************/
#define aht10i2c_CNT 1
#define aht10i2c_NAME "aht10i2c"
struct aht10i2c_dev {
dev_t devid; /* 设备号 */
struct cdev cdev; /* cdev */
struct class *class; /* 类 */
struct device *device; /* 设备 */
struct device_node *nd; /* 设备节点 */
int major; /* 主设备号 */
void *private_data; /* 私有数据 */
uint32_t temp, hum; /* 芯片数据 */
};
static struct aht10i2c_dev aht10i2cdev;
/*
* @description : 从aht10i2c读取多个寄存器数据
* @param - dev: aht10i2c设备
* @param - reg: 要读取的寄存器首地址
* @param - val: 读取到的数据
* @param - len: 要读取的数据长度
* @return : 操作结果
*/
static int aht10i2c_read_regs(struct aht10i2c_dev *dev, u8 reg, void *val, int len)
{
int ret;
struct i2c_msg msg[2];
struct i2c_client *client = (struct i2c_client *)dev->private_data;
/* msg[0]为发送要读取的首地址 */
msg[0].addr = client->addr; /* aht10i2c地址 */
msg[0].flags = 0; /* 标记为发送数据 */
msg[0].buf = ® /* 读取的首地址 */
msg[0].len = 1; /* reg长度*/
/* msg[1]读取数据 */
msg[1].addr = client->addr; /* aht10i2c地址 */
msg[1].flags = I2C_M_RD; /* 标记为读取数据*/
msg[1].buf = val; /* 读取数据缓冲区 */
msg[1].len = len; /* 要读取的数据长度*/
ret = i2c_transfer(client->adapter, msg, 2);
if(ret == 2) {
ret = 0;
} else {
printk("i2c rd failed=%d reg=%06x len=%d\n",ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
}
/*
* @description : 向aht10i2c多个寄存器写入数据
* @param - dev: aht10i2c设备
* @param - reg: 要写入的寄存器首地址
* @param - val: 要写入的数据缓冲区
* @param - len: 要写入的数据长度
* @return : 操作结果
*/
static s32 aht10i2c_write_regs(struct aht10i2c_dev *dev, u8 reg, u8 *buf, u8 len)
{
// u8 b[256];
unsigned char *b;
struct i2c_msg msg;
struct i2c_client *client = (struct i2c_client *)dev->private_data;
b = kmalloc( len + 1 ,GFP_KERNEL);
b[0] = reg; /* 寄存器首地址 */
memcpy(&b[1],buf,len); /* 将要写入的数据拷贝到数组b里面 */
msg.addr = client->addr; /* aht10i2c地址 */
msg.flags = 0; /* 标记为写数据 */
msg.buf = b; /* 要写入的数据缓冲区 */
msg.len = len + 1; /* 要写入的数据长度 */
return i2c_transfer(client->adapter, &msg, 1);
}
/*
* @description : 读取aht10i2c指定寄存器值,读取一个寄存器
* @param - dev: aht10i2c设备
* @param - reg: 要读取的寄存器
* @return : 读取到的寄存器值
*/
// static unsigned char aht10i2c_read_reg(struct aht10i2c_dev *dev, u8 reg)
// {
// u8 data = 0;
// aht10i2c_read_regs(dev, reg, &data, 1);
// return data;
// #if 0
// struct i2c_client *client = (struct i2c_client *)dev->private_data;
// return i2c_smbus_read_byte_data(client, reg);
// #endif
// }
/*
* @description : 向aht10i2c指定寄存器写入指定的值,写一个寄存器
* @param - dev: aht10i2c设备
* @param - reg: 要写的寄存器
* @param - data: 要写入的值
* @return : 无
*/
// static void aht10i2c_write_reg(struct aht10i2c_dev *dev, u8 reg, u8 data)
// {
// u8 buf = 0;
// buf = data;
// aht10i2c_write_regs(dev, reg, &buf, 1);
// }
// static void aht10_reset(void) {
// aht10i2c_write_reg(&aht10i2cdev, 0x6B, 0x00);
// }
void JH_Send_BA(struct i2c_client *client)//向AHT10发送BA命令
{
s32 ret;
ret = i2c_smbus_write_byte(client, 0x70);
printk("ret = %d\n", ret);
ret = i2c_smbus_write_byte(client, 0xba);
printk("ret = %d\n", ret);
}
void JH_SendAC(struct i2c_client *client) //向AHT10发送AC命令
{
// s32 ret;
u8 reg;
u8 buf[2];
reg = 0xac;
buf[0] = 0x33;
buf[1] = 0x00;
/* 错误写法,如果写数据这样写就要出错
// ret = i2c_smbus_write_byte(client, 0x70);
// // printk("ret = %d\n", ret);
// ret = i2c_smbus_write_byte(client, 0xac);
// // printk("ret = %d\n", ret);
// ret = i2c_smbus_write_byte(client, 0x33);
// // printk("ret = %d\n", ret);
// ret = i2c_smbus_write_byte(client, 0x00);
*/
aht10i2c_write_regs(&aht10i2cdev, reg, buf, 2);
}
uint8_t JH_Read_Status(struct i2c_client *client)//读取AHT10的状态寄存器
{
s32 ret;
uint8_t Byte_first;
ret = i2c_smbus_write_byte(client, 0x71);
// printk("ret = %d\n", ret);
Byte_first = i2c_smbus_read_byte(client);
/*
// aht10i2c_read_regs(&aht10i2cdev, 0, &Byte_first,1);
如果这样去读数据的话就要出错
*/
// printk("Byte_first = 0x%x\r\n", Byte_first);
return Byte_first;
}
uint8_t JH_Read_Cal_Enable(struct i2c_client *client) //查询cal enable位有没有使能?
{
uint8_t val = 0;//ret = 0,
val = JH_Read_Status(client);
// printk("val = 0x%x\r\n", val);
if((val & 0x08)) //判断NOR模式和校准输出是否有效
return 1;
else return 0;
}
static void aht10_init(struct i2c_client *client) {
s32 ret;
u8 count = 0;
u8 reg;
u8 *buf;
// u8 data[2] = {0};
buf = kmalloc(2, GFP_KERNEL);
msleep(40); // 上电后延时40ms
// printk("aht10_init\r\n");
/*
ret = i2c_smbus_write_byte(client, 0x70);
printk("ret = %d\n", ret);
ret = i2c_smbus_write_byte(client, 0xe1);
printk("ret = %d\n", ret);
ret = i2c_smbus_write_byte(client, 0x08);
printk("ret = %d\n", ret);
ret = i2c_smbus_write_byte(client, 0x00);
printk("ret = %d\n", ret);
经测试这样写也可以
*/
reg = 0xe1;
buf[0] = 0x08;
buf[1] = 0x00;
ret = aht10i2c_write_regs(&aht10i2cdev, reg, buf, 2);
while(JH_Read_Cal_Enable(client)==0)//需要等待状态字status的Bit[3]=1时才去读数据。如果Bit[3]不等于1 ,发软件复位0xBA给AHT10,再重新初始化AHT10,直至Bit[3]=1
{
JH_Send_BA(client); //复位
msleep(100);
// SensorDelay_us(11038);
// ret = i2c_smbus_write_byte(client, 0x70);
// printk("ret = %d\n", ret);
// ret = i2c_smbus_write_byte(client, 0xe1);
// printk("ret = %d\n", ret);
// ret = i2c_smbus_write_byte(client, 0x08);
// printk("ret = %d\n", ret);
// ret = i2c_smbus_write_byte(client, 0x00);
// printk("ret = %d\n", ret);
aht10i2c_write_regs(&aht10i2cdev, reg, buf, 2);
count++;
if(count>=10)
{
printk("有错误\r\n");
}
msleep(500);
}
}
/*
* @description : 读取aht10i2c的数据,读取原始数据
* @param - dev: aht10i2c设备
* @return : 无。
*/
void aht10i2c_readdata(struct i2c_client *client, u8* r_buf)
{
unsigned char i =0;
u8 reg;
reg = 0x71;
JH_SendAC(client);//向AHT10发送AC命令
// msleep(75);
while(((JH_Read_Status(client)&0x80)==0x80))//等待忙状态结束
{
// SensorDelay_us(1508);
if(i++>=100)
{
printk("error\r\n");
break;
}
}
aht10i2c_read_regs(&aht10i2cdev, reg, r_buf, 6);
/*
* // i2c_smbus_write_byte(client, 0x71);
// r_buf[0] = i2c_smbus_read_byte(client);
// r_buf[1] = i2c_smbus_read_byte(client);
// r_buf[2] = i2c_smbus_read_byte(client);
// r_buf[3] = i2c_smbus_read_byte(client);
// r_buf[4] = i2c_smbus_read_byte(client);
// r_buf[5] = i2c_smbus_read_byte(client);
像这种写法的话就只适合去读一个字节的数据,因为这样读出来6个值都是一样的。要读多个字节的话还是要用我们自己写的函数即
aht10i2c_read_regs
*/