On 27.05.2010 01:19, Joseph Smith wrote:
On 05/26/2010 06:12 PM, Michael Karcher wrote:
Am Mittwoch, den 26.05.2010, 19:23 +0200 schrieb Carl-Daniel Hailfinger:
+int rayer_bitbang_spi_init(void) +{
/* Pick a default value for now. */
lpt_iobase = 0x378;
get_io_perms();
Ah, direct port access for the parallel port. While this is definitely the way that works independent of the operating system (as it works around the operating system), it is a pity to use this on operating systems that have a clean parallel port bitbang interface. It happens to be the case that Linux does support parallel port bitbanging using /dev/parport. Any chance to use OS-specific parallel port interfaces where possible?
AH, be careful here, using the Linux driver /dev/parport vs direct pport access will surely slow things down. And with a parallel port you need as much speed as possible. I guess it is a question of speed vs the "proper" way....
IMHO the first step is to get it working and committed, and the second step is OS specific stuff. This allows us to run regression tests against a known working version if we add OS-specific support.
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.
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 1013) +++ 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 1013) +++ 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 1013) +++ 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 1013) +++ 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); Index: flashrom-bitbang_spi_rayer/spi.c =================================================================== --- flashrom-bitbang_spi_rayer/spi.c (Revision 1013) +++ 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 1013) +++ 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 1013) +++ 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,98 @@ +/* + * 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(); + + if (bitbang_spi_init()) + return 1; + spi_controller = SPI_CONTROLLER_RAYER_BITBANG; + + return 0; +}