diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index 9974b862..70abf712 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,9 @@
+2009-02-28  Thomas Fischl <tfischl@gmx.de>
+
+	Based on patch #6484 commited by Jurgis Brigmanis:
+	* usbasp.c: added software control for ISP speed
+	* usbasp.h: (Ditto.)
+
 2009-02-28  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* avr910.c (avr910_read_byte_flash): Eliminate a static variable that
diff --git a/avrdude/usbasp.c b/avrdude/usbasp.c
index b01a8762..dd0c1464 100644
--- a/avrdude/usbasp.c
+++ b/avrdude/usbasp.c
@@ -228,8 +228,14 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
 
   unsigned char temp[4];
   memset(temp, 0, sizeof(temp));
+
+  /* set sck period */
+  pgm->set_sck_period(pgm, pgm->bitclock);
+
+  /* connect to target device */
   usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
 
+  /* wait, so device is ready to receive commands */
   usleep(100000);
 
   return pgm->program_enable(pgm, p);
@@ -350,8 +356,8 @@ static int usbasp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     cmd[1] = address >> 8;
     cmd[2] = address >> 16;
     cmd[3] = address >> 24;
-    usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));	
-    
+    usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
+
     /* send command with address (compatibility mode) - if firmware on
 	  usbasp doesn't support newmode, then they use address from this */
     cmd[0] = address & 0xFF;
@@ -416,10 +422,10 @@ static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     cmd[2] = address >> 16;
     cmd[3] = address >> 24;
     usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
-    
+
     /* normal command - firmware what support newmode - use address from previous command,
       firmware what doesn't support newmode - ignore previous command and use address from this command */
-      
+
     cmd[0] = address & 0xFF;
     cmd[1] = address >> 8;
     cmd[2] = page_size & 0xFF;
@@ -444,6 +450,86 @@ static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
+
+/* The list of SCK frequencies in kHz supported by USBasp */
+static struct sckoptions_t usbaspSCKoptions[] = {
+  { USBASP_ISP_SCK_1500, 1500 },
+  { USBASP_ISP_SCK_750, 750 },
+  { USBASP_ISP_SCK_375, 375 },
+  { USBASP_ISP_SCK_187_5, 187.5 },
+  { USBASP_ISP_SCK_93_75, 93.75 },
+  { USBASP_ISP_SCK_32, 32 },
+  { USBASP_ISP_SCK_16, 16 },
+  { USBASP_ISP_SCK_8, 8 },
+  { USBASP_ISP_SCK_4, 4 },
+  { USBASP_ISP_SCK_2, 2 },
+  { USBASP_ISP_SCK_1, 1 },
+  { USBASP_ISP_SCK_0_5, 0.5 }
+};
+
+
+/*
+ * Set sck period (in seconds)
+ * Find next possible sck period and write it to the programmer.
+ */
+static int usbasp_set_sck_period(PROGRAMMER *pgm, double sckperiod)
+{
+  char clockoption = USBASP_ISP_SCK_AUTO;
+  unsigned char res[4];
+  unsigned char cmd[4];
+
+  memset(cmd, 0, sizeof(cmd));
+  memset(res, 0, sizeof(res));
+
+  if (sckperiod == 0) {
+    /* auto sck set */
+
+    if (verbose >= 1)
+      fprintf(stderr, "%s: auto set sck period (because given equals null)\n", progname);
+
+  } else {
+
+    double sckfreq = 1 / sckperiod / 1000; /* sck in kHz */
+    double usefreq = 0;
+
+    if (verbose >= 2)
+      fprintf(stderr, "%s: try to set SCK period to %g s (= %g kHz)\n", progname, sckperiod, sckfreq);
+
+    if (sckperiod >= 1500) {
+      clockoption = USBASP_ISP_SCK_1500;
+      usefreq = 1500;
+
+    } else {
+
+      /* find clock option next to given clock */
+      int i;
+      for (i = 0; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
+        if (sckfreq >= usbaspSCKoptions[i].frequency) {
+          clockoption = usbaspSCKoptions[i].id;
+          usefreq = usbaspSCKoptions[i].frequency;
+          break;
+        }
+      }
+    }
+
+    fprintf(stderr, "%s: set SCK frequency to %g kHz\n", progname, usefreq);
+  }
+
+  cmd[0] = clockoption;
+
+  int nbytes =
+    usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res));
+
+  if ((nbytes != 1) | (res[0] != 0)) {
+    fprintf(stderr, "%s: warning: cannot set sck period. please check for usbasp firmware update.\n",
+      progname);
+    return -1;
+  }
+
+  return 0;
+}
+
+
 void usbasp_initpgm(PROGRAMMER * pgm)
 {
   strcpy(pgm->type, "usbasp");
@@ -472,6 +558,7 @@ void usbasp_initpgm(PROGRAMMER * pgm)
   pgm->paged_load = usbasp_paged_load;
   pgm->setup          = usbasp_setup;
   pgm->teardown       = usbasp_teardown;
+  pgm->set_sck_period	= usbasp_set_sck_period;
 
 }
 
diff --git a/avrdude/usbasp.h b/avrdude/usbasp.h
index 2da429bc..c0d4468f 100644
--- a/avrdude/usbasp.h
+++ b/avrdude/usbasp.h
@@ -24,13 +24,14 @@
 
 #include "avrpart.h"
 
-
+/* USB identifiers */
 #define	USBASP_SHARED_VID   0x16C0  /* VOTI */
 #define	USBASP_SHARED_PID   0x05DC  /* Obdev's free shared PID */
 
 #define	USBASP_OLD_VID      0x03EB  /* ATMEL */
 #define	USBASP_OLD_PID	    0xC7B4  /* (unoffical) USBasp */
 
+/* USB function call identifiers */
 #define USBASP_FUNC_CONNECT    1
 #define USBASP_FUNC_DISCONNECT 2
 #define USBASP_FUNC_TRANSMIT   3
@@ -40,13 +41,37 @@
 #define USBASP_FUNC_READEEPROM 7
 #define USBASP_FUNC_WRITEEEPROM 8
 #define USBASP_FUNC_SETLONGADDRESS 9
+#define USBASP_FUNC_SETISPSCK 10
 
+/* Block mode flags */
 #define USBASP_BLOCKFLAG_FIRST    1
 #define USBASP_BLOCKFLAG_LAST     2
 
+/* Block mode data size */
 #define USBASP_READBLOCKSIZE   200
 #define USBASP_WRITEBLOCKSIZE  200
 
+/* ISP SCK speed identifiers */
+#define USBASP_ISP_SCK_AUTO   0
+#define USBASP_ISP_SCK_0_5    1   /* 500 Hz */
+#define USBASP_ISP_SCK_1      2   /*   1 kHz */
+#define USBASP_ISP_SCK_2      3   /*   2 kHz */
+#define USBASP_ISP_SCK_4      4   /*   4 kHz */
+#define USBASP_ISP_SCK_8      5   /*   8 kHz */
+#define USBASP_ISP_SCK_16     6   /*  16 kHz */
+#define USBASP_ISP_SCK_32     7   /*  32 kHz */
+#define USBASP_ISP_SCK_93_75  8   /*  93.75 kHz */
+#define USBASP_ISP_SCK_187_5  9   /* 187.5  kHz */
+#define USBASP_ISP_SCK_375    10  /* 375 kHz   */
+#define USBASP_ISP_SCK_750    11  /* 750 kHz   */
+#define USBASP_ISP_SCK_1500   12  /* 1.5 MHz   */
+
+typedef struct sckoptions_t {
+  int id;
+  double frequency;
+} CLOCKOPTIONS;
+
+/* USB error identifiers */
 #define USB_ERROR_NOTFOUND  1
 #define USB_ERROR_ACCESS    2
 #define USB_ERROR_IO        3