diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2010-07-21 10:26:01 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2010-07-21 10:26:01 +0000 |
commit | b9352f74b60d627095fc39bbab250f94dabaed61 (patch) | |
tree | 0bd5bf090f36ef8f444d37e5bf4f2238345ac617 /rayer_spi.c | |
parent | 06b30ea42246bf7142515d584fe19263fb83ebc9 (diff) | |
download | flashrom-b9352f74b60d627095fc39bbab250f94dabaed61.zip flashrom-b9352f74b60d627095fc39bbab250f94dabaed61.tar.gz |
Add support for RayeR SPIPGM hardware as described in http://rayer.ic.cz/elektro/spipgm.htm
To use the RayeR driver, run
flashrom -p rayer_spi -V
Known bugs/limitations:
- Won't compile/work on non-x86 architectures.
- Will always use direct port I/O access.
Log follows:
flashrom v0.9.2-r1039 on MS-DOS 7 (i686), built with libpci 3.1.5, GCC
4.3.2, little endian
Calibrating delay loop... OK.
Initializing rayer_bitbang_spi programmer
Using port 0x378 as I/O base for parallel port access.
...
Probing for Macronix MX25L1605, 2048 KB: probe_spi_rdid_generic: id1
0xc2, id2 0x2015
...
Found chip "Macronix MX25L1605" (2048 KB, SPI) at physical address
0xffe00000.
...
No operations were specified.
Corresponding to flashrom svn r1093.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Martin Rehak <rayer@seznam.cz>
Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
Diffstat (limited to 'rayer_spi.c')
-rw-r--r-- | rayer_spi.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/rayer_spi.c b/rayer_spi.c new file mode 100644 index 0000000..37cf752 --- /dev/null +++ b/rayer_spi.c @@ -0,0 +1,122 @@ +/* + * 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. + */ + +/* This driver uses non-portable direct I/O port accesses which won't work on + * any non-x86 platform, and even on x86 there is a high chance there will be + * collisions with any loaded parallel port drivers. + * The big advantage of direct port I/O is OS independence and speed because + * most OS parport drivers will perform many unnecessary accesses although + * this driver just treats the parallel port as a GPIO set. + */ +#if defined(__i386__) || defined(__x86_64__) + +#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 tmp; + + tmp = INB(lpt_iobase); + tmp &= ~(1 << SPI_CS_PIN); + tmp |= (val << SPI_CS_PIN); + OUTB(tmp, lpt_iobase); +} + +void rayer_bitbang_set_sck(int val) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase); + tmp &= ~(1 << SPI_SCK_PIN); + tmp |= (val << SPI_SCK_PIN); + OUTB(tmp, lpt_iobase); +} + +void rayer_bitbang_set_mosi(int val) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase); + tmp &= ~(1 << SPI_MOSI_PIN); + tmp |= (val << SPI_MOSI_PIN); + OUTB(tmp, lpt_iobase); +} + +int rayer_bitbang_get_miso(void) +{ + uint8_t tmp; + + tmp = INB(lpt_iobase + 1); + tmp = (tmp >> SPI_MISO_PIN) & 0x1; + return tmp; +} + +static const struct bitbang_spi_master bitbang_spi_master_rayer = { + .type = BITBANG_SPI_MASTER_RAYER, + .set_cs = rayer_bitbang_set_cs, + .set_sck = rayer_bitbang_set_sck, + .set_mosi = rayer_bitbang_set_mosi, + .get_miso = rayer_bitbang_get_miso, +}; + +int rayer_spi_init(void) +{ + /* Pick a default value for now. */ + lpt_iobase = 0x378; + + msg_pdbg("Using port 0x%x as I/O base for parallel port access.\n", + lpt_iobase); + + get_io_perms(); + + /* 1 usec halfperiod delay for now. */ + if (bitbang_spi_init(&bitbang_spi_master_rayer, 1)) + return 1; + + buses_supported = CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_RAYER; + + return 0; +} + +#else +#error PCI port I/O access is not supported on this architecture yet. +#endif |