[dif/adc_ctrl] Implement get/set-enabled DIFs

This implements the get/set-enabled DIFs for the ADC Controller, and
their corresponding unit tests.

Signed-off-by: Timothy Trippel <ttrippel@google.com>
diff --git a/sw/device/lib/dif/dif_adc_ctrl.c b/sw/device/lib/dif/dif_adc_ctrl.c
index 69ce4c0..0ea3c89 100644
--- a/sw/device/lib/dif/dif_adc_ctrl.c
+++ b/sw/device/lib/dif/dif_adc_ctrl.c
@@ -173,3 +173,34 @@
 
   return kDifOk;
 }
+
+dif_result_t dif_adc_ctrl_set_enabled(const dif_adc_ctrl_t *adc_ctrl,
+                                      dif_toggle_t enabled) {
+  if (adc_ctrl == NULL || !dif_is_valid_toggle(enabled)) {
+    return kDifBadArg;
+  }
+
+  uint32_t en_ctrl_reg =
+      mmio_region_read32(adc_ctrl->base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET);
+  en_ctrl_reg =
+      bitfield_bit32_write(en_ctrl_reg, ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT,
+                           dif_toggle_to_bool(enabled));
+  mmio_region_write32(adc_ctrl->base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
+                      en_ctrl_reg);
+
+  return kDifOk;
+}
+
+dif_result_t dif_adc_ctrl_get_enabled(const dif_adc_ctrl_t *adc_ctrl,
+                                      dif_toggle_t *is_enabled) {
+  if (adc_ctrl == NULL || is_enabled == NULL) {
+    return kDifBadArg;
+  }
+
+  uint32_t en_ctrl_reg =
+      mmio_region_read32(adc_ctrl->base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET);
+  *is_enabled = dif_bool_to_toggle(
+      bitfield_bit32_read(en_ctrl_reg, ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT));
+
+  return kDifOk;
+}
diff --git a/sw/device/lib/dif/dif_adc_ctrl_unittest.cc b/sw/device/lib/dif/dif_adc_ctrl_unittest.cc
index abfc99b..e7b10fd 100644
--- a/sw/device/lib/dif/dif_adc_ctrl_unittest.cc
+++ b/sw/device/lib/dif/dif_adc_ctrl_unittest.cc
@@ -169,5 +169,52 @@
       &adc_ctrl_, kDifAdcCtrlChannel0, filter_config_, kDifToggleEnabled));
 }
 
+class SetEnabledTest : public AdcCtrlTest {};
+
+TEST_F(SetEnabledTest, NullHandle) {
+  EXPECT_DIF_BADARG(dif_adc_ctrl_set_enabled(nullptr, kDifToggleEnabled));
+}
+
+TEST_F(SetEnabledTest, BadArgs) {
+  EXPECT_DIF_BADARG(
+      dif_adc_ctrl_set_enabled(&adc_ctrl_, static_cast<dif_toggle_t>(2)));
+}
+
+TEST_F(SetEnabledTest, Success) {
+  EXPECT_READ32(ADC_CTRL_ADC_EN_CTL_REG_OFFSET, 0);
+  EXPECT_WRITE32(ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
+                 {{ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT, true}});
+  EXPECT_DIF_OK(dif_adc_ctrl_set_enabled(&adc_ctrl_, kDifToggleEnabled));
+
+  EXPECT_READ32(ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
+                {{ADC_CTRL_ADC_EN_CTL_ONESHOT_MODE_BIT, true},
+                 {ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT, true}});
+  EXPECT_WRITE32(ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
+                 {{ADC_CTRL_ADC_EN_CTL_ONESHOT_MODE_BIT, true},
+                  {ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT, false}});
+  EXPECT_DIF_OK(dif_adc_ctrl_set_enabled(&adc_ctrl_, kDifToggleDisabled));
+}
+
+class GetEnabledTest : public AdcCtrlTest {};
+
+TEST_F(GetEnabledTest, NullArgs) {
+  dif_toggle_t is_enabled;
+  EXPECT_DIF_BADARG(dif_adc_ctrl_get_enabled(nullptr, &is_enabled));
+  EXPECT_DIF_BADARG(dif_adc_ctrl_get_enabled(&adc_ctrl_, nullptr));
+}
+
+TEST_F(GetEnabledTest, Success) {
+  dif_toggle_t is_enabled;
+
+  EXPECT_READ32(ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
+                {{ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT, true}});
+  EXPECT_DIF_OK(dif_adc_ctrl_get_enabled(&adc_ctrl_, &is_enabled));
+  EXPECT_EQ(is_enabled, kDifToggleEnabled);
+
+  EXPECT_READ32(ADC_CTRL_ADC_EN_CTL_REG_OFFSET, 0);
+  EXPECT_DIF_OK(dif_adc_ctrl_get_enabled(&adc_ctrl_, &is_enabled));
+  EXPECT_EQ(is_enabled, kDifToggleDisabled);
+}
+
 }  // namespace
 }  // namespace dif_adc_ctrl_unittest