From eb1fc2c92003420eab641c5f53a3047f09d9fbe3 Mon Sep 17 00:00:00 2001
From: Gordon Henderson <projects@drogon.net>
Date: Fri, 30 Jan 2015 18:14:49 +0000
Subject: [PATCH] Updates to the build process Moved the extensions into
 wiringPi from gpio and made it more general purpose more so that RTB and
 anything else can dymanically add devices into wiringPi. Changes to GPIO to
 updates for the SPI and I2C module loads Added gpio unload for SPI and I2C.

Added a new way to setup SPI - by passing the mode in.

Support for the new Pi2 thing too
---
 build                                         |  49 +++++++++
 gpio/Makefile                                 |   7 +-
 gpio/gpio.1                                   |  79 ++++++--------
 gpio/gpio.c                                   | 144 ++++++++++++--------------
 gpio/pins.c                                   |   2 +-
 gpio/pintest                                  |  16 +--
 gpio/readall.c                                |  25 +++--
 wiringPi/Makefile                             |   9 +-
 wiringPi/wiringPi.c                           |  76 ++++++++++----
 wiringPi/wiringPi.h                           |   6 +-
 wiringPi/wiringPiSPI.c                        |  28 +++--
 wiringPi/wiringPiSPI.h                        |   9 +-
 gpio/extensions.c => wiringPi/wpiExtensions.c | 136 ++++++++++++++----------
 gpio/extensions.h => wiringPi/wpiExtensions.h |   4 +-
 14 files changed, 345 insertions(+), 245 deletions(-)
 rename gpio/extensions.c => wiringPi/wpiExtensions.c (78%)
 rename gpio/extensions.h => wiringPi/wpiExtensions.h (89%)

diff --git a/build b/build
index bac483a..377bd16 100755
--- a/build
+++ b/build
@@ -1,5 +1,36 @@
 #!/bin/sh
 
+# build
+#	Simple wiringPi build and install script
+#
+#	Copyright (c) 2012-2015 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#	Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Lesser General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi 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 Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+#
+# wiringPi is designed to run on a Raspberry Pi only.
+#	However if you're clever enough to actually look at this script to
+#	see why it's not building for you, then good luck.
+#
+#	To everyone else: Stop using cheap alternatives. Support the
+#	Raspberry Pi Foundation	as they're the only ones putting money
+#	back into education!
+#################################################################################
+
 check_make_ok() {
   if [ $? != 0 ]; then
     echo ""
@@ -47,6 +78,24 @@ fi
   echo "====================="
   echo
 
+  hardware=`fgrep Hardware /proc/cpuinfo | head -1 | awk '{ print $3 }'`
+
+  if [ x$hardware != "xBCM2708" ]; then
+    echo ""
+    echo "   +------------------------------------------------------------+"
+    echo "   |   wiringPi is designed to run on the Raspberry Pi only.    |"
+    echo "   |   This processor does not appear to be a Raspberry Pi.     |"
+    echo "   +------------------------------------------------------------+"
+    echo "   | In the unlikely event that you think it is a Raspberry Pi, |"
+    echo "   | then please accept my apologies and email the contents of  |"
+    echo "   | /proc/cpuinfo to projects@drogon.net.                      |"
+    echo "   |    - Thanks, Gordon                                        |"
+    echo "   +------------------------------------------------------------+"
+    echo ""
+    exit 1
+  fi
+
+
   echo
   echo "WiringPi Library"
   cd wiringPi
diff --git a/gpio/Makefile b/gpio/Makefile
index 37b4887..9c8585f 100644
--- a/gpio/Makefile
+++ b/gpio/Makefile
@@ -4,7 +4,7 @@
 #	  A swiss-army knige of GPIO shenanigans.
 #	https://projects.drogon.net/wiring-pi
 #
-#	Copyright (c) 2012-2013 Gordon Henderson
+#	Copyright (c) 2012-2015 Gordon Henderson
 #################################################################################
 # This file is part of wiringPi:
 #	Wiring Compatable library for the Raspberry Pi
@@ -38,7 +38,7 @@ LIBS    = -lwiringPi -lwiringPiDev -lpthread -lm
 # May not need to  alter anything below this line
 ###############################################################################
 
-SRC	=	gpio.c extensions.c readall.c pins.c
+SRC	=	gpio.c readall.c pins.c
 
 OBJ	=	$(SRC:.c=.o)
 
@@ -82,6 +82,3 @@ depend:
 	makedepend -Y $(SRC)
 
 # DO NOT DELETE
-
-gpio.o: extensions.h
-extensions.o: extensions.h
diff --git a/gpio/gpio.1 b/gpio/gpio.1
index e7131c1..2d3b860 100644
--- a/gpio/gpio.1
+++ b/gpio/gpio.1
@@ -1,4 +1,4 @@
-.TH "GPIO" "March 2013" "Command-Line access to Raspberry Pi's GPIO"
+.TH "GPIO" "January 2015" "Command-Line access to Raspberry Pi's GPIO"
 
 .SH NAME
 gpio \- Command-line access to Raspberry Pi's GPIO
@@ -21,7 +21,7 @@ gpio \- Command-line access to Raspberry Pi's GPIO
 .B ...
 .PP
 .B gpio
-.B readall/reset
+.B readall
 .PP
 .B gpio
 .B unexportall/exports
@@ -157,16 +157,6 @@ but it's unable to determine pin modes or states, so will perform both a
 digital and analog read on each pin in-turn.
 
 .TP
-.B reset
-Resets the GPIO - As much as it's possible to do. All pins are set to
-input mode and all the internal pull-up/down resistors are disconnected
-(tristate mode).
-
-The reset command is usable with an extension module (via the -x parameter),
-but it's limited to turning the pin into input mode (if applicable) and
-removing any pull up/down resistor.
-
-.TP
 .B pwm <pin> <value>
 Write a PWM value (0-1023) to the given pin. The pin needs to be put
 into PWM mode first.
@@ -182,6 +172,8 @@ Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also
 use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal
 pull-up, pull-down or tristate (off) controls.
 
+The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR,  ... \fIalt5\fR.
+
 .TP
 .B unexportall
 Un-Export all the GPIO pins in the /sys/class/gpio directory.
@@ -257,12 +249,30 @@ on the associated /dev/ entries so that the current user has access to
 them. Optionally it will set the I2C baudrate to that supplied in Kb/sec
 (or as close as the Pi can manage) The default speed is 100Kb/sec.
 
+Note that on a Pi with a recent 3.18 kernel with the device-tree structure
+enable, the load may fail until you add:
+
+.I dtparam=i2c=on
+
+into \fB/boot/config.txt\fR to allow user use of the I2C bus.
+
 .TP
-.B load spi [buffer size in KB]
+.B load spi
 This loads the spi drivers into the kernel and changes the permissions
 on the associated /dev/ entries so that the current user has access to
-them. Optionally it will set the SPI buffer size to that supplied. The
-default is 4KB.
+them. It used to have the ability to change the buffer size from the
+default of 4096 bytes to an arbitary value, however for some time the
+Pi Foundation have compiled the SPI device driver into the kernel and
+this has fixed the buffer size. The way to change it now is to edit
+the /boot/cmdline.txt file and add on spdev.bufsiz=8192 to set it to
+e.g. 8192 bytes then reboot.
+
+Note that on a Pi with a recent 3.18 kernel with the device-tree structure
+enable, the load may fail until you add:
+
+.I dtparam=spi=on
+
+into \fB/boot/config.txt\fR to allow user use of the I2C bus.
 
 .TP
 .B gbr
@@ -280,41 +290,12 @@ SPI digital to analogue converter.
 The board jumpers need to be in-place to do this operation.
 
 
-.SH "WiringPi vs. BCM_GPIO Pin numbering"
+.SH "WiringPi vs. BCM_GPIO Pin numbering vs. Physical pin numbering"
 
 .PP
-.TS
-c c c c l.
-WiringPi	GPIO-r1	GPIO-r2	P1-Phys	Function
-_
- 0	17	17	11	
- 1	18	18	12	(PWM)
- 2	21	27	13
- 3	22	22	15
- 4	23	23	16
- 5	24	24	18
- 6	25	25	22
- 7	4	4	7
- 8	0	2	3	I2C: SDA0
- 9	1	3	5	I2C: SCL0
-10	8	8	24	SPI: CE0
-11	7	7	26	SPI: CE1
-12	10	10	19	SPI: MOSI
-13	9	9	21	SPI: MISO
-14	11	11	23	SPI: SCLK
-15	14	14	8	TxD
-16	15	16	10	RxD
-17	-	28
-18	-	29
-19	-	30
-20	-	31
-.TE
-
-Note that "r1" and "r2" above refers to the board revision. Normally
-wiringPi detects the correct board revision with use for it's own
-numbering scheme, but if you are using a Revision 2 board with some
-of the pins which change numbers between revisions you will need
-to alter your software.
+The quickest way to get a list of the pin differences is to run the command
+.TP
+gpio readall
 
 .SH FILES
 
@@ -361,7 +342,7 @@ Please report bugs to <projects@drogon.net>
 
 .SH COPYRIGHT
 
-Copyright (c) 2012-2013 Gordon Henderson
+Copyright (c) 2012-2015 Gordon Henderson
 This is free software; see the source for copying conditions. There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
diff --git a/gpio/gpio.c b/gpio/gpio.c
index 7881c65..3cee59f 100644
--- a/gpio/gpio.c
+++ b/gpio/gpio.c
@@ -2,7 +2,7 @@
  * gpio.c:
  *	Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
  *	Pi's GPIO.
- *	Copyright (c) 2012-2014 Gordon Henderson
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -35,11 +35,11 @@
 #include <sys/stat.h>
 
 #include <wiringPi.h>
+#include <wpiExtensions.h>
 
 #include <gertboard.h>
 #include <piFace.h>
 
-#include "extensions.h"
 
 extern int wiringPiDebug ;
 
@@ -53,7 +53,7 @@ extern void doPins       (void) ;
 #  define	FALSE	(1==2)
 #endif
 
-#define	VERSION			"2.22"
+#define	VERSION			"2.23"
 #define	PI_USB_POWER_CONTROL	38
 #define	I2CDETECT		"/usr/sbin/i2cdetect"
 
@@ -73,6 +73,7 @@ char *usage = "Usage: gpio -v\n"
 	      "       gpio pwmr <range> \n"
 	      "       gpio pwmc <divider> \n"
 	      "       gpio load spi/i2c\n"
+	      "       gpio unload spi/i2c\n"
 	      "       gpio i2cd/i2cdetect\n"
 	      "       gpio usbp high/low\n"
 	      "       gpio gbr <channel>\n"
@@ -115,12 +116,9 @@ static void changeOwner (char *cmd, char *file)
   if (chown (file, uid, gid) != 0)
   {
     if (errno == ENOENT)	// Warn that it's not there
-      fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
+      fprintf (stderr, "%s: Warning (not an error): File not present: %s\n", cmd, file) ;
     else
-    {
-      fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
-      exit (1) ;
-    }
+      fprintf (stderr, "%s: Warning (not an error): Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
   }
 }
 
@@ -167,7 +165,7 @@ static int moduleLoaded (char *modName)
 
 static void _doLoadUsage (char *argv [])
 {
-  fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
+  fprintf (stderr, "Usage: %s load <spi/i2c> [I2C baudrate in Kb/sec]\n", argv [0]) ;
   exit (1) ;
 }
 
@@ -190,7 +188,10 @@ static void doLoad (int argc, char *argv [])
     file1  = "/dev/spidev0.0" ;
     file2  = "/dev/spidev0.1" ;
     if (argc == 4)
-      sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ;
+    {
+      fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ;
+      exit (1) ;
+    }
     else if (argc > 4)
       _doLoadUsage (argv) ;
   }
@@ -210,13 +211,13 @@ static void doLoad (int argc, char *argv [])
 
   if (!moduleLoaded (module1))
   {
-    sprintf (cmd, "modprobe %s%s", module1, args1) ;
+    sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ;
     system (cmd) ;
   }
 
   if (!moduleLoaded (module2))
   {
-    sprintf (cmd, "modprobe %s%s", module2, args2) ;
+    sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ;
     system (cmd) ;
   }
 
@@ -234,6 +235,53 @@ static void doLoad (int argc, char *argv [])
 
 
 /*
+ * doUnLoad:
+ *	Un-Load either the spi or i2c modules and change device ownerships, etc.
+ *********************************************************************************
+ */
+
+static void _doUnLoadUsage (char *argv [])
+{
+  fprintf (stderr, "Usage: %s unload <spi/i2c>\n", argv [0]) ;
+  exit (1) ;
+}
+
+static void doUnLoad (int argc, char *argv [])
+{
+  char *module1, *module2 ;
+  char cmd [80] ;
+
+  if (argc != 3)
+    _doUnLoadUsage (argv) ;
+
+  /**/ if (strcasecmp (argv [2], "spi") == 0)
+  {
+    module1 = "spidev" ;
+    module2 = "spi_bcm2708" ;
+  }
+  else if (strcasecmp (argv [2], "i2c") == 0)
+  {
+    module1 = "i2c_dev" ;
+    module2 = "i2c_bcm2708" ;
+  }
+  else
+    _doUnLoadUsage (argv) ;
+
+  if (moduleLoaded (module1))
+  {
+    sprintf (cmd, "/sbin/rmmod %s", module1) ;
+    system (cmd) ;
+  }
+
+  if (moduleLoaded (module2))
+  {
+    sprintf (cmd, "/sbin/rmmod %s", module2) ;
+    system (cmd) ;
+  }
+}
+
+
+/*
  * doI2Cdetect:
  *	Run the i2cdetect command with the right runes for this Pi revision
  *********************************************************************************
@@ -587,24 +635,6 @@ void doUnexportall (char *progName)
 
 
 /*
- * doResetExternal:
- *	Load readallExternal, we try to do this with an external device.
- *********************************************************************************
- */
-
-static void doResetExternal (void)
-{
-  int pin ;
-
-  for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin)
-  {
-    pinMode         (pin, INPUT) ;
-    pullUpDnControl (pin, PUD_OFF) ;
-  }
-}
-
-
-/*
  * doReset:
  *	Reset the GPIO pins - as much as we can do
  *********************************************************************************
@@ -612,45 +642,9 @@ static void doResetExternal (void)
 
 static void doReset (char *progName)
 {
-  int model, rev, mem, maker, overVolted ;
-  int pin, endPin ;
-
-  printf ("GPIO Reset is dangerous!\n") ;
-  printf (" - Do Not rely on this to do anything sensible!\n") ;
-
-  if (wiringPiNodes != NULL)	// External
-  {
-    doResetExternal () ;
-    return ;
-  }
-
-  piBoardId (&model, &rev, &mem, &maker, &overVolted) ;
-
-  /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B))
-    endPin = 16 ;
-  else if (model == PI_MODEL_BP)
-    endPin = 39 ;
-  else if (model == PI_MODEL_CM)
-  {
-    printf (" - Don't know how to reset a comput module:\n") ;
-    printf ("   Write a shell-script to reset the pins to the state you need.\n") ;
-    return ;
-  }
-  else
-  {
-    printf ("Oops - unable to determine board type... model: %d\n", model) ;
-    return ;
-  }
-
-  for (pin = 0 ; pin <= endPin ; ++pin)
-  {
-    if (wpiPinToGpio (pin) == -1)
-      continue ;
-
-    digitalWrite    (pin, LOW) ;
-    pinMode         (pin, INPUT) ;
-    pullUpDnControl (pin, PUD_OFF) ;
-  }
+  printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ;
+  printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ;
+  printf ("   that you need them in for your applications.\n") ;
 }
 
 
@@ -686,9 +680,6 @@ void doMode (int argc, char *argv [])
   else if (strcasecmp (mode, "down")    == 0) pullUpDnControl (pin, PUD_DOWN) ;
   else if (strcasecmp (mode, "tri")     == 0) pullUpDnControl (pin, PUD_OFF) ;
   else if (strcasecmp (mode, "off")     == 0) pullUpDnControl (pin, PUD_OFF) ;
-
-// Undocumented
-
   else if (strcasecmp (mode, "alt0")    == 0) pinModeAlt (pin, 0b100) ;
   else if (strcasecmp (mode, "alt1")    == 0) pinModeAlt (pin, 0b101) ;
   else if (strcasecmp (mode, "alt2")    == 0) pinModeAlt (pin, 0b110) ;
@@ -1183,7 +1174,7 @@ int main (int argc, char *argv [])
   if (strcmp (argv [1], "-v") == 0)
   {
     printf ("gpio version: %s\n", VERSION) ;
-    printf ("Copyright (c) 2012-2014 Gordon Henderson\n") ;
+    printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
     printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
     printf ("For details type: %s -warranty\n", argv [0]) ;
     printf ("\n") ;
@@ -1206,7 +1197,7 @@ int main (int argc, char *argv [])
   if (strcasecmp (argv [1], "-warranty") == 0)
   {
     printf ("gpio version: %s\n", VERSION) ;
-    printf ("Copyright (c) 2012-2014 Gordon Henderson\n") ;
+    printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
     printf ("\n") ;
     printf ("    This program is free software; you can redistribute it and/or modify\n") ;
     printf ("    it under the terms of the GNU Leser General Public License as published\n") ;
@@ -1240,7 +1231,8 @@ int main (int argc, char *argv [])
 
 // Check for load command:
 
-  if (strcasecmp (argv [1], "load" ) == 0)	{ doLoad     (argc, argv) ; return 0 ; }
+  if (strcasecmp (argv [1], "load"   ) == 0)	{ doLoad   (argc, argv) ; return 0 ; }
+  if (strcasecmp (argv [1], "unload" ) == 0)	{ doUnLoad (argc, argv) ; return 0 ; }
 
 // Gertboard commands
 
@@ -1301,7 +1293,7 @@ int main (int argc, char *argv [])
       exit (EXIT_FAILURE) ;
     }
 
-    if (!doExtension (argv [0], argv [2]))	// Prints its own error messages
+    if (!loadWPiExtension (argv [0], argv [2], TRUE))	// Prints its own error messages
       exit (EXIT_FAILURE) ;
 
     for (i = 3 ; i < argc ; ++i)
diff --git a/gpio/pins.c b/gpio/pins.c
index 19fcc1a..d889a45 100644
--- a/gpio/pins.c
+++ b/gpio/pins.c
@@ -1,7 +1,7 @@
 /*
  * pins.c:
  *	Just display a handy Pi pinnout diagram.
- *	Copyright (c) 2012-2013 Gordon Henderson
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
diff --git a/gpio/pintest b/gpio/pintest
index 83ca12a..4da3d94 100755
--- a/gpio/pintest
+++ b/gpio/pintest
@@ -2,7 +2,7 @@
 #
 # pintest
 #	Test the Pi's GPIO port
-# Copyright (c) 2013 Gordon Henderson
+# Copyright (c) 2013-2015 Gordon Henderson
 #################################################################################
 # This file is part of wiringPi:
 #	Wiring Compatable library for the Raspberry Pi
@@ -104,13 +104,11 @@ testPins()
 
 intro()
 {
-  revision=`gpio -V`
   cat <<EOF
 PinTest
 =======
 
-This is a simple utility to test the GPIO pins on your revision $revision
-Raspberry Pi.
+This is a simple utility to test the GPIO pins on your Raspberry Pi.
 
 NOTE: All GPIO peripherals must be removed to perform this test. This
   includes serial, I2C and SPI connections. You may get incorrect results
@@ -123,6 +121,9 @@ the output drivers.
 You will need to reboot your Pi after this test if you wish to use the 
 serial port as it will be left in GPIO mode rather than serial mode.
 
+This test only tests the original pins present on the Rev A and B. It
+does not test the extra pins on the Revision A2, B2 nor the A+ or B+
+
 Please make sure everything is removed and press the ENTER key to continue,
 EOF
 
@@ -136,7 +137,6 @@ EOF
 
 intro
 gpio unexportall
-gpio reset
 
    errs=0
 totErrs=0
@@ -147,12 +147,6 @@ echo ""
 
 testPins 0 7 "The main 8 GPIO pins"
 
-# P5 pins, if a rev 2:
-
-if [ $revision = 2 ]; then
-  testPins 17 20 "The 4 pins on the P5 connector"
-fi
-
 # SPI
 
 testPins 10 14 "The 5 SPI pins"
diff --git a/gpio/readall.c b/gpio/readall.c
index aba8de8..cf9b5f0 100644
--- a/gpio/readall.c
+++ b/gpio/readall.c
@@ -1,7 +1,7 @@
 /*
  * readall.c:
  *	The readall functions - getting a bit big, so split them out.
- *	Copyright (c) 2012-2013 Gordon Henderson
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -283,14 +283,22 @@ void abReadall (int model, int rev)
  *********************************************************************************
  */
 
+static void plus2header (int model)
+{
+  /**/ if (model == PI_MODEL_AP)
+    printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ;
+  else if (model == PI_MODEL_BP)
+    printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ;
+  else
+    printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ;
+}
+
+
 void piPlusReadall (int model)
 {
   int pin ;
 
-  if (model == PI_MODEL_AP)
-    printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ;
-  else
-    printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ;
+  plus2header (model) ;
 
   printf (" | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |\n") ;
   printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
@@ -299,10 +307,7 @@ void piPlusReadall (int model)
   printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ;
   printf (" | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |\n") ;
 
-  if (model == PI_MODEL_AP)
-    printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ;
-  else
-    printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ;
+  plus2header (model) ;
 }
 
 
@@ -320,7 +325,7 @@ void doReadall (void)
 
   /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B))
     abReadall (model, rev) ;
-  else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP))
+  else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2))
     piPlusReadall (model) ;
   else if (model == PI_MODEL_CM)
     cmReadall () ;
diff --git a/wiringPi/Makefile b/wiringPi/Makefile
index 4e3342e..1a06c35 100644
--- a/wiringPi/Makefile
+++ b/wiringPi/Makefile
@@ -57,7 +57,8 @@ SRC	=	wiringPi.c						\
 		sn3218.c						\
 		drcSerial.c	\
 		pca9685.c \
-		dac7678.c
+		dac7678.c \
+		wpiExtensions.c
 
 OBJ	=	$(SRC:.c=.o)
 
@@ -120,6 +121,7 @@ install-headers:
 	@install -m 0644 pca9685.h		$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 pca9685reg.h	$(DESTDIR)$(PREFIX)/include
 	@install -m 0644 dac7678.h		$(DESTDIR)$(PREFIX)/include
+	@install -m 0644 wpiExtensions.h	$(DESTDIR)$(PREFIX)/include
 
 .PHONY:	install
 install:	$(DYNAMIC) install-headers
@@ -164,6 +166,7 @@ uninstall:
 	@rm -f $(DESTDIR)$(PREFIX)/include/pca9685.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/pca9685reg.h
 	@rm -f $(DESTDIR)$(PREFIX)/include/dac7678.h
+	@rm -f $(DESTDIR)$(PREFIX)/includewpiExtensions.h
 	@rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.*
 	@ldconfig
 
@@ -201,3 +204,7 @@ max31855.o: wiringPi.h wiringPiSPI.h max31855.h
 drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h
 pca9685.o: wiringPi.h pca9685.h pca9685reg.h
 dac7678.o: wiringPi.h wiringPiI2C.h dac7678.h
+wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h
+wpiExtensions.o: mcp23s17.h sr595.h pcf8591.h pcf8574.h max31855.h max5322.h
+wpiExtensions.o: mcp3002.h mcp3004.h mcp4802.h mcp3422.h sn3218.h drcSerial.h
+wpiExtensions.o: wpiExtensions.h
diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c
index 1c82aee..990c641 100644
--- a/wiringPi/wiringPi.c
+++ b/wiringPi/wiringPi.c
@@ -131,7 +131,7 @@ struct wiringPiNodeStruct *wiringPiNodes = NULL ;
 //	Taken from Gert/Doms code. Some of this is not in the manual
 //	that I can find )-:
 
-#define BCM2708_PERI_BASE	                     0x20000000
+static volatile unsigned int	BCM2708_PERI_BASE =  0x20000000 ;
 #define GPIO_PADS		(BCM2708_PERI_BASE + 0x00100000)
 #define CLOCK_BASE		(BCM2708_PERI_BASE + 0x00101000)
 #define GPIO_BASE		(BCM2708_PERI_BASE + 0x00200000)
@@ -203,7 +203,9 @@ static volatile uint32_t *timerIrqRaw ;
 //	and PI_VERSION_X defines in wiringPi.h
 //	Only intended for the gpio command - use at your own risk!
 
-const char *piModelNames [6] =
+static int piModel2 = FALSE ;
+
+const char *piModelNames [7] =
 {
   "Unknown",
   "Model A",
@@ -211,6 +213,7 @@ const char *piModelNames [6] =
   "Model B+",
   "Compute Module",
   "Model A+",
+  "Model 2",	// Quad Core
 } ;
 
 const char *piRevisionNames [5] =
@@ -604,6 +607,7 @@ int wiringPiFailure (int fatal, const char *message, ...)
  *
  *	Revision 1 really means the early Model B's.
  *	Revision 2 is everything else - it covers the B, B+ and CM.
+ *		... and the quad core Pi 2 - which is a B+ ++  ...
  *
  *	Seems there are some boards with 0000 in them (mistake in manufacture)
  *	So the distinction between boards that I can see is:
@@ -624,6 +628,9 @@ int wiringPiFailure (int fatal, const char *message, ...)
  *	0011 - Pi CM,    Rev 1.2, 512MB, Sony
  *	0012 - Model A+  Rev 1.2, 256MB, Sony
  *
+ *	For the Pi 2:
+ *	0010 - Model 2, Rev 1.1, Quad Core, 1GB, Sony
+ *
  *	A small thorn is the olde style overvolting - that will add in
  *		1000000
  *
@@ -657,6 +664,27 @@ int piBoardRev (void)
   if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
     piBoardRevOops ("Unable to open /proc/cpuinfo") ;
 
+// Start by looking for the Architecture, then we can look for a B2 revision....
+
+  while (fgets (line, 120, cpuFd) != NULL)
+    if (strncmp (line, "model name", 10) == 0)
+      break ;
+
+  if (strncmp (line, "model name", 10) != 0)
+    piBoardRevOops ("No \"model name\" line") ;
+
+  if (wiringPiDebug)
+    printf ("piboardRev: Model name: %s\n", line) ;
+
+// See if it's v7
+
+  if (strstr (line, "ARMv7") != NULL)
+    piModel2 = TRUE ;
+
+// Now do the rest of it as before
+
+  rewind (cpuFd) ;
+
   while (fgets (line, 120, cpuFd) != NULL)
     if (strncmp (line, "Revision", 8) == 0)
       break ;
@@ -774,22 +802,30 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted)
 
 // Fill out the replys as appropriate
 
-  /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_1   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
-  else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_1_1 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
-  else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_SONY   ; }
-  else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_QISDA  ; }
-  else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
-  else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
-  else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_SONY ; ; }
-  else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_QISDA  ; }
-  else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
-  else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
-  else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
-  else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
-  else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
-  else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 256 ; *maker = PI_MAKER_SONY   ; }
-  else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_MBEST  ; }
-  else                              { *model = 0           ; *rev = 0              ; *mem =   0 ; *maker = 0 ;               }
+  if (piModel2)
+  {
+    /**/ if (strcmp (c, "0010") == 0) { *model = PI_MODEL_2  ; *rev = PI_VERSION_1_1 ; *mem = 1024 ; *maker = PI_MAKER_SONY   ; }
+    else                              { *model = 0           ; *rev = 0              ; *mem =    0 ; *maker = 0 ;               }
+  }
+  else
+  {
+    /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_1   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+    else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_1_1 ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+    else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_SONY   ; }
+    else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_QISDA  ; }
+    else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+    else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_EGOMAN ; }
+    else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_SONY ; ; }
+    else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 256 ; *maker = PI_MAKER_QISDA  ; }
+    else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
+    else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
+    else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B  ; *rev = PI_VERSION_2   ; *mem = 512 ; *maker = PI_MAKER_EGOMAN ; }
+    else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
+    else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_SONY   ; }
+    else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 256 ; *maker = PI_MAKER_SONY   ; }
+    else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 512 ; *maker = PI_MAKER_MBEST  ; }
+    else                              { *model = 0           ; *rev = 0              ; *mem =   0 ; *maker = 0 ;               }
+  }
 }
  
 
@@ -1770,8 +1806,10 @@ int wiringPiSetup (void)
      pinToGpio =  pinToGpioR1 ;
     physToGpio = physToGpioR1 ;
   }
-  else 				// A, B, Rev 2, B+, CM
+  else 				// A, B, Rev 2, B+, CM, Pi2
   {
+    if (piModel2)
+      BCM2708_PERI_BASE = 0x3F000000 ;
      pinToGpio =  pinToGpioR2 ;
     physToGpio = physToGpioR2 ;
   }
diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h
index 2b3e295..dd110fa 100644
--- a/wiringPi/wiringPi.h
+++ b/wiringPi/wiringPi.h
@@ -76,6 +76,7 @@
 #define	PI_MODEL_BP		3
 #define	PI_MODEL_CM		4
 #define	PI_MODEL_AP		5
+#define	PI_MODEL_2		6
 
 #define	PI_VERSION_UNKNOWN	0
 #define	PI_VERSION_1		1
@@ -89,7 +90,7 @@
 #define	PI_MAKER_QISDA		3
 #define	PI_MAKER_MBEST		4
 
-extern const char *piModelNames    [6] ;
+extern const char *piModelNames    [7] ;
 extern const char *piRevisionNames [5] ;
 extern const char *piMakerNames    [5] ;
 
@@ -149,9 +150,6 @@ extern "C" {
 
 // Data
 
-//extern const char *piModelNames [] ;
-//extern const char *piRevisionNames[] ;
-
 // Internal
 
 extern int wiringPiFailure (int fatal, const char *message, ...) ;
diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c
index 002ee01..453df31 100644
--- a/wiringPi/wiringPiSPI.c
+++ b/wiringPi/wiringPiSPI.c
@@ -1,7 +1,7 @@
 /*
  * wiringPiSPI.c:
  *	Simplified SPI access routines
- *	Copyright (c) 2012 Gordon Henderson
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -40,7 +40,6 @@
 
 const static char       *spiDev0  = "/dev/spidev0.0" ;
 const static char       *spiDev1  = "/dev/spidev0.1" ;
-const static uint8_t     spiMode  = 0 ;
 const static uint8_t     spiBPW   = 8 ;
 const static uint16_t    spiDelay = 0 ;
 
@@ -92,16 +91,17 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len)
 
 
 /*
- * wiringPiSPISetup:
- *	Open the SPI device, and set it up, etc.
+ * wiringPiSPISetupMode:
+ *	Open the SPI device, and set it up, with the mode, etc.
  *********************************************************************************
  */
 
-int wiringPiSPISetup (int channel, int speed)
+int wiringPiSPISetupMode (int channel, int speed, int mode)
 {
   int fd ;
 
-  channel &= 1 ;
+  mode    &= 3 ;	// Mode is 0, 1, 2 or 3
+  channel &= 1 ;	// Channel is 0 or 1
 
   if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0)
     return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ;
@@ -110,10 +110,8 @@ int wiringPiSPISetup (int channel, int speed)
   spiFds    [channel] = fd ;
 
 // Set SPI parameters.
-//	Why are we reading it afterwriting it? I've no idea, but for now I'm blindly
-//	copying example code I've seen online...
 
-  if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode)         < 0)
+  if (ioctl (fd, SPI_IOC_WR_MODE, &mode)            < 0)
     return wiringPiFailure (WPI_ALMOST, "SPI Mode Change failure: %s\n", strerror (errno)) ;
   
   if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
@@ -124,3 +122,15 @@ int wiringPiSPISetup (int channel, int speed)
 
   return fd ;
 }
+
+
+/*
+ * wiringPiSPISetup:
+ *	Open the SPI device, and set it up, etc. in the default MODE 0
+ *********************************************************************************
+ */
+
+int wiringPiSPISetup (int channel, int speed)
+{
+  return wiringPiSPISetupMode (channel, speed, 0) ;
+}
diff --git a/wiringPi/wiringPiSPI.h b/wiringPi/wiringPiSPI.h
index f53697d..3980321 100644
--- a/wiringPi/wiringPiSPI.h
+++ b/wiringPi/wiringPiSPI.h
@@ -1,7 +1,7 @@
 /*
  * wiringPiSPI.h:
  *	Simplified SPI access routines
- *	Copyright (c) 2012 Gordon Henderson
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -26,9 +26,10 @@
 extern "C" {
 #endif
 
-int wiringPiSPIGetFd  (int channel) ;
-int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;
-int wiringPiSPISetup  (int channel, int speed) ;
+int wiringPiSPIGetFd     (int channel) ;
+int wiringPiSPIDataRW    (int channel, unsigned char *data, int len) ;
+int wiringPiSPISetupMode (int channel, int speed, int mode) ;
+int wiringPiSPISetup     (int channel, int speed) ;
 
 #ifdef __cplusplus
 }
diff --git a/gpio/extensions.c b/wiringPi/wpiExtensions.c
similarity index 78%
rename from gpio/extensions.c
rename to wiringPi/wpiExtensions.c
index 96d6255..da41f29 100644
--- a/gpio/extensions.c
+++ b/wiringPi/wpiExtensions.c
@@ -1,8 +1,10 @@
 /*
  * extensions.c:
- *	Part of the GPIO program to test, peek, poke and otherwise
+ *	Originally part of the GPIO program to test, peek, poke and otherwise
  *	noodle with the GPIO hardware on the Raspberry Pi.
- *	Copyright (c) 2012-2013 Gordon Henderson
+ *	Now used as a general purpose library to allow systems to dynamically
+ *	add in new devices into wiringPi at program run-time.
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -26,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <stdarg.h>
 #include <ctype.h>
 #include <string.h>
 #include <unistd.h>
@@ -35,27 +38,31 @@
 
 #include <wiringPi.h>
 
-#include <mcp23008.h>
-#include <mcp23016.h>
-#include <mcp23017.h>
-#include <mcp23s08.h>
-#include <mcp23s17.h>
-#include <sr595.h>
-#include <pcf8591.h>
-#include <pcf8574.h>
-#include <max31855.h>
-#include <max5322.h>
-#include <mcp3002.h>
-#include <mcp3004.h>
-#include <mcp4802.h>
-#include <mcp3422.h>
-#include <sn3218.h>
-#include <drcSerial.h>
-
-#include "extensions.h"
+#include "mcp23008.h"
+#include "mcp23016.h"
+#include "mcp23017.h"
+#include "mcp23s08.h"
+#include "mcp23s17.h"
+#include "sr595.h"
+#include "pcf8591.h"
+#include "pcf8574.h"
+#include "max31855.h"
+#include "max5322.h"
+#include "mcp3002.h"
+#include "mcp3004.h"
+#include "mcp4802.h"
+#include "mcp3422.h"
+#include "sn3218.h"
+#include "drcSerial.h"
+
+#include "wpiExtensions.h"
 
 extern int wiringPiDebug ;
 
+static int verbose ;
+static char errorMessage [1024] ;
+
+
 #ifndef TRUE
 #  define	TRUE	(1==1)
 #  define	FALSE	(1==2)
@@ -71,6 +78,24 @@ struct extensionFunctionStruct
 
 
 /*
+ * verbError:
+ *	Convenient error handling
+ *********************************************************************************
+ */
+
+static void verbError (const char *message, ...)
+{
+  va_list argp ;
+  va_start (argp, message) ;
+    vsnprintf (errorMessage, 1023, message, argp) ;
+  va_end (argp) ;
+
+  if (verbose)
+    fprintf (stderr, "%s\n", errorMessage) ;
+}
+
+
+/*
  * extractInt:
  *	Check & return an integer at the given location (prefixed by a :)
  *********************************************************************************
@@ -80,7 +105,7 @@ static char *extractInt (char *progName, char *p, int *num)
 {
   if (*p != ':')
   {
-    fprintf (stderr, "%s: colon expected\n", progName) ;
+    verbError ("%s: colon expected", progName) ;
     return NULL ;
   }
 
@@ -88,7 +113,7 @@ static char *extractInt (char *progName, char *p, int *num)
 
   if (!isdigit (*p))
   {
-    fprintf (stderr, "%s: digit expected\n", progName) ;
+    verbError ("%s: digit expected", progName) ;
     return NULL ;
   }
 
@@ -112,7 +137,7 @@ static char *extractStr (char *progName, char *p, char **str)
 
   if (*p != ':')
   {
-    fprintf (stderr, "%s: colon expected\n", progName) ;
+    verbError ("%s: colon expected", progName) ;
     return NULL ;
   }
 
@@ -120,7 +145,7 @@ static char *extractStr (char *progName, char *p, char **str)
 
   if (!isprint (*p))
   {
-    fprintf (stderr, "%s: character expected\n", progName) ;
+    verbError ("%s: character expected", progName) ;
     return NULL ;
   }
 
@@ -152,9 +177,9 @@ static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
   if ((params = extractInt (progName, params, &i2c)) == NULL)
     return FALSE ;
 
-  if ((i2c < 0x03) || (i2c > 0x77))
+  if ((i2c < 0x01) || (i2c > 0x77))
   {
-    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
     return FALSE ;
   }
 
@@ -180,7 +205,7 @@ static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
 
   if ((i2c < 0x03) || (i2c > 0x77))
   {
-    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
     return FALSE ;
   }
 
@@ -206,7 +231,7 @@ static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
 
   if ((i2c < 0x03) || (i2c > 0x77))
   {
-    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
     return FALSE ;
   }
 
@@ -232,7 +257,7 @@ static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI address (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -241,7 +266,7 @@ static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
 
   if ((port < 0) || (port > 7))
   {
-    fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
+    verbError ("%s: port address (%d) out of range", progName, port) ;
     return FALSE ;
   }
 
@@ -267,7 +292,7 @@ static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI address (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI address (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -276,7 +301,7 @@ static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
 
   if ((port < 0) || (port > 7))
   {
-    fprintf (stderr, "%s: port address (%d) out of range\n", progName, port) ;
+    verbError ("%s: port address (%d) out of range", progName, port) ;
     return FALSE ;
   }
 
@@ -304,7 +329,7 @@ static int doExtensionSr595 (char *progName, int pinBase, char *params)
 
   if ((pins < 8) || (pins > 32))
   {
-    fprintf (stderr, "%s: pin count (%d) out of range - 8-32 expected.\n", progName, pins) ;
+    verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ;
     return FALSE ;
   }
 
@@ -339,7 +364,7 @@ static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
 
   if ((i2c < 0x03) || (i2c > 0x77))
   {
-    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
     return FALSE ;
   }
 
@@ -365,7 +390,7 @@ static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
 
   if ((i2c < 0x03) || (i2c > 0x77))
   {
-    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
     return FALSE ;
   }
 
@@ -391,7 +416,7 @@ static int doExtensionMax31855 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -417,7 +442,7 @@ static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -443,7 +468,7 @@ static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -469,7 +494,7 @@ static int doExtensionMax5322 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -495,7 +520,7 @@ static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
 
   if ((spi < 0) || (spi > 1))
   {
-    fprintf (stderr, "%s: SPI channel (%d) out of range\n", progName, spi) ;
+    verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
     return FALSE ;
   }
 
@@ -535,7 +560,7 @@ static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
 
   if ((i2c < 0x03) || (i2c > 0x77))
   {
-    fprintf (stderr, "%s: i2c address (0x%X) out of range\n", progName, i2c) ;
+    verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
     return FALSE ;
   }
 
@@ -544,7 +569,7 @@ static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
 
   if ((sampleRate < 0) || (sampleRate > 3))
   {
-    fprintf (stderr, "%s: sample rate (%d) out of range\n", progName, sampleRate) ;
+    verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ;
     return FALSE ;
   }
 
@@ -553,7 +578,7 @@ static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
 
   if ((gain < 0) || (gain > 3))
   {
-    fprintf (stderr, "%s: gain (%d) out of range\n", progName, gain) ;
+    verbError ("%s: gain (%d) out of range", progName, gain) ;
     return FALSE ;
   }
 
@@ -562,6 +587,7 @@ static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
   return TRUE ;
 }
 
+
 /*
  * doExtensionDrcS:
  *	Interface to a DRC Serial system
@@ -579,7 +605,7 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
 
   if ((pins < 1) || (pins > 100))
   {
-    fprintf (stderr, "%s: pins (%d) out of range (2-100)\n", progName, pins) ;
+    verbError ("%s: pins (%d) out of range (2-100)", progName, pins) ;
     return FALSE ;
   }
   
@@ -588,7 +614,7 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
 
   if (strlen (port) == 0)
   {
-    fprintf (stderr, "%s: serial port device name required\n", progName) ;
+    verbError ("%s: serial port device name required", progName) ;
     return FALSE ;
   }
 
@@ -597,7 +623,7 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
 
   if ((baud < 1) || (baud > 4000000))
   {
-    fprintf (stderr, "%s: baud rate (%d) out of range\n", progName, baud) ;
+    verbError ("%s: baud rate (%d) out of range", progName, baud) ;
     return FALSE ;
   }
 
@@ -613,7 +639,7 @@ static int doExtensionDrcS (char *progName, int pinBase, char *params)
  *********************************************************************************
  */
 
-struct extensionFunctionStruct extensionFunctions [] = 
+static struct extensionFunctionStruct extensionFunctions [] = 
 {
   { "mcp23008",		&doExtensionMcp23008 	},
   { "mcp23016",		&doExtensionMcp23016 	},
@@ -636,18 +662,20 @@ struct extensionFunctionStruct extensionFunctions [] =
 
 
 /*
- * doExtension:
+ * loadWPiExtension:
  *	Load in a wiringPi extension
  *********************************************************************************
  */
 
-int doExtension (char *progName, char *extensionData)
+int loadWPiExtension (char *progName, char *extensionData, int printErrors)
 {
   char *p ;
   char *extension = extensionData ;
   struct extensionFunctionStruct *extensionFn ;
   int pinBase = 0 ;
 
+  verbose = printErrors ;
+
 // Get the extension extension name by finding the first colon
 
   p = extension ;
@@ -655,7 +683,7 @@ int doExtension (char *progName, char *extensionData)
   {
     if (!*p)	// ran out of characters
     {
-      fprintf (stderr, "%s: extension name not terminated by a colon\n", progName) ;
+      verbError ("%s: extension name not terminated by a colon", progName) ;
       return FALSE ;
     }
     ++p ;
@@ -665,7 +693,7 @@ int doExtension (char *progName, char *extensionData)
 
   if (!isdigit (*p))
   {
-    fprintf (stderr, "%s: pinBase number expected after extension name\n", progName) ;
+    verbError ("%s: pinBase number expected after extension name", progName) ;
     return FALSE ;
   }
 
@@ -673,7 +701,7 @@ int doExtension (char *progName, char *extensionData)
   {
     if (pinBase > 1000000000)
     {
-      fprintf (stderr, "%s: pinBase too large\n", progName) ;
+      verbError ("%s: pinBase too large", progName) ;
       return FALSE ;
     }
 
@@ -683,7 +711,7 @@ int doExtension (char *progName, char *extensionData)
 
   if (pinBase < 64)
   {
-    fprintf (stderr, "%s: pinBase (%d) too small. Minimum is 64.\n", progName, pinBase) ;
+    verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ;
     return FALSE ;
   }
 
@@ -695,6 +723,6 @@ int doExtension (char *progName, char *extensionData)
       return extensionFn->function (progName, pinBase, p) ;
   }
 
-  fprintf (stderr, "%s: extension %s not found\n", progName, extension) ;
+  verbError ("%s: extension %s not found", progName, extension) ;
   return FALSE ;
 }
diff --git a/gpio/extensions.h b/wiringPi/wpiExtensions.h
similarity index 89%
rename from gpio/extensions.h
rename to wiringPi/wpiExtensions.h
index 5d27123..fcaec96 100644
--- a/gpio/extensions.h
+++ b/wiringPi/wpiExtensions.h
@@ -2,7 +2,7 @@
  * extensions.h:
  *	Part of the GPIO program to test, peek, poke and otherwise
  *	noodle with the GPIO hardware on the Raspberry Pi.
- *	Copyright (c) 2012-2013 Gordon Henderson
+ *	Copyright (c) 2012-2015 Gordon Henderson
  ***********************************************************************
  * This file is part of wiringPi:
  *	https://projects.drogon.net/raspberry-pi/wiringpi/
@@ -23,4 +23,4 @@
  */
 
 
-extern int doExtension (char *progName, char *extensionData) ;
+extern int loadWPiExtension (char *progName, char *extensionData, int verbose) ;
-- 
2.0.0.GIT

