+ int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
+
+ /* dmi code ugliness, we get passed the address of the contents of
+ a complete DMI record, but in the form of a dmi_header pointer, in
+ reality this address holds header->length bytes of which the header
+ are the first 4 bytes */
+ u8 *dmi_data = (u8 *)header;
+
+ /* We are looking for OEM-specific type 185 */
+ if (header->type != 185)
+ return;
+
+ /* we are looking for what Siemens calls "subtype" 19, the subtype
+ is stored in byte 5 of the dmi block */
+ if (header->length < 5 || dmi_data[4] != 19)
+ return;
+
+ /* After the subtype comes 1 unknown byte and then blocks of 5 bytes,
+ consisting of what Siemens calls an "Entity" number, followed by
+ 2 16-bit words in LSB first order */
+ for (i = 6; (i + 4) < header->length; i += 5) {
+ /* entity 1 - 3: voltage multiplier and offset */
+ if (dmi_data[i] >= 1 && dmi_data[i] <= 3) {
+ /* Our in sensors order and the DMI order differ */
+ const int shuffle[3] = { 1, 0, 2 };
+ int in = shuffle[dmi_data[i] - 1];
+
+ /* Check for twice the same entity */
+ if (found & (1 << in))
+ return;
+
+ mult[in] = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
+ offset[in] = dmi_data[i + 3] | (dmi_data[i + 4] << 8);
+
+ found |= 1 << in;
+ }
+
+ /* entity 7: reference voltage */
+ if (dmi_data[i] == 7) {
+ /* Check for twice the same entity */
+ if (found & 0x08)
+ return;
+
+ vref = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
+
+ found |= 0x08;
+ }
+ }
+
+ if (found == 0x0F) {
+ for (i = 0; i < 3; i++) {
+ dmi_mult[i] = mult[i] * 10;
+ dmi_offset[i] = offset[i] * 10;
+ }
+ dmi_vref = vref;
+ }
+}
+
+static int fschmd_detect(struct i2c_client *client, int kind,
+ struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = client->adapter;