1731b4cace10f105a81d622b70f9a35f577612d63David George/* 2b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * Copyright (c) 2011 David George <david.george@ska.ac.za> 3b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * 4b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * based on adm1021.c 5b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * some credit to Christoph Scheurer, but largely a rewrite 6b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * 7b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * This program is free software; you can redistribute it and/or modify 8b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * it under the terms of the GNU General Public License as published by 9b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * the Free Software Foundation; either version 2 of the License, or 10b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * (at your option) any later version. 11b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * 12b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * This program is distributed in the hope that it will be useful, 13b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 14b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * GNU General Public License for more details. 16b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * 17b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * You should have received a copy of the GNU General Public License 18b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * along with this program; if not, write to the Free Software 19b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20b6707b78ff3172f03ee197b7e638cf6bc81d4407Guenter Roeck */ 21731b4cace10f105a81d622b70f9a35f577612d63David George 22731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/module.h> 23731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/init.h> 24731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/slab.h> 25731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/jiffies.h> 26731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/i2c.h> 27731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/hwmon.h> 28731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/hwmon-sysfs.h> 29731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/err.h> 30731b4cace10f105a81d622b70f9a35f577612d63David George#include <linux/mutex.h> 31731b4cace10f105a81d622b70f9a35f577612d63David George 32731b4cace10f105a81d622b70f9a35f577612d63David George/* Addresses to scan */ 33731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic unsigned short max1668_addr_list[] = { 34731b4cace10f105a81d622b70f9a35f577612d63David George 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; 35731b4cace10f105a81d622b70f9a35f577612d63David George 36731b4cace10f105a81d622b70f9a35f577612d63David George/* max1668 registers */ 37731b4cace10f105a81d622b70f9a35f577612d63David George 38731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_TEMP(nr) (nr) 39731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_STAT1 0x05 40731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_STAT2 0x06 41731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_MAN_ID 0xfe 42731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_DEV_ID 0xff 43731b4cace10f105a81d622b70f9a35f577612d63David George 44731b4cace10f105a81d622b70f9a35f577612d63David George/* limits */ 45731b4cace10f105a81d622b70f9a35f577612d63David George 46731b4cace10f105a81d622b70f9a35f577612d63David George/* write high limits */ 47731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_LIMH_WR(nr) (0x13 + 2 * (nr)) 48731b4cace10f105a81d622b70f9a35f577612d63David George/* write low limits */ 49731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_LIML_WR(nr) (0x14 + 2 * (nr)) 50731b4cace10f105a81d622b70f9a35f577612d63David George/* read high limits */ 51731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_LIMH_RD(nr) (0x08 + 2 * (nr)) 52731b4cace10f105a81d622b70f9a35f577612d63David George/* read low limits */ 53731b4cace10f105a81d622b70f9a35f577612d63David George#define MAX1668_REG_LIML_RD(nr) (0x09 + 2 * (nr)) 54731b4cace10f105a81d622b70f9a35f577612d63David George 55731b4cace10f105a81d622b70f9a35f577612d63David George/* manufacturer and device ID Constants */ 56731b4cace10f105a81d622b70f9a35f577612d63David George#define MAN_ID_MAXIM 0x4d 57731b4cace10f105a81d622b70f9a35f577612d63David George#define DEV_ID_MAX1668 0x3 58731b4cace10f105a81d622b70f9a35f577612d63David George#define DEV_ID_MAX1805 0x5 59731b4cace10f105a81d622b70f9a35f577612d63David George#define DEV_ID_MAX1989 0xb 60731b4cace10f105a81d622b70f9a35f577612d63David George 61731b4cace10f105a81d622b70f9a35f577612d63David George/* read only mode module parameter */ 6290ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool read_only; 63731b4cace10f105a81d622b70f9a35f577612d63David Georgemodule_param(read_only, bool, 0); 64731b4cace10f105a81d622b70f9a35f577612d63David GeorgeMODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); 65731b4cace10f105a81d622b70f9a35f577612d63David George 66731b4cace10f105a81d622b70f9a35f577612d63David Georgeenum chips { max1668, max1805, max1989 }; 67731b4cace10f105a81d622b70f9a35f577612d63David George 68731b4cace10f105a81d622b70f9a35f577612d63David Georgestruct max1668_data { 69731b4cace10f105a81d622b70f9a35f577612d63David George struct device *hwmon_dev; 70731b4cace10f105a81d622b70f9a35f577612d63David George enum chips type; 71731b4cace10f105a81d622b70f9a35f577612d63David George 72731b4cace10f105a81d622b70f9a35f577612d63David George struct mutex update_lock; 73731b4cace10f105a81d622b70f9a35f577612d63David George char valid; /* !=0 if following fields are valid */ 74731b4cace10f105a81d622b70f9a35f577612d63David George unsigned long last_updated; /* In jiffies */ 75731b4cace10f105a81d622b70f9a35f577612d63David George 76731b4cace10f105a81d622b70f9a35f577612d63David George /* 1x local and 4x remote */ 77731b4cace10f105a81d622b70f9a35f577612d63David George s8 temp_max[5]; 78731b4cace10f105a81d622b70f9a35f577612d63David George s8 temp_min[5]; 79731b4cace10f105a81d622b70f9a35f577612d63David George s8 temp[5]; 80731b4cace10f105a81d622b70f9a35f577612d63David George u16 alarms; 81731b4cace10f105a81d622b70f9a35f577612d63David George}; 82731b4cace10f105a81d622b70f9a35f577612d63David George 83731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic struct max1668_data *max1668_update_device(struct device *dev) 84731b4cace10f105a81d622b70f9a35f577612d63David George{ 85731b4cace10f105a81d622b70f9a35f577612d63David George struct i2c_client *client = to_i2c_client(dev); 86731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = i2c_get_clientdata(client); 87731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *ret = data; 88731b4cace10f105a81d622b70f9a35f577612d63David George s32 val; 89731b4cace10f105a81d622b70f9a35f577612d63David George int i; 90731b4cace10f105a81d622b70f9a35f577612d63David George 91731b4cace10f105a81d622b70f9a35f577612d63David George mutex_lock(&data->update_lock); 92731b4cace10f105a81d622b70f9a35f577612d63David George 93731b4cace10f105a81d622b70f9a35f577612d63David George if (data->valid && !time_after(jiffies, 94731b4cace10f105a81d622b70f9a35f577612d63David George data->last_updated + HZ + HZ / 2)) 95731b4cace10f105a81d622b70f9a35f577612d63David George goto abort; 96731b4cace10f105a81d622b70f9a35f577612d63David George 97731b4cace10f105a81d622b70f9a35f577612d63David George for (i = 0; i < 5; i++) { 98731b4cace10f105a81d622b70f9a35f577612d63David George val = i2c_smbus_read_byte_data(client, MAX1668_REG_TEMP(i)); 99731b4cace10f105a81d622b70f9a35f577612d63David George if (unlikely(val < 0)) { 100731b4cace10f105a81d622b70f9a35f577612d63David George ret = ERR_PTR(val); 101731b4cace10f105a81d622b70f9a35f577612d63David George goto abort; 102731b4cace10f105a81d622b70f9a35f577612d63David George } 103731b4cace10f105a81d622b70f9a35f577612d63David George data->temp[i] = (s8) val; 104731b4cace10f105a81d622b70f9a35f577612d63David George 105731b4cace10f105a81d622b70f9a35f577612d63David George val = i2c_smbus_read_byte_data(client, MAX1668_REG_LIMH_RD(i)); 106731b4cace10f105a81d622b70f9a35f577612d63David George if (unlikely(val < 0)) { 107731b4cace10f105a81d622b70f9a35f577612d63David George ret = ERR_PTR(val); 108731b4cace10f105a81d622b70f9a35f577612d63David George goto abort; 109731b4cace10f105a81d622b70f9a35f577612d63David George } 110731b4cace10f105a81d622b70f9a35f577612d63David George data->temp_max[i] = (s8) val; 111731b4cace10f105a81d622b70f9a35f577612d63David George 112731b4cace10f105a81d622b70f9a35f577612d63David George val = i2c_smbus_read_byte_data(client, MAX1668_REG_LIML_RD(i)); 113731b4cace10f105a81d622b70f9a35f577612d63David George if (unlikely(val < 0)) { 114731b4cace10f105a81d622b70f9a35f577612d63David George ret = ERR_PTR(val); 115731b4cace10f105a81d622b70f9a35f577612d63David George goto abort; 116731b4cace10f105a81d622b70f9a35f577612d63David George } 117731b4cace10f105a81d622b70f9a35f577612d63David George data->temp_min[i] = (s8) val; 118731b4cace10f105a81d622b70f9a35f577612d63David George } 119731b4cace10f105a81d622b70f9a35f577612d63David George 120731b4cace10f105a81d622b70f9a35f577612d63David George val = i2c_smbus_read_byte_data(client, MAX1668_REG_STAT1); 121731b4cace10f105a81d622b70f9a35f577612d63David George if (unlikely(val < 0)) { 122731b4cace10f105a81d622b70f9a35f577612d63David George ret = ERR_PTR(val); 123731b4cace10f105a81d622b70f9a35f577612d63David George goto abort; 124731b4cace10f105a81d622b70f9a35f577612d63David George } 125dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck data->alarms = val << 8; 126731b4cace10f105a81d622b70f9a35f577612d63David George 127731b4cace10f105a81d622b70f9a35f577612d63David George val = i2c_smbus_read_byte_data(client, MAX1668_REG_STAT2); 128731b4cace10f105a81d622b70f9a35f577612d63David George if (unlikely(val < 0)) { 129731b4cace10f105a81d622b70f9a35f577612d63David George ret = ERR_PTR(val); 130731b4cace10f105a81d622b70f9a35f577612d63David George goto abort; 131731b4cace10f105a81d622b70f9a35f577612d63David George } 132dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck data->alarms |= val; 133731b4cace10f105a81d622b70f9a35f577612d63David George 134731b4cace10f105a81d622b70f9a35f577612d63David George data->last_updated = jiffies; 135731b4cace10f105a81d622b70f9a35f577612d63David George data->valid = 1; 136731b4cace10f105a81d622b70f9a35f577612d63David Georgeabort: 137731b4cace10f105a81d622b70f9a35f577612d63David George mutex_unlock(&data->update_lock); 138731b4cace10f105a81d622b70f9a35f577612d63David George 139731b4cace10f105a81d622b70f9a35f577612d63David George return ret; 140731b4cace10f105a81d622b70f9a35f577612d63David George} 141731b4cace10f105a81d622b70f9a35f577612d63David George 142731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic ssize_t show_temp(struct device *dev, 143731b4cace10f105a81d622b70f9a35f577612d63David George struct device_attribute *devattr, char *buf) 144731b4cace10f105a81d622b70f9a35f577612d63David George{ 145731b4cace10f105a81d622b70f9a35f577612d63David George int index = to_sensor_dev_attr(devattr)->index; 146731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = max1668_update_device(dev); 147731b4cace10f105a81d622b70f9a35f577612d63David George 148731b4cace10f105a81d622b70f9a35f577612d63David George if (IS_ERR(data)) 149731b4cace10f105a81d622b70f9a35f577612d63David George return PTR_ERR(data); 150731b4cace10f105a81d622b70f9a35f577612d63David George 151731b4cace10f105a81d622b70f9a35f577612d63David George return sprintf(buf, "%d\n", data->temp[index] * 1000); 152731b4cace10f105a81d622b70f9a35f577612d63David George} 153731b4cace10f105a81d622b70f9a35f577612d63David George 154731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic ssize_t show_temp_max(struct device *dev, 155731b4cace10f105a81d622b70f9a35f577612d63David George struct device_attribute *devattr, char *buf) 156731b4cace10f105a81d622b70f9a35f577612d63David George{ 157731b4cace10f105a81d622b70f9a35f577612d63David George int index = to_sensor_dev_attr(devattr)->index; 158731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = max1668_update_device(dev); 159731b4cace10f105a81d622b70f9a35f577612d63David George 160731b4cace10f105a81d622b70f9a35f577612d63David George if (IS_ERR(data)) 161731b4cace10f105a81d622b70f9a35f577612d63David George return PTR_ERR(data); 162731b4cace10f105a81d622b70f9a35f577612d63David George 163731b4cace10f105a81d622b70f9a35f577612d63David George return sprintf(buf, "%d\n", data->temp_max[index] * 1000); 164731b4cace10f105a81d622b70f9a35f577612d63David George} 165731b4cace10f105a81d622b70f9a35f577612d63David George 166731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic ssize_t show_temp_min(struct device *dev, 167731b4cace10f105a81d622b70f9a35f577612d63David George struct device_attribute *devattr, char *buf) 168731b4cace10f105a81d622b70f9a35f577612d63David George{ 169731b4cace10f105a81d622b70f9a35f577612d63David George int index = to_sensor_dev_attr(devattr)->index; 170731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = max1668_update_device(dev); 171731b4cace10f105a81d622b70f9a35f577612d63David George 172731b4cace10f105a81d622b70f9a35f577612d63David George if (IS_ERR(data)) 173731b4cace10f105a81d622b70f9a35f577612d63David George return PTR_ERR(data); 174731b4cace10f105a81d622b70f9a35f577612d63David George 175731b4cace10f105a81d622b70f9a35f577612d63David George return sprintf(buf, "%d\n", data->temp_min[index] * 1000); 176731b4cace10f105a81d622b70f9a35f577612d63David George} 177731b4cace10f105a81d622b70f9a35f577612d63David George 178731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic ssize_t show_alarm(struct device *dev, struct device_attribute *attr, 179731b4cace10f105a81d622b70f9a35f577612d63David George char *buf) 180731b4cace10f105a81d622b70f9a35f577612d63David George{ 181731b4cace10f105a81d622b70f9a35f577612d63David George int index = to_sensor_dev_attr(attr)->index; 182731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = max1668_update_device(dev); 183731b4cace10f105a81d622b70f9a35f577612d63David George 184731b4cace10f105a81d622b70f9a35f577612d63David George if (IS_ERR(data)) 185731b4cace10f105a81d622b70f9a35f577612d63David George return PTR_ERR(data); 186731b4cace10f105a81d622b70f9a35f577612d63David George 187731b4cace10f105a81d622b70f9a35f577612d63David George return sprintf(buf, "%u\n", (data->alarms >> index) & 0x1); 188731b4cace10f105a81d622b70f9a35f577612d63David George} 189731b4cace10f105a81d622b70f9a35f577612d63David George 190dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeckstatic ssize_t show_fault(struct device *dev, 191dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck struct device_attribute *devattr, char *buf) 192dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck{ 193dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck int index = to_sensor_dev_attr(devattr)->index; 194dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck struct max1668_data *data = max1668_update_device(dev); 195dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck 196dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck if (IS_ERR(data)) 197dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck return PTR_ERR(data); 198dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck 199dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck return sprintf(buf, "%u\n", 200dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck (data->alarms & (1 << 12)) && data->temp[index] == 127); 201dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck} 202dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck 203731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic ssize_t set_temp_max(struct device *dev, 204731b4cace10f105a81d622b70f9a35f577612d63David George struct device_attribute *devattr, 205731b4cace10f105a81d622b70f9a35f577612d63David George const char *buf, size_t count) 206731b4cace10f105a81d622b70f9a35f577612d63David George{ 207731b4cace10f105a81d622b70f9a35f577612d63David George int index = to_sensor_dev_attr(devattr)->index; 208731b4cace10f105a81d622b70f9a35f577612d63David George struct i2c_client *client = to_i2c_client(dev); 209731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = i2c_get_clientdata(client); 210731b4cace10f105a81d622b70f9a35f577612d63David George long temp; 211731b4cace10f105a81d622b70f9a35f577612d63David George int ret; 212731b4cace10f105a81d622b70f9a35f577612d63David George 213731b4cace10f105a81d622b70f9a35f577612d63David George ret = kstrtol(buf, 10, &temp); 214731b4cace10f105a81d622b70f9a35f577612d63David George if (ret < 0) 215731b4cace10f105a81d622b70f9a35f577612d63David George return ret; 216731b4cace10f105a81d622b70f9a35f577612d63David George 217731b4cace10f105a81d622b70f9a35f577612d63David George mutex_lock(&data->update_lock); 218731b4cace10f105a81d622b70f9a35f577612d63David George data->temp_max[index] = SENSORS_LIMIT(temp/1000, -128, 127); 219731b4cace10f105a81d622b70f9a35f577612d63David George if (i2c_smbus_write_byte_data(client, 220731b4cace10f105a81d622b70f9a35f577612d63David George MAX1668_REG_LIMH_WR(index), 221731b4cace10f105a81d622b70f9a35f577612d63David George data->temp_max[index])) 222731b4cace10f105a81d622b70f9a35f577612d63David George count = -EIO; 223731b4cace10f105a81d622b70f9a35f577612d63David George mutex_unlock(&data->update_lock); 224731b4cace10f105a81d622b70f9a35f577612d63David George 225731b4cace10f105a81d622b70f9a35f577612d63David George return count; 226731b4cace10f105a81d622b70f9a35f577612d63David George} 227731b4cace10f105a81d622b70f9a35f577612d63David George 228731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic ssize_t set_temp_min(struct device *dev, 229731b4cace10f105a81d622b70f9a35f577612d63David George struct device_attribute *devattr, 230731b4cace10f105a81d622b70f9a35f577612d63David George const char *buf, size_t count) 231731b4cace10f105a81d622b70f9a35f577612d63David George{ 232731b4cace10f105a81d622b70f9a35f577612d63David George int index = to_sensor_dev_attr(devattr)->index; 233731b4cace10f105a81d622b70f9a35f577612d63David George struct i2c_client *client = to_i2c_client(dev); 234731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = i2c_get_clientdata(client); 235731b4cace10f105a81d622b70f9a35f577612d63David George long temp; 236731b4cace10f105a81d622b70f9a35f577612d63David George int ret; 237731b4cace10f105a81d622b70f9a35f577612d63David George 238731b4cace10f105a81d622b70f9a35f577612d63David George ret = kstrtol(buf, 10, &temp); 239731b4cace10f105a81d622b70f9a35f577612d63David George if (ret < 0) 240731b4cace10f105a81d622b70f9a35f577612d63David George return ret; 241731b4cace10f105a81d622b70f9a35f577612d63David George 242731b4cace10f105a81d622b70f9a35f577612d63David George mutex_lock(&data->update_lock); 243731b4cace10f105a81d622b70f9a35f577612d63David George data->temp_min[index] = SENSORS_LIMIT(temp/1000, -128, 127); 244731b4cace10f105a81d622b70f9a35f577612d63David George if (i2c_smbus_write_byte_data(client, 245731b4cace10f105a81d622b70f9a35f577612d63David George MAX1668_REG_LIML_WR(index), 246731b4cace10f105a81d622b70f9a35f577612d63David George data->temp_max[index])) 247731b4cace10f105a81d622b70f9a35f577612d63David George count = -EIO; 248731b4cace10f105a81d622b70f9a35f577612d63David George mutex_unlock(&data->update_lock); 249731b4cace10f105a81d622b70f9a35f577612d63David George 250731b4cace10f105a81d622b70f9a35f577612d63David George return count; 251731b4cace10f105a81d622b70f9a35f577612d63David George} 252731b4cace10f105a81d622b70f9a35f577612d63David George 253731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 254731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, 255731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_max, 0); 256731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp_min, 257731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_min, 0); 258731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); 259731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_max, 260731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_max, 1); 261731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO, show_temp_min, 262731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_min, 1); 263731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); 264731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_max, 265731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_max, 2); 266731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO, show_temp_min, 267731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_min, 2); 268731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); 269731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_max, 270731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_max, 3); 271731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO, show_temp_min, 272731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_min, 3); 273731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); 274731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_max, 275731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_max, 4); 276731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp5_min, S_IRUGO, show_temp_min, 277731b4cace10f105a81d622b70f9a35f577612d63David George set_temp_min, 4); 278731b4cace10f105a81d622b70f9a35f577612d63David George 279731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 14); 280731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 13); 281731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 7); 282731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 6); 283731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_alarm, NULL, 5); 284731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4); 285731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO, show_alarm, NULL, 3); 286731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 2); 287731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp5_min_alarm, S_IRUGO, show_alarm, NULL, 1); 288731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO, show_alarm, NULL, 0); 289731b4cace10f105a81d622b70f9a35f577612d63David George 290dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1); 291dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2); 292dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3); 293dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_fault, NULL, 4); 294dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck 295731b4cace10f105a81d622b70f9a35f577612d63David George/* Attributes common to MAX1668, MAX1989 and MAX1805 */ 296731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic struct attribute *max1668_attribute_common[] = { 297731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp1_max.dev_attr.attr, 298731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp1_min.dev_attr.attr, 299731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp1_input.dev_attr.attr, 300731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp2_max.dev_attr.attr, 301731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp2_min.dev_attr.attr, 302731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp2_input.dev_attr.attr, 303731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp3_max.dev_attr.attr, 304731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp3_min.dev_attr.attr, 305731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp3_input.dev_attr.attr, 306731b4cace10f105a81d622b70f9a35f577612d63David George 307731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 308731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 309731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, 310731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, 311731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, 312731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, 313dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck 314dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck &sensor_dev_attr_temp2_fault.dev_attr.attr, 315dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck &sensor_dev_attr_temp3_fault.dev_attr.attr, 316731b4cace10f105a81d622b70f9a35f577612d63David George NULL 317731b4cace10f105a81d622b70f9a35f577612d63David George}; 318731b4cace10f105a81d622b70f9a35f577612d63David George 319731b4cace10f105a81d622b70f9a35f577612d63David George/* Attributes not present on MAX1805 */ 320731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic struct attribute *max1668_attribute_unique[] = { 321731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp4_max.dev_attr.attr, 322731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp4_min.dev_attr.attr, 323731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp4_input.dev_attr.attr, 324731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp5_max.dev_attr.attr, 325731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp5_min.dev_attr.attr, 326731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp5_input.dev_attr.attr, 327731b4cace10f105a81d622b70f9a35f577612d63David George 328731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, 329731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, 330731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, 331731b4cace10f105a81d622b70f9a35f577612d63David George &sensor_dev_attr_temp5_min_alarm.dev_attr.attr, 332dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck 333dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck &sensor_dev_attr_temp4_fault.dev_attr.attr, 334dabaa0d2b4085a2037d80a40b86ba215f00b601eGuenter Roeck &sensor_dev_attr_temp5_fault.dev_attr.attr, 335731b4cace10f105a81d622b70f9a35f577612d63David George NULL 336731b4cace10f105a81d622b70f9a35f577612d63David George}; 337731b4cace10f105a81d622b70f9a35f577612d63David George 338587a1f1659e8b330b8738ef4901832a2b63f0bedAl Virostatic umode_t max1668_attribute_mode(struct kobject *kobj, 339731b4cace10f105a81d622b70f9a35f577612d63David George struct attribute *attr, int index) 340731b4cace10f105a81d622b70f9a35f577612d63David George{ 341587a1f1659e8b330b8738ef4901832a2b63f0bedAl Viro umode_t ret = S_IRUGO; 342731b4cace10f105a81d622b70f9a35f577612d63David George if (read_only) 343731b4cace10f105a81d622b70f9a35f577612d63David George return ret; 344731b4cace10f105a81d622b70f9a35f577612d63David George if (attr == &sensor_dev_attr_temp1_max.dev_attr.attr || 345731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp2_max.dev_attr.attr || 346731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp3_max.dev_attr.attr || 347731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp4_max.dev_attr.attr || 348731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp5_max.dev_attr.attr || 349731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp1_min.dev_attr.attr || 350731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp2_min.dev_attr.attr || 351731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp3_min.dev_attr.attr || 352731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp4_min.dev_attr.attr || 353731b4cace10f105a81d622b70f9a35f577612d63David George attr == &sensor_dev_attr_temp5_min.dev_attr.attr) 354731b4cace10f105a81d622b70f9a35f577612d63David George ret |= S_IWUSR; 355731b4cace10f105a81d622b70f9a35f577612d63David George return ret; 356731b4cace10f105a81d622b70f9a35f577612d63David George} 357731b4cace10f105a81d622b70f9a35f577612d63David George 358731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic const struct attribute_group max1668_group_common = { 359731b4cace10f105a81d622b70f9a35f577612d63David George .attrs = max1668_attribute_common, 360731b4cace10f105a81d622b70f9a35f577612d63David George .is_visible = max1668_attribute_mode 361731b4cace10f105a81d622b70f9a35f577612d63David George}; 362731b4cace10f105a81d622b70f9a35f577612d63David George 363731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic const struct attribute_group max1668_group_unique = { 364731b4cace10f105a81d622b70f9a35f577612d63David George .attrs = max1668_attribute_unique, 365731b4cace10f105a81d622b70f9a35f577612d63David George .is_visible = max1668_attribute_mode 366731b4cace10f105a81d622b70f9a35f577612d63David George}; 367731b4cace10f105a81d622b70f9a35f577612d63David George 368731b4cace10f105a81d622b70f9a35f577612d63David George/* Return 0 if detection is successful, -ENODEV otherwise */ 369731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic int max1668_detect(struct i2c_client *client, 370731b4cace10f105a81d622b70f9a35f577612d63David George struct i2c_board_info *info) 371731b4cace10f105a81d622b70f9a35f577612d63David George{ 372731b4cace10f105a81d622b70f9a35f577612d63David George struct i2c_adapter *adapter = client->adapter; 373731b4cace10f105a81d622b70f9a35f577612d63David George const char *type_name; 374731b4cace10f105a81d622b70f9a35f577612d63David George int man_id, dev_id; 375731b4cace10f105a81d622b70f9a35f577612d63David George 376731b4cace10f105a81d622b70f9a35f577612d63David George if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 377731b4cace10f105a81d622b70f9a35f577612d63David George return -ENODEV; 378731b4cace10f105a81d622b70f9a35f577612d63David George 379731b4cace10f105a81d622b70f9a35f577612d63David George /* Check for unsupported part */ 380731b4cace10f105a81d622b70f9a35f577612d63David George man_id = i2c_smbus_read_byte_data(client, MAX1668_REG_MAN_ID); 381731b4cace10f105a81d622b70f9a35f577612d63David George if (man_id != MAN_ID_MAXIM) 382731b4cace10f105a81d622b70f9a35f577612d63David George return -ENODEV; 383731b4cace10f105a81d622b70f9a35f577612d63David George 384731b4cace10f105a81d622b70f9a35f577612d63David George dev_id = i2c_smbus_read_byte_data(client, MAX1668_REG_DEV_ID); 385731b4cace10f105a81d622b70f9a35f577612d63David George if (dev_id < 0) 386731b4cace10f105a81d622b70f9a35f577612d63David George return -ENODEV; 387731b4cace10f105a81d622b70f9a35f577612d63David George 388731b4cace10f105a81d622b70f9a35f577612d63David George type_name = NULL; 389731b4cace10f105a81d622b70f9a35f577612d63David George if (dev_id == DEV_ID_MAX1668) 390731b4cace10f105a81d622b70f9a35f577612d63David George type_name = "max1668"; 391731b4cace10f105a81d622b70f9a35f577612d63David George else if (dev_id == DEV_ID_MAX1805) 392731b4cace10f105a81d622b70f9a35f577612d63David George type_name = "max1805"; 393731b4cace10f105a81d622b70f9a35f577612d63David George else if (dev_id == DEV_ID_MAX1989) 394731b4cace10f105a81d622b70f9a35f577612d63David George type_name = "max1989"; 395731b4cace10f105a81d622b70f9a35f577612d63David George 396731b4cace10f105a81d622b70f9a35f577612d63David George if (!type_name) 397731b4cace10f105a81d622b70f9a35f577612d63David George return -ENODEV; 398731b4cace10f105a81d622b70f9a35f577612d63David George 399731b4cace10f105a81d622b70f9a35f577612d63David George strlcpy(info->type, type_name, I2C_NAME_SIZE); 400731b4cace10f105a81d622b70f9a35f577612d63David George 401731b4cace10f105a81d622b70f9a35f577612d63David George return 0; 402731b4cace10f105a81d622b70f9a35f577612d63David George} 403731b4cace10f105a81d622b70f9a35f577612d63David George 404731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic int max1668_probe(struct i2c_client *client, 405731b4cace10f105a81d622b70f9a35f577612d63David George const struct i2c_device_id *id) 406731b4cace10f105a81d622b70f9a35f577612d63David George{ 407731b4cace10f105a81d622b70f9a35f577612d63David George struct i2c_adapter *adapter = client->adapter; 408731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data; 409731b4cace10f105a81d622b70f9a35f577612d63David George int err; 410731b4cace10f105a81d622b70f9a35f577612d63David George 411731b4cace10f105a81d622b70f9a35f577612d63David George if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 412731b4cace10f105a81d622b70f9a35f577612d63David George return -ENODEV; 413731b4cace10f105a81d622b70f9a35f577612d63David George 414731b4cace10f105a81d622b70f9a35f577612d63David George data = kzalloc(sizeof(struct max1668_data), GFP_KERNEL); 415731b4cace10f105a81d622b70f9a35f577612d63David George if (!data) 416731b4cace10f105a81d622b70f9a35f577612d63David George return -ENOMEM; 417731b4cace10f105a81d622b70f9a35f577612d63David George 418731b4cace10f105a81d622b70f9a35f577612d63David George i2c_set_clientdata(client, data); 419731b4cace10f105a81d622b70f9a35f577612d63David George data->type = id->driver_data; 420731b4cace10f105a81d622b70f9a35f577612d63David George mutex_init(&data->update_lock); 421731b4cace10f105a81d622b70f9a35f577612d63David George 422731b4cace10f105a81d622b70f9a35f577612d63David George /* Register sysfs hooks */ 423731b4cace10f105a81d622b70f9a35f577612d63David George err = sysfs_create_group(&client->dev.kobj, &max1668_group_common); 424731b4cace10f105a81d622b70f9a35f577612d63David George if (err) 425731b4cace10f105a81d622b70f9a35f577612d63David George goto error_free; 426731b4cace10f105a81d622b70f9a35f577612d63David George 427731b4cace10f105a81d622b70f9a35f577612d63David George if (data->type == max1668 || data->type == max1989) { 428731b4cace10f105a81d622b70f9a35f577612d63David George err = sysfs_create_group(&client->dev.kobj, 429731b4cace10f105a81d622b70f9a35f577612d63David George &max1668_group_unique); 430731b4cace10f105a81d622b70f9a35f577612d63David George if (err) 431731b4cace10f105a81d622b70f9a35f577612d63David George goto error_sysrem0; 432731b4cace10f105a81d622b70f9a35f577612d63David George } 433731b4cace10f105a81d622b70f9a35f577612d63David George 434731b4cace10f105a81d622b70f9a35f577612d63David George data->hwmon_dev = hwmon_device_register(&client->dev); 435731b4cace10f105a81d622b70f9a35f577612d63David George if (IS_ERR(data->hwmon_dev)) { 436731b4cace10f105a81d622b70f9a35f577612d63David George err = PTR_ERR(data->hwmon_dev); 437731b4cace10f105a81d622b70f9a35f577612d63David George goto error_sysrem1; 438731b4cace10f105a81d622b70f9a35f577612d63David George } 439731b4cace10f105a81d622b70f9a35f577612d63David George 440731b4cace10f105a81d622b70f9a35f577612d63David George return 0; 441731b4cace10f105a81d622b70f9a35f577612d63David George 442731b4cace10f105a81d622b70f9a35f577612d63David Georgeerror_sysrem1: 443731b4cace10f105a81d622b70f9a35f577612d63David George if (data->type == max1668 || data->type == max1989) 444731b4cace10f105a81d622b70f9a35f577612d63David George sysfs_remove_group(&client->dev.kobj, &max1668_group_unique); 445731b4cace10f105a81d622b70f9a35f577612d63David Georgeerror_sysrem0: 446731b4cace10f105a81d622b70f9a35f577612d63David George sysfs_remove_group(&client->dev.kobj, &max1668_group_common); 447731b4cace10f105a81d622b70f9a35f577612d63David Georgeerror_free: 448731b4cace10f105a81d622b70f9a35f577612d63David George kfree(data); 449731b4cace10f105a81d622b70f9a35f577612d63David George return err; 450731b4cace10f105a81d622b70f9a35f577612d63David George} 451731b4cace10f105a81d622b70f9a35f577612d63David George 452731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic int max1668_remove(struct i2c_client *client) 453731b4cace10f105a81d622b70f9a35f577612d63David George{ 454731b4cace10f105a81d622b70f9a35f577612d63David George struct max1668_data *data = i2c_get_clientdata(client); 455731b4cace10f105a81d622b70f9a35f577612d63David George 456731b4cace10f105a81d622b70f9a35f577612d63David George hwmon_device_unregister(data->hwmon_dev); 457731b4cace10f105a81d622b70f9a35f577612d63David George if (data->type == max1668 || data->type == max1989) 458731b4cace10f105a81d622b70f9a35f577612d63David George sysfs_remove_group(&client->dev.kobj, &max1668_group_unique); 459731b4cace10f105a81d622b70f9a35f577612d63David George 460731b4cace10f105a81d622b70f9a35f577612d63David George sysfs_remove_group(&client->dev.kobj, &max1668_group_common); 461731b4cace10f105a81d622b70f9a35f577612d63David George 462731b4cace10f105a81d622b70f9a35f577612d63David George kfree(data); 463731b4cace10f105a81d622b70f9a35f577612d63David George return 0; 464731b4cace10f105a81d622b70f9a35f577612d63David George} 465731b4cace10f105a81d622b70f9a35f577612d63David George 466731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic const struct i2c_device_id max1668_id[] = { 467731b4cace10f105a81d622b70f9a35f577612d63David George { "max1668", max1668 }, 468731b4cace10f105a81d622b70f9a35f577612d63David George { "max1805", max1805 }, 469731b4cace10f105a81d622b70f9a35f577612d63David George { "max1989", max1989 }, 470731b4cace10f105a81d622b70f9a35f577612d63David George { } 471731b4cace10f105a81d622b70f9a35f577612d63David George}; 472731b4cace10f105a81d622b70f9a35f577612d63David GeorgeMODULE_DEVICE_TABLE(i2c, max1668_id); 473731b4cace10f105a81d622b70f9a35f577612d63David George 474731b4cace10f105a81d622b70f9a35f577612d63David George/* This is the driver that will be inserted */ 475731b4cace10f105a81d622b70f9a35f577612d63David Georgestatic struct i2c_driver max1668_driver = { 476731b4cace10f105a81d622b70f9a35f577612d63David George .class = I2C_CLASS_HWMON, 477731b4cace10f105a81d622b70f9a35f577612d63David George .driver = { 478731b4cace10f105a81d622b70f9a35f577612d63David George .name = "max1668", 479731b4cace10f105a81d622b70f9a35f577612d63David George }, 480731b4cace10f105a81d622b70f9a35f577612d63David George .probe = max1668_probe, 481731b4cace10f105a81d622b70f9a35f577612d63David George .remove = max1668_remove, 482731b4cace10f105a81d622b70f9a35f577612d63David George .id_table = max1668_id, 483731b4cace10f105a81d622b70f9a35f577612d63David George .detect = max1668_detect, 484731b4cace10f105a81d622b70f9a35f577612d63David George .address_list = max1668_addr_list, 485731b4cace10f105a81d622b70f9a35f577612d63David George}; 486731b4cace10f105a81d622b70f9a35f577612d63David George 487f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(max1668_driver); 488731b4cace10f105a81d622b70f9a35f577612d63David George 489731b4cace10f105a81d622b70f9a35f577612d63David GeorgeMODULE_AUTHOR("David George <david.george@ska.ac.za>"); 490731b4cace10f105a81d622b70f9a35f577612d63David GeorgeMODULE_DESCRIPTION("MAX1668 remote temperature sensor driver"); 491731b4cace10f105a81d622b70f9a35f577612d63David GeorgeMODULE_LICENSE("GPL"); 492