⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adm1026.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    adm1026.c - Part of lm_sensors, Linux kernel modules for hardware	     monitoring    Copyright (C) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>    Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com>    Chip details at:    <http://www.analog.com/UploadedFiles/Data_Sheets/779263102ADM1026_a.pdf>    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 <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/i2c.h>#include <linux/i2c-sensor.h>#include <linux/i2c-vid.h>/* Addresses to scan */static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };/* Insmod parameters */SENSORS_INSMOD_1(adm1026);static int gpio_input[17]  = { -1, -1, -1, -1, -1, -1, -1, -1, -1,				-1, -1, -1, -1, -1, -1, -1, -1 }; static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,				-1, -1, -1, -1, -1, -1, -1, -1 };static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,				-1, -1, -1, -1, -1, -1, -1, -1 };static int gpio_normal[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,				-1, -1, -1, -1, -1, -1, -1, -1 };static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };module_param_array(gpio_input,int,NULL,0);MODULE_PARM_DESC(gpio_input,"List of GPIO pins (0-16) to program as inputs");module_param_array(gpio_output,int,NULL,0);MODULE_PARM_DESC(gpio_output,"List of GPIO pins (0-16) to program as "	"outputs");module_param_array(gpio_inverted,int,NULL,0);MODULE_PARM_DESC(gpio_inverted,"List of GPIO pins (0-16) to program as "	"inverted");module_param_array(gpio_normal,int,NULL,0);MODULE_PARM_DESC(gpio_normal,"List of GPIO pins (0-16) to program as "	"normal/non-inverted");module_param_array(gpio_fan,int,NULL,0);MODULE_PARM_DESC(gpio_fan,"List of GPIO pins (0-7) to program as fan tachs");/* Many ADM1026 constants specified below *//* The ADM1026 registers */#define ADM1026_REG_CONFIG1  0x00#define CFG1_MONITOR     0x01#define CFG1_INT_ENABLE  0x02#define CFG1_INT_CLEAR   0x04#define CFG1_AIN8_9      0x08#define CFG1_THERM_HOT   0x10#define CFG1_DAC_AFC     0x20#define CFG1_PWM_AFC     0x40#define CFG1_RESET       0x80#define ADM1026_REG_CONFIG2  0x01/* CONFIG2 controls FAN0/GPIO0 through FAN7/GPIO7 */#define ADM1026_REG_CONFIG3  0x07#define CFG3_GPIO16_ENABLE  0x01#define CFG3_CI_CLEAR  0x02#define CFG3_VREF_250  0x04#define CFG3_GPIO16_DIR  0x40#define CFG3_GPIO16_POL  0x80#define ADM1026_REG_E2CONFIG  0x13#define E2CFG_READ  0x01#define E2CFG_WRITE  0x02#define E2CFG_ERASE  0x04#define E2CFG_ROM  0x08#define E2CFG_CLK_EXT  0x80/* There are 10 general analog inputs and 7 dedicated inputs * They are: *    0 - 9  =  AIN0 - AIN9 *       10  =  Vbat *       11  =  3.3V Standby *       12  =  3.3V Main *       13  =  +5V *       14  =  Vccp (CPU core voltage) *       15  =  +12V *       16  =  -12V */static u16 ADM1026_REG_IN[] = {		0x30, 0x31, 0x32, 0x33, 0x34, 0x35,		0x36, 0x37, 0x27, 0x29, 0x26, 0x2a,		0x2b, 0x2c, 0x2d, 0x2e, 0x2f	};static u16 ADM1026_REG_IN_MIN[] = {		0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,		0x5e, 0x5f, 0x6d, 0x49, 0x6b, 0x4a,		0x4b, 0x4c, 0x4d, 0x4e, 0x4f	};static u16 ADM1026_REG_IN_MAX[] = {		0x50, 0x51, 0x52, 0x53, 0x54, 0x55,		0x56, 0x57, 0x6c, 0x41, 0x6a, 0x42,		0x43, 0x44, 0x45, 0x46, 0x47	};/* Temperatures are: *    0 - Internal *    1 - External 1 *    2 - External 2 */static u16 ADM1026_REG_TEMP[] = { 0x1f, 0x28, 0x29 };static u16 ADM1026_REG_TEMP_MIN[] = { 0x69, 0x48, 0x49 };static u16 ADM1026_REG_TEMP_MAX[] = { 0x68, 0x40, 0x41 };static u16 ADM1026_REG_TEMP_TMIN[] = { 0x10, 0x11, 0x12 };static u16 ADM1026_REG_TEMP_THERM[] = { 0x0d, 0x0e, 0x0f };static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f };#define ADM1026_REG_FAN(nr) (0x38 + (nr))#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr))#define ADM1026_REG_FAN_DIV_0_3 0x02#define ADM1026_REG_FAN_DIV_4_7 0x03#define ADM1026_REG_DAC  0x04#define ADM1026_REG_PWM  0x05#define ADM1026_REG_GPIO_CFG_0_3 0x08#define ADM1026_REG_GPIO_CFG_4_7 0x09#define ADM1026_REG_GPIO_CFG_8_11 0x0a#define ADM1026_REG_GPIO_CFG_12_15 0x0b/* CFG_16 in REG_CFG3 */#define ADM1026_REG_GPIO_STATUS_0_7 0x24#define ADM1026_REG_GPIO_STATUS_8_15 0x25/* STATUS_16 in REG_STATUS4 */#define ADM1026_REG_GPIO_MASK_0_7 0x1c#define ADM1026_REG_GPIO_MASK_8_15 0x1d/* MASK_16 in REG_MASK4 */#define ADM1026_REG_COMPANY 0x16#define ADM1026_REG_VERSTEP 0x17/* These are the recognized values for the above regs */#define ADM1026_COMPANY_ANALOG_DEV 0x41#define ADM1026_VERSTEP_GENERIC 0x40#define ADM1026_VERSTEP_ADM1026 0x44#define ADM1026_REG_MASK1 0x18#define ADM1026_REG_MASK2 0x19#define ADM1026_REG_MASK3 0x1a#define ADM1026_REG_MASK4 0x1b#define ADM1026_REG_STATUS1 0x20#define ADM1026_REG_STATUS2 0x21#define ADM1026_REG_STATUS3 0x22#define ADM1026_REG_STATUS4 0x23#define ADM1026_FAN_ACTIVATION_TEMP_HYST -6#define ADM1026_FAN_CONTROL_TEMP_RANGE 20#define ADM1026_PWM_MAX 255/* Conversions. Rounding and limit checking is only done on the TO_REG  * variants. Note that you should be a bit careful with which arguments * these macros are called: arguments may be evaluated more than once. *//* IN are scaled acording to built-in resistors.  These are the *   voltages corresponding to 3/4 of full scale (192 or 0xc0) *   NOTE: The -12V input needs an additional factor to account *      for the Vref pullup resistor. *      NEG12_OFFSET = SCALE * Vref / V-192 - Vref *                   = 13875 * 2.50 / 1.875 - 2500 *                   = 16000 * * The values in this table are based on Table II, page 15 of the *    datasheet. */static int adm1026_scaling[] = {  /* .001 Volts */		2250, 2250, 2250, 2250, 2250, 2250, 		1875, 1875, 1875, 1875, 3000, 3330, 		3330, 4995, 2250, 12000, 13875	};#define NEG12_OFFSET  16000#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))#define INS_TO_REG(n,val)  (SENSORS_LIMIT(SCALE(val,adm1026_scaling[n],192),\	0,255))#define INS_FROM_REG(n,val) (SCALE(val,192,adm1026_scaling[n]))/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses *   and we assume a 2 pulse-per-rev fan tach signal *      22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000 */#define FAN_TO_REG(val,div)  ((val)<=0 ? 0xff : SENSORS_LIMIT(1350000/((val)*\	(div)),1,254)) #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==0xff ? 0 : 1350000/((val)*\	(div)))#define DIV_FROM_REG(val) (1<<(val))#define DIV_TO_REG(val) ((val)>=8 ? 3 : (val)>=4 ? 2 : (val)>=2 ? 1 : 0)/* Temperature is reported in 1 degC increments */#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\	-127,127))#define TEMP_FROM_REG(val) ((val) * 1000)#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\	-127,127))#define OFFSET_FROM_REG(val) ((val) * 1000)#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255))#define PWM_FROM_REG(val) (val)#define PWM_MIN_TO_REG(val) ((val) & 0xf0)#define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4))/* Analog output is a voltage, and scaled to millivolts.  The datasheet  *   indicates that the DAC could be used to drive the fans, but in our  *   example board (Arima HDAMA) it isn't connected to the fans at all. */#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500),0,255)) #define DAC_FROM_REG(val) (((val)*2500)/255)/* Typically used with systems using a v9.1 VRM spec ? */#define ADM1026_INIT_VRM  91/* Chip sampling rates * * Some sensors are not updated more frequently than once per second *    so it doesn't make sense to read them more often than that. *    We cache the results and return the saved data if the driver *    is called again before a second has elapsed. * * Also, there is significant configuration data for this chip *    So, we keep the config data up to date in the cache *    when it is written and only sample it once every 5 *minutes* */#define ADM1026_DATA_INTERVAL  (1 * HZ)#define ADM1026_CONFIG_INTERVAL  (5 * 60 * HZ)/* We allow for multiple chips in a single system. * * For each registered ADM1026, we need to keep state information * at client->data. The adm1026_data structure is dynamically * allocated, when a new client structure is allocated. */struct pwm_data {	u8 pwm;	u8 enable;	u8 auto_pwm_min;};struct adm1026_data {	struct i2c_client client;	struct semaphore lock;	enum chips type;	struct semaphore update_lock;	int valid;		/* !=0 if following fields are valid */	unsigned long last_reading;	/* In jiffies */	unsigned long last_config;	/* In jiffies */	u8 in[17];              /* Register value */	u8 in_max[17];          /* Register value */	u8 in_min[17];          /* Register value */	s8 temp[3];             /* Register value */	s8 temp_min[3];         /* Register value */	s8 temp_max[3];         /* Register value */	s8 temp_tmin[3];        /* Register value */	s8 temp_crit[3];        /* Register value */	s8 temp_offset[3];      /* Register value */	u8 fan[8];              /* Register value */	u8 fan_min[8];          /* Register value */	u8 fan_div[8];          /* Decoded value */	struct pwm_data pwm1;   /* Pwm control values */	int vid;                /* Decoded value */	u8 vrm;                 /* VRM version */	u8 analog_out;		/* Register value (DAC) */	long alarms;            /* Register encoding, combined */	long alarm_mask;        /* Register encoding, combined */	long gpio;              /* Register encoding, combined */	long gpio_mask;         /* Register encoding, combined */	u8 gpio_config[17];     /* Decoded value */	u8 config1;             /* Register value */	u8 config2;             /* Register value */	u8 config3;             /* Register value */};static int adm1026_attach_adapter(struct i2c_adapter *adapter);static int adm1026_detect(struct i2c_adapter *adapter, int address,	int kind);static int adm1026_detach_client(struct i2c_client *client);static int adm1026_read_value(struct i2c_client *client, u8 register);static int adm1026_write_value(struct i2c_client *client, u8 register,	int value); static void adm1026_print_gpio(struct i2c_client *client);static void adm1026_fixup_gpio(struct i2c_client *client); static struct adm1026_data *adm1026_update_device(struct device *dev);static void adm1026_init_client(struct i2c_client *client);static struct i2c_driver adm1026_driver = {	.owner          = THIS_MODULE,	.name           = "adm1026",	.flags          = I2C_DF_NOTIFY,	.attach_adapter = adm1026_attach_adapter,	.detach_client  = adm1026_detach_client,};static int adm1026_id;int adm1026_attach_adapter(struct i2c_adapter *adapter){	if (!(adapter->class & I2C_CLASS_HWMON)) {		return 0;	}	return i2c_detect(adapter, &addr_data, adm1026_detect);}int adm1026_detach_client(struct i2c_client *client){	i2c_detach_client(client);	kfree(client);	return 0;}int adm1026_read_value(struct i2c_client *client, u8 reg){	int res;	if (reg < 0x80) {		/* "RAM" locations */		res = i2c_smbus_read_byte_data(client, reg) & 0xff;	} else {		/* EEPROM, do nothing */		res = 0;	}	return res;}int adm1026_write_value(struct i2c_client *client, u8 reg, int value){	int res;	if (reg < 0x80) {		/* "RAM" locations */		res = i2c_smbus_write_byte_data(client, reg, value);	} else {		/* EEPROM, do nothing */		res = 0;	}	return res;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -