问题描述
Linux内核中有regmap API,可以轻松访问基于寄存器的设备。
我的设备(内核本身当前不支持ADC)是基于命令的(这意味着您发送了一个命令,例如0x04
以开始ADC转换),并且您得到了答案。 。该设备将通过SPI进行访问并进行了注册。
与设备上的寄存器类似,因此您写0x2Y
,其中Y
是要读取的寄存器,接下来的8位是该寄存器的值,或{{1} },您将获得该寄存器的值。
这不再是基于普通寄存器的设备,但是恕我直言,这是regmap API的理想选择,因为寄存器具有字段,这些字段在寄存器本身具有一定的起始位和大小。 regmap API的reg_field
可以帮助您安全,轻松地访问它们,这意味着阅读,更新和编写将不再那么麻烦。
要实现这一目标,我想我只需在regmap_config
struct中提供0x4Y
和.reg_read
回调字段,就可以了,但是由于.reg_write
函数中的this code而无法正常工作。
regmap_init
问题在于,if (!bus) {
map->reg_read = config->reg_read;
map->reg_write = config->reg_write;
map->defer_caching = false;
goto skip_format_initialization;
} else if (!bus->read || !bus->write) {
map->reg_read = _regmap_bus_reg_read;
map->reg_write = _regmap_bus_reg_write;
map->reg_update_bits = bus->reg_update_bits;
map->defer_caching = false;
goto skip_format_initialization;
} else {
map->reg_read = _regmap_bus_read;
map->reg_update_bits = bus->reg_update_bits;
}
是指向spi设备的指针,这意味着将始终使用bus
回调,而不是我提供的_regmap_bus_read
。
实现目标的本质方法是什么,例如使用已提供的总线提供自定义config->reg_read
和reg_read
函数。
一些驱动程序提供了自己的用于读取和写入寄存器的“框架”,但是我想坚持使用普通的regmap API。
在reg_write
调用之后覆盖reg_read
和reg_write
是个好主意吗?它会带来任何不可预见的问题吗?有没有解决方法,或者我看不到什么可以使我的生活更轻松?
解决方法
我在某种程度上解决了问题,但是我仍然不确定这是否是正确的方法。
我现在使用devm_regmap_init_spi(spi,&config)
,而不是使用devm_regmap_init(&spi->dev,NULL,spi,&config)
。
我将NULL
作为bus
参数传递,这意味着map
字段reg_read
和reg_write
将由传递的配置填充。
将spi
之后的NULL
参数作为上下文指针传递给我的reg_read
/ reg_write
函数,因此我可以在其中使用它。如果需要,将其调整为任何其他指针。
(我很高兴听到其他解决方案)