drivers: hwmon: Add W83773G driver
PATCH 1/3 drivers: hwmon: Add W83773G driver
Nuvoton W83773G is a hardware monitor IC providing one local temperature and two remote temperature sensors.
--- drivers/hwmon/Kconfig | 11 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/w83773g.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 296 insertions(+) create mode 100644 drivers/hwmon/w83773g.c
drivers/hwmon/Kconfig +11 -0
@@ -1703,6 +1703,17 @@ config SENSORS_VT8231 This driver can also be built as a module. If so, the module will be called vt8231. +config SENSORS_W83773G + tristate "Nuvoton W83773G" + depends on I2C + select HWMON_VID + help + If you say yes here you get support for the Nuvoton W83773G hardware + monitoring chip. + + This driver can also be built as a module. If so, the module + will be called w83773g. + config SENSORS_W83781D tristate "Winbond W83781D, W83782D, W83783S, Asus AS99127F" depends on I2C
drivers/hwmon/Makefile +1 -0
@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o # asb100, then w83781d go first, as they can override other drivers' addresses. obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o +obj-$(CONFIG_SENSORS_W83773G) += w83773g.o obj-$(CONFIG_SENSORS_W83792D) += w83792d.o obj-$(CONFIG_SENSORS_W83793) += w83793.o obj-$(CONFIG_SENSORS_W83795) += w83795.o
drivers/hwmon/w83773g.c new file +284 -0
284 lines not on this page · raw message
Signature · 1 line
1.9.1
Quoted 4 lines · Lei YU
Nuvoton W83773G is a hardware monitor IC providing one local temperature and two remote temperature sensors.
Signed-off-by Lei YU <[email protected]>
Great work. Please send v2 upstream; you can find the email addresses to use by using ./scripts/get_maintainers.pl
I've got some trivial comments below.
Quoted 47 lines
--- drivers/hwmon/Kconfig | 11 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/w83773g.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 296 insertions(+) create mode 100644 drivers/hwmon/w83773g.cdrivers/hwmon/Kconfig +11
-0@@ -1703,6 +1703,17 @@ config SENSORS_VT8231 This driver can also be built as a module. If so, the module will be called vt8231. +config SENSORS_W83773G + tristate "Nuvoton W83773G" + depends on I2C + select HWMON_VID + help + If you say yes here you get support for the Nuvoton W83773G hardware + monitoring chip. + + This driver can also be built as a module. If so, the module + will be called w83773g. + config SENSORS_W83781D tristate "Winbond W83781D, W83782D, W83783S, Asus AS99127F" depends on I2Cdrivers/hwmon/Makefile +1
-0@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o # asb100, then w83781d go first, as they can override other drivers' addresses. obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o +obj-$(CONFIG_SENSORS_W83773G) += w83773g.o obj-$(CONFIG_SENSORS_W83792D) += w83792d.o obj-$(CONFIG_SENSORS_W83793) += w83793.o obj-$(CONFIG_SENSORS_W83795) += w83795.odrivers/hwmon/w83773g.c new file +0
-0
drivers/hwmon/w83773g.c line 5
Quoted 5 lines
drivers/hwmon/w83773g.c new file +5
-0@@ -0,0 +1,284 @@ +/* w83773g.c +* +* Copyright (C) 2017 <[email protected]> +* Preliminary support by: +* Nick Gruendler, Lei YU
Take a look at the other IBM copyright headers. Usually we write:
Copyright (C) 2017 IBM Corp
And optionally put your name after that.
Quoted 73 lines
drivers/hwmon/w83773g.c new file +73
-0+* +* 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. +*/ + +/* +* Driver for the Nuvoton W83773G SMBus temperature sensor IC. +* Supported models: W83773G +*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/i2c.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/sysfs.h> + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = {0x4c ,0x4d ,I2C_CLIENT_END }; + +enum chips { w83773g }; + +/* The W83773 registers */ +#define W83773_CONVERSION_RATE_REG_READ 0x04 +#define W83773_CONVERSION_RATE_REG_WRITE 0x0A +#define W83773_MANUFACTURER_ID_REG 0xFE +#define W83773_LOCAL_TEMP 0x00 + +static const u8 W83773_STATUS [2 ] = {0x02 ,0x17 }; + +static const u8 W83773_TEMP_LSB [2 ] = {0x10 ,0x25 }; +static const u8 W83773_TEMP_MSB [2 ] = {0x01 ,0x24 }; + +static const u8 W83773_OFFSET_LSB [2 ] = {0x12 ,0x16 }; +static const u8 W83773_OFFSET_MSB [2 ] = {0x11 ,0x15 }; + +/* Manufacturer / Device ID's */ +#define W83773_MANUFACTURER_ID 0x5c + + +/* this is the number of sensors in the device */ +static const struct i2c_device_id w83773_id[] = { + {"w83773g" ,3 }, + { } +}; + +MODULE_DEVICE_TABLE (i2c, w83773_id); + +static const struct of_device_id w83773_of_match[] = { + { + .compatible ="nuvoton,w83773g" , + .data = (void *)3 + }, + + { }, +}; +MODULE_DEVICE_TABLE (of, w83773_of_match); + +/* +* W83773G has 3 temp sensors: +* Channel 0 is the local sensor
drivers/hwmon/w83773g.c line 88
Quoted 10 lines
drivers/hwmon/w83773g.c new file +10
-0+* Channel 1-2 are two remote sensors +*/ +struct w83773_data { +struct i2c_client *client; +struct mutex update_lock; +u32 temp_config[4 ]; +struct hwmon_channel_info temp_info; +const struct hwmon_channel_info *info[2 ]; +struct hwmon_chip_info chip; +char valid;
this looks like a boolean, use the 'bool' type.
Quoted 6 lines
drivers/hwmon/w83773g.c new file +6
-0+unsigned long last_updated; +int channels; +s8 temp_local; +s8 status[2 ]; +s8 temp_hb[2 ]; +s8 temp_lb[2 ];
drivers/hwmon/w83773g.c line 104
Quoted 10 lines
drivers/hwmon/w83773g.c new file +10
-0+s8 offset_hb[2 ]; +s8 offset_lb[2 ]; +}; + +static int temp_of_local (s8 reg) +{ +return reg *1000 ; +} + +static int temp_of_remote (s8 hb,s8 lb,s8 offset_hb,s8 offset_lb)
You're putting this in a long, so use that as your return type.
drivers/hwmon/w83773g.c line 106
Quoted 2 lines
drivers/hwmon/w83773g.c new file +2
-0+{ +return (hb + offset_hb) *1000 + ((u8)(lb + offset_lb) >>5 ) *125 ;
Why the cast?
Quoted 181 lines
drivers/hwmon/w83773g.c new file +178
-1+} + + +static struct w83773_data *w83773_update_device (struct device *dev) +{ +struct w83773_data *data =dev_get_drvdata (dev); +struct i2c_client *client = data->client; +int i; + +mutex_lock (&data->update_lock); + +if (time_after (jiffies, data->last_updated +2 *HZ ) || !data->valid) { + data->temp_local =i2c_smbus_read_byte_data (client,W83773_LOCAL_TEMP ); +for (i =0 ; i < data->channels -1 ; i++) { + data->status[i] =i2c_smbus_read_byte_data (client,W83773_STATUS [i]); + data->temp_hb[i] =i2c_smbus_read_byte_data (client,W83773_TEMP_MSB [i]); + data->temp_lb[i] =i2c_smbus_read_byte_data (client,W83773_TEMP_LSB [i]); + data->offset_hb[i] =i2c_smbus_read_byte_data (client,W83773_OFFSET_MSB [i]); + data->offset_lb[i] =i2c_smbus_read_byte_data (client,W83773_OFFSET_LSB [i]); + } + data->last_updated = jiffies; + data->valid =1 ; + } + +mutex_unlock (&data->update_lock); + +return data; +} + +static int w83773_read (struct device *dev,enum hwmon_sensor_types type, +u32 attr,int channel,long *val) +{ +struct w83773_data *w83773 =w83773_update_device (dev); + +switch (attr) { +case hwmon_temp_input: +if (channel ==0 ) { +/* channel 0 is the local temp */ + *val =temp_of_local (w83773->temp_local); + } +else { +/* channel 1-2 are the remote temps */ + channel--; + *val =temp_of_remote ( + w83773->temp_hb[channel], + w83773->temp_lb[channel], + w83773->offset_hb[channel], + w83773->offset_lb[channel]); + } +return 0 ; +case hwmon_temp_fault: +if (channel ==0 ) + *val =0 ; +else +/* Check the status register bit 2 for faults */ + *val = (w83773->status[channel -1 ] &0x04 ) >>2 ; +return 0 ; +default : +return -EOPNOTSUPP ; + } + +} + +static umode_t w83773_is_visible (const void *data,enum hwmon_sensor_types type, +u32 attr,int channel) +{ +switch (attr) { +case hwmon_temp_fault: +if (channel ==0 ) +return 0 ; +return S_IRUGO ; +case hwmon_temp_input: +return S_IRUGO ; +default : +return 0 ; + } +} + +static int w83773_init_client (struct i2c_client *client) +{ +/* Set the conversion rate to 2 Hz */ +i2c_smbus_write_byte_data (client,W83773_CONVERSION_RATE_REG_WRITE ,0x05 ); + +return 0 ; +} + +static int w83773_detect (struct i2c_client *client, +struct i2c_board_info *info) +{ +enum chips kind; +struct i2c_adapter *adapter = client->adapter; +const char *const names[] = {"W83773G" }; +int addr = client->addr; +u8 reg; + +if (!i2c_check_functionality (adapter,I2C_FUNC_SMBUS_BYTE_DATA )) +return -ENODEV ; + + reg =i2c_smbus_read_byte_data (client,W83773_MANUFACTURER_ID_REG ); +if (reg !=W83773_MANUFACTURER_ID ) +return -ENODEV ; + + reg =i2c_smbus_read_byte_data (client,W83773_CONVERSION_RATE_REG_READ ); +if (reg &0xf8 ) +return -ENODEV ; + + kind = w83773g; + +strlcpy (info->type, w83773_id[kind].name,I2C_NAME_SIZE ); +dev_info (&adapter->dev,"Detected Nuvoton %s chip at 0x%02x\n" , + names[kind], client->addr); + +return 0 ; +} + +static const struct hwmon_ops w83773_ops = { + .is_visible = w83773_is_visible, + .read = w83773_read, +}; + +static int w83773_probe (struct i2c_client *client, +const struct i2c_device_id *id) +{ +struct device *dev = &client->dev; +struct device *hwmon_dev; +struct w83773_data *data; +int i, err; + + data =devm_kzalloc (dev,sizeof (struct w83773_data ),GFP_KERNEL ); +if (!data) +return -ENOMEM ; + +mutex_init (&data->update_lock); +if (client->dev.of_node) + data->channels = (int )of_device_get_match_data (&client->dev); +else + data->channels = id->driver_data; + data->client = client; + + err =w83773_init_client (client); +if (err) +return err; + +for (i =0 ; i < data->channels; i++) + data->temp_config[i] =HWMON_T_INPUT |HWMON_T_FAULT ; + + data->chip.ops = &w83773_ops; + data->chip.info = data->info; + + data->info[0 ] = &data->temp_info; + + data->temp_info.type = hwmon_temp; + data->temp_info.config = data->temp_config; + + hwmon_dev =devm_hwmon_device_register_with_info (dev, client->name, + data, + &data->chip, +NULL ); +return PTR_ERR_OR_ZERO (hwmon_dev); +} + +static struct i2c_driver w83773_driver = { + .class =I2C_CLASS_HWMON , + .driver = { + .name ="w83773g" , + .of_match_table =of_match_ptr (w83773_of_match), + }, + .probe = w83773_probe, + .id_table = w83773_id, + .detect = w83773_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver (w83773_driver); + +MODULE_AUTHOR ("Nickolaus Gruendler <[email protected]>" ); +MODULE_DESCRIPTION ("W83773G temperature sensor driver" ); +MODULE_LICENSE ("GPL" ); --1.9.1
Thanks for the review.
I will send v2 patch to upstream.
Quoted 66 lines · Joel Stanley
Quoted 4 lines · Lei YU
Nuvoton W83773G is a hardware monitor IC providing one local temperature and two remote temperature sensors.
Signed-off-by Lei YU <[email protected]>Great work. Please send v2 upstream; you can find the email addresses to use by using
./scripts/get_maintainers.plI've got some trivial comments below.
Quoted 47 lines
--- drivers/hwmon/Kconfig | 11 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/w83773g.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 296 insertions(+) create mode 100644 drivers/hwmon/w83773g.cdrivers/hwmon/Kconfig +11
-0@@ -1703,6 +1703,17 @@ config SENSORS_VT8231 This driver can also be built as a module. If so, the module will be called vt8231. +config SENSORS_W83773G + tristate "Nuvoton W83773G" + depends on I2C + select HWMON_VID + help + If you say yes here you get support for the Nuvoton W83773G hardware + monitoring chip. + + This driver can also be built as a module. If so, the module + will be called w83773g. + config SENSORS_W83781D tristate "Winbond W83781D, W83782D, W83783S, Asus AS99127F" depends on I2Cdrivers/hwmon/Makefile +1
-0@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o # asb100, then w83781d go first, as they can override other drivers' addresses. obj-$(CONFIG_SENSORS_ASB100) += asb100.o obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o +obj-$(CONFIG_SENSORS_W83773G) += w83773g.o obj-$(CONFIG_SENSORS_W83792D) += w83792d.o obj-$(CONFIG_SENSORS_W83793) += w83793.o obj-$(CONFIG_SENSORS_W83795) += w83795.odrivers/hwmon/w83773g.c new file +0
-0drivers/hwmon/w83773g.c line 5
Quoted 5 lines
drivers/hwmon/w83773g.c new file +5
-0@@ -0,0 +1,284 @@ +/* w83773g.c +* +* Copyright (C) 2017 <[email protected]> +* Preliminary support by: +* Nick Gruendler, Lei YU Take a look at the other IBM copyright headers. Usually we write:
Quoted 4 lines
Copyright (C) 2017 IBM Corp
And optionally put your name after that.
It will be fixed in v2.
Quoted 78 lines
Quoted 78 lines
drivers/hwmon/w83773g.c new file +77
-0+* +* 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. +*/ + +/* +* Driver for the Nuvoton W83773G SMBus temperature sensor IC. +* Supported models: W83773G +*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/i2c.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/sysfs.h> + +/* Addresses to scan */ +static const unsigned short normal_i2c[] = {0x4c ,0x4d ,I2C_CLIENT_END }; + +enum chips { w83773g }; + +/* The W83773 registers */ +#define W83773_CONVERSION_RATE_REG_READ 0x04 +#define W83773_CONVERSION_RATE_REG_WRITE 0x0A +#define W83773_MANUFACTURER_ID_REG 0xFE +#define W83773_LOCAL_TEMP 0x00 + +static const u8 W83773_STATUS [2 ] = {0x02 ,0x17 }; + +static const u8 W83773_TEMP_LSB [2 ] = {0x10 ,0x25 }; +static const u8 W83773_TEMP_MSB [2 ] = {0x01 ,0x24 }; + +static const u8 W83773_OFFSET_LSB [2 ] = {0x12 ,0x16 }; +static const u8 W83773_OFFSET_MSB [2 ] = {0x11 ,0x15 }; + +/* Manufacturer / Device ID's */ +#define W83773_MANUFACTURER_ID 0x5c + + +/* this is the number of sensors in the device */ +static const struct i2c_device_id w83773_id[] = { + {"w83773g" ,3 }, + { } +}; + +MODULE_DEVICE_TABLE (i2c, w83773_id); + +static const struct of_device_id w83773_of_match[] = { + { + .compatible ="nuvoton,w83773g" , + .data = (void *)3 + }, + + { }, +}; +MODULE_DEVICE_TABLE (of, w83773_of_match); + +/* +* W83773G has 3 temp sensors: +* Channel 0 is the local sensor +* Channel 1-2 are two remote sensors +*/ +struct w83773_data { +struct i2c_client *client;
Quoted 8 lines
drivers/hwmon/w83773g.c line 88
Quoted 6 lines
drivers/hwmon/w83773g.c new file +6
-0+struct mutex update_lock; +u32 temp_config[4 ]; +struct hwmon_channel_info temp_info; +const struct hwmon_channel_info *info[2 ]; +struct hwmon_chip_info chip; +char valid;this looks like a boolean, use the 'bool' type.
Will be fixed in v2
Quoted 12 lines
Quoted 12 lines
drivers/hwmon/w83773g.c new file +10
-0+unsigned long last_updated; +int channels; +s8 temp_local; +s8 status[2 ]; +s8 temp_hb[2 ]; +s8 temp_lb[2 ]; +s8 offset_hb[2 ]; +s8 offset_lb[2 ]; +}; +
Quoted 8 lines
drivers/hwmon/w83773g.c line 104
Quoted 6 lines
drivers/hwmon/w83773g.c new file +6
-0+static int temp_of_local (s8 reg) +{ +return reg *1000 ; +} + +static int temp_of_remote (s8 hb,s8 lb,s8 offset_hb,s8 offset_lb)You're putting this in a long, so use that as your return type.
Will be fixed in v2
Quoted 5 lines
drivers/hwmon/w83773g.c line 106
Quoted 3 lines
drivers/hwmon/w83773g.c new file +2
-0+{ +return (hb + offset_hb) *1000 + ((u8)(lb + offset_lb) >>5 ) *125 ;Why the cast?
Because lb and offset_lb are signed and could be negative values, it needs to be converted to unsigned and then do the shift.
Quoted 182 lines
Quoted 182 lines
drivers/hwmon/w83773g.c new file +178
-1+} + + +static struct w83773_data *w83773_update_device (struct device *dev) +{ +struct w83773_data *data =dev_get_drvdata (dev); +struct i2c_client *client = data->client; +int i; + +mutex_lock (&data->update_lock); + +if (time_after (jiffies, data->last_updated +2 *HZ ) || !data->valid) { + data->temp_local =i2c_smbus_read_byte_data (client,W83773_LOCAL_TEMP ); +for (i =0 ; i < data->channels -1 ; i++) { + data->status[i] =i2c_smbus_read_byte_data (client,W83773_STATUS [i]); + data->temp_hb[i] =i2c_smbus_read_byte_data (client,W83773_TEMP_MSB [i]); + data->temp_lb[i] =i2c_smbus_read_byte_data (client,W83773_TEMP_LSB [i]); + data->offset_hb[i] =i2c_smbus_read_byte_data (client,W83773_OFFSET_MSB [i]); + data->offset_lb[i] =i2c_smbus_read_byte_data (client,W83773_OFFSET_LSB [i]); + } + data->last_updated = jiffies; + data->valid =1 ; + } + +mutex_unlock (&data->update_lock); + +return data; +} + +static int w83773_read (struct device *dev,enum hwmon_sensor_types type, +u32 attr,int channel,long *val) +{ +struct w83773_data *w83773 =w83773_update_device (dev); + +switch (attr) { +case hwmon_temp_input: +if (channel ==0 ) { +/* channel 0 is the local temp */ + *val =temp_of_local (w83773->temp_local); + } +else { +/* channel 1-2 are the remote temps */ + channel--; + *val =temp_of_remote ( + w83773->temp_hb[channel], + w83773->temp_lb[channel], + w83773->offset_hb[channel], + w83773->offset_lb[channel]); + } +return 0 ; +case hwmon_temp_fault: +if (channel ==0 ) + *val =0 ; +else +/* Check the status register bit 2 for faults */ + *val = (w83773->status[channel -1 ] &0x04 ) >>2 ; +return 0 ; +default : +return -EOPNOTSUPP ; + } + +} + +static umode_t w83773_is_visible (const void *data,enum hwmon_sensor_types type, +u32 attr,int channel) +{ +switch (attr) { +case hwmon_temp_fault: +if (channel ==0 ) +return 0 ; +return S_IRUGO ; +case hwmon_temp_input: +return S_IRUGO ; +default : +return 0 ; + } +} + +static int w83773_init_client (struct i2c_client *client) +{ +/* Set the conversion rate to 2 Hz */ +i2c_smbus_write_byte_data (client,W83773_CONVERSION_RATE_REG_WRITE ,0x05 ); + +return 0 ; +} + +static int w83773_detect (struct i2c_client *client, +struct i2c_board_info *info) +{ +enum chips kind; +struct i2c_adapter *adapter = client->adapter; +const char *const names[] = {"W83773G" }; +int addr = client->addr; +u8 reg; + +if (!i2c_check_functionality (adapter,I2C_FUNC_SMBUS_BYTE_DATA )) +return -ENODEV ; + + reg =i2c_smbus_read_byte_data (client,W83773_MANUFACTURER_ID_REG ); +if (reg !=W83773_MANUFACTURER_ID ) +return -ENODEV ; + + reg =i2c_smbus_read_byte_data (client,W83773_CONVERSION_RATE_REG_READ ); +if (reg &0xf8 ) +return -ENODEV ; + + kind = w83773g; + +strlcpy (info->type, w83773_id[kind].name,I2C_NAME_SIZE ); +dev_info (&adapter->dev,"Detected Nuvoton %s chip at 0x%02x\n" , + names[kind], client->addr); + +return 0 ; +} + +static const struct hwmon_ops w83773_ops = { + .is_visible = w83773_is_visible, + .read = w83773_read, +}; + +static int w83773_probe (struct i2c_client *client, +const struct i2c_device_id *id) +{ +struct device *dev = &client->dev; +struct device *hwmon_dev; +struct w83773_data *data; +int i, err; + + data =devm_kzalloc (dev,sizeof (struct w83773_data ),GFP_KERNEL ); +if (!data) +return -ENOMEM ; + +mutex_init (&data->update_lock); +if (client->dev.of_node) + data->channels = (int )of_device_get_match_data (&client->dev); +else + data->channels = id->driver_data; + data->client = client; + + err =w83773_init_client (client); +if (err) +return err; + +for (i =0 ; i < data->channels; i++) + data->temp_config[i] =HWMON_T_INPUT |HWMON_T_FAULT ; + + data->chip.ops = &w83773_ops; + data->chip.info = data->info; + + data->info[0 ] = &data->temp_info; + + data->temp_info.type = hwmon_temp; + data->temp_info.config = data->temp_config; + + hwmon_dev =devm_hwmon_device_register_with_info (dev, client->name, + data, + &data->chip, +NULL ); +return PTR_ERR_OR_ZERO (hwmon_dev); +} + +static struct i2c_driver w83773_driver = { + .class =I2C_CLASS_HWMON , + .driver = { + .name ="w83773g" , + .of_match_table =of_match_ptr (w83773_of_match), + }, + .probe = w83773_probe, + .id_table = w83773_id, + .detect = w83773_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver (w83773_driver); + +MODULE_AUTHOR ("Nickolaus Gruendler <[email protected]>" ); +MODULE_DESCRIPTION ("W83773G temperature sensor driver" ); +MODULE_LICENSE ("GPL" ); --1.9.1