Issues with SPI kernel driver for PSX controllers
by Katemonster from LinuxQuestions.org on (#4RF6E)
Hi all.
I'm writing a module for talking to PSX/PS2 controllers. The code is here: https://github.com/katemonster33/psxpad_spi_ex
The way I'm intending it to work is, approximately every 16 ms it should do this:
1. Pull chip enable 0 low
2. Wait 100 us
3. Send a byte to SPI
4. Wait for an "acknowledge" GPIO to go low
5. Wait ~6 us
6. Repeat 3 and 4 for the remaining controller data
7. Repeat 1-6 for controller 2(chip enable 1)
To this end I've implemented a timer. During every tick it performs the steps above. However I get lots of kernel errors, it constantly says "BUG: scheduling while atomic". The stack trace shows the function where I attempt to transmit the SPI bytes.
So I didnt completely write this from scratch, I used the code from here as a base: http://domisan.sakura.ne.jp/article/psxpad/psxpad.html
His code is a bit different, he uses a polled input device, which must work better for SPI. I didnt think I could use that though, I'm intending my driver to dynamically register and unregister input devices as controllers are plugged in and unplugged. Plus, I am implementing multitap support so there could be up to 8 controllers.
Does anyone have ideas for a better method of implementing the periodic SPI transfers I need? The time between polls can vary, 10 to 25 ms is probably fine, as long as there is no noticeable delay. However, within the SPI transfer code the timing has to be extremely precise. For instance, the "acknowledge" pin only goes low for 1-2 ms, if I miss that window the driver stops working. Any wisdom would be greatly appreciated!


I'm writing a module for talking to PSX/PS2 controllers. The code is here: https://github.com/katemonster33/psxpad_spi_ex
The way I'm intending it to work is, approximately every 16 ms it should do this:
1. Pull chip enable 0 low
2. Wait 100 us
3. Send a byte to SPI
4. Wait for an "acknowledge" GPIO to go low
5. Wait ~6 us
6. Repeat 3 and 4 for the remaining controller data
7. Repeat 1-6 for controller 2(chip enable 1)
To this end I've implemented a timer. During every tick it performs the steps above. However I get lots of kernel errors, it constantly says "BUG: scheduling while atomic". The stack trace shows the function where I attempt to transmit the SPI bytes.
So I didnt completely write this from scratch, I used the code from here as a base: http://domisan.sakura.ne.jp/article/psxpad/psxpad.html
His code is a bit different, he uses a polled input device, which must work better for SPI. I didnt think I could use that though, I'm intending my driver to dynamically register and unregister input devices as controllers are plugged in and unplugged. Plus, I am implementing multitap support so there could be up to 8 controllers.
Does anyone have ideas for a better method of implementing the periodic SPI transfers I need? The time between polls can vary, 10 to 25 ms is probably fine, as long as there is no noticeable delay. However, within the SPI transfer code the timing has to be extremely precise. For instance, the "acknowledge" pin only goes low for 1-2 ms, if I miss that window the driver stops working. Any wisdom would be greatly appreciated!