On 26/01/2025 16:40, Nathan Hartman wrote:
On Sun, Jan 26, 2025 at 11:01 AM Stewart charnell <nu...@charnell.plus.com>
wrote:
Hello,
I have been working with a ina260 (digital current and power monitor via
ADC) sensor module (I2C interface). I created a device driver based on
the ina226 device. I have found some errors in the ina226 (and ina219)
drivers, and intend to feed back the changes (once I work out how to
generate a pull request), but had some questions on how these drivers
operate.
The ina226 device driver performs I2C write cycles to the ina226 device
configuration register during device 'initialization' and 'open'
routines, which call the driver ina226_write16 routine which in turn
calls the ina226_access routine. The ina226_access routine is not
correct for I2C register writes. I have produced a modified version for
the ina260 which correctly performs i2c register writes.
If I want to change device configuration within user routines (I want to
start and stop the ADC conversions to time them to other events) I only
have access via the driver ina260_write routine (based on the
ina226_write routine)?
I have modified the ina260_write driver routine (the ina226_write driver
just returned -ENOSYS) to perform writes to the ina260 configuration
register but had some general questions on how device driver write and
read operations work. For the ina226 device the driver ina226_read
routine perform specific operations (read the device shunt, bus, and
power registers) rather than generic device register reads. Is this
typical? In turn my ina260_write driver routine writes to the device
configuration register, rather than performing a generic device register
write. I appreciate any changes to the ina226/ina260 device driver write
or read operations could break existing user code, so I wouldn't be able
to include my modified version of the ina219_write, ina226_write (or
ina260_write) driver routine in any pull request?
Kind regards
Stewart Charnell
Hi Stewart,
Please note that device drivers are split to upper half and lower half
parts.
The upper half offers generic interfaces to applications while the lower
half provides register-level implementation details to the upper half.
Also, the same upper half could offer access to many similar devices, while
the lower half would normally be for each specific hardware peripheral.
Configuration register settings would usually be done through ioctl()
instead of read() and write(). You can look to other drivers that provide
an ioctl() implementation for inspiration.
Normally user-level application code would call some incantation of ioctl()
to query or modify settings, and would use read() and/or write() to read or
write the primary information that the device offers.
I recommend to look at the upper half ADC driver to see how it works, and
if you have settings that aren't compatible with other ADC drivers already
in the system, the ioctl() interface allows you to define new codes and
data structs, without affecting other drivers in incompatible ways.
Hope this helps,
Nathan
Hi Nathan,
I had forgotten about ioctl(), I'll take a look.
Kind regards
Stewart
ioctl()