svn commit: r222674 - head/sys/dev/iicbus
Andreas Tobler
andreast at FreeBSD.org
Sat Jun 4 09:23:55 UTC 2011
Author: andreast
Date: Sat Jun 4 09:23:54 2011
New Revision: 222674
URL: http://svn.freebsd.org/changeset/base/222674
Log:
- Improve error handling.
- Add a retry loop for the i2c sensor reading.
- Check on busy status of the chip and on invalid values.
- Fix a typo in a comment.
- Replace the constant 2732 with the ZERO_C_TO_K macro.
Approved by: nwhitehorn (mentor)
Modified:
head/sys/dev/iicbus/max6690.c
Modified: head/sys/dev/iicbus/max6690.c
==============================================================================
--- head/sys/dev/iicbus/max6690.c Sat Jun 4 09:19:53 2011 (r222673)
+++ head/sys/dev/iicbus/max6690.c Sat Jun 4 09:23:54 2011 (r222674)
@@ -51,12 +51,11 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <powerpc/powermac/powermac_thermal.h>
-#define FCU_ZERO_C_TO_K 2732
-
/* Inlet, Backside, U3 Heatsink sensor: MAX6690. */
#define MAX6690_INT_TEMP 0x0
#define MAX6690_EXT_TEMP 0x1
+#define MAX6690_RSL_STATUS 0x2
#define MAX6690_EEXT_TEMP 0x10
#define MAX6690_IEXT_TEMP 0x11
#define MAX6690_TEMP_MASK 0xe0
@@ -76,8 +75,8 @@ static int max6690_attach(device_t);
static int max6690_sensor_read(struct max6690_sensor *sens);
static int max6690_sensor_sysctl(SYSCTL_HANDLER_ARGS);
static void max6690_start(void *xdev);
-static int max6690_read_1(device_t dev, uint32_t addr, uint8_t reg,
- uint8_t *data);
+static int max6690_read(device_t dev, uint32_t addr, uint8_t reg,
+ uint8_t *data);
struct max6690_softc {
device_t sc_dev;
@@ -105,23 +104,43 @@ DRIVER_MODULE(max6690, iicbus, max6690_d
MALLOC_DEFINE(M_MAX6690, "max6690", "Temp-Monitor MAX6690");
static int
-max6690_read_1(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
+max6690_read(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
{
uint8_t buf[4];
+ uint8_t busy[1], rsl;
+ int err, try = 0;
- struct iic_msg msg[2] = {
+ /* Busy register RSL. */
+ rsl = MAX6690_RSL_STATUS;
+ /* first read the status register, 0x2. If busy, retry. */
+ struct iic_msg msg[4] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &rsl },
+ { addr, IIC_M_RD, 1, busy },
{ addr, IIC_M_WR | IIC_M_NOSTOP, 1, ® },
{ addr, IIC_M_RD, 1, buf },
};
- if (iicbus_transfer(dev, msg, 2) != 0) {
- device_printf(dev, "iicbus read failed\n");
- return (EIO);
+ for (;;)
+ {
+ err = iicbus_transfer(dev, msg, 4);
+ if (err != 0)
+ goto retry;
+ if (busy[0] & 0x80)
+ goto retry;
+ /* Check for invalid value and retry. */
+ if (buf[0] == 0xff)
+ goto retry;
+
+ *data = *((uint8_t*)buf);
+ return (0);
+
+ retry:
+ if (++try > 5) {
+ device_printf(dev, "iicbus read failed\n");
+ return (-1);
+ }
+ pause("max6690_read", hz);
}
-
- *data = *((uint8_t*)buf);
-
- return (0);
}
static int
@@ -193,8 +212,8 @@ max6690_fill_sensor_prop(device_t dev)
for (j = 0; j < i; j++) {
sc->sc_sensors[j].dev = dev;
- sc->sc_sensors[j].therm.target_temp = 400 + 2732;
- sc->sc_sensors[j].therm.max_temp = 800 + 2732;
+ sc->sc_sensors[j].therm.target_temp = 400 + ZERO_C_TO_K;
+ sc->sc_sensors[j].therm.max_temp = 800 + ZERO_C_TO_K;
sc->sc_sensors[j].therm.read =
(int (*)(struct pmac_therm *))(max6690_sensor_read);
@@ -302,14 +321,15 @@ static int
max6690_sensor_read(struct max6690_sensor *sens)
{
uint8_t reg_int = 0, reg_ext = 0;
- uint8_t integer;
- uint8_t fraction;
- int temp;
+ uint8_t integer = 0;
+ uint8_t fraction = 0;
+ int err, temp;
+
struct max6690_softc *sc;
sc = device_get_softc(sens->dev);
- /* The internal sensor id's are even, the external ar odd. */
+ /* The internal sensor id's are even, the external are odd. */
if ((sens->id % 2) == 0) {
reg_int = MAX6690_INT_TEMP;
reg_ext = MAX6690_IEXT_TEMP;
@@ -318,9 +338,11 @@ max6690_sensor_read(struct max6690_senso
reg_ext = MAX6690_EEXT_TEMP;
}
- max6690_read_1(sc->sc_dev, sc->sc_addr, reg_int, &integer);
+ err = max6690_read(sc->sc_dev, sc->sc_addr, reg_int, &integer);
+ err = max6690_read(sc->sc_dev, sc->sc_addr, reg_ext, &fraction);
- max6690_read_1(sc->sc_dev, sc->sc_addr, reg_ext, &fraction);
+ if (err < 0)
+ return (-1);
fraction &= MAX6690_TEMP_MASK;
@@ -329,7 +351,7 @@ max6690_sensor_read(struct max6690_senso
*/
temp = (integer * 10) + (fraction >> 5) * 10 / 8;
- return (temp + FCU_ZERO_C_TO_K);
+ return (temp + ZERO_C_TO_K);
}
static int
More information about the svn-src-all
mailing list