SietseAchterop
Posts: 13
Joined: Fri Mar 06, 2020 12:39 pm

compatible string to use in platform driver

Wed Mar 25, 2020 12:09 pm

Hello list,

I created an add on board for the rpi-zero-w with contains a spi adc and dac and a few gpio's.
The PCB description and the software is available at
https://github.com/SietseAchterop/Batradio

They work properly using a user space program: batradio_module/spiadc.c.

I now try to create an out-of-tree kernel module.
Eventually it will hopefully be using the system timer #1 with fiq to create realtime data collection, hopfully to up to a sample rate of 500kHz.

My question is about the platform driver I created.
The very simple driver can be found in batradio_module/tst5.c

The problem is that the probe-function is not called.
I assume that is because I do not connect to the correct dtb. I currently use:

Code: Select all

static const struct of_device_id bat_of_match[] = {
	{ .compatible = "brcm,bcm2835" },
	{}
};
One question is, what is a proper value for compatible to get a call to the probe function?
As long as I am not trying to use spi of gpio, I thought that this should work.

Also, do I have to create a custom dts for this?
If so, can it be a simple overlay to an existing one? Which one?

And finally, how to I add it to the system? Is it as simple copying it to /boot on the target?
I would hope that all can be done out-of-tree, just like the rest of the module.

Many thanks in advance,
Sietse

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2656
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: compatible string to use in platform driver

Wed Mar 25, 2020 12:24 pm

The name "compatible" can be confusing. The purpose is to give the hardware (usually) a name, optionally with a list of other bits of hardware that it is compatible with at a software level. It should go without saying that every type of hardware should either have a unique "compatible" string or be compatible with another piece of hardware that does have a unique "compatible" string - if not, there will probably be no way to match a driver to your device.

The list of "compatible" strings in a driver says which types of hardware it supports - not which platforms it can run on. Drivers for common devices like real time clocks, temperature and pressure sensors, audio codecs etc. can be run on hundreds of different platforms if configured correctly, but they probably only have a small number of "compatible" strings.

Your device's "compatible" string should be made up from a string to identify the vendor of the hardware and one for the device itself, say "mycorp,batradio".

As for the overlay - help me out and describe the hardware:
* How is it connected to the Pi?
* Does it contain any common devices that already have drivers?

SietseAchterop
Posts: 13
Joined: Fri Mar 06, 2020 12:39 pm

Re: compatible string to use in platform driver

Thu Mar 26, 2020 3:42 pm

Thanks for the informative reply!
From the software site my "hat" is not much more than an spi device connected to the spi0 channel on the header.
It is a microchip mcp33131, a 16 bit adc with 1Msps data rate.
I control it directly using reads/writes to/from memory, no function used whatsoever.
See the spiadc.c example used in user space.
So the driver only uses "internal" calculations that leave data in memory that can be accessed from user space via a mmap.

So I probably need some "dummy" dtb, because I need no information, I only want to create a platform driver.
Or should this be done without the device tree? Like before the existence of the device tree?

For completeness here my complete attempt at a platform driver, all standard.

Thanks again,
Sietse

Code: Select all

#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>

static int my_probe(struct platform_device *pdev)
{
pr_info("funcion %s() called\n", __func__);
return 0;
}

static int my_remove(struct platform_device *pdev)
{
pr_info("function %s() called\n", __func__);
return 0;
}

static const struct of_device_id my_of_id_table[] =
  {
   { .compatible = "brcm,bcm2835-i2s" },
   { }
  };

MODULE_DEVICE_TABLE(of, my_of_id_table);

static struct platform_driver my_driver =
  {
   .driver = {
	      .name = "batradio",
	      .of_match_table = my_of_id_table,
	      },
   .probe = my_probe,
   .remove = my_remove,
  };

module_platform_driver(my_driver);

MODULE_DESCRIPTION("Test platform driver");
MODULE_AUTHOR("Sietse Achterop");

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2656
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: compatible string to use in platform driver

Thu Mar 26, 2020 4:34 pm

Oh - you've done it like that. Linux drivers should use the Linux SPI subsystem. I suggest you look at https://github.com/raspberrypi/linux/bl ... /mcp3422.c for an example driver for a very similar device. Or ask MicroChip for their Linux driver.

SietseAchterop
Posts: 13
Joined: Fri Mar 06, 2020 12:39 pm

Re: compatible string to use in platform driver

Thu Mar 26, 2020 5:26 pm

Thanks for the quick reply.
Using that driver is not an option regrettably, I have looked at it.
My goal is to get a sample rate of 500KHz. I also cannot use DMA because of the CS-pulse the mcp33131 needs.
The only option is that everything is done in a very short interrupt routine that will not be interfered by though Linux.
This can be done using the so called FIQ, a non-interruptable interrupt. This leaves the data behind in memory that can
be accessed via mmap from user space.
Then an interrupt rate of 1Mhz is feasible.
When this interrput is running, Linux has nothing to do with it, it only consumes cpu cycles. In a way we have a single very simple
hard real time process in (or under) the regular linux. In this case, on a rpi-zero, about 50% of the cpu cycles are used by the fiq,
but that leaves the rest to Linux. We then effectively have a 500 MHz rpi-zero with Linux, which is still a capable device!

I want to control this using a platform driver, but it actually is not a real driver, it only configures the proper working of the fiq interrupt.
Turning the fiq on or off and setting the mmap for data collection.
So hence my question, how to write a platform driver that does actually nothing with hardware.

Hopefully this is a bit more clear.
Sietse

PhilE
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 2656
Joined: Mon Sep 29, 2014 1:07 pm
Location: Cambridge

Re: compatible string to use in platform driver

Thu Mar 26, 2020 5:33 pm

You want a 500KHz sampling rate of a 16-bit ADC over SPI? That's running the SPI bus at (probably quite a bit) over 8MHz, which sounds ambitious.

SietseAchterop
Posts: 13
Joined: Fri Mar 06, 2020 12:39 pm

Re: compatible string to use in platform driver

Thu Mar 26, 2020 10:23 pm

You're right! I gave myself quite a challenge :)
But it should be possible, the user space program works at 700 kHz, most of it busy waiting.
Last edited by SietseAchterop on Fri Mar 27, 2020 10:59 am, edited 1 time in total.

SietseAchterop
Posts: 13
Joined: Fri Mar 06, 2020 12:39 pm

Re: compatible string to use in platform driver

Fri Mar 27, 2020 10:53 am

I found a solution!
Instead of using the device tree I could use

Code: Select all

platform_device_register_simple
This function yields a platform_device structure that I needed in some calls.
Now I can do the init stuff in the init-routine of the module.
Thanks for your attention, Sietse

Return to “Device Tree”