On 27.05.2010 03:04, Carl-Daniel Hailfinger wrote:
On 27.05.2010 02:32, Carl-Daniel Hailfinger wrote:
New version, fixes a few bugs where #ifdefs were missing.
Add support for RayeR SPIPGM hardware as described in http://rayer.ic.cz/elektro/spipgm.htm
Known bugs/limitations:
- Won't compile/work on non-x86 architectures. Guards against
compilation on non-x86 are missing.
Besides that, using "byte" as variable name breaks on mingw because it shadows a global variable with that name in the mingw headers.
New version, fixes a missing variable initialization which led to immediate segfault on programmer init. The other limitations are still present.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-bitbang_spi_rayer/flash.h =================================================================== --- flashrom-bitbang_spi_rayer/flash.h (Revision 1017) +++ flashrom-bitbang_spi_rayer/flash.h (Arbeitskopie) @@ -79,6 +79,9 @@ #if DEDIPROG_SUPPORT == 1 PROGRAMMER_DEDIPROG, #endif +#if RAYER_BITBANG_SPI_SUPPORT == 1 + PROGRAMMER_RAYER_BITBANG_SPI, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -126,6 +129,9 @@ void programmer_delay(int usecs);
enum bitbang_spi_master { +#if RAYER_BITBANG_SPI_SUPPORT == 1 + BITBANG_SPI_MASTER_RAYER, +#endif BITBANG_SPI_INVALID /* This must always be the last entry. */ };
@@ -512,6 +518,15 @@ int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf);
+/* rayer_bitbang_spi.c */ +#if RAYER_BITBANG_SPI_SUPPORT == 1 +int rayer_bitbang_spi_init(void); +void rayer_bitbang_set_cs(int val); +void rayer_bitbang_set_sck(int val); +void rayer_bitbang_set_mosi(int val); +int rayer_bitbang_get_miso(void); +#endif + /* bitbang_spi.c */ extern int bitbang_spi_half_period; extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; @@ -632,6 +647,9 @@ #if DEDIPROG_SUPPORT == 1 SPI_CONTROLLER_DEDIPROG, #endif +#if RAYER_BITBANG_SPI_SUPPORT == 1 + SPI_CONTROLLER_RAYER_BITBANG, +#endif SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; Index: flashrom-bitbang_spi_rayer/spi25.c =================================================================== --- flashrom-bitbang_spi_rayer/spi25.c (Revision 1017) +++ flashrom-bitbang_spi_rayer/spi25.c (Arbeitskopie) @@ -192,6 +192,9 @@ #if DEDIPROG_SUPPORT == 1 case SPI_CONTROLLER_DEDIPROG: #endif +#if RAYER_BITBANG_SPI_SUPPORT == 1 + case SPI_CONTROLLER_RAYER_BITBANG: +#endif return probe_spi_rdid_generic(flash, 4); default: msg_cinfo("4b ID not supported on this SPI controller\n"); Index: flashrom-bitbang_spi_rayer/hwaccess.h =================================================================== --- flashrom-bitbang_spi_rayer/hwaccess.h (Revision 1017) +++ flashrom-bitbang_spi_rayer/hwaccess.h (Arbeitskopie) @@ -169,6 +169,10 @@ #define __DARWIN__ #endif
+/* Clarification about OUTB/OUTW/OUTL argument order: + * OUT[BWL](val, port) + */ + #if defined(__FreeBSD__) || defined(__DragonFly__) #include <machine/cpufunc.h> #define off64_t off_t Index: flashrom-bitbang_spi_rayer/bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_rayer/bitbang_spi.c (Revision 1017) +++ flashrom-bitbang_spi_rayer/bitbang_spi.c (Arbeitskopie) @@ -32,11 +32,20 @@ enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID;
const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { - {}, /* This entry corresponds to BITBANG_SPI_INVALID. */ +#if RAYER_BITBANG_SPI_SUPPORT == 1 + { + .set_cs = rayer_bitbang_set_cs, + .set_sck = rayer_bitbang_set_sck, + .set_mosi = rayer_bitbang_set_mosi, + .get_miso = rayer_bitbang_get_miso, + }, +#endif + {}, /* This entry corresponds to SPI_BITBANG_INVALID. */ };
const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table);
+/* Note that CS# is active low, so val=0 means the chip is active. */ void bitbang_spi_set_cs(int val) { bitbang_spi_master_table[bitbang_spi_master].set_cs(val); @@ -59,6 +68,12 @@
int bitbang_spi_init(void) { + if (bitbang_spi_master == BITBANG_SPI_INVALID) { + msg_perr("The bitbang SPI master needs to be set before " + "calling %s. Please report a bug at " + "flashrom@flashrom.org\n", __func__); + return 1; + } bitbang_spi_set_cs(1); bitbang_spi_set_sck(0); buses_supported = CHIP_BUSTYPE_SPI; Index: flashrom-bitbang_spi_rayer/spi.c =================================================================== --- flashrom-bitbang_spi_rayer/spi.c (Revision 1017) +++ flashrom-bitbang_spi_rayer/spi.c (Arbeitskopie) @@ -123,6 +123,15 @@ }, #endif
+#if RAYER_BITBANG_SPI_SUPPORT == 1 + { /* SPI_CONTROLLER_RAYER_BITBANG */ + .command = bitbang_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = bitbang_spi_read, + .write_256 = bitbang_spi_write_256, + }, +#endif + {}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ };
Index: flashrom-bitbang_spi_rayer/Makefile =================================================================== --- flashrom-bitbang_spi_rayer/Makefile (Revision 1017) +++ flashrom-bitbang_spi_rayer/Makefile (Arbeitskopie) @@ -85,8 +85,15 @@ # Always enable serprog for now. Needs to be disabled on Windows. CONFIG_SERPROG ?= yes
-# Bitbanging SPI infrastructure is not used yet. +# RayeR SPIPGM hardware support +CONFIG_RAYER_BITBANG_SPI ?= yes + +# Bitbanging SPI infrastructure, default off unless needed. +ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) +CONFIG_BITBANG_SPI = yes +else CONFIG_BITBANG_SPI ?= no +endif
# Always enable 3Com NICs for now. CONFIG_NIC3COM ?= yes @@ -138,6 +145,13 @@ endif endif
+ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) +FEATURE_CFLAGS += -D'RAYER_BITBANG_SPI_SUPPORT=1' +PROGRAMMER_OBJS += rayer_bitbang_spi.o +# Actually, NEED_PCI is wrong. NEED_IOPORT_ACCESS would be more correct. +NEED_PCI := yes +endif + ifeq ($(CONFIG_BITBANG_SPI), yes) FEATURE_CFLAGS += -D'BITBANG_SPI_SUPPORT=1' PROGRAMMER_OBJS += bitbang_spi.o Index: flashrom-bitbang_spi_rayer/flashrom.c =================================================================== --- flashrom-bitbang_spi_rayer/flashrom.c (Revision 1017) +++ flashrom-bitbang_spi_rayer/flashrom.c (Arbeitskopie) @@ -47,7 +47,7 @@ * if more than one of them is selected. If only one is selected, it is clear * that the user wants that one to become the default. */ -#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+ATAHPT_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT+DEDIPROG_SUPPORT+NICREALTEK_SUPPORT > 1 +#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+ATAHPT_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT+DEDIPROG_SUPPORT+NICREALTEK_SUPPORT+RAYER_BITBANG_SPI_SUPPORT > 1 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all external programmers except one. #endif enum programmer programmer = @@ -82,6 +82,9 @@ #if DEDIPROG_SUPPORT == 1 PROGRAMMER_DEDIPROG #endif +#if RAYER_BITBANG_SPI_SUPPORT == 1 + PROGRAMMER_RAYER_BITBANG_SPI +#endif ; #endif
@@ -372,6 +375,25 @@ }, #endif
+#if RAYER_BITBANG_SPI_SUPPORT == 1 + { + .name = "rayerbitbangspi", + .init = rayer_bitbang_spi_init, + .shutdown = noop_shutdown, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, + .chip_readb = noop_chip_readb, + .chip_readw = fallback_chip_readw, + .chip_readl = fallback_chip_readl, + .chip_readn = fallback_chip_readn, + .chip_writeb = noop_chip_writeb, + .chip_writew = fallback_chip_writew, + .chip_writel = fallback_chip_writel, + .chip_writen = fallback_chip_writen, + .delay = internal_delay, + }, +#endif + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
Index: flashrom-bitbang_spi_rayer/rayer_bitbang_spi.c =================================================================== --- flashrom-bitbang_spi_rayer/rayer_bitbang_spi.c (Revision 0) +++ flashrom-bitbang_spi_rayer/rayer_bitbang_spi.c (Revision 0) @@ -0,0 +1,101 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009,2010 Carl-Daniel Hailfinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the SPIPGM hardware by "RayeR" Martin Rehak. + * See http://rayer.ic.cz/elektro/spipgm.htm for schematics and instructions. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <ctype.h> +#include "flash.h" + +/* We have two sets of pins, out and in. The numbers for both sets are + * independent and are bitshift values, not real pin numbers. + */ +/* Pins for master->slave direction */ +#define SPI_CS_PIN 5 +#define SPI_SCK_PIN 6 +#define SPI_MOSI_PIN 7 +/* Pins for slave->master direction */ +#define SPI_MISO_PIN 6 + +static int lpt_iobase; + +/* FIXME: All rayer_bitbang_set_* functions could use caching of the value + * stored at port lpt_iobase to avoid unnecessary INB. In theory, only one + * INB(lpt_iobase) would be needed on programmer init to get the initial + * value. + */ + +void rayer_bitbang_set_cs(int val) +{ + uint8_t byte; + + byte = INB(lpt_iobase); + byte &= ~(1 << SPI_CS_PIN); + byte |= (val << SPI_CS_PIN); + OUTB(byte, lpt_iobase); +} + +void rayer_bitbang_set_sck(int val) +{ + uint8_t byte; + + byte = INB(lpt_iobase); + byte &= ~(1 << SPI_SCK_PIN); + byte |= (val << SPI_SCK_PIN); + OUTB(byte, lpt_iobase); +} + +void rayer_bitbang_set_mosi(int val) +{ + uint8_t byte; + + byte = INB(lpt_iobase); + byte &= ~(1 << SPI_MOSI_PIN); + byte |= (val << SPI_MOSI_PIN); + OUTB(byte, lpt_iobase); +} + +int rayer_bitbang_get_miso(void) +{ + uint8_t byte; + + byte = INB(lpt_iobase + 1); + byte = (byte >> SPI_MISO_PIN) & 0x1; + return byte; +} + +int rayer_bitbang_spi_init(void) +{ + /* Pick a default value for now. */ + lpt_iobase = 0x378; + + get_io_perms(); + + bitbang_spi_master = BITBANG_SPI_MASTER_RAYER; + + if (bitbang_spi_init()) + return 1; + + spi_controller = SPI_CONTROLLER_RAYER_BITBANG; + + return 0; +}