Using SPI in a kernel module

Hello,

I’m currently working on a kernel module which needs to communicate via SPI to an external microchip.

I used the cape manager to enable SPI. The device is accessible through /dev/spidev1.0.
But since it’s a kernel module, I guess it’s not recommended to access files via sys_open()?

Another approach I found would be adding a struct to arch/arm/mach-omap2/board-am335xevm.c and then use spi_register_driver() in my kernel module. But in my kernel sources (3.8.13) this file doesn’t exist.

What would be the right way to use SPI in my kernel module?

Regards,
Nils

Hello,

I’m currently working on a kernel module which needs to communicate via SPI to an external microchip.

I used the cape manager to enable SPI. The device is accessible through /dev/spidev1.0.
But since it’s a kernel module, I guess it’s not recommended to access files via sys_open()?

Another approach I found would be adding a struct to arch/arm/mach-omap2/board-am335xevm.c and then use spi_register_driver() in my kernel module. But in my kernel sources (3.8.13) this file doesn’t exist.

There is no board files since the introduction of device tree.

What would be the right way to use SPI in my kernel module?

Look at examples in /drivers/staging/iio or /drivers/iio

There are plenty of examples of using SPI calls in a kernel module.

Use the power of GIT to find what you are looking for. In the Kernel source do the following:

git grep spi_sync_transfer

Regards,
John

Thanks, John.

I Iooked at kernel/drivers/iio/dac/ad/5064.c

There’s the following struct which is passed to spi_register_driver():

`
static struct spi_driver ad5064_spi_driver = {
.driver = {
.name = “ad5064”,
.owner = THIS_MODULE,
},
.probe = ad5064_spi_probe,
.remove = ad5064_spi_remove,
.id_table = ad5064_spi_ids,
};

`

I compiled the module and loaded it but the probe function never gets called. Why?

Thanks, John.

I Iooked at kernel/drivers/iio/dac/ad/5064.c

There’s the following struct which is passed to spi_register_driver():

`
static struct spi_driver ad5064_spi_driver = {
.driver = {
.name = “ad5064”,
.owner = THIS_MODULE,
},
.probe = ad5064_spi_probe,
.remove = ad5064_spi_remove,
.id_table = ad5064_spi_ids,
};

`

I compiled the module and loaded it but the probe function never gets called. Why?

From this I can see that this driver isn’t DeviceTree enabled so I’m not sure which SPI interface it is using. Either you can add the devicetree support to this driver so that you can specify which SPI interface to use, or e-mail the Linux-IIO mailing list and see how to use this driver.

Regards,
John

I'm looking for a replacement for my antique Trixbox Asterisk servers using a BBB solution. One is a home system, the other is a small retail operation. Both in reliable operation since 2008. Run part time by a someone with a long term interest in Linux and communications systems (me).

The distribution http://www.beaglebone-asterisk.org/ is currently my focus. Is there anything I should know about it (good or bad)? Is there anything better for such use?

My occupation is embedded systems, not IT. I'd prefer to have a reasonable GUI to manage the configuration where possible. FreePbx seems to provide that in place of Trixbox. Not that I'm afraid of scripting or re-building kernels, I just have other things to do too.

Thanks!
Artie Lekstutis

Running debian the BBB can run lxde, but it wont be like a current x86 system experience. But for comparison, the BBB has the rPI trumped in all but graphics.

When I insmod ifx6x60.ko, its probe method isn’t called either. Is there anything else I have to do?

In case anyone else is interested in running an Asterisk server on the BBB I've found that http://www.beaglebone-asterisk.org performs fairly well. Even better than on one of my older x86 systems. After doing some testing I'm ready for an initial deployment. Looks like it should be able to handle at least 6 simultaneous calls, which is more than I'll ever need. I'll post updates if I find anything interesting (good or bad).

It's running on a 64G micro-SD card:
     Ubuntu 14.04 LTS
     Asterisk 11.8.0
     FreePBX 2.11.0.35

Later,
Artie

Hello,
I saw your publish question about using SPI in a kernel module. I kind of stucking in this problem as well.
So i wonder if you find a solution?

I know it’s too late to ask, but i hope i’m lucky to get some feedback from you.

Regards,
Cheng

It would be helpful if you explained what it is you are trying to do and then we will provide suggestions on how to proceed.

Regards,
John

Hello,

Thanks for replying firstly.

Actully, i am using beaglebone black with debian to developpe a system, which needs at least 72 I/Os (36 outputs, and 36 inputs for interruptions). So i use SPI and I/O expanders to controls the 36 outputs so that i have enough GPIOs for Inputs. I am writing an kernel module for the 36 interrupt inputs.

Now, my SPI is working in User-Space by using /dev/spidev1.0, but i want to integrate the SPI inside my kernel module as well. I wonder if it is possible?
Because i want to measure the time between output and input (input signal is from a sensor). Since SPI is in user-space, so the output is not always sent in time, sometimes it has 4 or 5 ms delay, which it’s a big deal to me.

Thanks,

Regards,

Cheng

OK, you have several options on how to implement this. First, look in drivers/iio or drivers/staging/iio for example drivers that use SPI. If you use the RT kernel, you will see latency of less than 1mS, but if this isn’t good enough, then I recommend using the PRU to program the McSPI. For examples of how to program the McSPI natively, look at Starterware for example code. If you look on Github, the Starterware examples have been ported to the PRU.

Regards,
John

OK, you have several options on how to implement this. First, look in drivers/iio or drivers/staging/iio for example drivers that use SPI. If you use the RT kernel, you will see latency of less than 1mS, but if this isn’t good enough, then I recommend using the PRU to program the McSPI. For examples of how to program the McSPI natively, look at Starterware for example code. If you look on Github, the Starterware examples have been ported to the PRU.

OK, you have several options on how to implement this. First, look in drivers/iio or drivers/staging/iio for example drivers that use SPI. If you use the RT kernel, you will see latency of less than 1mS, but if this isn’t good enough, then I recommend using the PRU to program the McSPI. For examples of how to program the McSPI natively, look at Starterware for example code. If you look on Github, the Starterware examples have been ported to the PRU.

Regards,
John

/dev/mem/ + mmap() is always going to have more latency than kernel module because kernel code is executed at a higher priority that user space app.

Regards,
John

Hi John,

i try to drive the BBB McSPI with using the Pru.
Maybe you can help me to find your tip:“If you look on Github, the Starterware examples have been ported to the PRU”.
Lot of thanks

Regards
Peter

I have the very same problem. If you google around, you find sometimes some factoids, and that is usually stuff like (SOC_SPI_0_REGS, chNum); (SOC_SPI_0_REGS, (chNum) | (chNum)); (SOC_SPI_0_REGS, chNum); Abstraction & insight gained == 0. Just repetition. This all floats in the middle of nowhere. Guess where the header files are or where some values hit some registers. If you search on, you end up at a frozen Wiki or a locked discussion thread. It seems, TI has given up on the Sitara. Maybe it is time to move on to Zynq. regards, Gerhard

I just did a quick search on Github for Starterware and found this:

https://github.com/kiran4399/starterware_PRU

From what I read, TI are no longer maintaining Starterware, but there is a community driven development on Sourceforge:

https://sourceforge.net/projects/starterwarefree/

Great!

Thank you very much.

Best wishes

Peter.

BTW, you mentioned moving to Zynq, but that processor is more expensive than the complete BBB. Zynq eval boards or kits are even more expensive, not to mention the cost of tools, etc. One other problem is the learning curve is very steep if you want to take advantage of the FPGA features. Anyway, the applications for Zynq and BBB are completely different. I know, because I have looked at the possibility of using Zynq over the years and each time, I have given it a pass.

I’m currently using PSOC6 (CortexM4 and CortexM0) for some of my projects (no Linux, using FreeRTOS) and it has a Verilog programmable frontend, which is much easier to learn.

Regards,
John