[OpenWrt-Devel] [PATCH] ar71xx: added to ath79 spi driver - SPI Transfer Modes

John Crispin blogic at openwrt.org
Thu Oct 23 04:42:18 EDT 2014



On 23/10/2014 09:22, Дмитрий Смирнов wrote:
> Added SPI_MODE_1, SPI_MODE_3 and SPI_MODE_3 to ath79 driver, also
> we must select GPIO=>miso_line if we use these three modes(except
> SPI_MODE_0), because "a dedicated GPIO pin is used as SPI MISO
> since SPI controller doesn't support modes other than mode-0" (from
> source for Atheros CUS227 board)
> 
> source:
> https://www.codeaurora.org/cgit/quic/qsdk/oss/system/openwrt/tag/?h=aa/banana&id=AU_LINUX_QSDK_BANANA_10.4_TARGET_ALL.2.4.406
>
> 
thanks to Gerd
> 

looking closer, this looks totally broekn to me. please explain why
spi_gpio is not used in this case. the code you want to add has a for
loop with 8 iterations in it with 2 sleep calls.

QCA seems to have forgotten that spi_gpio exists. if they want to bang
the bits on gpio in their driver they could have at least used the
bitbang api.

sorry, NAK for both patches


> 
> Signed-off-by: Dmytro <dioptimizer at hotmail.com> --- diff --git
> a/target/linux/ar71xx/patches-3.10/464-QCA-MIPS-ath79-spi-add-mode123-support.patch
> b/target/linux/ar71xx/patches-3.10/464-QCA-MIPS-ath79-spi-add-mode123-support.patch
>
> 
new file mode 100644
> index 0000000..0eeaab5 --- /dev/null +++
> b/target/linux/ar71xx/patches-3.10/464-QCA-MIPS-ath79-spi-add-mode123-support.patch
>
> 
@@ -0,0 +1,161 @@
> +Permission to use, copy, modify, and/or distribute this software
> for any +purpose with or without fee is hereby granted, provided
> that the above +copyright notice and this permission notice appear
> in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
> DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING
> ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT
> SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR
> CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM
> LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT,
> NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN
> CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +---
> a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h ++++
> b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h +@@ -1,6
> +1,7 @@ + /* +  *  Platform data definition for Atheros
> AR71XX/AR724X/AR913X SPI controller +  * ++ *  Copyright (c) 2013
> The Linux Foundation. All rights reserved. +  *  Copyright (C)
> 2008-2010 Gabor Juhos <juhosg at openwrt.org> +  * +  *  This program
> is free software; you can redistribute it and/or modify it +@@
> -14,6 +15,7 @@ + struct ath79_spi_platform_data { +     unsigned
> bus_num; +     unsigned    num_chipselect; ++    unsigned
> miso_line; + }; + + enum ath79_spi_cs_type { +---
> a/drivers/spi/spi-ath79.c ++++ b/drivers/spi/spi-ath79.c +@@ -1,6
> +1,7 @@ + /* +  * SPI controller driver for the Atheros
> AR71XX/AR724X/AR913X SoCs +  * ++ * Copyright (c) 2013 The Linux
> Foundation. All rights reserved. +  * Copyright (C) 2009-2011 Gabor
> Juhos <juhosg at openwrt.org> +  * +  * This driver has been based on
> the spi-gpio.c: +@@ -49,6 +50,7 @@ struct ath79_spi { +     void
> __iomem        *base; +     struct clk        *clk; +     unsigned
> rrw_delay; ++    unsigned        miso_line; + +     enum
> ath79_spi_state    state; +     u32            clk_div; +@@ -239,6
> +241,98 @@ static u32 ath79_spi_txrx_mode0(struct s +     return
> ath79_spi_rr(sp, AR71XX_SPI_REG_RDS); + } + ++static u32
> ath79_spi_txrx_mode1(struct spi_device *spi, unsigned nsecs, ++
> u32 word, u8 bits) ++{ ++    u32 readword = 0; ++    struct
> ath79_spi *sp = ath79_spidev_to_sp(spi); ++    u32 ioc =
> sp->ioc_base; ++ ++    /* clock starts at inactive polarity */ ++
> for (word <<= (32 - bits); likely(bits); bits--) { ++        u32
> out; ++ ++        if (word & (1 << 31)) ++            out = ioc |
> AR71XX_SPI_IOC_DO; ++        else ++            out = ioc &
> ~AR71XX_SPI_IOC_DO; ++ ++        /* setup MSB (to slave) on
> trailing edge */ ++        ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out
> | AR71XX_SPI_IOC_CLK); ++        ath79_spi_delay(sp, nsecs); ++
> readword <<= 1; ++        readword |=
> gpio_get_value(sp->miso_line); ++        ath79_spi_wr(sp,
> AR71XX_SPI_REG_IOC, out); ++        ath79_spi_delay(sp, nsecs); ++ 
> ++        word <<= 1; ++    } ++ ++    return readword; ++} ++ 
> ++static u32 ath79_spi_txrx_mode2(struct spi_device *spi, unsigned
> nsecs, ++                   u32 word, u8 bits) ++{ ++    u32
> readword = 0; ++    struct ath79_spi *sp =
> ath79_spidev_to_sp(spi); ++    u32 ioc = sp->ioc_base; ++ ++    /*
> clock starts at inactive polarity */ ++    for (word <<= (32 -
> bits); likely(bits); bits--) { ++        u32 out; ++ ++        if
> (word & (1 << 31)) ++            out = ioc | AR71XX_SPI_IOC_DO; ++
> else ++            out = ioc & ~AR71XX_SPI_IOC_DO; ++ ++        /*
> setup MSB (to slave) on trailing edge */ ++        ath79_spi_wr(sp,
> AR71XX_SPI_REG_IOC, out); ++        ath79_spi_delay(sp, nsecs); ++
> readword <<= 1; ++        readword |=
> gpio_get_value(sp->miso_line); ++        ath79_spi_wr(sp,
> AR71XX_SPI_REG_IOC, out & ~AR71XX_SPI_IOC_CLK); ++
> ath79_spi_delay(sp, nsecs); ++        if (bits == 1) ++
> ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out); ++ ++        word <<=
> 1; ++    } ++ ++    return readword; ++} ++ ++static u32
> ath79_spi_txrx_mode3(struct spi_device *spi, unsigned nsecs, ++
> u32 word, u8 bits) ++{ ++    u32 readword = 0; ++    struct
> ath79_spi *sp = ath79_spidev_to_sp(spi); ++    u32 ioc =
> sp->ioc_base; ++ ++    /* clock starts at inactive polarity */ ++
> for (word <<= (32 - bits); likely(bits); bits--) { ++        u32
> out; ++ ++        if (word & (1 << 31)) ++            out = ioc |
> AR71XX_SPI_IOC_DO; ++        else ++            out = ioc &
> ~AR71XX_SPI_IOC_DO; ++ ++        /* setup MSB (to slave) on
> trailing edge */ ++        ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out
> & ~AR71XX_SPI_IOC_CLK); ++        ath79_spi_delay(sp, nsecs); ++
> readword <<= 1; ++        readword |=
> gpio_get_value(sp->miso_line); ++        ath79_spi_wr(sp,
> AR71XX_SPI_REG_IOC, out); ++        ath79_spi_delay(sp, nsecs); ++ 
> ++        word <<= 1; ++    } ++ ++    return readword; ++} ++ +
> static int ath79_spi_do_read_flash_data(struct spi_device *spi, +
> struct spi_transfer *t) + { +@@ -372,9 +466,14 @@ static __devinit
> int ath79_spi_probe(str +     master->bus_num = pdata->bus_num; +
> master->num_chipselect = pdata->num_chipselect; + ++
> sp->miso_line = pdata->miso_line; ++ +     sp->bitbang.master =
> spi_master_get(master); +     sp->bitbang.chipselect =
> ath79_spi_chipselect; +     sp->bitbang.txrx_word[SPI_MODE_0] =
> ath79_spi_txrx_mode0; ++    sp->bitbang.txrx_word[SPI_MODE_1] =
> ath79_spi_txrx_mode1; ++    sp->bitbang.txrx_word[SPI_MODE_2] =
> ath79_spi_txrx_mode2; ++    sp->bitbang.txrx_word[SPI_MODE_3] =
> ath79_spi_txrx_mode3; +     sp->bitbang.setup_transfer =
> ath79_spi_setup_transfer; +     sp->bitbang.flags = SPI_CS_HIGH; +
> 
>  _______________________________________________ openwrt-devel
> mailing list openwrt-devel at lists.openwrt.org 
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
> 
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list