diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -26,4 +26,12 @@
 
 The [evdev-examples](https://github.com/georgefst/evdev/tree/master/evdev-examples) folder contains a basic `evtest` clone, with the added ability to read events from multiple devices concurrently.
 
-See [Hackage](http://hackage.haskell.org/package/evdev) for further documentation. Full descriptions for each function, datatype etc. will be uploaded in the very near future.
+See [Hackage](http://hackage.haskell.org/package/evdev) for further documentation.
+
+Still to come
+-------------
+Haddock documentation for the non-stream interface. I intend to redesign the interface in some minor ways first. Until then, everything maps quite directly to the C library, while taking care of the nitty-gritty low-level stuff.
+
+There are many more methods in the C library that I'd like to expose. So far the emphasis has very much been on squeezing out the functionality I personally needed.
+
+Some of the streaming functions print exceptions straight to `stderr`. Again, this was convenient at the time, but it would be cleaner to allow specifying a `Writer`, or passing callbacks.
diff --git a/evdev.cabal b/evdev.cabal
--- a/evdev.cabal
+++ b/evdev.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                evdev
-version:             1.2.0.0
+version:             1.2.0.1
 author:              George Thomas
 maintainer:          George Thomas
 description:         Provides access to the Linux event device interface, with an optional high-level Streamly-based API.
diff --git a/src/Evdev.hs b/src/Evdev.hs
--- a/src/Evdev.hs
+++ b/src/Evdev.hs
@@ -23,7 +23,7 @@
     devicePath,
     deviceProperties,
     Device,
-    Event,
+    Event(..), --TODO provide access to Word16 etc...
     EventCode(..),
     EventValue(..),
     KeyEventType(..),
diff --git a/src/Evdev/Stream.hs b/src/Evdev/Stream.hs
--- a/src/Evdev/Stream.hs
+++ b/src/Evdev/Stream.hs
@@ -1,3 +1,5 @@
+-- | The high-level, stream-based API.
+-- Unless stated otherwise, these functions will throw exceptions if the underlying C calls fail.
 module Evdev.Stream (
     allDevices,
     allEvents,
@@ -34,7 +36,7 @@
 readEvents dev = S.repeatM $ nextEvent dev defaultReadFlags
 
 -- | Concurrently read events from multiple devices.
--- | If a read fails on one, the exception is printed to stderr and the stream continues to read from the others.
+-- If a read fails on one, the exception is printed to stderr and the stream continues to read from the others.
 readEventsMany :: IsStream t => AsyncT IO Device -> t IO (Device, Event)
 readEventsMany ds = asyncly $ do
     d <- ds
@@ -45,22 +47,26 @@
         readEvents' dev = unfoldM $ printIOError' $ nextEvent dev defaultReadFlags
 
 -- | Create devices for all paths in the stream.
--- | Will throw an exception if a path doesn't correspond to a valid input device.
 makeDevices :: IsStream t => t IO RawFilePath -> t IO Device
 makeDevices = S.mapM newDevice
 
--- | All events on all valid devices (in /dev/input).
+-- | All events on all valid devices (in /\/dev\/input/).
+-- Prints any exceptions.
+-- > allEvents == readEventsMany allDevices
 allEvents :: IsStream t => t IO (Device, Event)
 allEvents = readEventsMany allDevices
 
--- | All valid existing devices (in /dev/input).
+--TODO call this 'oldDevices' or 'existingDevices', and have 'allDevices' include 'newDevices'?
+-- | All valid existing devices (in /\/dev\/input/).
+-- If a device can't be initialised for an individual path, then the exception is printed,
+-- and the function continues to try to initialise the others.
 allDevices :: (IsStream t, Monad (t IO)) => t IO Device
 allDevices =
     let paths = S.filterM doesFileExist $ S.map (evdevDir </>) $ S.fromFoldable =<< S.yieldM (listDirectory evdevDir)
     in  S.mapMaybeM (printIOError' . newDevice) paths
 
--- | All new devices created (in /dev/input).
--- | Watches for new file paths (using inotify), and those corresponding to valid devices are added to the stream.
+-- | All new devices created (in /\/dev\/input/).
+-- Watches for new file paths (using \inotify\), and those corresponding to valid devices are added to the stream.
 newDevices :: (IsStream t, Monad (t IO)) => t IO Device
 newDevices =
     let -- 'watching' keeps track of the set of paths which have been added, but don't yet have the right permissions
@@ -97,7 +103,7 @@
 -- I really can't think of a good name for this...
 -- TODO perhaps some way to use State monad instead?
 scanMaybe :: (IsStream t, Monad m) => (s -> a -> m (Maybe b, s)) -> s -> t m a -> t m b
-scanMaybe f e  = S.mapMaybe fst . S.scanlM' (f . snd) (Nothing, e) 
+scanMaybe f e  = S.mapMaybe fst . S.scanlM' (f . snd) (Nothing, e)
 
 -- specialised form of S.unfoldrM
 -- this should perhaps be in streamly (it's in monad-loops)
