update and standardize PWM support

git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1679 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Mark D. Studebaker committed 2002-12-21 21:05:48 +00:00
1 parent 4572d72782
commit bd4049d06e
5 files changed
+73 -23

No files matched your search

+13 -4
View File
@@ -726,6 +726,7 @@ void mtp008_update_client(struct i2c_client *client)
*/
inp = mtp008_read_value(client, MTP008_REG_PIN_CTRL2);
mtp008_getsensortype(data, inp);
data->pwmenable = inp;
/*
* Read the PWM registers if enabled.
@@ -740,10 +741,10 @@ void mtp008_update_client(struct i2c_client *client)
}
/*
* Read the fan sensors. Skip 3 if PWM3 enabled.
* Read the fan sensors. Skip 3 if PWM1 enabled.
*/
for (i = 1; i <= 3; i++) {
if(i == 3 && PWMENABLE_FROM_REG(3, inp)) {
if(i == 3 && PWMENABLE_FROM_REG(1, inp)) {
data->fan[2] = 0;
data->fan_min[2] = 0;
} else {
@@ -1079,12 +1080,20 @@ void mtp008_pwm(struct i2c_client *client, int operation, int ctl_name,
mtp008_update_client(client);
results[0] = PWM_FROM_REG(data->pwm[nr]);
*nrels_mag = 1;
results[1] = PWMENABLE_FROM_REG(nr + 1, data->pwmenable);
*nrels_mag = 2;
break;
case SENSORS_PROC_REAL_WRITE:
if (*nrels_mag >= 1) {
if (*nrels_mag >= 2) {
if(results[1])
data->pwmenable |= 0x10 << nr;
else
data->pwmenable &= ~(0x10 << nr);
mtp008_write_value(client, MTP008_REG_PIN_CTRL2,
data->pwmenable);
}
data->pwm[nr] = PWM_TO_REG(results[0]);
mtp008_write_value(client, MTP008_REG_PWM_CTRL(nr),
data->pwm[nr]);
+2 -2
View File
@@ -163,8 +163,8 @@ static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e, 0x2c, 0x2e, 0x30, 0x32 };
#define DIV_FROM_REG(val) (1 << (val))
#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
#define PWM_FROM_REG(val) (((val) * 1005) / 2550)
#define PWM_TO_REG(val) SENSORS_LIMIT((((val) * 2555) / 1000), 0, 255)
#define PWM_FROM_REG(val) (val)
#define PWM_TO_REG(val) SENSORS_LIMIT((val), 0, 255)
#define TEMP_FROM_REG(val) ((val)*10)
#define TEMP_FROM_REG10(val) (((val)*10)/4)
+2 -2
View File
@@ -121,8 +121,8 @@ static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e, 0x2c, 0x2e, 0x30, 0x32 };
#define DIV_FROM_REG(val) (1 << (val))
#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
#define PWM_FROM_REG(val) (((val) * 1005) / 2550)
#define PWM_TO_REG(val) SENSORS_LIMIT((((val) * 2555) / 1000), 0, 255)
#define PWM_FROM_REG(val) (val)
#define PWM_TO_REG(val) SENSORS_LIMIT((val), 0, 255)
#define TEMP_FROM_REG(val) ((val)*10)
#define TEMP_FROM_REG10(val) (((val)*10)/4)
+13 -7
View File
@@ -51,6 +51,10 @@
#define init_MUTEX(s) do { *(s) = MUTEX; } while(0)
#endif
#ifndef I2C_DRIVERID_W83627HF
#define I2C_DRIVERID_W83627HF 1038
#endif
#ifndef THIS_MODULE
#define THIS_MODULE NULL
#endif
@@ -59,7 +63,7 @@ static int force_addr;
MODULE_PARM(force_addr, "i");
MODULE_PARM_DESC(force_addr,
"Initialize the base address of the sensors");
static int force_i2c = 0x29;
static int force_i2c = 0x1f;
MODULE_PARM(force_i2c, "i");
MODULE_PARM_DESC(force_i2c,
"Initialize the i2c address of the sensors");
@@ -404,7 +408,8 @@ struct w83627hf_data {
u32 alarms; /* Register encoding, combined */
u32 beeps; /* Register encoding, combined */
u8 beep_enable; /* Boolean */
u8 pwm[4]; /* Register value */
u8 pwm[2]; /* Register value */
u8 pwmenable[2]; /* bool */
u16 sens[3]; /* 782D/783S only.
1 = pentium diode; 2 = 3904 diode;
3000-5000 = thermistor beta.
@@ -465,7 +470,7 @@ static int w83627hf_id = 0;
static struct i2c_driver w83627hf_driver = {
/* name */ "W83781D sensor driver",
/* id */ I2C_DRIVERID_W83781D,
/* id */ I2C_DRIVERID_W83627HF,
/* flags */ I2C_DF_NOTIFY,
/* attach_adapter */ &w83627hf_attach_adapter,
/* detach_client */ &w83627hf_detach_client,
@@ -726,9 +731,6 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
very code-efficient in this case. */
ERROR7:
ERROR6:
ERROR5:
ERROR4:
i2c_detach_client(new_client);
ERROR3:
release_region(address, WINB_EXTENT);
@@ -905,6 +907,9 @@ void w83627hf_init_client(struct i2c_client *client)
break;
}
data->pwmenable[0] = 1;
data->pwmenable[1] = 1;
if(init) {
w83627hf_write_value(client, W83781D_REG_IN_MIN(0),
IN_TO_REG(W83781D_INIT_IN_MIN_0));
@@ -1375,7 +1380,8 @@ void w83627hf_pwm(struct i2c_client *client, int operation, int ctl_name,
else if (operation == SENSORS_PROC_REAL_READ) {
w83627hf_update_client(client);
results[0] = data->pwm[nr - 1];
*nrels_mag = 1;
results[1] = data->pwmenable[nr - 1];
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->pwm[nr - 1] = PWM_TO_REG(results[0]);
+43 -8
View File
@@ -367,6 +367,7 @@ struct w83781d_data {
u32 beeps; /* Register encoding, combined */
u8 beep_enable; /* Boolean */
u8 pwm[4]; /* Register value */
u8 pwmenable[4]; /* bool */
u16 sens[3]; /* 782D/783S only.
1 = pentium diode; 2 = 3904 diode;
3000-5000 = thermistor beta.
@@ -1275,20 +1276,22 @@ int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
void w83781d_init_client(struct i2c_client *client)
{
struct w83781d_data *data = client->data;
int vid = 0, i;
int vid = 0, i, p;
int type = data->type;
u8 tmp;
if(init && type != as99127f) { /* this resets registers we don't have
documentation for on the as99127f */
/* save this register */
/* save these registers */
i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
p = w83781d_read_value(client, W83781D_REG_PWMCLK12);
/* Reset all except Watchdog values and last conversion values
This sets fan-divs to 2, among others */
w83781d_write_value(client, W83781D_REG_CONFIG, 0x80);
/* Restore the register and disable power-on abnormal beep.
/* Restore the registers and disable power-on abnormal beep.
This saves FAN 1/2/3 input/output values set by BIOS. */
w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
w83781d_write_value(client, W83781D_REG_PWMCLK12, p);
/* Disable master beep-enable (reset turns it on).
Individual beeps should be reset to off but for some reason
disabling this bit helps some people not get beeped */
@@ -1459,12 +1462,11 @@ void w83781d_init_client(struct i2c_client *client)
0x00);
}
if (type != w83781d) {
/* enable PWM2 control (can't hurt since PWM reg
should have been reset to 0xff) */
w83781d_write_value(client, W83781D_REG_PWMCLK12, 0x19);
/* enable comparator mode for temp2 and temp3 so
alarm indication will work correctly */
w83781d_write_value(client, W83781D_REG_IRQ, 0x41);
for(i = 0; i < 3; i++)
data->pwmenable[i] = 1;
}
}
@@ -1478,7 +1480,7 @@ void w83781d_init_client(struct i2c_client *client)
void w83781d_update_client(struct i2c_client *client)
{
struct w83781d_data *data = client->data;
int i;
int i, j;
down(&data->update_lock);
@@ -1504,7 +1506,16 @@ void w83781d_update_client(struct i2c_client *client)
&& (data->type != w83627hf) && (i == 6))
break;
}
/* PWM2 pin shared with FAN3 */
j = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG) & 0x10;
data->pwmenable[1] = (!j) &&
(w83781d_read_value(client, W83781D_REG_PWMCLK12) & 0x08);
for (i = 1; i <= 3; i++) {
if(i == 3 && !j) {
data->fan[2] = 255;
data->fan_min[2] = 255;
break;
}
data->fan[i - 1] =
w83781d_read_value(client, W83781D_REG_FAN(i));
data->fan_min[i - 1] =
@@ -1899,19 +1910,43 @@ void w83781d_pwm(struct i2c_client *client, int operation, int ctl_name,
{
struct w83781d_data *data = client->data;
int nr = 1 + ctl_name - W83781D_SYSCTL_PWM1;
int j, k;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
w83781d_update_client(client);
results[0] = PWM_FROM_REG(data->pwm[nr - 1]);
*nrels_mag = 1;
results[1] = data->pwmenable[nr - 1];
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
data->pwm[nr - 1] = PWM_TO_REG(results[0]);
w83781d_write_value(client, W83781D_REG_PWM(nr),
data->pwm[nr - 1]);
}
/* only PWM2 can be enabled/disabled */
if (*nrels_mag >= 2 && nr == 2) {
j = w83781d_read_value(client, W83781D_REG_PWMCLK12);
k = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
if(results[1]) {
if(!(j & 0x08))
w83781d_write_value(client,
W83781D_REG_PWMCLK12, j | 0x08);
if(k & 0x10)
w83781d_write_value(client,
W83781D_REG_BEEP_CONFIG, k & 0xef);
data->pwmenable[1] = 1;
} else {
if(j & 0x08)
w83781d_write_value(client,
W83781D_REG_PWMCLK12, j & 0xf7);
if(!(k & 0x10))
w83781d_write_value(client,
W83781D_REG_BEEP_CONFIG, j | 0x10);
data->pwmenable[1] = 0;
}
}
}
}