I2C adaption layer driver for libbsd (was: Re: rtems-libbsd build error)

Christian Mauderer list at c-mauderer.de
Mon Apr 22 19:09:48 UTC 2019


Am 22.04.19 um 20:57 schrieb Vijay Kumar Banerjee:
> 
> 
> 
> On Sun, Apr 21, 2019 at 12:08 AM Christian Mauderer <list at c-mauderer.de
> <mailto:list at c-mauderer.de>> wrote:
> 
>     Am 18.04.19 um 21:11 schrieb Vijay Kumar Banerjee:
>     >
>     >
>     > On Thu, Apr 18, 2019 at 12:39 AM Christian Mauderer
>     <list at c-mauderer.de <mailto:list at c-mauderer.de>
>     > <mailto:list at c-mauderer.de <mailto:list at c-mauderer.de>>> wrote:
>     >
>     >     First: Please note that I changed the toppic. The old one just
>     didn't
>     >     represent the content any more.
>     >
>     >     Am 17.04.19 um 20:40 schrieb Vijay Kumar Banerjee:
>     >     [...]
>     >     >     >     >
>     >     >     >     >     Am 09.04.19 um 18:12 schrieb Vijay Kumar
>     Banerjee:
>     >     >     >     >     > Hi,
>     >     >     >     >     >
>     >     >     >     >     > I have imported and ported the the drivers
>     in 2
>     >     >     pairs(import
>     >     >     >     and port)
>     >     >     >     >     > of commits 
>     >     >     >     >     > for each one. Please have a look at this
>     branch 
>     >     >     >     >     >
>     >     >     https://github.com/thelunatic/rtems-libbsd/commits/tda19988
>     >     >     >     >
>     >     >     >     >     One detail: You have a commit named "tda19988.c:
>     >     import from
>     >     >     >     FreeBSD".
>     >     >     >     >     Please remove the ".c".
>     >     >     >     >
>     >     >     >     > Noted. 
>     >     >     >     >
>     >     >     >     >     Maybe it would be a good idea to split of
>     the I2C part
>     >     >     and put
>     >     >     >     it in
>     >     >     >     >     front of the other two parts. You can
>     develop and
>     >     test that
>     >     >     >     independent
>     >     >     >     >     with a test that just accesses some of the
>     I2C devices
>     >     >     on the
>     >     >     >     board via
>     >     >     >     >     the FreeBSD API and the translation driver
>     >     discussed below.
>     >     >     >     >
>     >     >     >     > This is a good idea, I'll import iicbus
>     separately and add
>     >     >     the other 
>     >     >     >     > two on top of it.  
>     >     >     >     >
>     >     >     >     >     >
>     >     >     >     >     > I have also tried running the media01.exe and
>     >     have seen it
>     >     >     >     running
>     >     >     >     >     fine
>     >     >     >     >     > without
>     >     >     >     >     > throwing any exceptions.
>     >     >     >     >     >
>     >     >     >     >     > I have used the fb.c and iicbus.c codes
>     from the
>     >     >     >     freebsd source. From
>     >     >     >     >     > what I 
>     >     >     >     >     > understand, I think the next big steps
>     would be to
>     >     >     write an
>     >     >     >     RTEMS 
>     >     >     >     >     > implementation layer for these portions of
>     the code?
>     >     >     And then a
>     >     >     >     >     test in the 
>     >     >     >     >     > libbsd, like media01, to write to the
>     /dev/fb0 
>     >     >     >     >     >
>     >     >     >     >     > Can you please help me chalk out a rough
>     outline of
>     >     >     the next
>     >     >     >     set of
>     >     >     >     >     > actions? :)
>     >     >     >     >
>     >     >     >     >     As far as I can tell, there are two possible I2C
>     >     buses here:
>     >     >     >     >
>     >     >     >     >     1. The one between the AM335x and the TDA19988.
>     >     >     >     >
>     >     >     >     >     2. The one directly on the HDMI connector
>     (called
>     >     >     HDMI_DSCL and
>     >     >     >     >     HDMI_DSDA). I assume that's an I2C bus too.
>     >     >     >     >
>     >     >     >     >     For 1. the RTEMS driver should be used. You'll
>     >     need some
>     >     >     code that
>     >     >     >     >     translates the FreeBSD API to the one used
>     in RTEMS.
>     >     >     Basically
>     >     >     >     that will
>     >     >     >     >     just be a FreeBSD-I2C-driver.
>     >     >     >     >
>     >     >     >     >     For 2: If that even is an independent I2C
>     bus, you can
>     >     >     use the
>     >     >     >     driver
>     >     >     >     >     provided by FreeBSD. I don't think that it is
>     >     necessary to
>     >     >     >     translate to
>     >     >     >     >     the RTEMS API here.
>     >     >     >     >
>     >     >     >     > I had a look at the iic and iicbus codes in freebsd
>     >     and the
>     >     >     bbb-i2c.c
>     >     >     >     > This looks very confusing to me. Are we looking for
>     >     >     something like a
>     >     >     >     > rtems-iicbus.c in the rtemsbsd that works like a
>     >     wrapper to the
>     >     >     >     bbb-i2c
>     >     >     >     > code, and uses the freebsd api of DEVMETHODs?
>     >     >     >
>     >     >     >     Yes correct. Basically it would be necessary to
>     have a I2C
>     >     >     device driver
>     >     >     >     for FreeBSD that translates to the RTEMS API.
>     >     >     >
>     >     >     >     >
>     >     >     >     > I've not been able to figure out at one look, how to
>     >     relate
>     >     >     them and 
>     >     >     >     > get a wrapper like that. Any suggestions on how to
>     >     approach
>     >     >     this?
>     >     >     >
>     >     >     >     I haven't had a look at the FreeBSD drivers yet.
>     The first
>     >     >     part that I
>     >     >     >     would have a look at is the description of the
>     user facing
>     >     >     FreeBSD API:
>     >     >     >
>     >     >     >   
>     >     >   
>     >   
>        https://www.freebsd.org/cgi/man.cgi?query=iic&apropos=0&sektion=0&manpath=FreeBSD+12.0-RELEASE+and+Ports&arch=default&format=html
>     >     >     >
>     >     >     >     Nice thing: They use a struct iic_msg that is
>     compatible
>     >     with
>     >     >     Linux's
>     >     >     >     struct i2c_msg (according to the man page). We are
>     Linux
>     >     >     compatible too.
>     >     >     >     Can be a big advantage.
>     >     >     >
>     >     >     >     Then take a look at the simplest i2c driver that
>     you can
>     >     find
>     >     >     in FreeBSD
>     >     >     >     that uses the transfer API.
>     >     >     >     freebsd-org/sys/dev/drm2/radeon/atombios_i2c.c looks
>     >     good to me.
>     >     >     >     Basically you have to implement the following
>     functions
>     >     (replace
>     >     >     >     radeon_atom... by a useful prefix):
>     >     >     >
>     >     >     >     static device_method_t
>     radeon_atom_hw_i2c_methods[] = {
>     >     >     >             DEVMETHOD(device_probe,       
>     >      radeon_atom_hw_i2c_probe),
>     >     >     >             DEVMETHOD(device_attach,       
>     >     >     radeon_atom_hw_i2c_attach),
>     >     >     >             DEVMETHOD(device_detach,       
>     >     >     radeon_atom_hw_i2c_detach),
>     >     >     >             DEVMETHOD(iicbus_reset,       
>     >      radeon_atom_hw_i2c_reset),
>     >     >     >             DEVMETHOD(iicbus_transfer,     
>     >     radeon_atom_hw_i2c_xfer),
>     >     >     >             DEVMETHOD_END
>     >     >     >     };
>     >     >     >
>     >     >     >     The iicbus_transfer function seems to get a struct
>     >     iic_msg as a
>     >     >     >     parameter. Now that's really lucky.
>     >     >     >
>     >     >     >     With that you should be able to open the i2c
>     device in RTEMS
>     >     >     and just
>     >     >     >     pass the structure via the correct ioctl call to the
>     >     RTEMS driver.
>     >     >     >
>     >     >     >     Basically you just have to pass the bus to use as a
>     >     parameter
>     >     >     to the
>     >     >     >     driver. Take a look at some of the other drivers in
>     >     >     nexus-devices.h that
>     >     >     >     have for example an address as a parameter to see how
>     >     you can
>     >     >     do that.
>     >     >     >
>     >     >     > This gave a good idea of the objective. :)
>     >     >     >
>     >     >     > I had a look at the  bbb-i2c.c code and how it's
>     registering
>     >     >     > and setting up the i2c_bus struct with the transfer,
>     set and
>     >     destroy
>     >     >     > fucntions. 
>     >     >     > I have a question from the fundamentals, the only function
>     >     >     > of bbb-i2c.c
>     >     >     >
>     >   
>      <https://git.rtems.org/rtems/tree/bsps/arm/beagle/i2c/bbb-i2c.c#n414>
>     >     >     > that is 'accessible' with the header file is
>     >     am335x_i2c_bus_register
>     >     >     > which basically sets the i2c_bus struct
>     >     >     > and calls the i2c_bus_register function from the
>     dev/i2c.c .
>     >     >     > To use the DEVMETHOD api, we need to be able to call the 
>     >     >     > transfer, destroy etc. functions of the bbb-i2c.c from the
>     >     translation
>     >     >     > layer in rtemsbsd. How do I #include the bbb-i2c.c in
>     the new 
>     >     >     > translation driver that I'll write?
>     >     >     >
>     >     >     > Hope my question is stated clearly, please correct me
>     if I'm
>     >     getting
>     >     >     > some fundamentals wrong.
>     >     >
>     >     >     You are not fundamentally wrong but slightly off:
>     >     >
>     >     >     Regarding the question how you access transfer, destroy, ...
>     >     of the
>     >     >     driver directly: Don't.
>     >     >
>     >     >     You basically don't need to have a look at the bbb-i2c.c
>     file
>     >     of RTEMS
>     >     >     for that driver. Where you should have a look is the
>     Linux I2C API
>     >     >     (which has been the model for the RTEMS API).
>     >     >
>     >     >     Basically your drivers transfer function will do about the
>     >     following:
>     >     >
>     >     >     - Open "/dev/i2c0" (or some other path - that will be a
>     >     parameter to the
>     >     >     driver and has to be stored by probe or attach in some
>     device
>     >     >     structure).
>     >     >
>     >     >     - Translate the "struct iic_msg" you get as an input to
>     a "struct
>     >     >     i2c_msg". Most likely that's just a cast.
>     >     >
>     >     >     - Pass that via an ioctl call to the opened bus.
>     >     >
>     >     >     - Check return value and translate to the matching return of
>     >     FreeBSD.
>     >     >
>     >     >     - Close "/dev/i2c0"
>     >     >
>     >     >     Some of the open / close might could move to attach /
>     detach.
>     >     But that
>     >     >     would be an optimization.
>     >     >
>     >     >     That driver will work on any BSP that implements the current
>     >     i2c API. So
>     >     >     it's a generic translation layer.
>     >     >
>     >     >     Best regards
>     >     >
>     >     >     Christian
>     >     >
>     >     > Hi!
>     >     >
>     >     > I started writing the driver layer implementation in the
>     rtemsbsd, is
>     >     > this going in the right
>     >     > direction
>     >     >
>     >   
>      <https://gist.github.com/thelunatic/2d8a2bf2cbead5bf82abe09000afea56> ?
>     >
>     >     Yes. That's the direction I had in mind.
>     >
>     >     Regarding that part:
>     >
>     >         //XXX: Open /dev/iic0
>     >         strcpy(addr, "/dev/");
>     >         strcat(addr, device_get_nameunit(dev));
>     >
>     >     Sooner or later that should be received via a parameter. I
>     just had a
>     >     look at nexus-devices.h: It seems that there is currently only
>     support
>     >     for two kinds of "parameters": memory resources and interrupts.
>     >
>     >     What would be necessary would be more of a string parameter
>     like they
>     >     are available via the device tree interface. This kind of
>     parameters is
>     >     normally retrieved in the driver with the OF_getprop_alloc()
>     function.
>     >
>     >     Problem is: The driver you currently write isn't one that is
>     normally
>     >     put into a device tree file. So some other source for the string
>     >     parameter is necessary. I'll have to have a more detailed look
>     at how
>     >     the parameter could get into the driver in the next few days.
>     >
>     >     I would suggest to start with a fixed string for now. Assume
>     that it
>     >     will somehow appear in the attach function (that would be the
>     location
>     >     where such parameters would be parsed most of the time).
>     >
>     > Hi,
>     > I have updated the gist a bit, to use a macro for the path for
>     now, and
>     > also added
>     > the probe and destroy function. This looks like a better outline
>     now, I
>     > haven't written
>     > the attach function, you can have a detailed look at it and
>     suggest ways
>     > to parse the
>     > path in the attach.
> 
>     Regarding the path: Like already mentioned, I think the best solution
>     would be to get that via the open firmware "OF_getprop*" interface.
>     Currently the only subsystem implementing this is the FDT interface. So
>     a way to get the information into FDT is necessary.
> 
>     I think the best one would be to use a FDT overlay. The function for
>     applying a overlay isn't implemented in RTEMS yet. But luckily U-Boot
>     can do that for us. Please have a look at
> 
>         https://github.com/u-boot/u-boot/blob/master/doc/README.fdt-overlays
> 
>     That solution isn't optimal because it needs some extra U-Boot calls.
>     But It's the best that I have found on a short notice.
> 
>     I could think of two alternative solutions:
> 
>     1. Add some possibility to RTEMS libbsd to allow giving a string
>     parameter to a driver.
> 
>     2. Just instantiate one instance for each RTEMS i2c.
> 
>     The first one is more effort than using U-Boot.
> 
>     The second one could be an alternative.
> 
>     To get the LCD controller driver to use the i2c adaption driver, it will
>     be necessary to modify the FDT anyway. So using an overlay to do that
>     might is the cleanest solution.
> 
> Hi,
> 
> From what I understood looking at the man pages, we want to add a
> property to
> the FDT and from our adaptation layer, call OF_getprop to get that value
> (path)
> and then use that in our program. 

Correct.

> 
> How to add this overlay to the FDT? Is there some other app using the
> FDT overlays
> that I can use as a reference? 

No and yes. I don't know of a RTEMS application that uses overlays. The
RTEMS fdt part doesn't even support them (also there is an interface for
it). But U-Boot can apply one for us. You should be able to find a lot
of guides on the internet. For example:

    https://irq5.io/2018/07/24/boot-time-device-tree-overlays-with-u-boot/

You will have to find the U-Boot commands and add them to the U-Boot
boot line.

> 
> Also, we have ofw_iicbus.c in the freebsd source tree, how do we make
> use of that? 

Quite possible that it is necessary to import it so that the i2c section
of the FDT is parsed correctly. But I'm not entirely sure.

Have you ever written or at least have a look at device tree files? If
not please take a look at the ones in FreeBSD that are relevant for BBB.
That's ./freebsd-org/sys/gnu/dts/arm/am335x-boneblack.dts and the ones
included by it.

Especially take a look at am33xx.dtsi. There are some i2c sections.
These define the i2c controllers. We need something similar for a
controller compatible with "rtems,bsp-i2c" (or some better name if you
have one).

Beneath that you can take a look at for example
am335x-boneblack-common.dtsi. In the i2c section there, the tda19988 is
connected to the i2c controller.

> 
>     >
>     >     >  
>     >     >
>     >     >     >
>     >     >     >     >
>     >     >     >     > Can we not totally use the iicbus in the freebsd
>     source?
>     >     >     >
>     >     >     >     We already have a I2C driver for that BSP in
>     RTEMS. If you
>     >     >     would use the
>     >     >     >     FreeBSD code, they would fight for the hardware. Of
>     >     course it
>     >     >     would be
>     >     >     >     possible to replace the RTEMS driver by a FreeBSD
>     one. But
>     >     >     that would
>     >     >     >     potentially break some applications. Besides that I
>     >     think that
>     >     >     a lot of
>     >     >     >     RTEMS BSPs already have an I2C driver so a generic
>     wrapper
>     >     >     could be
>     >     >     >     helpful for other BSPs too.
>     >     >     >
>     >     >     >     >
>     >     >     >     >     >
>     >     >     >     >     > Thanks
>     >     >     >     >     >
>     >     [...]
>     >
> 



More information about the devel mailing list