From mboxrd@z Thu Jan 1 00:00:00 1970 From: Herbert Poetzl Subject: [PATCH] hwmon: LM96000 support Date: Wed, 1 Oct 2008 20:52:35 +0200 Message-ID: <20081001185235.GC1173@MAIL.13thfloor.at> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Content-Disposition: inline List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: i2c-bounces-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org Errors-To: i2c-bounces-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org To: I2C ML List-Id: linux-i2c@vger.kernel.org this patch adds proper support for LM96000 (at least the version I could test with) and provides some 'generic' control of the tachometer monitor mode for lm85/lm96000 pwm control. please consider for (mainline) inclusion! TIA, Herbert Signed-off-by: Herbert Poetzl diff -NurpP --minimal linux-2.6.27-rc8-khali/Documentation/hwmon/lm85 linux-2.6.27-rc8-khali-lm96k-v0.1/Documentation/hwmon/lm85 --- linux-2.6.27-rc8-khali/Documentation/hwmon/lm85 2008-10-01 19:39:51.000000000 +0200 +++ linux-2.6.27-rc8-khali-lm96k-v0.1/Documentation/hwmon/lm85 2008-10-01 20:39:01.000000000 +0200 @@ -189,6 +189,22 @@ Configuration choices: -1 PWM always 100% (full on) -2 Manual control (write to 'pwm#' to set) +* PWM Tachometer Monitor Mode + +* pwm#_tmm - controls the monitor mode for pwm# + +Configuration choices: + + Value Meaning pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val); lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), (data->zone[nr].range << 4) - | data->pwm_freq[nr]); + | (data->pwm_freq[nr] & 0x0f)); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t show_pwm_tmm(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int nr = to_sensor_dev_attr(attr)->index; + struct lm85_data *data = lm85_update_device(dev); + return sprintf(buf, "%d\n", (data->tmm >> (2*nr)) & 3); +} + +static ssize_t set_pwm_tmm(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int nr = to_sensor_dev_attr(attr)->index; + struct i2c_client *client = to_i2c_client(dev); + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + int mask = 3 << (2*nr); + + mutex_lock(&data->update_lock); + data->tmm = (data->tmm & ~mask) | ((val & 3) << (2*nr)); + lm85_write_value(client, LM85_REG_TACHO_MON_MODE, data->tmm); mutex_unlock(&data->update_lock); return count; } @@ -578,7 +619,9 @@ static SENSOR_DEVICE_ATTR(pwm##offset, S static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ show_pwm_enable, set_pwm_enable, offset - 1); \ static SENSOR_DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \ - show_pwm_freq, set_pwm_freq, offset - 1) + show_pwm_freq, set_pwm_freq, offset - 1); \ +static SENSOR_DEVICE_ATTR(pwm##offset##_tmm, S_IRUGO | S_IWUSR, \ + show_pwm_tmm, set_pwm_tmm, offset - 1) show_pwm_reg(1); @@ -886,7 +929,7 @@ static ssize_t set_temp_auto_temp_min(st TEMP_FROM_REG(data->zone[nr].limit)); lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), ((data->zone[nr].range & 0x0f) << 4) - | (data->pwm_freq[nr] & 0x07)); + | (data->pwm_freq[nr] & 0x0f)); /* Update temp_auto_hyst and temp_auto_off */ data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG( @@ -929,7 +972,7 @@ static ssize_t set_temp_auto_temp_max(st val - min); lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), ((data->zone[nr].range & 0x0f) << 4) - | (data->pwm_freq[nr] & 0x07)); + | (data->pwm_freq[nr] & 0x0f)); mutex_unlock(&data->update_lock); return count; } @@ -999,6 +1042,9 @@ static struct attribute *lm85_attributes &sensor_dev_attr_pwm1_freq.dev_attr.attr, &sensor_dev_attr_pwm2_freq.dev_attr.attr, &sensor_dev_attr_pwm3_freq.dev_attr.attr, + &sensor_dev_attr_pwm1_tmm.dev_attr.attr, + &sensor_dev_attr_pwm2_tmm.dev_attr.attr, + &sensor_dev_attr_pwm3_tmm.dev_attr.attr, &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, @@ -1145,6 +1191,9 @@ static int lm85_detect(struct i2c_client case LM85_VERSTEP_LM85B: kind = lm85b; break; + case LM85_VERSTEP_LM96000: + kind = lm96000; + break; } } else if (company == LM85_COMPANY_ANALOG_DEV) { switch (verstep) { @@ -1193,6 +1242,9 @@ static int lm85_detect(struct i2c_client case lm85c: type_name = "lm85c"; break; + case lm96000: + type_name = "lm96000"; + break; case adm1027: type_name = "adm1027"; break; @@ -1237,6 +1289,9 @@ static int lm85_probe(struct i2c_client case emc6d102: data->freq_map = adm1027_freq_map; break; + case lm96000: + data->freq_map = lm96000_freq_map; + break; default: data->freq_map = lm85_freq_map; } @@ -1401,6 +1456,9 @@ static struct lm85_data *lm85_update_dev lm85_read_value(client, LM85_REG_PWM(i)); } + /* maybe restrict to LM85/LM96000? */ + data->tmm = lm85_read_value(client, LM85_REG_TACHO_MON_MODE); + data->alarms = lm85_read_value(client, LM85_REG_ALARM1); if (data->type == emc6d100) { @@ -1480,7 +1538,7 @@ static struct lm85_data *lm85_update_dev data->autofan[i].config = lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); - data->pwm_freq[i] = val & 0x07; + data->pwm_freq[i] = val & 0x0f; data->zone[i].range = val >> 4; data->autofan[i].min_pwm = lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); _______________________________________________ i2c mailing list i2c-GZX6beZjE8VD60Wz+7aTrA@public.gmane.org http://lists.lm-sensors.org/mailman/listinfo/i2c