pw_digital_io_pico: PicoDigitalIn implementation

- Add a PicoDigitalIn implementation
- Include a tear effect pin definition for rp2040 boards
- Setup the tear effect pin in common_pico.cc

Change-Id: Ib18bedfe7ebf5d909595e7ec00477b7e780c1505
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/experimental/+/169932
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
diff --git a/applications/app_common_impl/BUILD.gn b/applications/app_common_impl/BUILD.gn
index f47e05d..92e3f0a 100644
--- a/applications/app_common_impl/BUILD.gn
+++ b/applications/app_common_impl/BUILD.gn
@@ -24,6 +24,7 @@
     "-DDISPLAY_WIDTH=" + pw_app_common_DISPLAY_WIDTH,
     "-DDISPLAY_HEIGHT=" + pw_app_common_DISPLAY_HEIGHT,
     "-DDISPLAY_RESET_GPIO=" + pw_app_common_DISPLAY_RESET_GPIO,
+    "-DDISPLAY_TE_GPIO=" + pw_app_common_DISPLAY_TE_GPIO,
     "-DBACKLIGHT_GPIO=" + pw_app_common_BACKLIGHT_GPIO,
     "-DFRAMEBUFFER_WIDTH=" + pw_app_common_FRAMEBUFFER_WIDTH,
     "-DFRAMEBUFFER_START_X=" + pw_app_common_FRAMEBUFFER_START_X,
diff --git a/applications/app_common_impl/app_common_vars.gni b/applications/app_common_impl/app_common_vars.gni
index 9257edf..11c229c 100644
--- a/applications/app_common_impl/app_common_vars.gni
+++ b/applications/app_common_impl/app_common_vars.gni
@@ -33,6 +33,9 @@
   # Display backlight pin (ex "4", or "-1" if unused)
   pw_app_common_BACKLIGHT_GPIO = "-1"
 
+  # Display tear effect output GPIO pin (ex "2", or "-1" if unused)
+  pw_app_common_DISPLAY_TE_GPIO = "-1"
+
   # Display reset GPIO pin (ex "2", or "-1" if unused)
   pw_app_common_DISPLAY_RESET_GPIO = "-1"
 
diff --git a/applications/app_common_impl/common_pico.cc b/applications/app_common_impl/common_pico.cc
index 30e2ab5..8f1973a 100644
--- a/applications/app_common_impl/common_pico.cc
+++ b/applications/app_common_impl/common_pico.cc
@@ -42,6 +42,7 @@
 #endif
 
 using pw::Status;
+using pw::digital_io::PicoDigitalIn;
 using pw::digital_io::PicoDigitalOut;
 using pw::display::Display;
 using pw::framebuffer::Framebuffer;
@@ -100,6 +101,9 @@
 #if DISPLAY_RESET_GPIO != -1
 PicoDigitalOut s_display_reset_pin(DISPLAY_RESET_GPIO);
 #endif
+#if DISPLAY_TE_GPIO != -1
+PicoDigitalIn s_display_tear_effect_pin(DISPLAY_TE_GPIO);
+#endif
 PicoDigitalOut s_display_cs_pin(DISPLAY_CS_GPIO);
 PicoChipSelector s_spi_chip_selector(s_display_cs_pin);
 PicoInitiator s_spi_initiator(SPI_PORT);
@@ -127,6 +131,11 @@
 #else
   .reset_gpio = nullptr,
 #endif
+#if DISPLAY_TE_GPIO != -1
+  .tear_effect_gpio = &s_display_tear_effect_pin,
+#else
+  .tear_effect_gpio = nullptr,
+#endif
   .spi_device_8_bit = s_spi_8_bit.device,
   .spi_device_16_bit = s_spi_16_bit.device,
 });
@@ -167,6 +176,10 @@
   s_display_reset_pin.Enable();
 #endif
 
+#if DISPLAY_TE_GPIO != -1
+  s_display_tear_effect_pin.Enable();
+#endif
+
 #if BACKLIGHT_GPIO != -1
   SetBacklight(0xffff);  // Full brightness.
 #endif
diff --git a/pw_digital_io_pico/digital_io.cc b/pw_digital_io_pico/digital_io.cc
index ea18f17..7df4f62 100644
--- a/pw_digital_io_pico/digital_io.cc
+++ b/pw_digital_io_pico/digital_io.cc
@@ -20,9 +20,31 @@
 
 namespace pw::digital_io {
 
-PicoDigitalOut::PicoDigitalOut(uint32_t pin) : pin_(pin) {}
+PicoDigitalIn::PicoDigitalIn(uint32_t pin) : pin_(pin) {}
+
+// pw::digital_io::DigitalIn implementation:
+Status PicoDigitalIn::DoEnable(bool enable) {
+  if (!enable) {
+    // Added later: https://github.com/raspberrypi/pico-sdk/issues/792
+    // which first appeared in Pico SDK 1.3.0.
+    // Cannot find a way to check Pico SDK version at compile time.
+    // gpio_deinit(pin_);
+    return Status::Unavailable();
+  }
+
+  gpio_init(pin_);
+  gpio_set_dir(pin_, GPIO_IN);
+  return OkStatus();
+}
+
+Result<State> PicoDigitalIn::DoGetState() {
+  const pw::Result<State> result(State(gpio_get(pin_)));
+  return result;
+}
 
 // pw::digital_io::DigitalOut implementation:
+PicoDigitalOut::PicoDigitalOut(uint32_t pin) : pin_(pin) {}
+
 Status PicoDigitalOut::DoEnable(bool enable) {
   if (!enable) {
     // Added later: https://github.com/raspberrypi/pico-sdk/issues/792
diff --git a/pw_digital_io_pico/public/pw_digital_io_pico/digital_io.h b/pw_digital_io_pico/public/pw_digital_io_pico/digital_io.h
index 0138d2b..b04386c 100644
--- a/pw_digital_io_pico/public/pw_digital_io_pico/digital_io.h
+++ b/pw_digital_io_pico/public/pw_digital_io_pico/digital_io.h
@@ -32,4 +32,16 @@
   uint32_t pin_;
 };
 
+class PicoDigitalIn : public DigitalIn {
+ public:
+  PicoDigitalIn(uint32_t pin);
+
+  // pw::digital_io::DigitalIn implementation:
+  Status DoEnable(bool enable) override;
+  Result<State> DoGetState() override;
+
+ private:
+  uint32_t pin_;
+};
+
 }  // namespace pw::digital_io
diff --git a/pw_display_driver_st7789/public/pw_display_driver_st7789/display_driver.h b/pw_display_driver_st7789/public/pw_display_driver_st7789/display_driver.h
index e4910ef..7000a8a 100644
--- a/pw_display_driver_st7789/public/pw_display_driver_st7789/display_driver.h
+++ b/pw_display_driver_st7789/public/pw_display_driver_st7789/display_driver.h
@@ -30,6 +30,7 @@
     pw::digital_io::DigitalOut& data_cmd_gpio;
     // GPIO line to reset the display controller.
     pw::digital_io::DigitalOut* reset_gpio;
+    pw::digital_io::DigitalIn* tear_effect_gpio;
     // The SPI device to which the display controller is connected for 8-bit
     // data.
     pw::spi::Device& spi_device_8_bit;
diff --git a/targets/rp2040/board_configs.gni b/targets/rp2040/board_configs.gni
index 454efb5..e114ecc 100644
--- a/targets/rp2040/board_configs.gni
+++ b/targets/rp2040/board_configs.gni
@@ -24,6 +24,7 @@
   pw_app_common_DISPLAY_WIDTH = "320"
   pw_app_common_DISPLAY_HEIGHT = "240"
   pw_app_common_BACKLIGHT_GPIO = "-1"
+  pw_app_common_DISPLAY_TE_GPIO = "-1"
   pw_app_common_DISPLAY_CS_GPIO = "9"
   pw_app_common_DISPLAY_DC_GPIO = "10"
   pw_app_common_DISPLAY_RESET_GPIO = "11"
@@ -39,6 +40,7 @@
   pw_app_common_DISPLAY_WIDTH = "160"
   pw_app_common_DISPLAY_HEIGHT = "128"
   pw_app_common_BACKLIGHT_GPIO = "7"
+  pw_app_common_DISPLAY_TE_GPIO = "-1"
   pw_app_common_DISPLAY_CS_GPIO = "26"
   pw_app_common_DISPLAY_DC_GPIO = "20"
   pw_app_common_DISPLAY_RESET_GPIO = "21"
@@ -53,6 +55,7 @@
   pw_app_common_DISPLAY_WIDTH = "320"
   pw_app_common_DISPLAY_HEIGHT = "240"
   pw_app_common_BACKLIGHT_GPIO = "20"
+  pw_app_common_DISPLAY_TE_GPIO = "21"
   pw_app_common_DISPLAY_CS_GPIO = "17"
   pw_app_common_DISPLAY_DC_GPIO = "16"
   pw_app_common_DISPLAY_RESET_GPIO = "-1"