Generalize SIM switching code and allow local/remote switching via USB
diff --git a/firmware/libboard/common/include/sim_switch.h b/firmware/libboard/common/include/sim_switch.h
new file mode 100644
index 0000000..16c5aa3
--- /dev/null
+++ b/firmware/libboard/common/include/sim_switch.h
@@ -0,0 +1,4 @@
+#pragma once
+
+int sim_switch_use_physical(unsigned int nr, int physical);
+int sim_switch_init(void);
diff --git a/firmware/libboard/common/source/sim_switch.c b/firmware/libboard/common/source/sim_switch.c
new file mode 100644
index 0000000..49e6cea
--- /dev/null
+++ b/firmware/libboard/common/source/sim_switch.c
@@ -0,0 +1,64 @@
+/* Code to switch between local (physical) and remote (emulated) SIM */
+
+#include "board.h"
+#include "trace.h"
+#include "sim_switch.h"
+
+#ifdef PIN_SIM_SWITCH1
+static const Pin pin_conn_usim1 = {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
+#endif
+#ifdef PIN_SIM_SWITCH2
+static const Pin pin_conn_usim2 = {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
+#endif
+
+static int initialized = 0;
+
+int sim_switch_use_physical(unsigned int nr, int physical)
+{
+ const Pin *pin;
+
+ if (!initialized) {
+ TRACE_ERROR("Somebody forgot to call sim_switch_init()\r\n");
+ sim_switch_init();
+ }
+
+ TRACE_INFO("Modem %d: %s SIM\n\r", nr,
+ physical ? "physical" : "virtual");
+
+ switch (nr) {
+#ifdef PIN_SIM_SWITCH1
+ case 1:
+ pin = &pin_conn_usim1;
+ break;
+#endif
+#ifdef PIN_SIM_SWITCH2
+ case 2:
+ pin = &pin_conn_usim2;
+ break;
+#endif
+ default:
+ TRACE_ERROR("Invalid SIM%u\n\r", nr);
+ return -1;
+ }
+
+ if (physical)
+ PIO_Clear(pin);
+ else
+ PIO_Set(pin);
+
+ return 0;
+}
+
+int sim_switch_init(void)
+{
+ int num_switch = 0;
+#ifdef PIN_SIM_SWITCH1
+ PIO_Configure(&pin_conn_usim1, 1);
+ num_switch++;
+#endif
+#ifdef PIN_SIM_SWITCH2
+ PIO_Configure(&pin_conn_usim2, 1);
+ num_switch++;
+#endif
+ return num_switch;
+}
diff --git a/firmware/libboard/qmod/include/board.h b/firmware/libboard/qmod/include/board.h
index 082d254..d49ff9d 100644
--- a/firmware/libboard/qmod/include/board.h
+++ b/firmware/libboard/qmod/include/board.h
@@ -56,6 +56,10 @@
#define PIN_VERSION_DET {PIO_PA19, PIOA, ID_PIOA, PIO_PERIPH_D, PIO_DEFAULT}
+/* GPIO towards SPDT switches between real SIM and SAM3 */
+#define PIN_SIM_SWITCH1 {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+#define PIN_SIM_SWITCH2 {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
+
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_NORWAKEUP
#define BOARD_USB_VENDOR_ID USB_VENDOR_OPENMOKO
diff --git a/firmware/libboard/qmod/source/board_qmod.c b/firmware/libboard/qmod/source/board_qmod.c
index 889d31e..54983d7 100644
--- a/firmware/libboard/qmod/source/board_qmod.c
+++ b/firmware/libboard/qmod/source/board_qmod.c
@@ -6,6 +6,7 @@
#include "utils.h"
#include "wwan_led.h"
#include "wwan_perst.h"
+#include "sim_switch.h"
#include "boardver_adc.h"
#include "card_pres.h"
#include "osmocom/core/timer.h"
@@ -17,37 +18,9 @@
static const Pin pin_peer_rst = {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
static const Pin pin_peer_erase = {PIO_PA11, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
-static const Pin pin_conn_usim1 = {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
-static const Pin pin_conn_usim2 = {PIO_PA28, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT};
-
/* array of generated USB Strings */
extern unsigned char *usb_strings[];
-static void qmod_use_physical_sim(unsigned int nr, int physical)
-{
- const Pin *pin;
-
- TRACE_INFO("Modem %d: %s SIM\n\r", nr,
- physical ? "physical" : "virtual");
-
- switch (nr) {
- case 1:
- pin = &pin_conn_usim1;
- break;
- case 2:
- pin = &pin_conn_usim2;
- break;
- default:
- TRACE_ERROR("Invalid SIM%u\n\r", nr);
- return;
- }
-
- if (physical)
- PIO_Clear(pin);
- else
- PIO_Set(pin);
-}
-
static int qmod_sam3_is_12(void)
{
if (PIO_Get(&pin_1234_detect) == 0)
@@ -218,10 +191,10 @@
wwan_perst_do_reset_pulse(2, 300);
break;
case '!':
- qmod_use_physical_sim(1, 0);
+ sim_switch_use_physical(1, 0);
break;
case '@':
- qmod_use_physical_sim(2, 0);
+ sim_switch_use_physical(2, 0);
break;
default:
if (!qmod_sam3_is_12())
@@ -238,6 +211,7 @@
wwan_led_init();
wwan_perst_init();
+ sim_switch_init();
/* make sure we can detect whether running in ST12 or ST34 */
PIO_Configure(&pin_1234_detect, 1);
@@ -250,8 +224,6 @@
}
PIO_Configure(&pin_peer_rst, 1);
PIO_Configure(&pin_peer_erase, 1);
- PIO_Configure(&pin_conn_usim1, 1);
- PIO_Configure(&pin_conn_usim2, 1);
i2c_pin_init();
if (qmod_sam3_is_12()) {