diff --git a/libevdev/const.py b/libevdev/const.py
index ab7a6d0ac0e4ecde2de85126698d3d98ca03d934..eeb19ee423b7b82eee1969fa114bc1ab0f579dca 100644
--- a/libevdev/const.py
+++ b/libevdev/const.py
@@ -96,6 +96,15 @@ class EventCode(EvdevBit):
     .. attribute:: type
 
         The :class:`EventType` for this event code
+
+    .. attribute:: is_defined
+
+        ``True`` if this event bit has a ``#define`` in the kernel header.
+        :class:`EventCode` objects not defined in the header have a name
+        composed of the type name plus the hex code, e.g. ``KEY_2E8``.
+
+        Usually you will not need to check this property unless you need to
+        filter for known codes only.
     """
     __hash__ = super.__hash__
 
@@ -347,6 +356,7 @@ def _load_consts():
         codes = []
         for c in range(cmax + 1):
             cname = Libevdev.event_to_name(t, c)
+            has_name = cname is not None
             # For those without names, we just use the type name plus
             # hexcode
             if cname is None:
@@ -355,7 +365,8 @@ def _load_consts():
             new_class = type(cname, (EventCode, ),
                              {'type': type_object,
                               'name': cname,
-                              'value': c})
+                              'value': c,
+                              'is_defined': has_name})
             code_object = new_class()
             setattr(type_object, cname, code_object)
             codes.append(code_object)
diff --git a/test/test-const.py b/test/test-const.py
index 1e54e7c8382d25e9a7a2b6d63beada4a4ab32f22..6563d56eb61f3ab3038e380e50fedeb1d462a6b8 100644
--- a/test/test-const.py
+++ b/test/test-const.py
@@ -88,6 +88,15 @@ class TestEventBits(unittest.TestCase):
         self.assertEqual(evbit('SYN_REPORT'), libevdev.EV_SYN.SYN_REPORT)
         self.assertEqual(evbit('REP_PERIOD'), libevdev.EV_REP.REP_PERIOD)
 
+    def test_evcode_is_defined(self):
+        for t in libevdev.types:
+            for c in t.codes:
+                fake_name = '{}_{:02X}'.format(t.name[3:], c.value)
+                if c.is_defined:
+                    self.assertNotEqual(c.name, fake_name)
+                else:
+                    self.assertEqual(c.name, fake_name)
+
     def test_propbit_string(self):
         self.assertEqual(propbit('INPUT_PROP_POINTER'), libevdev.INPUT_PROP_POINTER)
         self.assertEqual(propbit('INPUT_PROP_DIRECT'), libevdev.INPUT_PROP_DIRECT)