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

hwmon: (max6639) : Add additional hwmon attributes for fan and pwm

Add additional attributes for fan & pwm i.e.,
fanY_pulses
pwmY_freq

Signed-off-by: Naresh Solanki <naresh.solanki@9elements.com>
Link: https://lore.kernel.org/r/20240614055533.2735210-2-naresh.solanki@9elements.com
[groeck: Fix value range for fanX_pulses]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Naresh Solanki and committed by
Guenter Roeck
842b4d98 0f33272b

+86 -4
+86 -4
drivers/hwmon/max6639.c
··· 76 76 */ 77 77 struct max6639_data { 78 78 struct regmap *regmap; 79 + struct mutex update_lock; 79 80 80 81 /* Register values initialized only once */ 81 82 u8 ppr[MAX6639_NUM_CHANNELS]; /* Pulses per rotation 0..3 for 1..4 ppr */ ··· 233 232 return res; 234 233 *fan_val = !!(val & BIT(1 - channel)); 235 234 return 0; 235 + case hwmon_fan_pulses: 236 + *fan_val = data->ppr[channel]; 237 + return 0; 236 238 default: 237 239 return -EOPNOTSUPP; 238 240 } ··· 245 241 { 246 242 /* Decrement the PPR value and shift left by 6 to match the register format */ 247 243 return regmap_write(data->regmap, MAX6639_REG_FAN_PPR(channel), ppr-- << 6); 244 + } 245 + 246 + static int max6639_write_fan(struct device *dev, u32 attr, int channel, 247 + long val) 248 + { 249 + struct max6639_data *data = dev_get_drvdata(dev); 250 + int err; 251 + 252 + switch (attr) { 253 + case hwmon_fan_pulses: 254 + if (val <= 0 || val > 4) 255 + return -EINVAL; 256 + 257 + mutex_lock(&data->update_lock); 258 + /* Set Fan pulse per revolution */ 259 + err = max6639_set_ppr(data, channel, val); 260 + if (err < 0) { 261 + mutex_unlock(&data->update_lock); 262 + return err; 263 + } 264 + data->ppr[channel] = val; 265 + 266 + mutex_unlock(&data->update_lock); 267 + return 0; 268 + default: 269 + return -EOPNOTSUPP; 270 + } 248 271 } 249 272 250 273 static umode_t max6639_fan_is_visible(const void *_data, u32 attr, int channel) ··· 293 262 struct max6639_data *data = dev_get_drvdata(dev); 294 263 unsigned int val; 295 264 int res; 265 + u8 i; 296 266 297 267 switch (attr) { 298 268 case hwmon_pwm_input: ··· 301 269 if (res < 0) 302 270 return res; 303 271 *pwm_val = val * 255 / 120; 272 + return 0; 273 + case hwmon_pwm_freq: 274 + mutex_lock(&data->update_lock); 275 + res = regmap_read(data->regmap, MAX6639_REG_FAN_CONFIG3(channel), &val); 276 + if (res < 0) { 277 + mutex_unlock(&data->update_lock); 278 + return res; 279 + } 280 + i = val & MAX6639_FAN_CONFIG3_FREQ_MASK; 281 + 282 + res = regmap_read(data->regmap, MAX6639_REG_GCONFIG, &val); 283 + if (res < 0) { 284 + mutex_unlock(&data->update_lock); 285 + return res; 286 + } 287 + 288 + if (val & MAX6639_GCONFIG_PWM_FREQ_HI) 289 + i |= 0x4; 290 + i &= 0x7; 291 + *pwm_val = freq_table[i]; 292 + 293 + mutex_unlock(&data->update_lock); 304 294 return 0; 305 295 default: 306 296 return -EOPNOTSUPP; ··· 334 280 { 335 281 struct max6639_data *data = dev_get_drvdata(dev); 336 282 int err; 283 + u8 i; 337 284 338 285 switch (attr) { 339 286 case hwmon_pwm_input: ··· 342 287 return -EINVAL; 343 288 err = regmap_write(data->regmap, MAX6639_REG_TARGTDUTY(channel), 344 289 val * 120 / 255); 290 + return err; 291 + case hwmon_pwm_freq: 292 + val = clamp_val(val, 0, 25000); 293 + 294 + i = find_closest(val, freq_table, ARRAY_SIZE(freq_table)); 295 + 296 + mutex_lock(&data->update_lock); 297 + err = regmap_update_bits(data->regmap, MAX6639_REG_FAN_CONFIG3(channel), 298 + MAX6639_FAN_CONFIG3_FREQ_MASK, i); 299 + if (err < 0) { 300 + mutex_unlock(&data->update_lock); 301 + return err; 302 + } 303 + 304 + if (i >> 2) 305 + err = regmap_set_bits(data->regmap, MAX6639_REG_GCONFIG, 306 + MAX6639_GCONFIG_PWM_FREQ_HI); 307 + else 308 + err = regmap_clear_bits(data->regmap, MAX6639_REG_GCONFIG, 309 + MAX6639_GCONFIG_PWM_FREQ_HI); 310 + 311 + mutex_unlock(&data->update_lock); 345 312 return err; 346 313 default: 347 314 return -EOPNOTSUPP; ··· 374 297 { 375 298 switch (attr) { 376 299 case hwmon_pwm_input: 300 + case hwmon_pwm_freq: 377 301 return 0644; 378 302 default: 379 303 return 0; ··· 480 402 u32 attr, int channel, long val) 481 403 { 482 404 switch (type) { 405 + case hwmon_fan: 406 + return max6639_write_fan(dev, attr, channel, val); 483 407 case hwmon_pwm: 484 408 return max6639_write_pwm(dev, attr, channel, val); 485 409 case hwmon_temp: ··· 509 429 510 430 static const struct hwmon_channel_info * const max6639_info[] = { 511 431 HWMON_CHANNEL_INFO(fan, 512 - HWMON_F_INPUT | HWMON_F_FAULT, 513 - HWMON_F_INPUT | HWMON_F_FAULT), 432 + HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_PULSES, 433 + HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_PULSES), 514 434 HWMON_CHANNEL_INFO(pwm, 515 - HWMON_PWM_INPUT, 516 - HWMON_PWM_INPUT), 435 + HWMON_PWM_INPUT | HWMON_PWM_FREQ, 436 + HWMON_PWM_INPUT | HWMON_PWM_FREQ), 517 437 HWMON_CHANNEL_INFO(temp, 518 438 HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_MAX | HWMON_T_MAX_ALARM | 519 439 HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY | ··· 723 643 return err; 724 644 } 725 645 } 646 + 647 + mutex_init(&data->update_lock); 726 648 727 649 /* Initialize the max6639 chip */ 728 650 err = max6639_init_client(client, data);