Ага, я хочу использовать Type Traits - тогда можно вообще пихать в шаблон что-угодно. Главное, чтобы нужные поля присутствовали. Немного искусственно, но хотя бы так:
template <class traitsT> struct UART {
  static_assert(::std::is_same_v<traitsT, ::std::decay_t<decltype(traitsT)>>);
  inline constexpr static auto Init() noexcept(true) {
    constexpr auto const databits_ = traitsT::databits();
    constexpr auto const parity_ = traitsT::parity();
    constexpr auto const stb_ = traitsT::stb();
    using DataBits = ::std::decay_t<decltype(databits_)>;
    using Parity = ::std::decay_t<decltype(parity_)>;
    using StopBit = ::std::decay_t<decltype(stb_)>;
    // LCRH Register
    constexpr ::std::uint32_t PEN  = (parity_ != Parity::unused) ? 1 << 1 : 0;
    constexpr ::std::uint32_t EPS  = (parity_ == Parity::even)   ? 1 << 2 : 0;
    constexpr ::std::uint32_t STP2 = (stb_ == StopBit::_2) ? 1 << 3 : 0;
    constexpr ::std::uint32_t WLEN = static_cast<::std::uint32_t>(databits_) << 5;
    constexpr ::std::uint32_t SPS  = (parity_ == Parity::stick) ? 1 << 7 : 0;
    constexpr ::std::uint32_t lcrh = PEN | EPS | STP2 | WLEN | SPS;
    return lcrh;
  }
};
int main(int, char **) {
  struct MyTraits final {
    constexpr inline static auto const databits() noexcept(true) { using Result = ::std::uint32_t; return static_cast<Result>(8); }
    constexpr inline static auto const parity() noexcept(true) { enum class Result { unused, even, odd, stick }; return Result::odd; }
    constexpr inline static auto const stb() noexcept(true) { enum class Result { _1 = 1, _2 = 2 }; return Result::_1; }
  };
  ::std::cout << UART<MyTraits>{}.Init() << ::std::endl;
  return 0;
}