regmap_read val 指针的类型应该是什么

问题描述 投票:0回答:1

我正在尝试使用 regmap api 来访问 I2C 设备,但完全不清楚 val 指针的预期类型是什么。

Cfr : int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)

我看到的两个选项是(恕我直言,两者都很糟糕):

[1] 它实际上应该是一个指向 unsigned int 类型的指针,并且在读取它时必须使用中间变量。由于您不知道位大小和 unsigned int 类型是什么,因此您永远无法确定它是否能容纳 32 位。

[2] 它应该是一个指向与您在 regmap_config 中传入 val_bits 的内容相对应的类型的指针(并且您必须错误地将该指针重新转换为 API 期望的类型以使其可编译)。

该文档根本没有帮助(惊讶):

/**
...
* @val: Pointer to store read value
...
*/

类似https://patchwork.kernel.org/patch/9378201/之类的东西似乎表明它是[1], 但我看到其他驱动程序,我认为这些驱动程序可以做[2],例如:

static inline int
ar1335_read_reg(struct ar1335_info *info, u16 addr, u16 *val)
{
    return regmap_read(info->regmap, addr, (unsigned int *) val);
}

https://github.com/Bogdacutu/STLinux-Kernel/blob/master/drivers/media/platform/tegra/ar1335.c

如果我尝试遵循实际上分配给读取的功能(我认为,这是完整的抽象和更多抽象),我想我最终会得到

static int regmap_i2c_read(void *context,
                       const void *reg, size_t reg_size,
                       void *val, size_t val_size)
{
    struct device *dev = context;
    struct i2c_client *i2c = to_i2c_client(dev);
    struct i2c_msg xfer[2];
    int ret;

    xfer[0].addr = i2c->addr;
    xfer[0].flags = 0;
    xfer[0].len = reg_size;
    xfer[0].buf = (void *)reg;

    xfer[1].addr = i2c->addr;
    xfer[1].flags = I2C_M_RD;
    xfer[1].len = val_size;
    xfer[1].buf = val;

    ret = i2c_transfer(i2c->adapter, xfer, 2);
    if (ret == 2)
            return 0;
    else if (ret < 0)
            return ret;
    else
            return -EIO;
}

这表明它必须是指向真实数据类型的指针,例如 u16 * 如果 val_bits = 16。

有人有任何见解吗? 如果是 [2] 为什么不使用 void * 指针来避免像 i2c 读取中那样的丑陋的强制转换?历史混乱?

谢谢,

布拉姆

c linux-kernel linux-device-driver
1个回答
0
投票

根据AR1335寄存器参考

,AR1335上的所有寄存器都是16位,又名uint16
© www.soinside.com 2019 - 2024. All rights reserved.