Skip to content

Commit

Permalink
iio: adc: mcp320x: Fix readout of negative voltages
Browse files Browse the repository at this point in the history
commit e6f4794 upstream.

Commit f686a36 ("iio: adc: mcp320x: Add support for mcp3301")
returns a signed voltage from mcp320x_adc_conversion() but neglects that
the caller interprets a negative return value as failure.  Only mcp3301
(and the upcoming mcp3550/1/3) is affected as the other chips are
incapable of measuring negative voltages.

Fix and while at it, add mcp3301 to the list of supported chips at the
top of the file.

Fixes: f686a36 ("iio: adc: mcp320x: Add support for mcp3301")
Cc: Andrea Galbusera <[email protected]>
Signed-off-by: Lukas Wunner <[email protected]>
Signed-off-by: Jonathan Cameron <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
l1k authored and gregkh committed Oct 12, 2017
1 parent ff24f48 commit d91dc01
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions drivers/iio/adc/mcp320x.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* MCP3204
* MCP3208
* ------------
* 13 bit converter
* MCP3301
*
* Datasheet can be found here:
* http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf mcp3001
Expand Down Expand Up @@ -96,7 +98,7 @@ static int mcp320x_channel_to_tx_data(int device_index,
}

static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
bool differential, int device_index)
bool differential, int device_index, int *val)
{
int ret;

Expand All @@ -117,19 +119,25 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,

switch (device_index) {
case mcp3001:
return (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3);
*val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3);
return 0;
case mcp3002:
case mcp3004:
case mcp3008:
return (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6);
*val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6);
return 0;
case mcp3201:
return (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1);
*val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1);
return 0;
case mcp3202:
case mcp3204:
case mcp3208:
return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
*val = (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
return 0;
case mcp3301:
return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12);
*val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8
| adc->rx_buf[1], 12);
return 0;
default:
return -EINVAL;
}
Expand All @@ -150,12 +158,10 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = mcp320x_adc_conversion(adc, channel->address,
channel->differential, device_index);

channel->differential, device_index, val);
if (ret < 0)
goto out;

*val = ret;
ret = IIO_VAL_INT;
break;

Expand Down

0 comments on commit d91dc01

Please sign in to comment.