I think you are making this much more difficult than it needs to be.
The standard linux SPI device works fine for talking to any slave
device. What you need to do is to connect one device to CS0 and the
other device to CS1, and then tell the (one) driver to use one or the
other chip select when you open() the slave. If you had two drivers
controlling the same SPI hardware, then you could interleave register
accesses! You don't want to do that. You want each SPI read, write, or
ioctl to access one of your devices in an atomic manner.
If the standard SPI driver you are using does not support anything but
CS0, then you need to add support for the other chip select.
On 10/28/2014 7:16 PM, [email protected] wrote:
On Saturday, October 25, 2014 4:43:02 PM UTC-7, [email protected] wrote:
*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).
|
staticintnrf51822_spi_probe(structspi_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
//
...
return0;
}
staticintnrf51822_spi_remove(structspi_device *spi_device)
{
ERR(KERN_INFO,"Removing SPI protocol driver.");
nrf51822_spi_device =NULL;
// Free memory and close things
}
staticconststructspi_device_id nrf51822_ids[]={
{"nrf51822",},
{},
};
MODULE_DEVICE_TABLE(spi,nrf51822_ids);
staticconststructof_device_id nrf51822_of_ids[]={
{.compatible ="brad,nrf51822",},
{},
};
MODULE_DEVICE_TABLE(of,nrf51822_of_ids);
// Configure SPI
staticstructspi_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 thiscape uses */
exclusive-use =
/*the pin header uses */
/*GPIO */
"P9.16", /*InterruptfromNRF51822 */
/*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.
You don't say where your got the drivers, I couldn't find either in
linux-3.16.1.
Under normal use spi0 will be controlled by spi/spi-omap2-mcspi.c, as
indicated by its inclusion of the compatible entry "ti,omap4-mcspi".
See am33xx.dtsi for the definition of this term.
By using modprobe, etc. you are bypassing this logic.
I believe you may need a master driver that will control the bus, and
slave drivers that can manage each device. They could communicate
using some kind of message passing.
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google
Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.