diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2010-11-09 22:00:31 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2010-11-09 22:00:31 +0000 |
commit | e1515a2ee030e33bebd3f093c935ead2d7e6fc0f (patch) | |
tree | c229d9a277e2a2fc95f210ce0f01ce3d5b025d27 /dediprog.c | |
parent | 1d0d0a5f02e18caaee4dec74e867f848c064ea5c (diff) | |
download | flashrom-e1515a2ee030e33bebd3f093c935ead2d7e6fc0f.zip flashrom-e1515a2ee030e33bebd3f093c935ead2d7e6fc0f.tar.gz |
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: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Stefan Reinauer <stepan@coreboot.org>
Diffstat (limited to 'dediprog.c')
-rw-r--r-- | dediprog.c | 94 |
1 files changed, 78 insertions, 16 deletions
@@ -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; |