Commit c2441387 authored by Carl-Daniel Hailfinger's avatar Carl-Daniel Hailfinger
Browse files

Support setting the Dediprog SF100 SPI voltage


Add a generic voltage parameter parser.
Move tolower_string() from dummyflasher.c to flashrom.c to make it
available everywhere.

Corresponding to flashrom svn r1226.
Signed-off-by: default avatarCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: default avatarStefan Reinauer <stepan@coreboot.org>
parent 12d6d821
......@@ -55,34 +55,35 @@ static struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid)
//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);
static int dediprog_set_spi_voltage(uint16_t voltage)
static int dediprog_set_spi_voltage(int millivolt)
{
int ret;
unsigned int mv;
uint16_t voltage_selector;
switch (voltage) {
case 0x0:
switch (millivolt) {
case 0:
/* Admittedly this one is an assumption. */
mv = 0;
voltage_selector = 0x0;
break;
case 0x12:
mv = 1800;
case 1800:
voltage_selector = 0x12;
break;
case 0x11:
mv = 2500;
case 2500:
voltage_selector = 0x11;
break;
case 0x10:
mv = 3500;
case 3500:
voltage_selector = 0x10;
break;
default:
msg_perr("Unknown voltage selector 0x%x! Aborting.\n", voltage);
msg_perr("Unknown voltage %i mV! Aborting.\n", millivolt);
return 1;
}
msg_pdbg("Setting SPI voltage to %u.%03u V\n", mv / 1000, mv % 1000);
msg_pdbg("Setting SPI voltage to %u.%03u V\n", millivolt / 1000,
millivolt % 1000);
ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage, 0xff, NULL, 0x0, DEFAULT_TIMEOUT);
ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage_selector, 0xff, NULL, 0x0, DEFAULT_TIMEOUT);
if (ret != 0x0) {
msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage);
msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage_selector);
return 1;
}
return 0;
......@@ -279,13 +280,74 @@ static int dediprog_command_f(int timeout)
}
#endif
static int parse_voltage(char *voltage)
{
char *tmp = NULL;
int i;
int millivolt;
int fraction = 0;
if (!voltage || !strlen(voltage)) {
msg_perr("Empty voltage= specified.\n");
return -1;
}
millivolt = (int)strtol(voltage, &tmp, 0);
voltage = tmp;
/* Handle "," and "." as decimal point. Everything after it is assumed
* to be in decimal notation.
*/
if ((*voltage == '.') || (*voltage == ',')) {
voltage++;
for (i = 0; i < 3; i++) {
fraction *= 10;
/* Don't advance if the current character is invalid,
* but continue multiplying.
*/
if ((*voltage < '0') || (*voltage > '9'))
continue;
fraction += *voltage - '0';
voltage++;
}
/* Throw away remaining digits. */
voltage += strspn(voltage, "0123456789");
}
/* The remaining string must be empty or "mV" or "V". */
tolower_string(voltage);
/* No unit or "V". */
if ((*voltage == '\0') || !strncmp(voltage, "v", 1)) {
millivolt *= 1000;
millivolt += fraction;
} else if (!strncmp(voltage, "mv", 2) ||
!strncmp(voltage, "milliv", 6)) {
/* No adjustment. fraction is discarded. */
} else {
/* Garbage at the end of the string. */
msg_perr("Garbage voltage= specified.\n");
return -1;
}
return millivolt;
}
/* URB numbers refer to the first log ever captured. */
int dediprog_init(void)
{
struct usb_device *dev;
char *voltage;
int millivolt = 3500;
msg_pspew("%s\n", __func__);
voltage = extract_programmer_param("voltage");
if (voltage) {
millivolt = parse_voltage(voltage);
free(voltage);
if (millivolt < 0) {
return 1;
}
msg_pinfo("Setting voltage to %i mV\n", millivolt);
}
/* Here comes the USB stuff. */
usb_init();
usb_find_busses();
......@@ -315,7 +377,7 @@ int dediprog_init(void)
if (dediprog_command_c())
return 1;
/* URB 11. Command Set SPI Voltage. */
if (dediprog_set_spi_voltage(0x10))
if (dediprog_set_spi_voltage(millivolt))
return 1;
buses_supported = CHIP_BUSTYPE_SPI;
......
......@@ -19,7 +19,6 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "flash.h"
#include "chipdrivers.h"
#include "programmer.h"
......@@ -61,12 +60,6 @@ static int emu_jedec_ce_c7_size = 0;
static int spi_write_256_chunksize = 256;
static void tolower_string(char *str)
{
for (; *str != '\0'; str++)
*str = (char)tolower((unsigned char)*str);
}
int dummy_init(void)
{
char *bustext = NULL;
......
......@@ -197,6 +197,7 @@ struct flashchip *probe_flash(struct flashchip *first_flash, int force);
int read_flash_to_file(struct flashchip *flash, char *filename);
int min(int a, int b);
int max(int a, int b);
void tolower_string(char *str);
char *extract_param(char **haystack, char *needle, char *delim);
int check_erased_range(struct flashchip *flash, int start, int len);
int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
......
......@@ -402,7 +402,20 @@ can be any of
(in Hz). The default is the maximum frequency of 8 MHz.
.TP
.BR "dediprog " programmer
No parameters defined yet.
An optional
.B voltage
parameter specifies the voltage the Dediprog should use. The default unit is
Volt if no unit is specified. You can use
.BR mV ", " milliVolt ", " V " or " Volt
as unit specifier. Syntax is
.sp
.B "flashrom \-p dediprog:voltage=value"
.sp
where
.B value
can be any of
.BR 0V ", " 1.8V ", " 2.5V ", " 3.5V
or the equivalent in mV.
.TP
.BR "rayer_spi " programmer
The default I/O base address used for the parallel port is 0x378 and you can use
......
......@@ -29,6 +29,7 @@
#endif
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <getopt.h>
#if HAVE_UTSNAME == 1
#include <sys/utsname.h>
......@@ -615,6 +616,12 @@ int bitcount(unsigned long a)
return i;
}
void tolower_string(char *str)
{
for (; *str != '\0'; str++)
*str = (char)tolower((unsigned char)*str);
}
char *strcat_realloc(char *dest, const char *src)
{
dest = realloc(dest, strlen(dest) + strlen(src) + 1);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment