[flashrom] [PATCH] Enable spi clock setting in dediprog driver
Nico Huber
nico.huber at secunet.com
Wed Jun 13 11:01:57 CEST 2012
This adds a programmer parameter 'speed' in the dediprog driver to
controll the transfer rate on the spi bus. The following rates are
available (all in kHz):
24000, 12000, 8000, 3000, 2180, 1500, 750, 375
Signed-off-by: Nico Huber <nico.huber at secunet.com>
Index: dediprog.c
===================================================================
--- dediprog.c (Revision 1541)
+++ dediprog.c (Arbeitskopie)
@@ -135,7 +144,6 @@
return 0;
}
-#if 0
/* After dediprog_set_spi_speed, the original app always calls
* dediprog_set_spi_voltage(0) and then
* dediprog_check_devicestring() four times in a row.
@@ -149,43 +157,43 @@
* This looks suspiciously like the microprocessor in the SF100 has to be
* restarted/reinitialized in case the speed changes.
*/
-static int dediprog_set_spi_speed(uint16_t speed)
+static int dediprog_set_spi_speed(unsigned int khz)
{
int ret;
- unsigned int khz;
+ uint16_t speed;
/* Case 1 and 2 are in weird order. Probably an organically "grown"
* interface.
* Base frequency is 24000 kHz, divisors are (in order)
* 1, 3, 2, 8, 11, 16, 32, 64.
*/
- switch (speed) {
- case 0x0:
- khz = 24000;
+ switch (khz) {
+ case 24000:
+ speed = 0;
break;
- case 0x1:
- khz = 8000;
+ case 8000:
+ khz = 1;
break;
- case 0x2:
- khz = 12000;
+ case 12000:
+ khz = 2;
break;
- case 0x3:
- khz = 3000;
+ case 3000:
+ khz = 3;
break;
- case 0x4:
- khz = 2180;
+ case 2180:
+ khz = 4;
break;
- case 0x5:
- khz = 1500;
+ case 1500:
+ khz = 5;
break;
- case 0x6:
- khz = 750;
+ case 750:
+ khz = 6;
break;
- case 0x7:
- khz = 375;
+ case 375:
+ khz = 7;
break;
default:
- msg_perr("Unknown frequency selector 0x%x! Aborting.\n", speed);
+ msg_perr("Unsupported frequency %d kHz! Aborting.\n", khz);
return 1;
}
msg_pdbg("Setting SPI speed to %u kHz\n", khz);
@@ -198,7 +206,6 @@
}
return 0;
}
-#endif
/* Bulk read interface, will read multiple 512 byte chunks aligned to 512 bytes.
* @start start address
@@ -701,6 +708,28 @@
return millivolt;
}
+static int dediprog_setup(void)
+{
+ /* URB 6. Command A. */
+ if (dediprog_command_a()) {
+ return 1;
+ }
+ /* URB 7. Command A. */
+ if (dediprog_command_a()) {
+ return 1;
+ }
+ /* URB 8. Command Prepare Receive Device String. */
+ /* URB 9. Command Receive Device String. */
+ if (dediprog_check_devicestring()) {
+ return 1;
+ }
+ /* URB 10. Command C. */
+ if (dediprog_command_c()) {
+ return 1;
+ }
+ return 0;
+}
+
static const struct spi_programmer spi_programmer_dediprog = {
.type = SPI_CONTROLLER_DEDIPROG,
.max_data_read = MAX_DATA_UNSPECIFIED,
@@ -741,12 +770,18 @@
int dediprog_init(void)
{
struct usb_device *dev;
- char *voltage;
- int millivolt = 3500;
+ char *voltage, *speed;
+ int khz = 0, millivolt = 3500;
int ret;
msg_pspew("%s\n", __func__);
+ speed = extract_programmer_param("speed");
+ if (speed) {
+ khz = strtol(speed, NULL, 0);
+ free(speed);
+ msg_pinfo("Setting speed to %i kHz\n", khz);
+ }
voltage = extract_programmer_param("voltage");
if (voltage) {
millivolt = parse_voltage(voltage);
@@ -791,27 +843,25 @@
dediprog_set_leds(PASS_ON|BUSY_ON|ERROR_ON);
- /* URB 6. Command A. */
- if (dediprog_command_a()) {
+ /* Perform basic setup. */
+ if (dediprog_setup()) {
dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON);
return 1;
}
- /* URB 7. Command A. */
- if (dediprog_command_a()) {
- dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON);
- return 1;
+
+ /*
+ * Set speed if requested. Set voltage to zero beforehand and setup
+ * again afterwards. Maybe we can skip the first setup.
+ */
+ if (khz) {
+ if (dediprog_set_spi_voltage(0) ||
+ dediprog_set_spi_speed(khz) ||
+ dediprog_setup()) {
+ dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON);
+ return 1;
+ }
}
- /* URB 8. Command Prepare Receive Device String. */
- /* URB 9. Command Receive Device String. */
- if (dediprog_check_devicestring()) {
- dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON);
- return 1;
- }
- /* URB 10. Command C. */
- if (dediprog_command_c()) {
- dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON);
- return 1;
- }
+
/* URB 11. Command Set SPI Voltage. */
if (dediprog_set_spi_voltage(millivolt)) {
dediprog_set_leds(PASS_OFF|BUSY_OFF|ERROR_ON);
More information about the flashrom
mailing list