def read(self, pin):
if type(pin) is list:<EOL><INDENT>return [self.read(p) for p in pin]<EOL><DEDENT>pin_id = self._pin_mapping.get(pin, None)<EOL>if pin_id:<EOL><INDENT>value = self._read(pin_id)<EOL>lpin = self._pin_lin.get(pin, None)<EOL>if lpin and type(lpin['<STR_LIT>']) is tuple:<EOL><INDENT>read_range = lpin['<STR_LIT>']<EOL>value = self._linear_interpolation(value, *read_range)<EOL><DEDENT>return value<EOL><DEDENT>else:<EOL><INDENT>raise KeyError('<STR_LIT>' % pin)<EOL><DEDENT>
Reads value from pin `pin`.

        Returns the value read from pin `pin`. If it's an analog pin, returns
        a number in analog.input_range. If it's digital, returns
        `ahio.LogicValue`.

        If you're developing a driver, implement _read(self, pin)

        @arg pin the pin to read from
        @returns the value read from the pin

        @throw KeyError if pin isn't mapped.