From e2401b4422c31905d49cb09b1b9cb0ee8e4786ab Mon Sep 17 00:00:00 2001 From: pwisutti <33824525+pwisutti@users.noreply.github.com> Date: Thu, 1 Mar 2018 01:20:01 +0700 Subject: [PATCH] [celestica] change to use lm75 standard driver (#19) --- .../x86_64-cel_seastone-r0/sensors.conf | 27 +- .../debian/platform-modules-dx010.init | 11 +- .../dx010/modules/Makefile | 7 +- .../dx010/modules/lm75.c | 557 ------------------ .../dx010/modules/lm75.h | 49 -- 5 files changed, 19 insertions(+), 632 deletions(-) delete mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c delete mode 100644 platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h diff --git a/device/celestica/x86_64-cel_seastone-r0/sensors.conf b/device/celestica/x86_64-cel_seastone-r0/sensors.conf index 6ce4540b226e..307587f687e5 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sensors.conf +++ b/device/celestica/x86_64-cel_seastone-r0/sensors.conf @@ -36,33 +36,30 @@ chip "dps460-i2c-*-5b" set in3_crit 13.0 set in3_lcrit 11.0 -# These sensors located on CPU Board. -chip "dx010_lm75b-i2c-*-48" - label temp1 "CPU_external temp sensor" +# These sensors located on Main Switch Board. +chip "lm75b-i2c-*-48" + label temp1 "Front-panel temp sensor 1" set temp1_max 43 set temp1_max_hyst 28 -chip "dx010_lm75b-i2c-*-4e" - label temp1 "Rear_panel temp sensor" +chip "lm75b-i2c-*-49" + label temp1 "Front-panel temp sensor 2" set temp1_max 43 set temp1_max_hyst 28 -# These sensors located on Main Switch Board. -bus "i2c-5" "i2c-1-mux (chan_id 3)" -chip "dx010_lm75b-i2c-5-48" - label temp1 "Front_panel left temp sensor" +chip "lm75b-i2c-*-4a" + label temp1 "ASIC temp sensor" set temp1_max 43 set temp1_max_hyst 28 -bus "i2c-6" "i2c-1-mux (chan_id 4)" -chip "dx010_lm75b-i2c-6-49" - label temp1 "Front_panel right temp sensor" +# These sensors located on CPU Board. +chip "lm75b-i2c-*-48" + label temp1 "Rear-panel temp sensor 1" set temp1_max 43 set temp1_max_hyst 28 -bus "i2c-7" "i2c-1-mux (chan_id 5)" -chip "dx010_lm75b-i2c-7-4a" - label temp1 "Switch_external temp sensor" +chip "lm75b-i2c-*-4e" + label temp1 "Rear-panel temp sensor 2" set temp1_max 43 set temp1_max_hyst 28 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 0c883cd388ae..c51aa742076b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -20,6 +20,7 @@ start) modprobe i2c-mux-pca954x modprobe dx010_wdt modprobe leds-dx010 + modprobe lm75 found=0 for devnum in 0 1; do @@ -56,11 +57,11 @@ start) echo 24lc64t 0x50 > /sys/bus/i2c/devices/i2c-12/new_device # Attach temperature sensors - echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device - echo dx010_lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device - echo dx010_lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device - echo dx010_lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device - echo dx010_lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device + echo lm75b 0x48 > /sys/bus/i2c/devices/i2c-5/new_device + echo lm75b 0x49 > /sys/bus/i2c/devices/i2c-6/new_device + echo lm75b 0x4a > /sys/bus/i2c/devices/i2c-7/new_device + echo lm75b 0x48 > /sys/bus/i2c/devices/i2c-14/new_device + echo lm75b 0x4e > /sys/bus/i2c/devices/i2c-15/new_device # Attach fans echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-13/new_device diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile index bb398cc5a745..9b0f10604811 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/Makefile @@ -1,6 +1 @@ -obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o -KVERSION = $(shell uname -r) -all: - make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules -clean: - make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean +obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c deleted file mode 100644 index 140d8f365598..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * lm75.c - Part of lm_sensors, Linux kernel modules for hardware - * monitoring - * Copyright (c) 1998, 1999 Frodo Looijaard - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lm75.h" - - -/* - * This driver handles the LM75 and compatible digital temperature sensors. - */ - -enum lm75_type { /* keep sorted in alphabetical order */ -adt75, -ds1775, -ds75, -ds7505, -g751, -lm75, -lm75a, -lm75b, -max6625, -max6626, -mcp980x, -stds75, -tcn75, -tmp100, -tmp101, -tmp105, -tmp112, -tmp175, -tmp275, -tmp75, -}; - -/* Addresses scanned */ -static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, - 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; - - -/* The LM75 registers */ -#define LM75_REG_CONF 0x01 - static const u8 LM75_REG_TEMP[3] = { - 0x00, /* input */ - 0x03, /* max */ - 0x02, /* hyst */ - }; - -/* Each client has this additional data */ - struct lm75_data { - struct i2c_client *client; - struct device *hwmon_dev; - struct thermal_zone_device *tz; - struct mutex update_lock; - u8 orig_conf; - u8 resolution; /* In bits, between 9 and 12 */ - u8 resolution_limits; - char valid; /* !=0 if registers are valid */ - unsigned long last_updated; /* In jiffies */ - unsigned long sample_time; /* In jiffies */ - s16 temp[3]; /* Register values, - 0 = input - 1 = max - 2 = hyst */ - }; - - static int lm75_read_value(struct i2c_client *client, u8 reg); - static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); - static struct lm75_data *lm75_update_device(struct device *dev); - - -/*-----------------------------------------------------------------------*/ - - static inline long lm75_reg_to_mc(s16 temp, u8 resolution) - { - return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); - } - -/* sysfs attributes for hwmon */ - - static int lm75_read_temp(void *dev, int *temp) - { - struct lm75_data *data = lm75_update_device(dev); - - if (IS_ERR(data)) - return PTR_ERR(data); - - *temp = lm75_reg_to_mc(data->temp[0], data->resolution); - - return 0; - } - - static ssize_t show_temp(struct device *dev, struct device_attribute *da, - char *buf) - { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm75_data *data = lm75_update_device(dev); - - if (IS_ERR(data)) - return PTR_ERR(data); - - return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], - data->resolution)); - } - - static ssize_t set_temp(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) - { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm75_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - int nr = attr->index; - long temp; - int error; - u8 resolution; - - error = kstrtol(buf, 10, &temp); - if (error) - return error; - - /* - * Resolution of limit registers is assumed to be the same as the - * temperature input register resolution unless given explicitly. - */ - if (attr->index && data->resolution_limits) - resolution = data->resolution_limits; - else - resolution = data->resolution; - - mutex_lock(&data->update_lock); - temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); - data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), - 1000) << (16 - resolution); - lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); - mutex_unlock(&data->update_lock); - return count; - } - - static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, - show_temp, set_temp, 1); - static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, - show_temp, set_temp, 2); - static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); - - static struct attribute *lm75_attrs[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - - NULL - }; - ATTRIBUTE_GROUPS(lm75); - -/*-----------------------------------------------------------------------*/ - - static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = { - .get_temp = lm75_read_temp, - }; - -/* device probe and removal */ - - static int - lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) - { - struct device *dev = &client->dev; - struct lm75_data *data; - int status; - u8 set_mask, clr_mask; - int new; - enum lm75_type kind = id->driver_data; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) - return -EIO; - - data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->client = client; - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. - * Then tweak to be more precise when appropriate. - */ - set_mask = 0; - clr_mask = LM75_SHUTDOWN; /* continuous conversions */ - - switch (kind) { - case adt75: - clr_mask |= 1 << 5; /* not one-shot mode */ - data->resolution = 12; - data->sample_time = HZ / 8; - break; - case ds1775: - case ds75: - case stds75: - clr_mask |= 3 << 5; - set_mask |= 2 << 5; /* 11-bit mode */ - data->resolution = 11; - data->sample_time = HZ; - break; - case ds7505: - set_mask |= 3 << 5; /* 12-bit mode */ - data->resolution = 12; - data->sample_time = HZ / 4; - break; - case g751: - case lm75: - case lm75a: - data->resolution = 9; - data->sample_time = HZ / 2; - break; - case lm75b: - data->resolution = 11; - data->sample_time = HZ / 4; - break; - case max6625: - data->resolution = 9; - data->sample_time = HZ / 4; - break; - case max6626: - data->resolution = 12; - data->resolution_limits = 9; - data->sample_time = HZ / 4; - break; - case tcn75: - data->resolution = 9; - data->sample_time = HZ / 8; - break; - case mcp980x: - data->resolution_limits = 9; - /* fall through */ - case tmp100: - case tmp101: - set_mask |= 3 << 5; /* 12-bit mode */ - data->resolution = 12; - data->sample_time = HZ; - clr_mask |= 1 << 7; /* not one-shot mode */ - break; - case tmp112: - set_mask |= 3 << 5; /* 12-bit mode */ - clr_mask |= 1 << 7; /* not one-shot mode */ - data->resolution = 12; - data->sample_time = HZ / 4; - break; - case tmp105: - case tmp175: - case tmp275: - case tmp75: - set_mask |= 3 << 5; /* 12-bit mode */ - clr_mask |= 1 << 7; /* not one-shot mode */ - data->resolution = 12; - data->sample_time = HZ / 2; - break; - } - - /* configure as specified */ - status = lm75_read_value(client, LM75_REG_CONF); - if (status < 0) { - dev_dbg(dev, "Can't read config? %d\n", status); - return status; - } - data->orig_conf = status; - new = status & ~clr_mask; - new |= set_mask; - if (status != new) - lm75_write_value(client, LM75_REG_CONF, new); - dev_dbg(dev, "Config %02x\n", new); - - data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, - data, lm75_groups); - if (IS_ERR(data->hwmon_dev)) - return PTR_ERR(data->hwmon_dev); - - data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, - 0, - data->hwmon_dev, - &lm75_of_thermal_ops); - if (IS_ERR(data->tz)) - data->tz = NULL; - - dev_info(dev, "%s: sensor '%s'\n", - dev_name(data->hwmon_dev), client->name); - - return 0; - } - - static int lm75_remove(struct i2c_client *client) - { - struct lm75_data *data = i2c_get_clientdata(client); - - thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz); - hwmon_device_unregister(data->hwmon_dev); - lm75_write_value(client, LM75_REG_CONF, data->orig_conf); - return 0; - } - - static const struct i2c_device_id lm75_ids[] = { - { "adt75", adt75, }, - { "ds1775", ds1775, }, - { "ds75", ds75, }, - { "ds7505", ds7505, }, - { "g751", g751, }, - { "lm75", lm75, }, - { "lm75a", lm75a, }, - { "dx010_lm75b", lm75b, }, - { "max6625", max6625, }, - { "max6626", max6626, }, - { "mcp980x", mcp980x, }, - { "stds75", stds75, }, - { "tcn75", tcn75, }, - { "tmp100", tmp100, }, - { "tmp101", tmp101, }, - { "tmp105", tmp105, }, - { "tmp112", tmp112, }, - { "tmp175", tmp175, }, - { "tmp275", tmp275, }, - { "tmp75", tmp75, }, - { /* LIST END */ } - }; - MODULE_DEVICE_TABLE(i2c, lm75_ids); - -#define LM75A_ID 0xA1 - -/* Return 0 if detection is successful, -ENODEV otherwise */ - static int lm75_detect(struct i2c_client *new_client, - struct i2c_board_info *info) - { - struct i2c_adapter *adapter = new_client->adapter; - int i; - int conf, hyst, os; - bool is_lm75a = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - return -ENODEV; - - /* - * 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. - * The cycling+unused addresses combination is not tested, - * since it would significantly slow the detection down and would - * hardly add any value. - * - * The National Semiconductor LM75A is different than earlier - * LM75s. It has an ID byte of 0xaX (where X is the chip - * revision, with 1 being the only revision in existence) in - * register 7, and unused registers return 0xff rather than the - * last read value. - * - * Note that this function only detects the original National - * Semiconductor LM75 and the LM75A. Clones from other vendors - * aren't detected, on purpose, because they are typically never - * found on PC hardware. They are found on embedded designs where - * they can be instantiated explicitly so detection is not needed. - * The absence of identification registers on all these clones - * would make their exhaustive detection very difficult and weak, - * and odds are that the driver would bind to unsupported devices. - */ - - /* Unused bits */ - conf = i2c_smbus_read_byte_data(new_client, 1); - if (conf & 0xe0) - return -ENODEV; - - /* First check for LM75A */ - if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { - /* LM75A returns 0xff on unused registers so - just to be sure we check for that too. */ - if (i2c_smbus_read_byte_data(new_client, 4) != 0xff - || i2c_smbus_read_byte_data(new_client, 5) != 0xff - || i2c_smbus_read_byte_data(new_client, 6) != 0xff) - return -ENODEV; - is_lm75a = 1; - hyst = i2c_smbus_read_byte_data(new_client, 2); - os = i2c_smbus_read_byte_data(new_client, 3); - } else { /* Traditional style LM75 detection */ - /* Unused addresses */ - hyst = i2c_smbus_read_byte_data(new_client, 2); - if (i2c_smbus_read_byte_data(new_client, 4) != hyst - || i2c_smbus_read_byte_data(new_client, 5) != hyst - || i2c_smbus_read_byte_data(new_client, 6) != hyst - || i2c_smbus_read_byte_data(new_client, 7) != hyst) - return -ENODEV; - os = i2c_smbus_read_byte_data(new_client, 3); - if (i2c_smbus_read_byte_data(new_client, 4) != os - || i2c_smbus_read_byte_data(new_client, 5) != os - || i2c_smbus_read_byte_data(new_client, 6) != os - || i2c_smbus_read_byte_data(new_client, 7) != os) - return -ENODEV; - } - - /* Addresses cycling */ - for (i = 8; i <= 248; i += 40) { - if (i2c_smbus_read_byte_data(new_client, i + 1) != conf - || i2c_smbus_read_byte_data(new_client, i + 2) != hyst - || i2c_smbus_read_byte_data(new_client, i + 3) != os) - return -ENODEV; - if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) - != LM75A_ID) - return -ENODEV; - } - - strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); - - return 0; - } - -#ifdef CONFIG_PM - static int lm75_suspend(struct device *dev) - { - int status; - struct i2c_client *client = to_i2c_client(dev); - status = lm75_read_value(client, LM75_REG_CONF); - if (status < 0) { - dev_dbg(&client->dev, "Can't read config? %d\n", status); - return status; - } - status = status | LM75_SHUTDOWN; - lm75_write_value(client, LM75_REG_CONF, status); - return 0; - } - - static int lm75_resume(struct device *dev) - { - int status; - struct i2c_client *client = to_i2c_client(dev); - status = lm75_read_value(client, LM75_REG_CONF); - if (status < 0) { - dev_dbg(&client->dev, "Can't read config? %d\n", status); - return status; - } - status = status & ~LM75_SHUTDOWN; - lm75_write_value(client, LM75_REG_CONF, status); - return 0; - } - - static const struct dev_pm_ops lm75_dev_pm_ops = { - .suspend = lm75_suspend, - .resume = lm75_resume, - }; -#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) -#else -#define LM75_DEV_PM_OPS NULL -#endif /* CONFIG_PM */ - - static struct i2c_driver lm75_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "dx010_lm75", - .pm = LM75_DEV_PM_OPS, - }, - .probe = lm75_probe, - .remove = lm75_remove, - .id_table = lm75_ids, -/* - .detect = lm75_detect, - .address_list = normal_i2c, -*/ - }; - -/*-----------------------------------------------------------------------*/ - -/* register access */ - -/* - * All registers are word-sized, except for the configuration register. - * LM75 uses a high-byte first convention, which is exactly opposite to - * the SMBus standard. - */ - static int lm75_read_value(struct i2c_client *client, u8 reg) - { - if (reg == LM75_REG_CONF) - return i2c_smbus_read_byte_data(client, reg); - else - return i2c_smbus_read_word_swapped(client, reg); - } - - static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) - { - if (reg == LM75_REG_CONF) - return i2c_smbus_write_byte_data(client, reg, value); - else - return i2c_smbus_write_word_swapped(client, reg, value); - } - - static struct lm75_data *lm75_update_device(struct device *dev) - { - struct lm75_data *data = dev_get_drvdata(dev); - struct i2c_client *client = data->client; - struct lm75_data *ret = data; - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + data->sample_time) - || !data->valid) { - int i; - dev_dbg(&client->dev, "Starting lm75 update\n"); - - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - int status; - - status = lm75_read_value(client, LM75_REG_TEMP[i]); - if (unlikely(status < 0)) { - dev_dbg(dev, - "LM75: Failed to read value: reg %d, error %d\n", - LM75_REG_TEMP[i], status); - ret = ERR_PTR(status); - data->valid = 0; - goto abort; - } - data->temp[i] = status; - } - data->last_updated = jiffies; - data->valid = 1; - } - - abort: - mutex_unlock(&data->update_lock); - return ret; -} - -module_i2c_driver(lm75_driver); - -MODULE_AUTHOR("Frodo Looijaard "); -MODULE_DESCRIPTION("LM75 driver"); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h deleted file mode 100644 index c9097f9db7ab..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/lm75.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - lm75.h - Part of lm_sensors, Linux kernel modules for hardware - monitoring - Copyright (c) 2003 Mark M. Hoffman - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - This file contains common code for encoding/decoding LM75 type - temperature readings, which are emulated by many of the chips - we support. As the user is unlikely to load more than one driver - which contains this code, we don't worry about the wasted space. -*/ - -#include - -/* straight from the datasheet */ -#define LM75_TEMP_MIN (-55000) -#define LM75_TEMP_MAX 125000 -#define LM75_SHUTDOWN 0x01 - -/* TEMP: 0.001C/bit (-55C to +125C) - REG: (0.5C/bit, two's complement) << 7 */ -static inline u16 LM75_TEMP_TO_REG(long temp) -{ - int ntemp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); - ntemp += (ntemp < 0 ? -250 : 250); - return (u16)((ntemp / 500) << 7); -} - -static inline int LM75_TEMP_FROM_REG(u16 reg) -{ - /* use integer division instead of equivalent right shift to - guarantee arithmetic shift and preserve the sign */ - return ((s16)reg / 128) * 500; -} \ No newline at end of file