[lm-sensors] DS75
Jean Delvare
khali at linux-fr.org
Fri Feb 9 10:39:22 CET 2007
Hi Alan,
On Wed, 07 Feb 2007 10:14:36 +0000, Alan Clucas wrote:
> Attached is the kernel patch and a patch for libsensors as well. The
> libsensors patch does not include your sensors-detect patch.
Could you please also include the required changes to the sensors
program and possibly sensord as well? These should be trivial.
> I have changed the detected name to ds75, hence the libsensors patch. I
> haven't managed to find any lm75 devices here, so I haven't tested this
> on one of those, which would be good before it goes too far. The patch
> is simple enough, but you never can tell.
I have an LM75, I just tested and it works OK.
Comments on your kernel patch:
> diff -ur linux-2.6.19.2/drivers/hwmon/lm75.c linux/drivers/hwmon/lm75.c
> --- linux-2.6.19.2/drivers/hwmon/lm75.c 2007-02-06 15:53:57.000000000 +0000
> +++ linux/drivers/hwmon/lm75.c 2007-02-06 17:45:19.000000000 +0000
> @@ -34,7 +34,7 @@
> 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
>
> /* Insmod parameters */
> -I2C_CLIENT_INSMOD_1(lm75);
> +I2C_CLIENT_INSMOD_2(lm75, ds75);
>
> /* Many LM75 constants specified below */
>
> @@ -153,50 +153,63 @@
> new_client->flags = 0;
>
> /* Now, we do the remaining detection. There is no identification-
> - dedicated register so we have to rely on several tricks:
> - unused bits, registers cycling over 8-address boundaries,
> - addresses 0x04-0x07 returning the last read value.
> + dedicated register so we have to rely on several tricks.
> + The LM75 and DS75 share unused bits. The LM75 has registers
> + cycling over 8-address boundaries, and addresses 0x04-0x07
> + returning the last read value.
> + The DS75 has addresses 0x04-0x0f returning the last read value,
> + but does not register cycle.
> The cycling+unused addresses combination is not tested,
> since it would significantly slow the detection down and would
> hardly add any value. */
> if (kind < 0) {
> - int cur, conf, hyst, os;
> + int cur, conf, hyst, os, addr;
>
> /* Unused addresses */
> cur = i2c_smbus_read_word_data(new_client, 0);
> conf = i2c_smbus_read_byte_data(new_client, 1);
> hyst = i2c_smbus_read_word_data(new_client, 2);
> - if (i2c_smbus_read_word_data(new_client, 4) != hyst
> - || i2c_smbus_read_word_data(new_client, 5) != hyst
> - || i2c_smbus_read_word_data(new_client, 6) != hyst
> - || i2c_smbus_read_word_data(new_client, 7) != hyst)
> - goto exit_free;
> +
> + for (addr = 0x04; addr <= 0x0f; addr++)
> + if (i2c_smbus_read_word_data(new_client, addr) != hyst)
> + break;
> +
> + if (addr < 0x08)
> + goto exit_free;
> + if (addr == 0x10)
> + kind = ds75;
> + else
> + kind = lm75;
> +
> os = i2c_smbus_read_word_data(new_client, 3);
> - if (i2c_smbus_read_word_data(new_client, 4) != os
> - || i2c_smbus_read_word_data(new_client, 5) != os
> - || i2c_smbus_read_word_data(new_client, 6) != os
> - || i2c_smbus_read_word_data(new_client, 7) != os)
> - goto exit_free;
> + for (addr = 0x04; addr <= 0x0f; addr++)
> + if (i2c_smbus_read_word_data(new_client, addr) != os)
> + break;
> +
> + if (addr < (kind == ds75 ? 0x10 : 0x08))
> + goto exit_free;
It's smart :) I admit I had no clear idea how to implement the
detection efficiently. I like your approach.
>
> /* Unused bits */
> if (conf & 0xe0)
> goto exit_free;
Note that this requires the DS75 to be in 9-bit resolution mode. The
dump you provided suggests your DS75 is in 10-bit resolution mode, so I
expect it not to be detected properly. Maybe this is OK as a first
approximation, but you may want to submit a second patch to properly
support the high resolution modes of the DS75.
>
> - /* Addresses cycling */
> - for (i = 8; i < 0xff; i += 8)
> - if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
> - || i2c_smbus_read_word_data(new_client, i + 2) != hyst
> - || i2c_smbus_read_word_data(new_client, i + 3) != os)
> - goto exit_free;
> - }
> + /* Addresses cycling - LM75 only*/
Missing space before end of comment.
> + if (kind == lm75)
> + for (i = 8; i < 0xff; i += 8)
> + if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
> + || i2c_smbus_read_word_data(new_client, i + 2) != hyst
> + || i2c_smbus_read_word_data(new_client, i + 3) != os)
> + goto exit_free;
I strongly suggest adding a pair of curly braces for the outer-most if
statement. Three nested statements without any curly braces is asking
for trouble on any further change.
>
> - /* Determine the chip type - only one kind supported! */
> - if (kind <= 0)
> - kind = lm75;
> + }
This change breaks the case kind == 0, you'll end up with an empty
name. You need to force the type to one of the supported ones if the
user uses force without a kind.
>
> + /* Determine the chip type */
> if (kind == lm75) {
> name = "lm75";
> }
> + else if (kind == ds75) {
> + name = "ds75";
> + }
>
> /* Fill in the remaining client fields and put it into the global list */
> strlcpy(new_client->name, name, I2C_NAME_SIZE);
>
Can you also please update Documentation/hwmon/lm75 to mention the
separate prefix?
Thanks,
--
Jean Delvare
More information about the lm-sensors
mailing list