I would pull this to its own function:

     encoding_ok(Enc) when is_atom(Enc) -> ok;
     encoding_ok({Enc, Coll}) when is_atom(Enc), is_atom(Coll) -> ok;
     encoding_ok(_)  -> erlang:error(badarg).

Because it simplifies the encoding scheme a bit.