mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-10-25 12:14:33 +00:00
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:
1 parent
4572d72782
commit
bd4049d06e
5 files changed
+73
-23
No files matched your search
+13
-4
@@ -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]);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user