Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (gsc-hwmon) add fan sensor

Add a fan sensor to report RPM's from a fan tach input.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Tim Harvey and committed by
Guenter Roeck
7497d4a6 d6144a40

+30 -3
+29 -3
drivers/hwmon/gsc-hwmon.c
··· 17 17 18 18 #define GSC_HWMON_MAX_TEMP_CH 16 19 19 #define GSC_HWMON_MAX_IN_CH 16 20 + #define GSC_HWMON_MAX_FAN_CH 16 20 21 21 22 #define GSC_HWMON_RESOLUTION 12 22 23 #define GSC_HWMON_VREF 2500 ··· 28 27 struct regmap *regmap; 29 28 const struct gsc_hwmon_channel *temp_ch[GSC_HWMON_MAX_TEMP_CH]; 30 29 const struct gsc_hwmon_channel *in_ch[GSC_HWMON_MAX_IN_CH]; 30 + const struct gsc_hwmon_channel *fan_ch[GSC_HWMON_MAX_FAN_CH]; 31 31 u32 temp_config[GSC_HWMON_MAX_TEMP_CH + 1]; 32 32 u32 in_config[GSC_HWMON_MAX_IN_CH + 1]; 33 + u32 fan_config[GSC_HWMON_MAX_FAN_CH + 1]; 33 34 struct hwmon_channel_info temp_info; 34 35 struct hwmon_channel_info in_info; 35 - const struct hwmon_channel_info *info[3]; 36 + struct hwmon_channel_info fan_info; 37 + const struct hwmon_channel_info *info[4]; 36 38 struct hwmon_chip_info chip; 37 39 }; 38 40 ··· 159 155 case hwmon_temp: 160 156 ch = hwmon->temp_ch[channel]; 161 157 break; 158 + case hwmon_fan: 159 + ch = hwmon->fan_ch[channel]; 160 + break; 162 161 default: 163 162 return -EOPNOTSUPP; 164 163 } ··· 194 187 /* adjust by uV offset */ 195 188 tmp += ch->mvoffset; 196 189 break; 190 + case mode_fan: 191 + tmp *= 30; /* convert to revolutions per minute */ 192 + break; 197 193 case mode_voltage_24bit: 198 194 case mode_voltage_16bit: 199 195 /* no adjustment needed */ ··· 220 210 break; 221 211 case hwmon_temp: 222 212 *buf = hwmon->temp_ch[channel]->name; 213 + break; 214 + case hwmon_fan: 215 + *buf = hwmon->fan_ch[channel]->name; 223 216 break; 224 217 default: 225 218 return -ENOTSUPP; ··· 317 304 struct gsc_hwmon_platform_data *pdata = dev_get_platdata(dev); 318 305 struct gsc_hwmon_data *hwmon; 319 306 const struct attribute_group **groups; 320 - int i, i_in, i_temp; 307 + int i, i_in, i_temp, i_fan; 321 308 322 309 if (!pdata) { 323 310 pdata = gsc_hwmon_get_devtree_pdata(dev); ··· 337 324 if (IS_ERR(hwmon->regmap)) 338 325 return PTR_ERR(hwmon->regmap); 339 326 340 - for (i = 0, i_in = 0, i_temp = 0; i < hwmon->pdata->nchannels; i++) { 327 + for (i = 0, i_in = 0, i_temp = 0, i_fan = 0; i < hwmon->pdata->nchannels; i++) { 341 328 const struct gsc_hwmon_channel *ch = &pdata->channels[i]; 342 329 343 330 switch (ch->mode) { ··· 350 337 hwmon->temp_config[i_temp] = HWMON_T_INPUT | 351 338 HWMON_T_LABEL; 352 339 i_temp++; 340 + break; 341 + case mode_fan: 342 + if (i_fan == GSC_HWMON_MAX_FAN_CH) { 343 + dev_err(gsc->dev, "too many fan channels\n"); 344 + return -EINVAL; 345 + } 346 + hwmon->fan_ch[i_fan] = ch; 347 + hwmon->fan_config[i_fan] = HWMON_F_INPUT | 348 + HWMON_F_LABEL; 349 + i_fan++; 353 350 break; 354 351 case mode_voltage_24bit: 355 352 case mode_voltage_16bit: ··· 384 361 hwmon->chip.info = hwmon->info; 385 362 hwmon->info[0] = &hwmon->temp_info; 386 363 hwmon->info[1] = &hwmon->in_info; 364 + hwmon->info[2] = &hwmon->fan_info; 387 365 hwmon->temp_info.type = hwmon_temp; 388 366 hwmon->temp_info.config = hwmon->temp_config; 389 367 hwmon->in_info.type = hwmon_in; 390 368 hwmon->in_info.config = hwmon->in_config; 369 + hwmon->fan_info.type = hwmon_fan; 370 + hwmon->fan_info.config = hwmon->fan_config; 391 371 392 372 groups = pdata->fan_base ? gsc_hwmon_groups : NULL; 393 373 hwmon_dev = devm_hwmon_device_register_with_info(dev,
+1
include/linux/platform_data/gsc_hwmon.h
··· 7 7 mode_voltage_24bit, 8 8 mode_voltage_raw, 9 9 mode_voltage_16bit, 10 + mode_fan, 10 11 mode_max, 11 12 }; 12 13