Commit a30b044a authored by Jean Delvare's avatar Jean Delvare Committed by Greg Kroah-Hartman

[PATCH] I2C: pwm support in w83781d.c

Here is a general pwm support cleanup patch for the w83781d chip driver.
Featuring:

* Don't pretend that we handle PWM on AS99127F chips. We don't know how
it works, and one of the register we are accessing for now is clearly
not a PWM register, and changing its value usually breaks temperature
readings.

* Discard irrelevant comments.

* Rewrite show_pwmenable_reg. It was obviously taken from the 2.4
driver, with unneeded tests and the code was much too complicated
anyway. And now we handle errors correctly.

* Initialize pwm_enable at load time. So far it was done conditionally
(if init=1) while it should always be done. And pwm2_enable wasn't read
from the chip, while it should.

I could test that my AS99127F doesn't expose pwm files through ssysfs
anymore. Which means that I couldn't test the rest of the pwm changes,
unfortunately.

I've applied similar changes to our 2.4/CVS repository.
parent ee23f4b7
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
Supports following chips: Supports following chips:
Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
as99127f 7 3 1? 3 0x31 0x12c3 yes no as99127f 7 3 0 3 0x31 0x12c3 yes no
as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes
w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC) w83627hf 9 3 2 3 0x21 0x5ca3 yes yes(LPC)
...@@ -670,7 +670,6 @@ do { \ ...@@ -670,7 +670,6 @@ do { \
device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
} while (0) } while (0)
/* w83697hf only has two fans */
static ssize_t static ssize_t
show_pwm_reg(struct device *dev, char *buf, int nr) show_pwm_reg(struct device *dev, char *buf, int nr)
{ {
...@@ -678,7 +677,6 @@ show_pwm_reg(struct device *dev, char *buf, int nr) ...@@ -678,7 +677,6 @@ show_pwm_reg(struct device *dev, char *buf, int nr)
return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1])); return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));
} }
/* w83697hf only has two fans */
static ssize_t static ssize_t
show_pwmenable_reg(struct device *dev, char *buf, int nr) show_pwmenable_reg(struct device *dev, char *buf, int nr)
{ {
...@@ -706,38 +704,26 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) ...@@ -706,38 +704,26 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client); struct w83781d_data *data = i2c_get_clientdata(client);
u32 val, j, k; u32 val, reg;
val = simple_strtoul(buf, NULL, 10); val = simple_strtoul(buf, NULL, 10);
/* only PWM2 can be enabled/disabled */ switch (val) {
if (nr == 2) { case 0:
j = w83781d_read_value(client, W83781D_REG_PWMCLK12); case 1:
k = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); reg = w83781d_read_value(client, W83781D_REG_PWMCLK12);
w83781d_write_value(client, W83781D_REG_PWMCLK12,
(reg & 0xf7) | (val << 3));
if (val > 0) { reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
if (!(j & 0x08)) w83781d_write_value(client, W83781D_REG_BEEP_CONFIG,
w83781d_write_value(client, (reg & 0xef) | (!val << 4));
W83781D_REG_PWMCLK12,
j | 0x08);
if (k & 0x10)
w83781d_write_value(client,
W83781D_REG_BEEP_CONFIG,
k & 0xef);
data->pwmenable[1] = 1; data->pwmenable[nr - 1] = val;
} else { break;
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; default:
} return -EINVAL;
} }
return count; return count;
...@@ -1250,6 +1236,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1250,6 +1236,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
data->fan_min[i - 1] = w83781d_read_value(new_client, data->fan_min[i - 1] = w83781d_read_value(new_client,
W83781D_REG_FAN_MIN(i)); W83781D_REG_FAN_MIN(i));
} }
if (kind != w83781d && kind != as99127f)
for (i = 0; i < 4; i++)
data->pwmenable[i] = 1;
/* Register sysfs hooks */ /* Register sysfs hooks */
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
...@@ -1290,7 +1279,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1290,7 +1279,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file_beep(new_client); device_create_file_beep(new_client);
if (kind != w83781d) { if (kind != w83781d && kind != as99127f) {
device_create_file_pwm(new_client, 1); device_create_file_pwm(new_client, 1);
device_create_file_pwm(new_client, 2); device_create_file_pwm(new_client, 2);
device_create_file_pwmenable(new_client, 2); device_create_file_pwmenable(new_client, 2);
...@@ -1578,9 +1567,6 @@ w83781d_init_client(struct i2c_client *client) ...@@ -1578,9 +1567,6 @@ w83781d_init_client(struct i2c_client *client)
if (!(i & 0x40)) if (!(i & 0x40))
w83781d_write_value(client, W83781D_REG_IRQ, w83781d_write_value(client, W83781D_REG_IRQ,
i | 0x40); i | 0x40);
for (i = 0; i < 3; i++)
data->pwmenable[i] = 1;
} }
} }
...@@ -1624,20 +1610,19 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) ...@@ -1624,20 +1610,19 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
data->fan_min[i - 1] = data->fan_min[i - 1] =
w83781d_read_value(client, W83781D_REG_FAN_MIN(i)); w83781d_read_value(client, W83781D_REG_FAN_MIN(i));
} }
if (data->type != w83781d) { if (data->type != w83781d && data->type != as99127f) {
for (i = 1; i <= 4; i++) { for (i = 1; i <= 4; i++) {
data->pwm[i - 1] = data->pwm[i - 1] =
w83781d_read_value(client, w83781d_read_value(client,
W83781D_REG_PWM(i)); W83781D_REG_PWM(i));
if (((data->type == w83783s) if ((data->type != w83782d
|| (data->type == w83627hf) || i2c_is_isa_client(client))
|| (data->type == as99127f)
|| (data->type == w83697hf)
|| ((data->type == w83782d)
&& i2c_is_isa_client(client)))
&& i == 2) && i == 2)
break; break;
} }
/* Only PWM2 can be disabled */
data->pwmenable[1] = (w83781d_read_value(client,
W83781D_REG_PWMCLK12) & 0x08) >> 3;
} }
data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1)); data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment