If you want a driver that acts a bit more like a kernel-level driver, but does not live in kernel space, you can also make a FIFO, or named pipe. This usually lives in the /dev/ directory (although it doesn't need to) and acts substantially like a device once set up. However, FIFOs are one-directional only --- they have one reader and one writer.
For instance, it used to be that if you had a PS/2-style mouse, and
wanted to run XFree86, you had to create a FIFO called /dev/mouse,
and run a program called mconv which read PS/2 mouse ``droppings''
from /dev/psaux, and wrote the equivalent microsoft-style
``droppings'' to /dev/mouse. Then XFree86 would read the ``droppings'' from
/dev/mouse, and it would be as if there were a microsoft mouse connected to
/dev/mouse.