Add SB-TSI hwmon driver
Subsystems (3)
cover Add SB-TSI hwmon driver
*** BLURB HERE ***
This patchset adds hwmon support for AMD SoC SB-TSI emulated temperature sensor and related documentation.
Kun Yi (3):
hwmon: (sbtsi) Add basic support for SB-TSI sensors
hwmon: (sbtsi) Add documentation
dt-bindings: (hwmon/sbtsi_tmep) Add SB-TSI hwmon driver bindings
.../devicetree/bindings/hwmon/sbtsi_temp.txt | 14 ++ Documentation/hwmon/sbtsi_temp.rst | 33 +++ drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/sbtsi_temp.c | 218 ++++++++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 Documentation/devicetree/bindings/hwmon/sbtsi_temp.txt create mode 100644 Documentation/hwmon/sbtsi_temp.rst create mode 100644 drivers/hwmon/sbtsi_temp.c
Signature · 1 line
2.25.1.696.g5e7596f4ac-goog
PATCH 1/3 hwmon: (sbtsi) Add basic support for SB-TSI sensors
SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible interface that reports AMD SoC's Ttcl (normalized temperature), and resembles a typical 8-pin remote temperature sensor's I2C interface to BMC.
This commit adds basic support using this interface to read CPU temperature, and read/write high/low CPU temp thresholds.
Test status: tested reading temp1_input, and reading/writing temp1_max/min.
--- drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/sbtsi_temp.c | 218 +++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 drivers/hwmon/sbtsi_temp.c
drivers/hwmon/Kconfig +10 -0
@@ -1412,6 +1412,16 @@ config SENSORS_RASPBERRYPI_HWMON This driver can also be built as a module. If so, the module will be called raspberrypi-hwmon. +config SENSORS_SBTSI + tristate "Emulated SB-TSI temperature sensor" + depends on I2C + help + If you say yes here you get support for emulated temperature + sensors on AMD SoCs with SB-TSI interface connected to a BMC device. + + This driver can also be built as a module. If so, the module will + be called sbtsi_temp. + config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." depends on GPIOLIB || COMPILE_TEST
drivers/hwmon/Makefile +1 -0
@@ -152,6 +152,7 @@ obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o +obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
drivers/hwmon/sbtsi_temp.c new file +218 -0
218 lines not on this page · raw message
Signature · 1 line
2.25.1.696.g5e7596f4ac-goog
Guenter Roeck
maintainerRe: [PATCH linux hwmon-next v1 1/3] hwmon: (sbtsi) Add basic support for SB-TSI sensors
Quoted 11 lines · Kun Yi
SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible interface that reports AMD SoC's Ttcl (normalized temperature), and resembles a typical 8-pin remote temperature sensor's I2C interface to BMC.
This commit adds basic support using this interface to read CPU temperature, and read/write high/low CPU temp thresholds.
Test status: tested reading
temp1_input, and reading/writing temp1_max/min.
How do I instantiate this driver on a system with an AMD CPU (in other words, what is the i2c bus and the i2c address) ?
Quoted 74 lines
Signed-off-by Kun Yi <[email protected]>--- drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/sbtsi_temp.c | 218 +++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 drivers/hwmon/sbtsi_temp.cdrivers/hwmon/Kconfig +10
-0@@ -1412,6 +1412,16 @@ config SENSORS_RASPBERRYPI_HWMON This driver can also be built as a module. If so, the module will be called raspberrypi-hwmon. +config SENSORS_SBTSI + tristate "Emulated SB-TSI temperature sensor" + depends on I2C + help + If you say yes here you get support for emulated temperature + sensors on AMD SoCs with SB-TSI interface connected to a BMC device. + + This driver can also be built as a module. If so, the module will + be called sbtsi_temp. + config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." depends on GPIOLIB || COMPILE_TESTdrivers/hwmon/Makefile +1
-0@@ -152,6 +152,7 @@ obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o +obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o obj-$(CONFIG_SENSORS_SCH5636) += sch5636.odrivers/hwmon/sbtsi_temp.c new file +27
-0@@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* sbtsi_temp.c - hwmon driver for a SBI Temperature Sensor Interface (SB-TSI) +* compliant AMD SoC temperature device. +* +* Copyright (c) 2020, Google Inc. +* Copyright (c) 2020, Kun Yi <[email protected]> +*/ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> + +/* +* SB-TSI registers only support SMBus byte data access. "_INT" registers are +* the integer part of a temperature value or limit, and "_DEC" registers are +* corresponding decimal parts. +*/ +#define SBTSI_REG_TEMP_INT 0x01/* RO */ +#define SBTSI_REG_STATUS 0x02/* RO */ +#define SBTSI_REG_CONFIG 0x03/* RO */ +#define SBTSI_REG_TEMP_HIGH_INT 0x07/* RW */ +#define SBTSI_REG_TEMP_LOW_INT 0x08/* RW */
drivers/hwmon/sbtsi_temp.c line 37
Quoted 10 lines
drivers/hwmon/sbtsi_temp.c new file +10
-0+#define SBTSI_REG_TEMP_DEC 0x10/* RW */ +#define SBTSI_REG_TEMP_HIGH_DEC 0x13/* RW */ +#define SBTSI_REG_TEMP_LOW_DEC 0x14/* RW */ +#define SBTSI_REG_REV 0xFF/* RO */ + +#define SBTSI_CONFIG_READ_ORDER_SHIFT 5 + +#define SBTSI_TEMP_MIN (0) +#define SBTSI_TEMP_MAX (255875) +#define SBTSI_REV_MAX_VALID_ID (4)
Unnecessary ( ) around literals.
Quoted 11 lines
drivers/hwmon/sbtsi_temp.c new file +11
-0+ +struct sbtsi_data { +struct device *dev; +struct i2c_client *client; +struct mutex lock; +}; + +/* +* From SB-TSI spec: CPU temperature readings and limit registers encode the +* temperature in increments of 0.125 from 0 to 255.875. The "high byte" +* register encodes the base-2 of the integer portion, and the upper 3 bits of
drivers/hwmon/sbtsi_temp.c line 58
Quoted 10 lines
drivers/hwmon/sbtsi_temp.c new file +10
-0+* the "low byte" encode in base-2 the decimal portion. +* +* e.g. INT=0x19, DEC=0x20 represents 25.125 degrees Celsius +* +* Therefore temperature in millidegree Celsius = +* (INT + DEC / 256) * 1000 = (INT * 8 + DEC / 32) * 125 +*/ +static inline int SBTSI_REGS_TO_TEMP (s32 integer,s32 decimal) +{ +return (((u32 )integer <<3 ) + ((u32 )decimal >>5 )) *125 ;
Why pass s32 as parameter just to typecast to u32 ? The values are known to be between 0 and 255, and thus will never be negative, even with s32, so this is really unnecessary.
Quoted 122 lines
drivers/hwmon/sbtsi_temp.c new file +122
-0+} + +/* +* Inversely, given temperature in millidegree Celsius +* INT = (TEMP / 125) / 8 +* DEC = ((TEMP / 125) % 8) * 32 +* Caller have to make sure temp doesn't exceed 255875, the max valid value. +*/ +static inline void SBTSI_TEMP_TO_REGS (u32 temp,u8 *integer,u8 *decimal) +{ + temp /=125 ; + *integer = temp >>3 ; + *decimal = (temp &0x7 ) <<5 ; +} + +static ssize_t sbtsi_show_temp (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct sbtsi_data *data =dev_get_drvdata (dev); +struct i2c_client *client = data->client; +s32 err, temp_int, temp_dec; +u8 read_order; + +/* +* ReadOrder bit specifies the reading order of integer and decimal +* part of CPU temp for atomic reads. If bit == 0, reading integer part +* triggers latching of the decimal part, so integer part should be read +* first. If bit == 1, read order should be reversed. +*/ + err =i2c_smbus_read_byte_data (client,SBTSI_REG_CONFIG ); +if (err <0 ) +return err; + + read_order = (u8 )err &BIT (SBTSI_CONFIG_READ_ORDER_SHIFT ); + +if (read_order ==0 ) { + temp_int =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_INT ); + temp_dec =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_DEC ); + }else { + temp_dec =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_DEC ); + temp_int =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_INT ); + } + +if (temp_int <0 ) +return temp_int; +if (temp_dec <0 ) +return temp_dec; + +return scnprintf (buf,PAGE_SIZE ,"%d\n" , +SBTSI_REGS_TO_TEMP (temp_int, temp_dec)); +} + +#define sbtsi_show_temp_limit (name,REG ) \ +static ssize_t sbtsi_show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct sbtsi_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = data->client; \ + s32 temp_int, temp_dec; \ +\ + temp_int = i2c_smbus_read_byte_data(client, REG##_INT); \ + temp_dec = i2c_smbus_read_byte_data(client, REG##_DEC); \ +\ + if (temp_int < 0) \ + return temp_int; \ + if (temp_dec < 0) \ + return temp_dec; \ +\ + return scnprintf(buf, PAGE_SIZE, "%d\n", \ + SBTSI_REGS_TO_TEMP(temp_int, temp_dec)); \ +} + +sbtsi_show_temp_limit (temp1_min,SBTSI_REG_TEMP_LOW ); +sbtsi_show_temp_limit (temp1_max,SBTSI_REG_TEMP_HIGH ); + +#define sbtsi_set_temp_limit (name,REG ) \ +static ssize_t sbtsi_set_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct sbtsi_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = data->client; \ + long val; \ + u8 temp_int, temp_dec; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ +\ + val = clamp_val(val, SBTSI_TEMP_MIN, SBTSI_TEMP_MAX); \ + mutex_lock(&data->lock); \ + SBTSI_TEMP_TO_REGS(val, &temp_int, &temp_dec); \ + i2c_smbus_write_byte_data(client, REG##_INT, temp_int); \ + i2c_smbus_write_byte_data(client, REG##_DEC, temp_dec); \ + mutex_unlock(&data->lock); \ +\ + return count; \ +} + +sbtsi_set_temp_limit (temp1_min,SBTSI_REG_TEMP_LOW ); +sbtsi_set_temp_limit (temp1_max,SBTSI_REG_TEMP_HIGH ); + +static SENSOR_DEVICE_ATTR(temp1_input, 0444, sbtsi_show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_min, 0644, sbtsi_show_temp1_min, + sbtsi_set_temp1_min, 1); +static SENSOR_DEVICE_ATTR(temp1_max, 0644, sbtsi_show_temp1_max, + sbtsi_set_temp1_max, 2); + +static struct attribute *sbtsi_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, +NULL , +}; +ATTRIBUTE_GROUPS (sbtsi); + +static int sbtsi_probe (struct i2c_client *client, +const struct i2c_device_id *id) +{ +struct device *dev = &client->dev; +struct device *hwmon_dev; +struct sbtsi_data *data; +
drivers/hwmon/sbtsi_temp.c line 190
Quoted 10 lines
drivers/hwmon/sbtsi_temp.c new file +10
-0+ data =devm_kzalloc (dev,sizeof (struct sbtsi_data ),GFP_KERNEL ); +if (!data) +return -ENOMEM ; + + data->client = client; +mutex_init (&data->lock); + + hwmon_dev = +devm_hwmon_device_register_with_groups (dev, client->name, data, + sbtsi_groups);
Please rewrite to use the devm_hwmon_device_register_with_info() API.
drivers/hwmon/sbtsi_temp.c line 194
Quoted 4 lines
drivers/hwmon/sbtsi_temp.c new file +4
-0+if (IS_ERR (hwmon_dev)) +return PTR_ERR (hwmon_dev); + +dev_info (dev,"sensor '%s'\n" , client->name);
Is that really valuable / necessary ?
Quoted 25 lines
drivers/hwmon/sbtsi_temp.c new file +24
-0+ +return 0 ; +} + +static const struct i2c_device_id sbtsi_id[] = { + {"sbtsi" ,0 }, + {} +}; +MODULE_DEVICE_TABLE (i2c, sbtsi_id); + +static struct i2c_driver sbtsi_driver = { + .class =I2C_CLASS_HWMON , + .driver = { + .name ="sbtsi" , + }, + .probe = sbtsi_probe, + .id_table = sbtsi_id, +}; + +module_i2c_driver (sbtsi_driver); + +MODULE_AUTHOR ("Kun Yi <[email protected]>" ); +MODULE_DESCRIPTION ("Hwmon driver for AMD SB-TSI emulated sensor" ); +MODULE_LICENSE ("GPL" );
Re: [PATCH linux hwmon-next v1 1/3] hwmon: (sbtsi) Add basic support for SB-TSI sensors
Thanks for the review comments!
Quoted 10 lines · Guenter Roeck
Quoted 8 lines · Kun Yi
SB Temperature Sensor Interface (SB-TSI) is an SMBus compatible interface that reports AMD SoC's Ttcl (normalized temperature), and resembles a typical 8-pin remote temperature sensor's I2C interface to BMC.
This commit adds basic support using this interface to read CPU temperature, and read/write high/low CPU temp thresholds.
Quoted 6 lines
Quoted 3 lines
Test status: tested reading
temp1_input, and reading/writing temp1_max/min.How do I instantiate this driver on a system with an AMD CPU (in other words, what is the i2c bus and the i2c address) ?
The i2c bus number would be the bus connected from BMC to the AMD CPU. The i2c address is specified in the spec:
Section 6.3.1: The SB-TSI address is normally 98h for socket 0 and 90h for socket 1, but it could vary based on hardware address select pins.
I will add this information to v2 commit message and the Documentation.
Quoted 79 lines
Quoted 79 lines
Signed-off-by Kun Yi <[email protected]>--- drivers/hwmon/Kconfig | 10 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/sbtsi_temp.c | 218 +++++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 drivers/hwmon/sbtsi_temp.cdrivers/hwmon/Kconfig +10
-0@@ -1412,6 +1412,16 @@ config SENSORS_RASPBERRYPI_HWMON This driver can also be built as a module. If so, the module will be called raspberrypi-hwmon. +config SENSORS_SBTSI + tristate "Emulated SB-TSI temperature sensor" + depends on I2C + help + If you say yes here you get support for emulated temperature + sensors on AMD SoCs with SB-TSI interface connected to a BMC device. + + This driver can also be built as a module. If so, the module will + be called sbtsi_temp. + config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." depends on GPIOLIB || COMPILE_TESTdrivers/hwmon/Makefile +1
-0@@ -152,6 +152,7 @@ obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o +obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o obj-$(CONFIG_SENSORS_SCH5636) += sch5636.odrivers/hwmon/sbtsi_temp.c new file +31
-0@@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* +* sbtsi_temp.c - hwmon driver for a SBI Temperature Sensor Interface (SB-TSI) +* compliant AMD SoC temperature device. +* +* Copyright (c) 2020, Google Inc. +* Copyright (c) 2020, Kun Yi <[email protected]> +*/ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> + +/* +* SB-TSI registers only support SMBus byte data access. "_INT" registers are +* the integer part of a temperature value or limit, and "_DEC" registers are +* corresponding decimal parts. +*/ +#define SBTSI_REG_TEMP_INT 0x01/* RO */ +#define SBTSI_REG_STATUS 0x02/* RO */ +#define SBTSI_REG_CONFIG 0x03/* RO */ +#define SBTSI_REG_TEMP_HIGH_INT 0x07/* RW */ +#define SBTSI_REG_TEMP_LOW_INT 0x08/* RW */ +#define SBTSI_REG_TEMP_DEC 0x10/* RW */ +#define SBTSI_REG_TEMP_HIGH_DEC 0x13/* RW */ +#define SBTSI_REG_TEMP_LOW_DEC 0x14/* RW */ +#define SBTSI_REG_REV 0xFF/* RO */
Quoted 8 lines
drivers/hwmon/sbtsi_temp.c line 37
Quoted 6 lines
drivers/hwmon/sbtsi_temp.c new file +6
-0+ +#define SBTSI_CONFIG_READ_ORDER_SHIFT 5 + +#define SBTSI_TEMP_MIN (0) +#define SBTSI_TEMP_MAX (255875) +#define SBTSI_REV_MAX_VALID_ID (4)Unnecessary ( ) around literals.
Will fix in v2.
Quoted 18 lines
Quoted 18 lines
drivers/hwmon/sbtsi_temp.c new file +17
-0+ +struct sbtsi_data { +struct device *dev; +struct i2c_client *client; +struct mutex lock; +}; + +/* +* From SB-TSI spec: CPU temperature readings and limit registers encode the +* temperature in increments of 0.125 from 0 to 255.875. The "high byte" +* register encodes the base-2 of the integer portion, and the upper 3 bits of +* the "low byte" encode in base-2 the decimal portion. +* +* e.g. INT=0x19, DEC=0x20 represents 25.125 degrees Celsius +* +* Therefore temperature in millidegree Celsius = +* (INT + DEC / 256) * 1000 = (INT * 8 + DEC / 32) * 125
Quoted 8 lines
drivers/hwmon/sbtsi_temp.c line 58
Quoted 4 lines
drivers/hwmon/sbtsi_temp.c new file +4
-0+*/ +static inline int SBTSI_REGS_TO_TEMP (s32 integer,s32 decimal) +{ +return (((u32 )integer <<3 ) + ((u32 )decimal >>5 )) *125 ;Why pass s32 as parameter just to typecast to u32 ? The values are known to be between 0 and 255, and thus will never be negative, even with s32, so this is really unnecessary.
That's a good point, will fix in v2.
Quoted 126 lines
Quoted 126 lines
drivers/hwmon/sbtsi_temp.c new file +126
-0+} + +/* +* Inversely, given temperature in millidegree Celsius +* INT = (TEMP / 125) / 8 +* DEC = ((TEMP / 125) % 8) * 32 +* Caller have to make sure temp doesn't exceed 255875, the max valid value. +*/ +static inline void SBTSI_TEMP_TO_REGS (u32 temp,u8 *integer,u8 *decimal) +{ + temp /=125 ; + *integer = temp >>3 ; + *decimal = (temp &0x7 ) <<5 ; +} + +static ssize_t sbtsi_show_temp (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct sbtsi_data *data =dev_get_drvdata (dev); +struct i2c_client *client = data->client; +s32 err, temp_int, temp_dec; +u8 read_order; + +/* +* ReadOrder bit specifies the reading order of integer and decimal +* part of CPU temp for atomic reads. If bit == 0, reading integer part +* triggers latching of the decimal part, so integer part should be read +* first. If bit == 1, read order should be reversed. +*/ + err =i2c_smbus_read_byte_data (client,SBTSI_REG_CONFIG ); +if (err <0 ) +return err; + + read_order = (u8 )err &BIT (SBTSI_CONFIG_READ_ORDER_SHIFT ); + +if (read_order ==0 ) { + temp_int =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_INT ); + temp_dec =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_DEC ); + }else { + temp_dec =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_DEC ); + temp_int =i2c_smbus_read_byte_data (client,SBTSI_REG_TEMP_INT ); + } + +if (temp_int <0 ) +return temp_int; +if (temp_dec <0 ) +return temp_dec; + +return scnprintf (buf,PAGE_SIZE ,"%d\n" , +SBTSI_REGS_TO_TEMP (temp_int, temp_dec)); +} + +#define sbtsi_show_temp_limit (name,REG ) \ +static ssize_t sbtsi_show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct sbtsi_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = data->client; \ + s32 temp_int, temp_dec; \ +\ + temp_int = i2c_smbus_read_byte_data(client, REG##_INT); \ + temp_dec = i2c_smbus_read_byte_data(client, REG##_DEC); \ +\ + if (temp_int < 0) \ + return temp_int; \ + if (temp_dec < 0) \ + return temp_dec; \ +\ + return scnprintf(buf, PAGE_SIZE, "%d\n", \ + SBTSI_REGS_TO_TEMP(temp_int, temp_dec)); \ +} + +sbtsi_show_temp_limit (temp1_min,SBTSI_REG_TEMP_LOW ); +sbtsi_show_temp_limit (temp1_max,SBTSI_REG_TEMP_HIGH ); + +#define sbtsi_set_temp_limit (name,REG ) \ +static ssize_t sbtsi_set_##name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct sbtsi_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = data->client; \ + long val; \ + u8 temp_int, temp_dec; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ +\ + val = clamp_val(val, SBTSI_TEMP_MIN, SBTSI_TEMP_MAX); \ + mutex_lock(&data->lock); \ + SBTSI_TEMP_TO_REGS(val, &temp_int, &temp_dec); \ + i2c_smbus_write_byte_data(client, REG##_INT, temp_int); \ + i2c_smbus_write_byte_data(client, REG##_DEC, temp_dec); \ + mutex_unlock(&data->lock); \ +\ + return count; \ +} + +sbtsi_set_temp_limit (temp1_min,SBTSI_REG_TEMP_LOW ); +sbtsi_set_temp_limit (temp1_max,SBTSI_REG_TEMP_HIGH ); + +static SENSOR_DEVICE_ATTR(temp1_input, 0444, sbtsi_show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_min, 0644, sbtsi_show_temp1_min, + sbtsi_set_temp1_min, 1); +static SENSOR_DEVICE_ATTR(temp1_max, 0644, sbtsi_show_temp1_max, + sbtsi_set_temp1_max, 2); + +static struct attribute *sbtsi_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, +NULL , +}; +ATTRIBUTE_GROUPS (sbtsi); + +static int sbtsi_probe (struct i2c_client *client, +const struct i2c_device_id *id) +{ +struct device *dev = &client->dev; +struct device *hwmon_dev; +struct sbtsi_data *data; + + data =devm_kzalloc (dev,sizeof (struct sbtsi_data ),GFP_KERNEL ); +if (!data) +return -ENOMEM ; +
Quoted 8 lines
drivers/hwmon/sbtsi_temp.c line 190
Quoted 6 lines
drivers/hwmon/sbtsi_temp.c new file +6
-0+ data->client = client; +mutex_init (&data->lock); + + hwmon_dev = +devm_hwmon_device_register_with_groups (dev, client->name, data, + sbtsi_groups);Please rewrite to use the
devm_hwmon_device_register_with_info()API.
Done in v2.
Quoted 7 lines
drivers/hwmon/sbtsi_temp.c line 194
Quoted 5 lines
drivers/hwmon/sbtsi_temp.c new file +4
-0+if (IS_ERR (hwmon_dev)) +return PTR_ERR (hwmon_dev); + +dev_info (dev,"sensor '%s'\n" , client->name);Is that really valuable / necessary ?
Removed in v2.
Quoted 18 lines
Quoted 18 lines
drivers/hwmon/sbtsi_temp.c new file +17
-0+ +return 0 ; +} + +static const struct i2c_device_id sbtsi_id[] = { + {"sbtsi" ,0 }, + {} +}; +MODULE_DEVICE_TABLE (i2c, sbtsi_id); + +static struct i2c_driver sbtsi_driver = { + .class =I2C_CLASS_HWMON , + .driver = { + .name ="sbtsi" , + }, + .probe = sbtsi_probe, + .id_table = sbtsi_id,
Quoted 9 lines
drivers/hwmon/sbtsi_temp.c line 218
Quoted 8 lines
drivers/hwmon/sbtsi_temp.c new file +7
-0+}; + +module_i2c_driver (sbtsi_driver); + +MODULE_AUTHOR ("Kun Yi <[email protected]>" ); +MODULE_DESCRIPTION ("Hwmon driver for AMD SB-TSI emulated sensor" ); +MODULE_LICENSE ("GPL" );
--
Regards,
Kun
PATCH 2/3 hwmon: (sbtsi) Add documentation
In reply to Kun YiDocument the SB-TSI sensor interface driver.
--- Documentation/hwmon/sbtsi_temp.rst | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/hwmon/sbtsi_temp.rst
Documentation/hwmon/sbtsi_temp.rst new file +33 -0
@@ -0,0 +1,33 @@ +Kernel driver sbtsi_temp +================== + +Supported hardware: + + * Sideband interface (SBI) Temperature Sensor Interface (SB-TSI) + compliant AMD SoC temperature device. + + Prefix: 'sbtsi_temp' + + Addresses scanned: This driver doesn't support address scanning. + + Datasheet: The SB-TSI interface and protocol is available as part of + the open source SoC register reference at: + + https://www.amd.com/system/files/TechDocs/56255_OSRR.pdf + + The Advanced Platform Management Link (APML) Specification is + available at: + + http://developer.amd.com/wordpress/media/2012/10/41918.pdf + +Author: Kun Yi <[email protected]> + +Description +----------- + +The SBI temperature sensor interface (SB-TSI) is an emulation of the software +and physical interface of a typical 8-pin remote temperature sensor (RTS) on +AMD SoCs. It implements one temperature sensor with readings and limit +registers encode the temperature in increments of 0.125 from 0 to 255.875. +Limits can be set through the writable thresholds, and if reached will trigger +corresponding alert signals.
Signature · 1 line
2.25.1.696.g5e7596f4ac-goog
PATCH 3/3 dt-bindings: (hwmon/sbtsi_tmep) Add SB-TSI hwmon driver bindings
In reply to Kun YiDocument device tree bindings for AMD SB-TSI emulated temperature sensor.
--- .../devicetree/bindings/hwmon/sbtsi_temp.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Documentation/devicetree/bindings/hwmon/sbtsi_temp.txt
Documentation/devicetree/bindings/hwmon/sbtsi_temp.txt new file +14 -0
@@ -0,0 +1,14 @@ +*AMD SoC SB-TSI hwmon driver. + +Required properties: +- compatible: manufacturer and chip name, should be + "amd,sbtsi", + +- reg: I2C bus address of the device + +Example: + +sbtsi@4c { + compatible = "amd,sbtsi"; + reg = <0x4c>; +};
Signature · 1 line
2.25.1.696.g5e7596f4ac-goog