| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * smsc47m1.c - Part of lm_sensors, Linux kernel modules |
|---|
| 3 | 4 | * for hardware monitoring |
|---|
| .. | .. |
|---|
| 10 | 11 | * Copyright (C) 2004-2007 Jean Delvare <jdelvare@suse.de> |
|---|
| 11 | 12 | * Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com> |
|---|
| 12 | 13 | * and Jean Delvare |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 15 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 16 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 17 | | - * (at your option) any later version. |
|---|
| 18 | | - * |
|---|
| 19 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 20 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 21 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 22 | | - * GNU General Public License for more details. |
|---|
| 23 | | - * |
|---|
| 24 | | - * You should have received a copy of the GNU General Public License |
|---|
| 25 | | - * along with this program; if not, write to the Free Software |
|---|
| 26 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 27 | 14 | */ |
|---|
| 28 | 15 | |
|---|
| 29 | 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 207 | 194 | return data; |
|---|
| 208 | 195 | } |
|---|
| 209 | 196 | |
|---|
| 210 | | -static ssize_t get_fan(struct device *dev, struct device_attribute |
|---|
| 211 | | - *devattr, char *buf) |
|---|
| 197 | +static ssize_t fan_show(struct device *dev, struct device_attribute *devattr, |
|---|
| 198 | + char *buf) |
|---|
| 212 | 199 | { |
|---|
| 213 | 200 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 214 | 201 | struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); |
|---|
| .. | .. |
|---|
| 226 | 213 | return sprintf(buf, "%d\n", rpm); |
|---|
| 227 | 214 | } |
|---|
| 228 | 215 | |
|---|
| 229 | | -static ssize_t get_fan_min(struct device *dev, struct device_attribute |
|---|
| 230 | | - *devattr, char *buf) |
|---|
| 216 | +static ssize_t fan_min_show(struct device *dev, |
|---|
| 217 | + struct device_attribute *devattr, char *buf) |
|---|
| 231 | 218 | { |
|---|
| 232 | 219 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 233 | 220 | struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); |
|---|
| .. | .. |
|---|
| 237 | 224 | return sprintf(buf, "%d\n", rpm); |
|---|
| 238 | 225 | } |
|---|
| 239 | 226 | |
|---|
| 240 | | -static ssize_t get_fan_div(struct device *dev, struct device_attribute |
|---|
| 241 | | - *devattr, char *buf) |
|---|
| 227 | +static ssize_t fan_div_show(struct device *dev, |
|---|
| 228 | + struct device_attribute *devattr, char *buf) |
|---|
| 242 | 229 | { |
|---|
| 243 | 230 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 244 | 231 | struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); |
|---|
| 245 | 232 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); |
|---|
| 246 | 233 | } |
|---|
| 247 | 234 | |
|---|
| 248 | | -static ssize_t get_fan_alarm(struct device *dev, struct device_attribute |
|---|
| 249 | | - *devattr, char *buf) |
|---|
| 235 | +static ssize_t fan_alarm_show(struct device *dev, |
|---|
| 236 | + struct device_attribute *devattr, char *buf) |
|---|
| 250 | 237 | { |
|---|
| 251 | 238 | int bitnr = to_sensor_dev_attr(devattr)->index; |
|---|
| 252 | 239 | struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); |
|---|
| 253 | 240 | return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); |
|---|
| 254 | 241 | } |
|---|
| 255 | 242 | |
|---|
| 256 | | -static ssize_t get_pwm(struct device *dev, struct device_attribute |
|---|
| 257 | | - *devattr, char *buf) |
|---|
| 243 | +static ssize_t pwm_show(struct device *dev, struct device_attribute *devattr, |
|---|
| 244 | + char *buf) |
|---|
| 258 | 245 | { |
|---|
| 259 | 246 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 260 | 247 | struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); |
|---|
| 261 | 248 | return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[attr->index])); |
|---|
| 262 | 249 | } |
|---|
| 263 | 250 | |
|---|
| 264 | | -static ssize_t get_pwm_en(struct device *dev, struct device_attribute |
|---|
| 265 | | - *devattr, char *buf) |
|---|
| 251 | +static ssize_t pwm_en_show(struct device *dev, |
|---|
| 252 | + struct device_attribute *devattr, char *buf) |
|---|
| 266 | 253 | { |
|---|
| 267 | 254 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 268 | 255 | struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); |
|---|
| .. | .. |
|---|
| 276 | 263 | return sprintf(buf, "%d\n", data->alarms); |
|---|
| 277 | 264 | } |
|---|
| 278 | 265 | |
|---|
| 279 | | -static ssize_t set_fan_min(struct device *dev, struct device_attribute |
|---|
| 280 | | - *devattr, const char *buf, size_t count) |
|---|
| 266 | +static ssize_t fan_min_store(struct device *dev, |
|---|
| 267 | + struct device_attribute *devattr, |
|---|
| 268 | + const char *buf, size_t count) |
|---|
| 281 | 269 | { |
|---|
| 282 | 270 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 283 | 271 | struct smsc47m1_data *data = dev_get_drvdata(dev); |
|---|
| .. | .. |
|---|
| 312 | 300 | * of least surprise; the user doesn't expect the fan minimum to change just |
|---|
| 313 | 301 | * because the divider changed. |
|---|
| 314 | 302 | */ |
|---|
| 315 | | -static ssize_t set_fan_div(struct device *dev, struct device_attribute |
|---|
| 316 | | - *devattr, const char *buf, size_t count) |
|---|
| 303 | +static ssize_t fan_div_store(struct device *dev, |
|---|
| 304 | + struct device_attribute *devattr, |
|---|
| 305 | + const char *buf, size_t count) |
|---|
| 317 | 306 | { |
|---|
| 318 | 307 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 319 | 308 | struct smsc47m1_data *data = dev_get_drvdata(dev); |
|---|
| .. | .. |
|---|
| 362 | 351 | tmp |= data->fan_div[2] << 4; |
|---|
| 363 | 352 | smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp); |
|---|
| 364 | 353 | break; |
|---|
| 354 | + default: |
|---|
| 355 | + BUG(); |
|---|
| 365 | 356 | } |
|---|
| 366 | 357 | |
|---|
| 367 | 358 | /* Preserve fan min */ |
|---|
| .. | .. |
|---|
| 375 | 366 | return count; |
|---|
| 376 | 367 | } |
|---|
| 377 | 368 | |
|---|
| 378 | | -static ssize_t set_pwm(struct device *dev, struct device_attribute |
|---|
| 379 | | - *devattr, const char *buf, size_t count) |
|---|
| 369 | +static ssize_t pwm_store(struct device *dev, struct device_attribute *devattr, |
|---|
| 370 | + const char *buf, size_t count) |
|---|
| 380 | 371 | { |
|---|
| 381 | 372 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 382 | 373 | struct smsc47m1_data *data = dev_get_drvdata(dev); |
|---|
| .. | .. |
|---|
| 401 | 392 | return count; |
|---|
| 402 | 393 | } |
|---|
| 403 | 394 | |
|---|
| 404 | | -static ssize_t set_pwm_en(struct device *dev, struct device_attribute |
|---|
| 405 | | - *devattr, const char *buf, size_t count) |
|---|
| 395 | +static ssize_t pwm_en_store(struct device *dev, |
|---|
| 396 | + struct device_attribute *devattr, const char *buf, |
|---|
| 397 | + size_t count) |
|---|
| 406 | 398 | { |
|---|
| 407 | 399 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
|---|
| 408 | 400 | struct smsc47m1_data *data = dev_get_drvdata(dev); |
|---|
| .. | .. |
|---|
| 427 | 419 | return count; |
|---|
| 428 | 420 | } |
|---|
| 429 | 421 | |
|---|
| 430 | | -#define fan_present(offset) \ |
|---|
| 431 | | -static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan, \ |
|---|
| 432 | | - NULL, offset - 1); \ |
|---|
| 433 | | -static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
|---|
| 434 | | - get_fan_min, set_fan_min, offset - 1); \ |
|---|
| 435 | | -static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ |
|---|
| 436 | | - get_fan_div, set_fan_div, offset - 1); \ |
|---|
| 437 | | -static SENSOR_DEVICE_ATTR(fan##offset##_alarm, S_IRUGO, get_fan_alarm, \ |
|---|
| 438 | | - NULL, offset - 1); \ |
|---|
| 439 | | -static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ |
|---|
| 440 | | - get_pwm, set_pwm, offset - 1); \ |
|---|
| 441 | | -static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ |
|---|
| 442 | | - get_pwm_en, set_pwm_en, offset - 1) |
|---|
| 443 | | - |
|---|
| 444 | | -fan_present(1); |
|---|
| 445 | | -fan_present(2); |
|---|
| 446 | | -fan_present(3); |
|---|
| 422 | +static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0); |
|---|
| 423 | +static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0); |
|---|
| 424 | +static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0); |
|---|
| 425 | +static SENSOR_DEVICE_ATTR_RO(fan1_alarm, fan_alarm, 0); |
|---|
| 426 | +static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0); |
|---|
| 427 | +static SENSOR_DEVICE_ATTR_RW(pwm1_enable, pwm_en, 0); |
|---|
| 428 | +static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1); |
|---|
| 429 | +static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1); |
|---|
| 430 | +static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1); |
|---|
| 431 | +static SENSOR_DEVICE_ATTR_RO(fan2_alarm, fan_alarm, 1); |
|---|
| 432 | +static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, 1); |
|---|
| 433 | +static SENSOR_DEVICE_ATTR_RW(pwm2_enable, pwm_en, 1); |
|---|
| 434 | +static SENSOR_DEVICE_ATTR_RO(fan3_input, fan, 2); |
|---|
| 435 | +static SENSOR_DEVICE_ATTR_RW(fan3_min, fan_min, 2); |
|---|
| 436 | +static SENSOR_DEVICE_ATTR_RW(fan3_div, fan_div, 2); |
|---|
| 437 | +static SENSOR_DEVICE_ATTR_RO(fan3_alarm, fan_alarm, 2); |
|---|
| 438 | +static SENSOR_DEVICE_ATTR_RW(pwm3, pwm, 2); |
|---|
| 439 | +static SENSOR_DEVICE_ATTR_RW(pwm3_enable, pwm_en, 2); |
|---|
| 447 | 440 | |
|---|
| 448 | 441 | static DEVICE_ATTR_RO(alarms); |
|---|
| 449 | 442 | |
|---|