regmap I2C_SMBUS_BLOCK_PROC_CALL 实例
时间: 2023-08-02 07:07:49 浏览: 107
下面是一个使用`regmap I2C_SMBUS_BLOCK_PROC_CALL`函数的实例:
```c
#include <linux/i2c.h>
#include <linux/regmap.h>
/* 假设我们已经获取了一个i2c_client结构体指针,称为client */
/* 定义一个块读处理函数 */
static int my_i2c_block_read(struct i2c_client *client, u8 reg,
u8 *val, u16 len)
{
struct i2c_msg msg[2];
int ret;
/* 发送写命令,以设置寄存器地址 */
msg[0].addr = client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = ®
/* 发送读命令,以获取数据 */
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD | I2C_M_RECV_LEN;
msg[1].len = len;
msg[1].buf = val;
/* 发送I2C消息,执行块读操作 */
ret = i2c_transfer(client->adapter, msg, 2);
if (ret == 2)
ret = 0;
else
ret = (ret < 0) ? ret : -EIO;
return ret;
}
/* 定义一个块写处理函数 */
static int my_i2c_block_write(struct i2c_client *client, u8 reg,
u8 *val, u16 len)
{
struct i2c_msg msg;
u8 *buf;
int ret;
/* 分配一个缓冲区,用于组装要发送的数据 */
buf = kmalloc(len + 1, GFP_KERNEL);
if (!buf)
return -ENOMEM;
/* 将寄存器地址和数据组装到缓冲区中 */
buf[0] = reg;
memcpy(&buf[1], val, len);
/* 发送I2C消息,执行块写操作 */
msg.addr = client->addr;
msg.flags = 0;
msg.len = len + 1;
msg.buf = buf;
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret == 1)
ret = 0;
else
ret = (ret < 0) ? ret : -EIO;
kfree(buf);
return ret;
}
/* 定义一个regmap_config结构体 */
static const struct regmap_config my_regmap_config = {
.name = "my_regmap",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.write = my_i2c_block_write,
.read = my_i2c_block_read,
.cache_type = REGCACHE_NONE,
};
/* 初始化一个regmap结构体 */
static struct regmap *my_regmap_init(struct i2c_client *client)
{
struct regmap *map;
/* 分配一个regmap结构体 */
map = devm_regmap_init_i2c(client, &my_regmap_config);
if (IS_ERR(map)) {
pr_err("Failed to allocate regmap: %ld\n", PTR_ERR(map));
return NULL;
}
return map;
}
/* 在驱动程序中使用regmap */
static int my_driver_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regmap *map;
/* 初始化一个regmap结构体 */
map = my_regmap_init(client);
if (!map)
return -ENODEV;
/* 使用regmap进行读写操作 */
regmap_write(map, 0x10, 0x55);
regmap_read(map, 0x20, &val);
return 0;
}
/* 在驱动程序中使用regmap */
static int my_driver_remove(struct i2c_client *client)
{
/* 在驱动程序卸载时,释放regmap结构体 */
regmap_exit(dev_get_regmap(client, NULL));
return 0;
}
/* 定义一个i2c_driver结构体 */
static const struct i2c_device_id my_driver_id[] = {
{ "my_device", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, my_driver_id);
static struct i2c_driver my_driver = {
.driver = {
.name = "my_driver",
},
.probe = my_driver_probe,
.remove = my_driver_remove,
.id_table = my_driver_id,
};
/* 注册i2c_driver */
module_i2c_driver(my_driver);
```
在上面的代码中,我们定义了两个块处理函数`my_i2c_block_read`和`my_i2c_block_write`,用于在I2C设备上执行块读写操作。然后,我们定义了一个`regmap_config`结构体,在其中指定了`write`和`read`函数为上述定义的块处理函数。接着,我们使用`devm_regmap_init_i2c`函数初始化了一个`regmap`结构体,并在驱动程序中使用`regmap_write`和`regmap_read`函数来进行寄存器读写操作。
注意:这只是一个简单的示例,实际上使用`regmap`需要更多的代码和配置。
阅读全文