Hi, I am trying to enable the SPI interface in mini2440 board. I followed the link http://members.cox.net/ebrombaugh1/embedded/mini2440/index.html and made changes to my board file accordingly. Now I am trying to connect a GPIO expander via SPI. It is not working. When I insert the module, nothing happens. (I can't even see the print messages that I inserted in the probe function). So, I checked the SPICLK0 pin. It doesn't seem to be active. It always stays low. 1) Should I enable the SPI clock to make it work? If so, which will be the best place to do it? 2) I did a few changes in the file (arch/arm/plat-s3c24xx/s3c2410-clock.c). I moved the clock structure of SPI from init_clocks_disable and to init_clocks. What else should I do to enable the clock? GPIO expander : MAX7301 from Maxim semiconductor Kernel module : max7301.c (in location drivers/gpio/)
Enabling SPI in mini2440
Do similar and it work fine: Check this: http://open-nandra.com/2010/09/friendly-arm-2440-and-sca3000-accelerometer/ marek
Thanks for the link. I followed it and somehow initialized the max7301 driver. But the device doesn't seem to be working. When I checked the SPICLK0 it always stays low. What should I do to enable the SPICLOCK. In which file I should add it?
These are the changes, In file mach-mini2440.c // static void mini2440_spi0_cs(struct s3c2410_spi_info *spi, int cs, int pol) { s3c2410_gpio_setpin(S3C2410_GPG(2), pol); } static struct s3c2410_spi_info mini2440_spi0_platdata = { .num_cs = 1, .bus_num = 0, .set_cs = mini2440_spi0_cs, }; static struct max7301_platform_data max7301_info = { .base = -1, }; /* bus_num must match id in pxa2xx_set_spi_info() call */ static struct spi_board_info mini2440_spi_board_info[] __initdata = { { .modalias = "max7301", .platform_data = &max7301_info, .max_speed_hz = 13000000, .bus_num = 0, .chip_select = 0, .mode = SPI_MODE_0, }, }; In platform_device structure I added this line to enable the SPI device, &s3c_device_spi0, And in the static void __init mini2440_machine_init(void) /* setup SPI0 pins */ s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); s3c2410_gpio_cfgpin(S3C2410_GPG(2), S3C2410_GPIO_OUTPUT); s3c_device_spi0.dev.platform_data = &mini2440_spi0_platdata; spi_register_board_info(mini2440_spi_board_info, ARRAY_SIZE(mini2440_spi_board_info)); printk(KERN_ERR "Setup SPI0\n"); Please let me know If I have missed something. - Neo
Your code doesn't work? Seems good. Try patch in attachment. Don't have HW to test. It's just compile tested. If it wouldn't work will look next week ;). marek
Thanks for the patch. Will test with this. Hoping to solve it this week at least. Also I would like to try with the bit banging driver. If you have any idea on how to use that in mini2440, Please let me know. - Neo
Hello, I would like to use a GPIO expander max 7301. I have made the modifications that are described above, compiled and downloaded the new kernel on my target, but i don't know what to do after that. I would like to write a simple application to toggle a led connected on a pin of my max7301. Thanks for your kindness, i'm completely newbie...
Hello, To add more GPIOs on the mini2440, i would like to use 2 max7301. I started with only one max7301, it works well. Now, i would like to add a second max7301, but i'm a bit confused : if i have well understood, the mini2440_spi_board_info table contains the definition of each SPI slave connected on the bus. Then i only have to add a new element in this table. But where can i define the pin number used for the chip select of the second component ? For the first one, it is in the mini2440_spi0_platdata structure, thanks to a pointer on the mini2440_spi0_cs() function that drives the output, but i don't see where to define the chip select of the second SPI slave... I would be happy if someone takes the time to answer me. domodom
NO you need to do similar for second slave mac7301 chip as here: http://friendlyarm.net/forum/attachment/11539 You need add specific struct same as for mini2440_spi0_pdata. Then extend mini2440_spi_devs for your next device and register platform data. Lemme know if it works. marek
Hello Marek, Thank you very much for your answer. Just to be sure to well understand you, are you suggesting to do that ? (it's a test i made with spidev, but i think it's the same as with mx7301 ): // First SPI slave static struct s3c2410_spi_info mini2440_spi0_platdata = { .num_cs = 1, .bus_num = 0, .pin_cs = S3C2410_GPG(2), .gpio_setup = &s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, }; static struct spi_board_info mini2440_spi_board_info[] __initdata = { { .modalias = "spidev", .max_speed_hz = 13000000, .bus_num = 0, .chip_select = 0, .mode = SPI_MODE_0, }, }; // Second SPI slave static struct s3c2410_spi_info mini2440_spi0_platdata2 = { .num_cs = 1, .bus_num = 0, .pin_cs = S3C2410_GPG(0), .gpio_setup = &s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, }; static struct spi_board_info mini2440_spi_board_info2[] __initdata = { { .modalias = "spidev", .max_speed_hz = 13000000, .bus_num = 1, .chip_select = 0, .mode = SPI_MODE_0, }, }; In platform_device structure, there are 2 lines : &s3c_device_spi0, &s3c_device_spi1, And in the static void __init mini2440_machine_init(void) /* setup SPI0 pins */ s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0); s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0); s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0); // first SPI driver instance s3c2410_gpio_cfgpin(S3C2410_GPG(2), S3C2410_GPIO_OUTPUT); s3c_device_spi0.dev.platform_data = &mini2440_spi0_platdata; spi_register_board_info(mini2440_spi_board_info, ARRAY_SIZE(mini2440_spi_board_info)); // Second SPI driver instance s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPIO_OUTPUT); s3c_device_spi0.dev.platform_data = &mini2440_spi0_platdata2; spi_register_board_info(mini2440_spi_board_info2, ARRAY_SIZE(mini2440_spi_board_info2)); The idea is to declare 2 SPI drivers with a SPI slave for each one. The ls /dev command returns : spidev0.0 spidev0.1 What i wanted to do was to have spidev0.0 and spidev0.1. It's possible with the following code : static struct s3c2410_spi_info mini2440_spi0_platdata = { .num_cs = 2, .bus_num = 0, .pin_cs = S3C2410_GPG(2), .gpio_setup = &s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, }; static struct spi_board_info mini2440_spi_board_info[] __initdata = { { .modalias = "spidev", .max_speed_hz = 13000000, .bus_num = 0, .chip_select = 0, .mode = SPI_MODE_0, }, { .modalias = "spidev", .max_speed_hz = 13000000, .bus_num = 0, .chip_select = 1, .mode = SPI_MODE_0, }, }; The rest stay the same as in the post of Neo. With this configuration, the command ls /dev returns : spidev0.0 spidev0.1 It should be possible, BUT in this configuration, i have the same Chip_select for the both SPI slaves !! I don't understand why it is not possible to have this configuration... Whatever, i will use your solution. If i not abuse, a last question : with 2 drivers declared for the same physical bus, what mecanism prevents 2 threads to access the bus at the same time ? Thanks you very much for your help domodom
I have found a solution ! In the mini2440_spi0_platdata structure, there are 2 ways to declare the chip_select : - the new one, with pin_cs, that is the pin number of the chip_select signal. - the old one, with the set_cs parameter, that is a pointer on a function called each time the chip_select state must be changed. With the new way, there is no possibility to declare several chip_select signals. But with the old one, it is possible to write a function that drives the good chip_select. The, the source code is : static void mini2440_spi0_cs(struct s3c2410_spi_info *spi, int cs, int pol) { switch(cs): case 0: s3c2410_gpio_setpin(S3C2410_GPF(0), pol); break; case 1: s3c2410_gpio_setpin(S3C2410_GPF(3), pol); break; } static struct s3c2410_spi_info mini2440_spi0_platdata = { .num_cs = 2, // = the number of SPI devices declared in mini2440_spi_board_info .bus_num = 0, .set_cs = mini2440_spi0_cs, .gpio_setup = &s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, }; static struct spi_board_info mini2440_spi_board_info[] __initdata = { { .modalias = "spidev", .max_speed_hz = 13000000, .bus_num = 0, .chip_select = 0, // = the number passed to the mini2440_spi0_cs function .mode = SPI_MODE_0, }, { .modalias = "spidev", .max_speed_hz = 13000000, .bus_num = 0, .chip_select = 1, .mode = SPI_MODE_0, }, }; Best regards domodom
My guess is that it would be possible. One issue is how much time it will take. Have you any kernel driver experience? I took a different route, after trying to do something similar, and that was to control a ATmega32U4 via USB. See Teensy and Adafruit for dev boards and software. Also the Odroid platforms have a add-on board using a PIC
No davef, I don't have a kernel driver experience. I need to connect a PIC micro to mini2440 over SPI. can you pls guide me? Is there any step by step approach what exactly has to be done to enable SPI from mini24440 and how? In my case, mini will work as the master. Thanks in advance
Meher, Read through this thread http://www.friendlyarm.net/forum/topic/4801 I think it summarises my SPI experience. This should get the mini2440 enabled as a SPI master. I know there are a few steps to set up the AVR ATmega series as a SPI slave so you would have to work out how to do that on the PIC devices. Good luck.
Hi To start with, I am trying to have a kernel experience with the "Hello Module" as described in mini2440 manual. But I am stuck at "make menuconfig" in the linux-2.6.32.2 directory, as I'm not able to change the driver option from "[]" to "<M>". It only takes "[]" and "[*]". can anybody help?
davef in your note for enabling SPI "In the BSP go to: platform-mini2440/build-target/ and make a copy of linux-3.1 and call it linux-3.1.orig." where is this located? I could find linux-2.6.32.2.
There should be a folder called Linux 3.1 Appears to me that you are not looking in the installed Pengutronix mini2440 BSP. If you are, what version of the BSP have you installed? In the latest mini2440 BSP there should be much more recent Linux versions in that folder.
Well the pre-loaded linux will not have SPI enabled. You can either start with your existing kernel version and get setup for cross-compilation on a host computer and try with 2.6.32.2 or if you haven't done any cross-compilation yet go to the Pengutronix webpage and look for instructions on getting setup using their BSP. And then you will find 3.1 and much later versions as well.
Thanks davef can you please guide me what exactly I have to do for the Pengutronix BSP. for your information, I have extracted the linux tar file supplied with CD. and there is a /Bootstrap-v1.11/linux-2.6.32.2/drivers/spi/spi_s3c24xx.c file. Is this the SPI driver?
I think you found it, now all you have to do is hack it. There are some other SPI examples around. Try searching for <buserror SPI> and <eric bromaugh spi mini2440> Pengutronix ... download the QuickStart.pdf guide and download the latest toolchain, PTXdist and mini2440BSP versions and have a go.
I should have said, download the toolchain and PTXdist recommended in the latest QuickStart guide and the latest mini2440BSP
Sorry, I got that wrong. That may the SPI driver file, but the two files that need modifying are in my document: Enabling SPI in the Pengutronix kernel version 3.1 Did you get a copy of that?
Yes I got that doc, As I got confused of linux 3.1 and pengutronix BSP, I asked you about that. So can I do the same changes to this file as well and do the same procedure to compile the existing kernel?
You could try. First I would do a diff on the files in question both in 3.1 and 2.6.32.2 and if the are the same maybe you will get lucky.
Hello Davef whatever "/Bootstrap-v1.11/linux-2.6.32.2/drivers/spi/spi_s3c24xx.c" file I had in linux folder, I have modified according to the instruction in your "Enabling SPI in the Pengutronix kernel version 3.1" document and saved it. But while doing "make", under the linux directory, I get the following error. What is this error? can you please suggest solution? CHK include/linux/version.h make[1]: `include/asm-arm/mach-types.h' is up to date. CHK include/linux/utsrelease.h SYMLINK include/asm -> include/asm-arm CALL scripts/checksyscalls.sh CHK include/linux/compile.h CC [M] drivers/message/fusion/mptscsih.o CC [M] drivers/message/fusion/mptspi.o CC [M] drivers/message/fusion/mptfc.o CC [M] drivers/message/fusion/mptsas.o CC [M] drivers/message/fusion/mptctl.o CC [M] drivers/message/fusion/mptlan.o CC [M] drivers/message/i2o/bus-osm.o CC [M] drivers/message/i2o/config-osm.o CC [M] drivers/message/i2o/iop.o CC [M] drivers/message/i2o/driver.o CC [M] drivers/message/i2o/device.o CC [M] drivers/message/i2o/debug.o CC [M] drivers/message/i2o/pci.o CC [M] drivers/message/i2o/exec-osm.o CC [M] drivers/message/i2o/memory.o LD [M] drivers/message/i2o/i2o_core.o LD [M] drivers/message/i2o/i2o_config.o LD [M] drivers/message/i2o/i2o_bus.o CC [M] drivers/message/i2o/i2o_block.o CC [M] drivers/message/i2o/i2o_scsi.o CC [M] drivers/message/i2o/i2o_proc.o CC drivers/mfd/ezx-pcap.o drivers/mfd/ezx-pcap.c: In function 'pcap_isr_work': drivers/mfd/ezx-pcap.c:213: error: implicit declaration of function 'irq_to_gpio' make[2]: *** [drivers/mfd/ezx-pcap.o] Error 1 make[1]: *** [drivers/mfd] Error 2 make: *** [drivers] Error 2 By the way, I have downloaded the Pengutronix ptxdist and OSELAS toolchain and installed it my PC. But before proceeding further, I just wanted to check if it works with the existing kernel. Please reply.
Just guessing here ... what is ezx-pcap? Have you enabled something else in the provided kernel? I tried searching ezx-cap and it doesn't help much. I first thought it might have something to do with Wireshark or WinPcap or the Linux version of packet capture. > implicit declaration of function is telling you that some .h file is not available to the compiler. Look for a ezx-pcap.h file. Is it there?
http://mirrors.neusoft.edu.cn/rpi-kernel/drivers/mfd/ezx-pcap.c Driver for Motorola PCAP2 as present in EZX phones Huh???
Thanks for your reply, I am trying to make zImage, it gives the following error. LD arch/arm/mach-s3c2400/built-in.o LD arch/arm/mach-s3c2412/built-in.o CC arch/arm/mach-s3c2440/s3c2440.o CC arch/arm/mach-s3c2440/dsc.o CC arch/arm/mach-s3c2440/irq.o CC arch/arm/mach-s3c2440/clock.o CC arch/arm/mach-s3c2440/mach-mini2440.o arch/arm/mach-s3c2440/mach-mini2440.c:79: error: 's3c2410_GPG2' undeclared here (not in a function) arch/arm/mach-s3c2440/mach-mini2440.c:82: error: 's3c24XX_spi_gpiocfg_bus0_gpe11_12_13' undeclared here (not in a function) arch/arm/mach-s3c2440/mach-mini2440.c:87: error: field name not in record or union initializer arch/arm/mach-s3c2440/mach-mini2440.c:87: error: (near initialization for 'mini2440_spi_devs') arch/arm/mach-s3c2440/mach-mini2440.c:87: warning: missing braces around initializer arch/arm/mach-s3c2440/mach-mini2440.c:87: warning: (near initialization for 'mini2440_spi_devs[0]') arch/arm/mach-s3c2440/mach-mini2440.c:88: error: field name not in record or union initializer arch/arm/mach-s3c2440/mach-mini2440.c:88: error: (near initialization for 'mini2440_spi_devs') arch/arm/mach-s3c2440/mach-mini2440.c:89: error: field name not in record or union initializer arch/arm/mach-s3c2440/mach-mini2440.c:89: error: (near initialization for 'mini2440_spi_devs') arch/arm/mach-s3c2440/mach-mini2440.c:89: warning: large integer implicitly truncated to unsigned type arch/arm/mach-s3c2440/mach-mini2440.c:90: error: field name not in record or union initializer arch/arm/mach-s3c2440/mach-mini2440.c:90: error: (near initialization for 'mini2440_spi_devs') arch/arm/mach-s3c2440/mach-mini2440.c: In function 'mini2440_machine_init': arch/arm/mach-s3c2440/mach-mini2440.c:516: error: implicit declaration of function 'Array_SIZE' make[1]: *** [arch/arm/mach-s3c2440/mach-mini2440.o] Error 1 make: *** [arch/arm/mach-s3c2440] Error 2 what is the error?
How did you fix the previous error? Just guessing again ... either there is some major difference between the kernel versions of mach-mini2440.c or you have not modified it correctly. Or some .h file needs modifying. Checking my document I see a last step: ***** From platform-mini2440/build-target/ run: diff -urB linux-3.1.orig linux-3.1 > enable-spidev.diff Manually added header information, changed the number of files changed and the number of insertions. (There must be an option in diff for this!) ***** Suggests to me that you may only succeed when you use the Pengutronix BSP ... with this document.
As described in the attached video for linux-2.6.32.2(Please see that) I have done accordingly. But at the last step while making zImage, the error comes. https://www.youtube.com/watch?v=OzrxEIAHdxo
Watched the video. First thing to understand that he is enabling GPIO and (I think) SPI for the userspace. My document is for enabling SPI in kernel space. So, focusing on the video and your error ... always sort out the first error. > 's3c2410_GPG2' undeclared here (not in a function) This tells you that either the mach-mini2440.c is not including the mach-mini2440.h, the mach-mini2440.h file is not present (usually in the same directory) as the mach-mini2440.c (can you find that?) OR there is an error in the mach-mini2440.h file, ie there is no mention of s3c2410_GPG2. What do you find?
The attached file is the one which I have modified according to your doc and presently using. there is no s3c2410_GPG2.and mach-mini2440.h.
hello davef I have included the 'ezx-pcap.h' file in the same directory where the ezx-pcap.c file belongs i.e. '/home/mou/Downloads/linux-2.6.32.2/drivers/mfd' but still get the error while making zImage. CC drivers/mfd/mfd-core.o CC drivers/mfd/ezx-pcap.o drivers/mfd/ezx-pcap.c:21:28: error: linux/gpio-pxa.h: No such file or directory drivers/mfd/ezx-pcap.c: In function 'pcap_isr_work': drivers/mfd/ezx-pcap.c:214: error: implicit declaration of function 'irq_to_gpio' make[2]: *** [drivers/mfd/ezx-pcap.o] Error 1 make[1]: *** [drivers/mfd] Error 2 make: *** [drivers] Error 2 and the follwing error while 'make' under the linux 2.6.32.2 directory. drivers/input/touchscreen/eeti_ts.c: In function 'eeti_ts_irq_active': drivers/input/touchscreen/eeti_ts.c:64: error: implicit declaration of function 'irq_to_gpio' make[3]: *** [drivers/input/touchscreen/eeti_ts.o] Error 1 make[2]: *** [drivers/input/touchscreen] Error 2 make[1]: *** [drivers/input] Error 2 make: *** [drivers] Error 2 Please suggest.............I'm just stuck here Also attached is the new 'mach-mini2440.c' file I have downloaded . kindly have a look. Is it the correct file to get through with SPI?
Meher, Something has gone wrong with our communications. I am sure I replied to your posting of 2015-05-22. Let's try again. The problem with 's3c2410_GPG2' undeclared here (not in a function) I think a typo might have creep into my document, ie s3c2410_GPG2 became S3C2410_GPG2. s3c2410_GPG2 has to be declared somewhere in an included file. You are right, there is no mach-mini2440.h. For your most problem there are still missing files.