Background
I have a Beagle Bone Black cape with both a Nordic nRF51822 and TI CC2520. Both of these devices are on the SPI0 bus. I have kernel drivers that work for each separately on Debian 3.8.13.
Goal
I would like to be able to load both kernel drivers at the same time and have them share the SPI bus.
Issue
While I have figured out how to make each kernel driver take control of the SPI0 bus when loaded separately, I can’t seem to get them to each have access when loaded together. I’m far from an expert on device tree overlays and am not sure how to glue everything together so that the kernel drives are successfully loaded.
Here is my code so far in the kernel driver that pertains to creating the SPI device for the nRF51822. I create a struct spi_driver with config information and then call module_spi_driver() to init, etc. (copied from /linux/drivers/net/ieee802154/cc2520.c). The probe() function callback sets up a character device and configures some GPIOs (that code needs to be updated to work with device tree, but for now it should be fine).
`
static int nrf51822_spi_probe(struct spi_device *spi_device)
{
ERR(KERN_INFO, “Inserting SPI protocol driver.\n”);
nrf51822_spi_device = spi_device;
//
// Create a buffer to move data over the character device
//
…
//
// Setup the interrupt from the nRF51822
//
…
//
// Configure the character device in /dev
//
…
return 0;
}
static int nrf51822_spi_remove(struct spi_device *spi_device)
{
ERR(KERN_INFO, “Removing SPI protocol driver.”);
nrf51822_spi_device = NULL;
// Free memory and close things
}
static const struct spi_device_id nrf51822_ids = {
{“nrf51822”, },
{},
};
MODULE_DEVICE_TABLE(spi, nrf51822_ids);
static const struct of_device_id nrf51822_of_ids = {
{.compatible = “brad,nrf51822”, },
{},
};
MODULE_DEVICE_TABLE(of, nrf51822_of_ids);
// Configure SPI
static struct spi_driver nrf51822_spi_driver = {
.driver = {
.name = nrf51822_name,
.owner = THIS_MODULE,
.bus = &spi_bus_type,
.of_match_table = of_match_ptr(nrf51822_of_ids),
},
.id_table = nrf51822_ids,
.probe = nrf51822_spi_probe,
.remove = nrf51822_spi_remove,
};
// This I believe will load this driver correctly
// and cause it to be probed when it is needed.
module_spi_driver(nrf51822_spi_driver);
MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
`
And here is my attempt at a device overlay. I’m only claiming a single GPIO which I use as an interrupt from the nRF51822 back to the beagle bone.
`
/dts-v1/;
/plugin/;
/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;
/* identification */
part-number = “BB-BONE-NRF51822”;
version = “00A0”;
/* state the resources this cape uses /
exclusive-use =
/ the pin header uses */
/* GPIO /
“P9.16”, / Interrupt from NRF51822 */
/* the hardware ip uses */
“gpio1_19”;
fragment@0 {
target = <&am33xx_pinmux>;
overlay {
bb_cc2520_gpio_pins: pinmux_bb_2520_gpio_pins {
compatible = “nrf51822”;
pinctrl-single,pins = <
/* GPIO /
0x04C 0x2F / ehrpwm1b.gpio1_19, INPUT | MODE7 */
;
};
};
};
fragment@1 {
target = <&ocp>;
overlay {
nrf51822 {
compatible = “brad,nrf51822”;
/* the power control gpio */
interrupt-gpio = <&gpio1 19 0x0>;
/* the muxing */
pinctrl-names = “default”;
pinctrl-0 = <&nrf51822_pins>;
};
};
};
};
`
The end effect is that my probe() function in the kernel driver is never called, even after loading the overlay and kernel module.
How do I set things up so that two kernel modules can both use SPI0? Has anyone tried this? Everything I’ve looked at appears to assume only one device is attached to the SPI bus so it can specify the SPI pins in its .dts file (but I could be wrong about that).
Thanks for any help or direction.