OpenWrt Forum Archive

Topic: ath79: SD-card on SPI-bus

The content of this topic has been archived between 6 Feb 2018 and 18 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

hi

i'm trying gpio mmc mod but card not detected

root@OpenWrt:~# cat /sys/kernel/debug/mmc0/clock
0
root@OpenWrt:~# cat /sys/kernel/debug/mmc0/ios
clock:        0 Hz
vdd:        0 (invalid)
bus mode:    2 (push-pull)
chip select:    1 (active high)
power mode:    0 (off)
bus width:    0 (1 bits)
timing spec:    0 (legacy)
signal voltage:    1 (3.30 V)

looks like problem with clock and power, 3.3V taken from spi flash pin is it enough?

update: gpio debug

 gpio-1   (spi_cs              ) out lo    
 gpio-6   (sw1                 ) in  hi    
 gpio-7   (sw2                 ) in  lo    
 gpio-11  (reset               ) in  lo    
 gpio-14  (spi_mosi            ) out hi    
 gpio-16  (spi_clock           ) out lo    
 gpio-17  (spi_miso            ) in  hi    
 gpio-18  (USB power           ) out hi    
 gpio-27  (tp-link:blue:system ) out hi   

(Last edited by anarchy99 on 19 Mar 2016, 17:12)

switched clock and miso and got this, but only for 2-3 seconds before it goes back to previously posted state

root@OpenWrt:~# cat /sys/kernel/debug/mmc0/ios
clock:        400000 Hz
vdd:        21 (3.3 ~ 3.4 V)
bus mode:    2 (push-pull)
chip select:    1 (active high)
power mode:    2 (on)
bus width:    0 (1 bits)
timing spec:    0 (legacy)
signal voltage:    1 (3.30 V)

dmesg:

[ 8167.810000] gpio-mmc: MMC-Card "default" attached to GPIO pins di=14, do=16, clk=17, cs=1
[ 8167.820000] mmc_spi spi32759.0: no support for card's volts
[ 8167.830000] mmc0: error -22 whilst initialising SDIO card
[ 8167.840000] mmc_spi spi32759.0: no support for card's volts
[ 8167.840000] mmc0: error -22 whilst initialising SD card
[ 8167.850000] mmc_spi spi32759.0: no support for card's volts
[ 8167.850000] mmc0: error -22 whilst initialising MMC card

Hi, I've been trying to rig up the deep mmc mod for dir-601 a1 ( ar7240, mx25l3205d spi flash ) using pins 8 (miso)15 (mosi) and 16 (clock) on flash and cs on wps led ( for internal cs on gpio0 ) or button, with no additional components other than a microsd card with sd adapter soldered to those pins. With that kernel mod ( trying to get extroot on card ) I get a freeze up at boot just as all leds light up. Serial console shows nothing, no uboot at that point and with the card out of the adapter it boots normally.

Anybody have any luck with this router? I have ordered an arduino style card reader module so that should eliminate any question of signal problems with pull up resistors etc, although spi is supposed to work anyhow. I feel like it's a short somewhere.

(Last edited by lobonse on 7 Jan 2017, 23:14)

lobonse wrote:

... With that kernel mod ( trying to get extroot on card ) I get a freeze up at boot just as all leds light up. Serial console shows nothing, no uboot at that point and with the card out of the adapter it boots normally.

Anybody have any luck with this router?...

I have same problem with kernel integration of necessary modules(i used "make kernel_menuconfig"), but I had this problem only if i used fresh trunk.
Try to use Chaos Calmer branch.

Write please if you success.

Interesting, I am using Barrier Breaker. So CC sysupgrades no problem? I'd be worried about it being too large for 4mb. I am waiting for those arduino-style sd card adapters to see if they will help. if not, I'll definitely try the CC sysupgrade, thanks!

Chaos Calmer installed, now to wait a few weeks for the sd card adapter..

Hi again, I've got the new sd card adapter wired in. I have tried building chaos calmer with the WPS button, LAN4 LED and now the WAN AMBER LED ( which doesn't use active low I guess ) as CS gpio. Both the sd card and the adapter were tested and work. The following is with the card in the adapter; when it's out the router boots fine.

I seem to be stuck on this one problem. From the serial console:

[    2.210000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
[    2.210000] TCP: cubic registered
[    2.220000] NET: Registered protocol family 17
[    2.220000] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[    2.230000] 8021q: 802.1Q VLAN Support v1.8
[    2.250000] jffs2: Flash size not aligned to erasesize, reducing to 2368KiB
[    2.270000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c0054: 0xffff instead
[    2.290000] jffs2: Empty flash at 0x000c0058 ends at 0x000c5074
[    2.290000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c5074: 0xf8ff instead
[    2.310000] jffs2: Empty flash at 0x000c5078 ends at 0x000c51b4
[    2.310000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c51b4: 0xffff instead
[    2.330000] jffs2: Empty flash at 0x000c51b8 ends at 0x000c51d4
[    2.330000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c51d4: 0xffff instead
[    2.340000] jffs2: Empty flash at 0x000c51d8 ends at 0x000c51f4
[    2.350000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c51f4: 0xffff instead
[    2.360000] jffs2: Empty flash at 0x000c51f8 ends at 0x000c5214
[    2.370000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c5214: 0xffff instead
[    2.380000] jffs2: Empty flash at 0x000c5218 ends at 0x000c5234
[    2.390000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c5234: 0xffff instead
[    2.400000] jffs2: Empty flash at 0x000c5238 ends at 0x000c5254
[    2.410000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c5254: 0xffff instead
[    2.420000] jffs2: Empty flash at 0x000c5258 ends at 0x000c5274
[    2.430000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c5274: 0xffff instead
[    2.440000] jffs2: Empty flash at 0x000c5278 ends at 0x000c5294
[    2.450000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000c5294: 0xffff instead
[    2.460000] jffs2: Further such events for this erase block will not be printed
[    2.470000] jffs2: Empty flash at 0x000c5298 ends at 0x000c52b4
[    2.470000] jffs2: Empty flash at 0x000c52b8 ends at 0x000c52d4
[    2.480000] jffs2: Empty flash at 0x000c52d8 ends at 0x000c52f4
[    2.490000] jffs2: Empty flash at 0x000c52f8 ends at 0x000c5314
[    2.500000] jffs2: Empty flash at 0x000c5318 ends at 0x000c5334
[    2.510000] jffs2: Empty flash at 0x000c5338 ends at 0x000c5354
[    2.520000] jffs2: Empty flash at 0x000c5358 ends at 0x000c5374
[    2.530000] jffs2: Empty flash at 0x000c5378 ends at 0x000c5394
[    2.540000] jffs2: Empty flash at 0x000c5398 ends at 0x000c53b4
[    2.540000] jffs2: Empty flash at 0x000c53b8 ends at 0x000c53d4
[    2.550000] jffs2: Empty flash at 0x000c53d8 ends at 0x000c53f4
[    2.560000] jffs2: Empty flash at 0x000c53f8 ends at 0x000c5414
[    2.570000] jffs2: Empty flash at 0x000c5418 ends at 0x000c5434
[    2.580000] jffs2: Empty flash at 0x000c5438 ends at 0x000c5454
[    2.590000] jffs2: Empty flash at 0x000c5458 ends at 0x000c5474
[    2.600000] jffs2: Empty flash at 0x000c5478 ends at 0x000c5494
[    2.600000] jffs2: Empty flash at 0x000c5498 ends at 0x000c54b4
[    2.610000] jffs2: Empty flash at 0x000c54b8 ends at 0x000c54d4
[    2.620000] jffs2: Empty flash at 0x000c54d8 ends at 0x000c54f4
[    2.630000] jffs2: Empty flash at 0x000c54f8 ends at 0x000c5514
[    2.640000] jffs2: Empty flash at 0x000c5518 ends at 0x000c5534
[    2.650000] jffs2: Empty flash at 0x000c5538 ends at 0x000c6554
[    2.660000] jffs2: Empty flash at 0x000c6558 ends at 0x000c65b4
[    2.670000] jffs2: Empty flash at 0x000c65b8 ends at 0x000c6614
[    2.680000] jffs2: Empty flash at 0x000c6618 ends at 0x000c6654
[    2.690000] jffs2: Empty flash at 0x000c6658 ends at 0x000c9674
[    2.700000] jffs2: Empty flash at 0x000c9678 ends at 0x000c97b4
[    2.710000] jffs2: Empty flash at 0x000c97b8 ends at 0x000c98f4
[    2.720000] jffs2: Empty flash at 0x000c98f8 ends at 0x000c9914
[    2.720000] jffs2: Empty flash at 0x000c9918 ends at 0x000c9934
[    2.730000] jffs2: Empty flash at 0x000c9938 ends at 0x000c9954
[    2.740000] jffs2: Empty flash at 0x000c9958 ends at 0x000c9974
[    2.750000] jffs2: Empty flash at 0x000c9978 ends at 0x000c9994
[    2.760000] jffs2: Empty flash at 0x000c9998 ends at 0x000c9ab4
[    2.770000] jffs2: Empty flash at 0x000c9ab8 ends at 0x000c9ad4
[    2.780000] jffs2: Empty flash at 0x000c9ad8 ends at 0x000c9af4
[    2.780000] jffs2: Empty flash at 0x000c9afc ends at 0x000c9b14
[    2.790000] jffs2: Empty flash at 0x000c9b18 ends at 0x000c9b34
[    2.810000] jffs2: Empty flash at 0x000c9b38 ends at 0x000ccb54
[    2.820000] jffs2: Empty flash at 0x000ccb58 ends at 0x000ccb74
[    2.820000] jffs2: Empty flash at 0x000ccb78 ends at 0x000ccb94
[    2.830000] jffs2: Empty flash at 0x000ccb98 ends at 0x000ccbb4
[    2.840000] jffs2: Empty flash at 0x000ccbb8 ends at 0x000ccbd4
[    2.850000] jffs2: Empty flash at 0x000ccbd8 ends at 0x000ccbf4
[    2.860000] jffs2: Empty flash at 0x000ccbf8 ends at 0x000ccc14
[    2.870000] jffs2: Empty flash at 0x000ccc18 ends at 0x000ccc34
[    2.890000] jffs2: Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes
[    2.900000] jffs2: empty_blocks 36, bad_blocks 0, c->nr_blocks 37
[    2.900000] VFS: Cannot open root device "(null)" or unknown-block(31,4): error -5
[    2.910000] Please append a correct "root=" boot option; here are the available partitions:
[    2.920000] 1f00             192 mtdblock0  (driver?)
[    2.920000] 1f01              64 mtdblock1  (driver?)
[    2.930000] 1f02            3712 mtdblock2  (driver?)
[    2.930000] 1f03            1288 mtdblock3  (driver?)
[    2.940000] 1f04            2423 mtdblock4  (driver?)
[    2.940000] 1f05             320 mtdblock5  (driver?)
[    2.950000] 1f06              64 mtdblock6  (driver?)
[    2.950000] 1f07              64 mtdblock7  (driver?)
[    2.960000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,4)
[    2.960000] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,4)

(Last edited by lobonse on 2 Feb 2017, 02:02)

I've also sometimes noticed mmc messages mixed in with the jffs2 messages:

...
[    2.670000] jffs2: Empty flash at 0x00002658 ends at 0x00002694
[    2.690000] mmc0: host does not support reading read-only switch, assuming write-enable
[    2.690000] mmc0: new SDHC card on SPI
[    2.700000] jffs2: Empty flash at 0x00002698 ends at 0x000026b4
[    2.710000] jffs2: Empty flash at 0x000026b8 ends at 0x000026d4
[    2.720000] jffs2: Empty flash at 0x000026d8 ends at 0x00002714
[    2.730000] jffs2: Empty flash at 0x00002718 ends at 0x00002734
[    2.730000] jffs2: Empty flash at 0x00002738 ends at 0x00002774
[    2.740000] mmcblk0: mmc0:0000 SA08G 7.21 GiB
[    2.750000] jffs2: Empty flash at 0x00002778 ends at 0x00002794
[    2.760000] jffs2: Empty flash at 0x00002798 ends at 0x000027d4
[    2.760000] jffs2: Empty flash at 0x000027d8 ends at 0x00002814
[    2.770000] mmcblk0: timed out sending r/w cmd command, card status 0x0
[    2.780000] blk_update_request: I/O error, dev mmcblk0, sector 0
[    2.780000] Buffer I/O error on dev mmcblk0, logical block 0, async page read
[    2.790000] jffs2: Empty flash at 0x00002818 ends at 0x00002834
[    2.800000] jffs2: Empty flash at 0x00002838 ends at 0x00002874
[    2.810000] jffs2: Empty flash at 0x00002878 ends at 0x000028b4
[    2.820000] jffs2: Empty flash at 0x000028b8 ends at 0x000028f4
[    2.820000] jffs2: Empty flash at 0x000028f8 ends at 0x00002934
[    2.830000] mmcblk0: timed out sending r/w cmd command, card status 0x0
[    2.840000] blk_update_request: I/O error, dev mmcblk0, sector 0
[    2.840000] Buffer I/O error on dev mmcblk0, logical block 0, async page read
[    2.850000]  mmcblk0: unable to read partition table
[    2.860000] jffs2: Empty flash at 0x00002938 ends at 0x00002974
...


and on another boot:

[    4.280000] jffs2: Empty flash at 0x000f20d8 ends at 0x000f2114
[    4.290000] mmc0: card never left busy state
[    4.290000] mmc0: error -145 whilst initialising SD card
[    4.300000] jffs2: Empty flash at 0x000f2118 ends at 0x000f2134


So card is being read, but it seems the system is looking for a jffs2 partition to mount root on? I'm guessing it's the CS line confusing the flash..?

(Last edited by lobonse on 2 Feb 2017, 16:40)

Not only CS can confuse flash, also can DI and DO line. MB need pull-up resistors

Here's a picture if it helps. The sd card is an 8gb class 4 from kingston.

https://i.imgur.com/RLveJf1.jpg

The card reader has resistors built in, but I don't know if they are pulling the lines up. The gpio is internal cs1 on gpio0 ( active_low in the code, LED is always on when the sd card access takes place at boot ).

Voltages at boot:

CS: 2.48v, drops to .5v when LED lights
MISO: 1.3v, 3.05v
MOSI: 70mv, 6mv ( ignoring master I guess )
CLK: 200mv, 6mv

That's a rough measurement, I have no idea what they should be, GND to 3v3 is steady at 3.39v

(Last edited by lobonse on 21 Mar 2018, 13:09)

I tried adding one 10k resistor between each line and 3.3v and the only change was as if there was no sd card in the reader. Just this one line:

mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff

(Last edited by lobonse on 3 Feb 2017, 20:21)

I tried adding all three 10k resistors from MISO MOSI and CS to 3.3V, same result, just the one line as above.

Slightly different boot, after the single line from previous post:


[   10.170000] jffs2: jffs2_scan_eraseblock(): Node at 0x0000c448 {0x1985, 0xe002, 0x00200044) has invalid CRC 0xa4ef223e (calculated 0x9ca264de)
[   10.180000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000c44c: 0x0020 instead
[   10.190000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000c450: 0xa4ef instead
[   10.200000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000c488: 0x5aa3 instead
[   10.220000] jffs2: notice: (354) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[   10.230000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab
[   10.250000] block: extroot: not configured
[   10.280000] jffs2: jffs2_scan_eraseblock(): Node at 0x0000c448 {0x1985, 0xe002, 0x00200044) has invalid CRC 0xa4ef223e (calculated 0x9ca264de)
[   10.290000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000c44c: 0x0020 instead
[   10.300000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000c450: 0xa4ef instead
[   10.310000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000c488: 0x5aa3 instead
[   10.330000] jffs2: notice: (351) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[   10.560000] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab

I've also tried ext3, ext4, fat32 and no partition tables. Card is still alive, I also switched the card reader with another identical one. no difference yet.

(Last edited by lobonse on 3 Feb 2017, 21:43)

This time I tried just 10k pullups on CS, MOSI, no MISO:

[    2.470000] mmc0: host does not support reading read-only switch, assuming write-enable
[    2.480000] mmc0: new SDHC card on SPI
[    2.780000] SQUASHFS error: xz decompression failed, data probably corrupt
[    2.790000] SQUASHFS error: squashfs_read_data failed to read block 0x6e
[    2.980000] SQUASHFS error: xz decompression failed, data probably corrupt
[    2.980000] SQUASHFS error: squashfs_read_data failed to read block 0x6e
[    2.990000] mmcblk0: mmc0:0000 SA08G 7.21 GiB
[    3.000000]  mmcblk0: p1
[    3.010000] Starting init: /etc/preinit exists but couldn't execute it (error -5)
[    3.070000] SQUASHFS error: xz decompression failed, data probably corrupt
[    3.080000] SQUASHFS error: squashfs_read_data failed to read block 0x1525c2
[    3.080000] SQUASHFS error: Unable to read fragment cache entry [1525c2]
[    3.090000] SQUASHFS error: Unable to read page, block 1525c2, size 12a68
[    3.100000] SQUASHFS error: Unable to read fragment cache entry [1525c2]
[    3.100000] SQUASHFS error: Unable to read page, block 1525c2, size 12a68
[    3.110000] SQUASHFS error: Unable to read fragment cache entry [1525c2]
[    3.120000] SQUASHFS error: Unable to read page, block 1525c2, size 12a68
[    3.130000] SQUASHFS error: Unable to read fragment cache entry [1525c2]
[    3.130000] SQUASHFS error: Unable to read page, block 1525c2, size 12a68
[    3.140000] Starting init: /sbin/init exists but couldn't execute it (error -5)
[    3.330000] SQUASHFS error: xz decompression failed, data probably corrupt
[    3.340000] SQUASHFS error: squashfs_read_data failed to read block 0x6e
[    3.340000] Starting init: /bin/sh exists but couldn't execute it (error -5)
[    3.350000] Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
[    3.350000] ---[ end Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
[   82.510000] random: nonblocking pool is initialized

Then rebooted:
...
[    2.350000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000024: 0x2000 instead
[    2.360000] jffs2: Further such events for this erase block will not be printed
[    2.370000] jffs2: Empty flash at 0x00000038 ends at 0x00000040
[    2.390000] jffs2: Old JFFS2 bitmask found at 0x00005798
[    2.400000] jffs2: You cannot use older JFFS2 filesystems with newer kernels
[    2.430000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00010000: 0x9ed6 instead
...
[    2.520000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00010024: 0x258e instead
[    2.530000] jffs2: Further such events for this erase block will not be printed
[    2.560000] jffs2: Old JFFS2 bitmask found at 0x00015200
[    2.570000] jffs2: You cannot use older JFFS2 filesystems with newer kernels
[    2.600000] jffs2: jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00020000: 0xe0e2 instead
...plus many more "jffs2 scan_eraseblock" type messages

I'm wondering if the cs line is the problem, would TP29 (GPIO11) which is to the left of SoC be suitable to use? I wonder this because there are no components such as resistors between it and the SoC.

(Last edited by lobonse on 4 Feb 2017, 01:58)

lobonse
You told that you use WPS (GPIO 0) as internal CS.
Do you patch your profile as in this instruction "Second way, using Internal CS1"?
i.e. do you add this line:

    /* Enabling internal CS1, disable GPIO 0 */
    ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);

to "static void __init dir_600_a1_setup(void)" function?

(Last edited by Deoptim on 4 Feb 2017, 15:02)

Deoptim wrote:

lobonse

i.e. do you add this line:

    /* Enabling internal CS1, disable GPIO 0 */
    ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);

to "static void __init dir_600_a1_setup(void)" function?

Yes, I followed the deep mmc mod. Here's the file mach-dir-600-a1.c:

/*
 *  D-Link DIR-600 rev. A1 board support
 *
 *  Copyright (C) 2010-2012 Gabor Juhos <juhosg@openwrt.org>
 *  Copyright (C) 2012 Vadim Girlin <vadimgirlin@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 */

#include <linux/mmc/host.h>
#include <linux/spi/spi.h>
#include <linux/spi/mmc_spi.h>

#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>

#include "common.h"
#include "dev-ap9x-pci.h"
#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
#include "dev-m25p80.h"
#include "machtypes.h"
#include "nvram.h"

#define DIR_600_A1_GPIO_LED_WPS            0
#define DIR_600_A1_GPIO_LED_POWER_AMBER        1
#define DIR_600_A1_GPIO_LED_POWER_GREEN        6
#define DIR_600_A1_GPIO_LED_LAN1        13
#define DIR_600_A1_GPIO_LED_LAN2        14
#define DIR_600_A1_GPIO_LED_LAN3        15
#define DIR_600_A1_GPIO_LED_LAN4        16
#define DIR_600_A1_GPIO_LED_WAN_AMBER        7
#define DIR_600_A1_GPIO_LED_WAN_GREEN        17

#define DIR_600_A1_GPIO_BTN_RESET        8
#define DIR_600_A1_GPIO_BTN_WPS            12

#define DIR_600_A1_KEYS_POLL_INTERVAL        20    /* msecs */
#define DIR_600_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_600_A1_KEYS_POLL_INTERVAL)

#define DIR_600_A1_NVRAM_ADDR    0x1f030000
#define DIR_600_A1_NVRAM_SIZE    0x10000

static struct gpio_led dir_600_a1_leds_gpio[] __initdata = {
    {
        .name        = "d-link:green:power",
        .gpio        = DIR_600_A1_GPIO_LED_POWER_GREEN,
    }, {
        .name        = "d-link:amber:power",
        .gpio        = DIR_600_A1_GPIO_LED_POWER_AMBER,
    }, {
        .name        = "d-link:amber:wan",
        .gpio        = DIR_600_A1_GPIO_LED_WAN_AMBER,
    }, {
        .name        = "d-link:green:wan",
        .gpio        = DIR_600_A1_GPIO_LED_WAN_GREEN,
        .active_low    = 1,
    }, {
        .name        = "d-link:green:lan1",
        .gpio        = DIR_600_A1_GPIO_LED_LAN1,
        .active_low    = 1,
    }, {
        .name        = "d-link:green:lan2",
        .gpio        = DIR_600_A1_GPIO_LED_LAN2,
        .active_low    = 1,
    }, {
        .name        = "d-link:green:lan3",
        .gpio        = DIR_600_A1_GPIO_LED_LAN3,
        .active_low    = 1,
    }, {
        .name        = "d-link:green:lan4",
        .gpio        = DIR_600_A1_GPIO_LED_LAN4,
        .active_low    = 1,
    }, {
        .name        = "d-link:blue:wps",
        .gpio        = DIR_600_A1_GPIO_LED_WPS,
        .active_low    = 1,
    }
};

static struct gpio_keys_button dir_600_a1_gpio_keys[] __initdata = {
    {
        .desc        = "reset",
        .type        = EV_KEY,
        .code        = KEY_RESTART,
        .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL,
        .gpio        = DIR_600_A1_GPIO_BTN_RESET,
        .active_low    = 1,
    }, {
        .desc        = "wps",
        .type        = EV_KEY,
        .code        = KEY_WPS_BUTTON,
        .debounce_interval = DIR_600_A1_KEYS_DEBOUNCE_INTERVAL,
        .gpio        = DIR_600_A1_GPIO_BTN_WPS,
        .active_low    = 1,
    }
};

static struct mmc_spi_platform_data ath79_mmc_data = {
//    .detect_delay = 100, /* msecs */
    .ocr_mask    = MMC_VDD_32_33 | MMC_VDD_33_34,
};

static struct ath79_spi_controller_data ath79_spi1_cdata = {
//    .cs_type = ATH79_SPI_CS_TYPE_GPIO,
    .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
    .cs_line = 1,
//    .cs_line = DIR_600_A1_GPIO_CS1_MMC,
};

static struct spi_board_info ath79_spi_info[] = {
    {
        .bus_num    = 0,
        .chip_select    = 1,
        .max_speed_hz    = 25000000,
        .modalias    = "mmc_spi",
        .platform_data    = &ath79_mmc_data,
        .controller_data = &ath79_spi1_cdata,
    }
};

static void __init dir_600_a1_setup(void)
{
    const char *nvram = (char *) KSEG1ADDR(DIR_600_A1_NVRAM_ADDR);
    u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
    u8 mac_buff[6];
    u8 *mac = NULL;

    if (ath79_nvram_parse_mac_addr(nvram, DIR_600_A1_NVRAM_SIZE,
                       "lan_mac=", mac_buff) == 0) {
        ath79_init_mac(ath79_eth0_data.mac_addr, mac_buff, 0);
        ath79_init_mac(ath79_eth1_data.mac_addr, mac_buff, 1);
        mac = mac_buff;
    }

    /* Enabling internal CS1, disable GPIO 0 */
    ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);

    ath79_register_m25p80(NULL);

    ath79_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
                    AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
                    AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
                    AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
                    AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);

    ath79_register_leds_gpio(-1, ARRAY_SIZE(dir_600_a1_leds_gpio),
                 dir_600_a1_leds_gpio);

    ath79_register_gpio_keys_polled(-1, DIR_600_A1_KEYS_POLL_INTERVAL,
                    ARRAY_SIZE(dir_600_a1_gpio_keys),
                    dir_600_a1_gpio_keys);

    ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0);
    ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1);

    ath79_register_mdio(0, 0x0);

    /* LAN ports */
    ath79_register_eth(1);

    /* WAN port */
    ath79_register_eth(0);

    ap91_pci_init(ee, mac);

    spi_register_board_info(ath79_spi_info,
                ARRAY_SIZE(ath79_spi_info));
}

MIPS_MACHINE(ATH79_MACH_DIR_600_A1, "DIR-600-A1", "D-Link DIR-600 rev. A1",
         dir_600_a1_setup);

static void __init dir_615_e1_setup(void)
{
    dir_600_a1_setup();
}

MIPS_MACHINE(ATH79_MACH_DIR_615_E1, "DIR-615-E1", "D-Link DIR-615 rev. E1",
         dir_615_e1_setup);

static void __init dir_615_e4_setup(void)
{
    dir_600_a1_setup();
    ap9x_pci_setup_wmac_led_pin(0, 1);
}

MIPS_MACHINE(ATH79_MACH_DIR_615_E4, "DIR-615-E4", "D-Link DIR-615 rev. E4",
         dir_615_e4_setup);

(Last edited by lobonse on 4 Feb 2017, 16:01)

From Deep MMC Mod:

Keep in mind, very often the unused GPIOs a pulled-down to the ground or pulled-up to the power bus via resistor - this may affect on detection of SD memory cards.

Would a 220 ohm resistor on the WPS led negative side pulling it low affect the cs line?

It could be anything.
When SPI0.0 bus is enabled (CS must be low when active) then SPI0.1 must be disabled (CS must be high when deactive) or contrariwise.
On hardware level, we do not touch CS0, but we create CS1 - when device read/detect the flash (SPI0,0) CS1 must be ~3.-3.3V (not less); when device read/detect the SD (SPI0,1) CS1 must be ~0.-1.V (not more).
The same applies to other lines: DI, DO and SCLK.
Ideal signal must be: ~ 3.-3.3V when logic is high and ~ 0.-1.V when logic is low.

In theory, when we connect to our balanced SPI0.0 bus a new other device, we can break this balance.
Therefore we need these pull-up resistors on the common signals DI, DO and SCLK.

Ok, well, thanks for your help.

One thing ( out of many clearly ) that I don't understand is why there is no conflict in these two parts:

From dev-m25p80.c:

static struct spi_board_info ath79_spi_info[] = {
    {
        .bus_num    = 0,
        .chip_select    = 0,
        .max_speed_hz   = 25000000,
        .modalias   = "m25p80",
        .controller_data = &ath79_spi0_cdata,
    },
    {
        .bus_num    = 0,
        .chip_select    = 1,
        .max_speed_hz   = 25000000,
        .modalias   = "m25p80",
        .controller_data = &ath79_spi1_cdata,
    }
};

From mach-dir-600-a1.c:

static struct spi_board_info ath79_spi_info[] = {
    {
        .bus_num    = 0,
        .chip_select    = 1,
        .max_speed_hz   = 25000000,
        .modalias   = "mmc_spi",
        .platform_data  = &ath79_mmc_data,
        .controller_data = &ath79_spi1_cdata,
    }
};

From what I can see the line .platform_data is a reference to "MMC_VDD_32_33 | MMC_VDD_33_34" ie a voltage measurement taken to confirm the proper voltage of the card during init I guess. So the rest is identical, apart from the aliases. Why no conflict?

(Last edited by lobonse on 5 Feb 2017, 17:18)

lobonse wrote:

One thing ( out of many clearly ) that I don't understand is why there is no conflict in these two parts:
...
Why no conflict?

Because in the function "void __init ath79 register m25p80" we call only one part "ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1);" of the ath79_spi_info[] array enclosed in curly braces.

For example, in function "void __init ath79_register_m25p80_multi" we use two elements of array "ath79_register_spi(&ath79_spi_data, ath79_spi_info, 2);"

By the way, you can patch the kernel in another way.
http://www.right.com.cn/Forum/thread-136884-1-1.html
(where we change only dev-m25p80.c driver)

(Last edited by Deoptim on 5 Feb 2017, 17:31)

Another concern I have is the WPS LED being lit constantly. If it is active low, this would indicate that the CS line is constantly being pulled low, no? I am wondering if I have the wire soldered to the wrong place. It's on the negative post of the LED, after the on board resistor:

https://i.imgur.com/JeplxuL.jpg

(Last edited by lobonse on 21 Mar 2018, 13:07)