diff options
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | flashrom.c | 10 | ||||
| -rw-r--r-- | pony_spi.c | 160 | ||||
| -rw-r--r-- | print.c | 6 | ||||
| -rw-r--r-- | programmer.h | 40 | ||||
| -rw-r--r-- | serial.c | 55 | 
6 files changed, 283 insertions, 1 deletions
| @@ -292,6 +292,9 @@ CONFIG_SERPROG ?= yes  # RayeR SPIPGM hardware support  CONFIG_RAYER_SPI ?= yes +# PonyProg2000 SPI hardware support +CONFIG_PONY_SPI ?= yes +  # Always enable 3Com NICs for now.  CONFIG_NIC3COM ?= yes @@ -348,6 +351,9 @@ CONFIG_PRINT_WIKI ?= no  ifeq ($(CONFIG_RAYER_SPI), yes)  override CONFIG_BITBANG_SPI = yes  else +ifeq ($(CONFIG_PONY_SPI), yes) +override CONFIG_BITBANG_SPI = yes +else  ifeq ($(CONFIG_INTERNAL), yes)  override CONFIG_BITBANG_SPI = yes  else @@ -362,6 +368,7 @@ endif  endif  endif  endif +endif  ifeq ($(CONFIG_INTERNAL), yes)  FEATURE_CFLAGS += -D'CONFIG_INTERNAL=1' @@ -388,6 +395,12 @@ PROGRAMMER_OBJS += rayer_spi.o  NEED_PCI := yes  endif +ifeq ($(CONFIG_PONY_SPI), yes) +FEATURE_CFLAGS += -D'CONFIG_PONY_SPI=1' +PROGRAMMER_OBJS += pony_spi.o +NEED_SERIAL := yes +endif +  ifeq ($(CONFIG_BITBANG_SPI), yes)  FEATURE_CFLAGS += -D'CONFIG_BITBANG_SPI=1'  PROGRAMMER_OBJS += bitbang_spi.o @@ -201,6 +201,16 @@ const struct programmer_entry programmer_table[] = {  	},  #endif +#if CONFIG_PONY_SPI == 1 +	{ +		.name			= "pony_spi", +		.init			= pony_spi_init, +		.map_flash_region	= fallback_map, +		.unmap_flash_region	= fallback_unmap, +		.delay			= internal_delay, +}, +#endif +  #if CONFIG_NICINTEL == 1  	{  		.name			= "nicintel", diff --git a/pony_spi.c b/pony_spi.c new file mode 100644 index 00000000..b5dfc2f7 --- /dev/null +++ b/pony_spi.c @@ -0,0 +1,160 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2012 Virgil-Adrian Teaca + * + * 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 SI-Prog like hardware by Lancos.com. + * See http://www.lancos.com/siprogsch.html for schematics and instructions. + */ + +#include <stdlib.h> +#include <string.h> + +#include "flash.h" +#include "programmer.h" + +/* We have: + + MOSI -----> DTR + MISO -----> CTS + SCK  --+--> RTS +        +--> DSR + CS#  -----> TXD + +*/ + +enum pony_type { +	TYPE_SI_PROG, +	TYPE_SERBANG, +}; + +/* The hardware programmer used. */ +static enum pony_type pony_type = TYPE_SI_PROG; + +static void pony_bitbang_set_cs(int val) +{ +	if (pony_type == TYPE_SI_PROG) +	{ +		/* CS# is negated by the SI-Prog programmer. */ +		val ^=  1; +	} +	sp_set_pin(PIN_TXD, val); +} + +static void pony_bitbang_set_sck(int val) +{ +	sp_set_pin(PIN_RTS, val); +} + +static void pony_bitbang_set_mosi(int val) +{ +	sp_set_pin(PIN_DTR, val); +} + +static int pony_bitbang_get_miso(void) +{ +	int tmp; + +	tmp = sp_get_pin(PIN_CTS); + +	if (pony_type == TYPE_SERBANG) +	{ +		/* MISO is negated by the SERBANG programmer. */ +		tmp ^= 1; +	} +	return tmp; +} + +static const struct bitbang_spi_master bitbang_spi_master_pony = { +	.type = BITBANG_SPI_MASTER_PONY, +	.set_cs = pony_bitbang_set_cs, +	.set_sck = pony_bitbang_set_sck, +	.set_mosi = pony_bitbang_set_mosi, +	.get_miso = pony_bitbang_get_miso, +	.half_period = 0, +}; + +int pony_spi_init(void) +{ +	char *arg = NULL; +	int i, data_in, data_out, have_device = 0; +	int have_prog = 1; + +	/* The parameter is on format "dev=/dev/device,type=serbang" */ +	arg = extract_programmer_param("dev"); + +	if (arg && strlen(arg)) { +		sp_fd = sp_openserport( arg, 9600 ); +		have_device++; +	} +	free(arg); + +	if (!have_device) { +		msg_perr("Error: No valid device specified.\n" +			 "Use flashrom -p pony_spi:dev=/dev/device\n"); + +		return 1; +	} +	/* Register the shutdown callback. */ +	if (register_shutdown(serialport_shutdown, NULL)) { +		return 1; +	} +	arg = extract_programmer_param("type"); + +	if (arg) { +		if (!strcasecmp( arg, "serbang")) { +			pony_type = TYPE_SERBANG; +		} else if (!strcasecmp( arg, "si_prog") ) { +			pony_type = TYPE_SI_PROG; +		} else { +			msg_perr("Error: Invalid programmer type specified.\n"); +			free(arg); +			return 1; +		} +	} +	free(arg); + +	msg_pdbg("Using the %s programmer.\n", ((pony_type == TYPE_SI_PROG ) ? "SI-Prog" : "SERBANG")); +	/* +	 * Detect if there is a SI-Prog compatible programmer connected. +	 */ +	pony_bitbang_set_cs(1); +	pony_bitbang_set_mosi(1); + +	/* We toggle SCK while we keep MOSI and CS# on. */ +	for (i = 1; i <= 10; ++i) { +		data_out = i & 1; +		sp_set_pin(PIN_RTS, data_out); +		programmer_delay( 1000 ); +		data_in = sp_get_pin(PIN_DSR); + +		if (data_out != data_in) { +			have_prog = 0; +			break; +		} +	} + +	if (!have_prog) { +		msg_perr( "No SI-Prog compatible hardware detected.\n" ); +		return 1; +	} + +	if (bitbang_spi_init(&bitbang_spi_master_pony)) { +		return 1; +	} +	return 0; +} @@ -507,6 +507,12 @@ void print_supported(void)  	/* FIXME */  	msg_ginfo("RayeR parallel port programmer\n");  #endif +#if CONFIG_PONY_SPI == 1 +	msg_ginfo("\nSupported devices for the %s programmer:\n", +	       programmer_table[PROGRAMMER_PONY_SPI].name); +	/* FIXME */ +	msg_ginfo("SI-Prog and SERBANG serial port programmer\n"); +#endif  #if CONFIG_NICINTEL == 1  	msg_ginfo("\nSupported devices for the %s programmer:\n",  	       programmer_table[PROGRAMMER_NICINTEL].name); diff --git a/programmer.h b/programmer.h index 50be1592..4d153e6c 100644 --- a/programmer.h +++ b/programmer.h @@ -69,6 +69,9 @@ enum programmer {  #if CONFIG_RAYER_SPI == 1  	PROGRAMMER_RAYER_SPI,  #endif +#if CONFIG_PONY_SPI == 1 +	PROGRAMMER_PONY_SPI, +#endif  #if CONFIG_NICINTEL == 1  	PROGRAMMER_NICINTEL,  #endif @@ -110,6 +113,9 @@ enum bitbang_spi_master_type {  #if CONFIG_RAYER_SPI == 1  	BITBANG_SPI_MASTER_RAYER,  #endif +#if CONFIG_PONY_SPI == 1 +	BITBANG_SPI_MASTER_PONY, +#endif  #if CONFIG_NICINTEL_SPI == 1  	BITBANG_SPI_MASTER_NICINTEL,  #endif @@ -430,6 +436,11 @@ void print_supported_usbdevs(const struct usbdev_status *devs);  int rayer_spi_init(void);  #endif +/* pony_spi.c */ +#if CONFIG_PONY_SPI == 1 +int pony_spi_init(void); +#endif +  /* bitbang_spi.c */  int bitbang_spi_init(const struct bitbang_spi_master *master); @@ -492,7 +503,7 @@ enum spi_controller {  #if CONFIG_DEDIPROG == 1  	SPI_CONTROLLER_DEDIPROG,  #endif -#if CONFIG_OGP_SPI == 1 || CONFIG_NICINTEL_SPI == 1 || CONFIG_RAYER_SPI == 1 || (CONFIG_INTERNAL == 1 && (defined(__i386__) || defined(__x86_64__))) +#if CONFIG_OGP_SPI == 1 || CONFIG_NICINTEL_SPI == 1 || CONFIG_RAYER_SPI == 1 || CONFIG_PONY_SPI == 1 || (CONFIG_INTERNAL == 1 && (defined(__i386__) || defined(__x86_64__)))  	SPI_CONTROLLER_BITBANG,  #endif  #if CONFIG_LINUX_SPI == 1 @@ -636,4 +647,31 @@ int serialport_shutdown(void *data);  int serialport_write(unsigned char *buf, unsigned int writecnt);  int serialport_read(unsigned char *buf, unsigned int readcnt); +/* Serial port/pin mapping: + +  1	CD	<- +  2	RXD	<- +  3	TXD	-> +  4	DTR	-> +  5	GND     -- +  6	DSR	<- +  7	RTS	-> +  8	CTS	<- +  9	RI	<- +*/ +enum SP_PIN { +	PIN_CD = 1, +	PIN_RXD, +	PIN_TXD, +	PIN_DTR, +	PIN_GND, +	PIN_DSR, +	PIN_RTS, +	PIN_CTS, +	PIN_RI, +}; + +void sp_set_pin(enum SP_PIN pin, int val); +int sp_get_pin(enum SP_PIN pin); +  #endif				/* !__PROGRAMMER_H__ */ @@ -32,6 +32,9 @@  #include <conio.h>  #else  #include <termios.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/ioctl.h>  #endif  #include "flash.h"  #include "programmer.h" @@ -172,6 +175,58 @@ fdtype sp_openserport(char *dev, unsigned int baud)  #endif  } +void sp_set_pin(enum SP_PIN pin, int val) { +#ifdef _WIN32 +	DWORD ctl; + +	if(pin == PIN_TXD) { +		ctl = val ? SETBREAK: CLRBREAK; +	} +	else if(pin == PIN_DTR) { +		ctl = val ? SETDTR: CLRDTR; +	} +	else { +		ctl = val ? SETRTS: CLRRTS; +	} +	EscapeCommFunction(sp_fd, ctl); +#else +	int ctl, s; + +	if(pin == PIN_TXD) { +		ioctl(sp_fd, val ? TIOCSBRK : TIOCCBRK, 0); +	} +	else { +		s = (pin == PIN_DTR) ? TIOCM_DTR : TIOCM_RTS; +		ioctl(sp_fd, TIOCMGET, &ctl); + +		if (val) { +			ctl |= s; +		} +		else { +			ctl &= ~s; +		} +		ioctl(sp_fd, TIOCMSET, &ctl); +	} +#endif +} + +int sp_get_pin(enum SP_PIN pin) { +	int s; +#ifdef _WIN32 +	DWORD ctl; + +	s = (pin == PIN_CTS) ? MS_CTS_ON : MS_DSR_ON; +	GetCommModemStatus(sp_fd, &ctl); +#else +	int ctl; +	s = (pin == PIN_CTS) ? TIOCM_CTS : TIOCM_DSR; +	ioctl(sp_fd, TIOCMGET, &ctl); +#endif + +	return ((ctl & s) ? 1 : 0); + +} +  void sp_flush_incoming(void)  {  #ifdef _WIN32 | 
