root/drivers/hwmon/tc654.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tc654_update_client
  2. fan_show
  3. fan_min_show
  4. fan_min_store
  5. fan_alarm_show
  6. fan_pulses_show
  7. fan_pulses_store
  8. pwm_mode_show
  9. pwm_mode_store
  10. pwm_show
  11. pwm_store
  12. tc654_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * tc654.c - Linux kernel modules for fan speed controller
   4  *
   5  * Copyright (C) 2016 Allied Telesis Labs NZ
   6  */
   7 
   8 #include <linux/bitops.h>
   9 #include <linux/err.h>
  10 #include <linux/hwmon.h>
  11 #include <linux/hwmon-sysfs.h>
  12 #include <linux/i2c.h>
  13 #include <linux/init.h>
  14 #include <linux/jiffies.h>
  15 #include <linux/module.h>
  16 #include <linux/mutex.h>
  17 #include <linux/slab.h>
  18 #include <linux/util_macros.h>
  19 
  20 enum tc654_regs {
  21         TC654_REG_RPM1 = 0x00,  /* RPM Output 1 */
  22         TC654_REG_RPM2 = 0x01,  /* RPM Output 2 */
  23         TC654_REG_FAN_FAULT1 = 0x02,    /* Fan Fault 1 Threshold */
  24         TC654_REG_FAN_FAULT2 = 0x03,    /* Fan Fault 2 Threshold */
  25         TC654_REG_CONFIG = 0x04,        /* Configuration */
  26         TC654_REG_STATUS = 0x05,        /* Status */
  27         TC654_REG_DUTY_CYCLE = 0x06,    /* Fan Speed Duty Cycle */
  28         TC654_REG_MFR_ID = 0x07,        /* Manufacturer Identification */
  29         TC654_REG_VER_ID = 0x08,        /* Version Identification */
  30 };
  31 
  32 /* Macros to easily index the registers */
  33 #define TC654_REG_RPM(idx)              (TC654_REG_RPM1 + (idx))
  34 #define TC654_REG_FAN_FAULT(idx)        (TC654_REG_FAN_FAULT1 + (idx))
  35 
  36 /* Config register bits */
  37 #define TC654_REG_CONFIG_RES            BIT(6)  /* Resolution Selection */
  38 #define TC654_REG_CONFIG_DUTYC          BIT(5)  /* Duty Cycle Control */
  39 #define TC654_REG_CONFIG_SDM            BIT(0)  /* Shutdown Mode */
  40 
  41 /* Status register bits */
  42 #define TC654_REG_STATUS_F2F            BIT(1)  /* Fan 2 Fault */
  43 #define TC654_REG_STATUS_F1F            BIT(0)  /* Fan 1 Fault */
  44 
  45 /* RPM resolution for RPM Output registers */
  46 #define TC654_HIGH_RPM_RESOLUTION       25      /* 25 RPM resolution */
  47 #define TC654_LOW_RPM_RESOLUTION        50      /* 50 RPM resolution */
  48 
  49 /* Convert to the fan fault RPM threshold from register value */
  50 #define TC654_FAN_FAULT_FROM_REG(val)   ((val) * 50)    /* 50 RPM resolution */
  51 
  52 /* Convert to register value from the fan fault RPM threshold */
  53 #define TC654_FAN_FAULT_TO_REG(val)     (((val) / 50) & 0xff)
  54 
  55 /* Register data is read (and cached) at most once per second. */
  56 #define TC654_UPDATE_INTERVAL           HZ
  57 
  58 struct tc654_data {
  59         struct i2c_client *client;
  60 
  61         /* update mutex */
  62         struct mutex update_lock;
  63 
  64         /* tc654 register cache */
  65         bool valid;
  66         unsigned long last_updated;     /* in jiffies */
  67 
  68         u8 rpm_output[2];       /* The fan RPM data for fans 1 and 2 is then
  69                                  * written to registers RPM1 and RPM2
  70                                  */
  71         u8 fan_fault[2];        /* The Fan Fault Threshold Registers are used to
  72                                  * set the fan fault threshold levels for fan 1
  73                                  * and fan 2
  74                                  */
  75         u8 config;      /* The Configuration Register is an 8-bit read/
  76                          * writable multi-function control register
  77                          *   7: Fan Fault Clear
  78                          *      1 = Clear Fan Fault
  79                          *      0 = Normal Operation (default)
  80                          *   6: Resolution Selection for RPM Output Registers
  81                          *      RPM Output Registers (RPM1 and RPM2) will be
  82                          *      set for
  83                          *      1 = 25 RPM (9-bit) resolution
  84                          *      0 = 50 RPM (8-bit) resolution (default)
  85                          *   5: Duty Cycle Control Method
  86                          *      The V OUT duty cycle will be controlled via
  87                          *      1 = the SMBus interface.
  88                          *      0 = via the V IN analog input pin. (default)
  89                          * 4,3: Fan 2 Pulses Per Rotation
  90                          *      00 = 1
  91                          *      01 = 2 (default)
  92                          *      10 = 4
  93                          *      11 = 8
  94                          * 2,1: Fan 1 Pulses Per Rotation
  95                          *      00 = 1
  96                          *      01 = 2 (default)
  97                          *      10 = 4
  98                          *      11 = 8
  99                          *   0: Shutdown Mode
 100                          *      1 = Shutdown mode.
 101                          *      0 = Normal operation. (default)
 102                          */
 103         u8 status;      /* The Status register provides all the information
 104                          * about what is going on within the TC654/TC655
 105                          * devices.
 106                          * 7,6: Unimplemented, Read as '0'
 107                          *   5: Over-Temperature Fault Condition
 108                          *      1 = Over-Temperature condition has occurred
 109                          *      0 = Normal operation. V IN is less than 2.6V
 110                          *   4: RPM2 Counter Overflow
 111                          *      1 = Fault condition
 112                          *      0 = Normal operation
 113                          *   3: RPM1 Counter Overflow
 114                          *      1 = Fault condition
 115                          *      0 = Normal operation
 116                          *   2: V IN Input Status
 117                          *      1 = V IN is open
 118                          *      0 = Normal operation. voltage present at V IN
 119                          *   1: Fan 2 Fault
 120                          *      1 = Fault condition
 121                          *      0 = Normal operation
 122                          *   0: Fan 1 Fault
 123                          *      1 = Fault condition
 124                          *      0 = Normal operation
 125                          */
 126         u8 duty_cycle;  /* The DUTY_CYCLE register is a 4-bit read/
 127                          * writable register used to control the duty
 128                          * cycle of the V OUT output.
 129                          */
 130 };
 131 
 132 /* helper to grab and cache data, at most one time per second */
 133 static struct tc654_data *tc654_update_client(struct device *dev)
 134 {
 135         struct tc654_data *data = dev_get_drvdata(dev);
 136         struct i2c_client *client = data->client;
 137         int ret = 0;
 138 
 139         mutex_lock(&data->update_lock);
 140         if (time_before(jiffies, data->last_updated + TC654_UPDATE_INTERVAL) &&
 141             likely(data->valid))
 142                 goto out;
 143 
 144         ret = i2c_smbus_read_byte_data(client, TC654_REG_RPM(0));
 145         if (ret < 0)
 146                 goto out;
 147         data->rpm_output[0] = ret;
 148 
 149         ret = i2c_smbus_read_byte_data(client, TC654_REG_RPM(1));
 150         if (ret < 0)
 151                 goto out;
 152         data->rpm_output[1] = ret;
 153 
 154         ret = i2c_smbus_read_byte_data(client, TC654_REG_FAN_FAULT(0));
 155         if (ret < 0)
 156                 goto out;
 157         data->fan_fault[0] = ret;
 158 
 159         ret = i2c_smbus_read_byte_data(client, TC654_REG_FAN_FAULT(1));
 160         if (ret < 0)
 161                 goto out;
 162         data->fan_fault[1] = ret;
 163 
 164         ret = i2c_smbus_read_byte_data(client, TC654_REG_CONFIG);
 165         if (ret < 0)
 166                 goto out;
 167         data->config = ret;
 168 
 169         ret = i2c_smbus_read_byte_data(client, TC654_REG_STATUS);
 170         if (ret < 0)
 171                 goto out;
 172         data->status = ret;
 173 
 174         ret = i2c_smbus_read_byte_data(client, TC654_REG_DUTY_CYCLE);
 175         if (ret < 0)
 176                 goto out;
 177         data->duty_cycle = ret & 0x0f;
 178 
 179         data->last_updated = jiffies;
 180         data->valid = true;
 181 out:
 182         mutex_unlock(&data->update_lock);
 183 
 184         if (ret < 0)            /* upon error, encode it in return value */
 185                 data = ERR_PTR(ret);
 186 
 187         return data;
 188 }
 189 
 190 /*
 191  * sysfs attributes
 192  */
 193 
 194 static ssize_t fan_show(struct device *dev, struct device_attribute *da,
 195                         char *buf)
 196 {
 197         int nr = to_sensor_dev_attr(da)->index;
 198         struct tc654_data *data = tc654_update_client(dev);
 199         int val;
 200 
 201         if (IS_ERR(data))
 202                 return PTR_ERR(data);
 203 
 204         if (data->config & TC654_REG_CONFIG_RES)
 205                 val = data->rpm_output[nr] * TC654_HIGH_RPM_RESOLUTION;
 206         else
 207                 val = data->rpm_output[nr] * TC654_LOW_RPM_RESOLUTION;
 208 
 209         return sprintf(buf, "%d\n", val);
 210 }
 211 
 212 static ssize_t fan_min_show(struct device *dev, struct device_attribute *da,
 213                             char *buf)
 214 {
 215         int nr = to_sensor_dev_attr(da)->index;
 216         struct tc654_data *data = tc654_update_client(dev);
 217 
 218         if (IS_ERR(data))
 219                 return PTR_ERR(data);
 220 
 221         return sprintf(buf, "%d\n",
 222                        TC654_FAN_FAULT_FROM_REG(data->fan_fault[nr]));
 223 }
 224 
 225 static ssize_t fan_min_store(struct device *dev, struct device_attribute *da,
 226                              const char *buf, size_t count)
 227 {
 228         int nr = to_sensor_dev_attr(da)->index;
 229         struct tc654_data *data = dev_get_drvdata(dev);
 230         struct i2c_client *client = data->client;
 231         unsigned long val;
 232         int ret;
 233 
 234         if (kstrtoul(buf, 10, &val))
 235                 return -EINVAL;
 236 
 237         val = clamp_val(val, 0, 12750);
 238 
 239         mutex_lock(&data->update_lock);
 240 
 241         data->fan_fault[nr] = TC654_FAN_FAULT_TO_REG(val);
 242         ret = i2c_smbus_write_byte_data(client, TC654_REG_FAN_FAULT(nr),
 243                                         data->fan_fault[nr]);
 244 
 245         mutex_unlock(&data->update_lock);
 246         return ret < 0 ? ret : count;
 247 }
 248 
 249 static ssize_t fan_alarm_show(struct device *dev, struct device_attribute *da,
 250                               char *buf)
 251 {
 252         int nr = to_sensor_dev_attr(da)->index;
 253         struct tc654_data *data = tc654_update_client(dev);
 254         int val;
 255 
 256         if (IS_ERR(data))
 257                 return PTR_ERR(data);
 258 
 259         if (nr == 0)
 260                 val = !!(data->status & TC654_REG_STATUS_F1F);
 261         else
 262                 val = !!(data->status & TC654_REG_STATUS_F2F);
 263 
 264         return sprintf(buf, "%d\n", val);
 265 }
 266 
 267 static const u8 TC654_FAN_PULSE_SHIFT[] = { 1, 3 };
 268 
 269 static ssize_t fan_pulses_show(struct device *dev,
 270                                struct device_attribute *da, char *buf)
 271 {
 272         int nr = to_sensor_dev_attr(da)->index;
 273         struct tc654_data *data = tc654_update_client(dev);
 274         u8 val;
 275 
 276         if (IS_ERR(data))
 277                 return PTR_ERR(data);
 278 
 279         val = BIT((data->config >> TC654_FAN_PULSE_SHIFT[nr]) & 0x03);
 280         return sprintf(buf, "%d\n", val);
 281 }
 282 
 283 static ssize_t fan_pulses_store(struct device *dev,
 284                                 struct device_attribute *da, const char *buf,
 285                                 size_t count)
 286 {
 287         int nr = to_sensor_dev_attr(da)->index;
 288         struct tc654_data *data = dev_get_drvdata(dev);
 289         struct i2c_client *client = data->client;
 290         u8 config;
 291         unsigned long val;
 292         int ret;
 293 
 294         if (kstrtoul(buf, 10, &val))
 295                 return -EINVAL;
 296 
 297         switch (val) {
 298         case 1:
 299                 config = 0;
 300                 break;
 301         case 2:
 302                 config = 1;
 303                 break;
 304         case 4:
 305                 config = 2;
 306                 break;
 307         case 8:
 308                 config = 3;
 309                 break;
 310         default:
 311                 return -EINVAL;
 312         }
 313 
 314         mutex_lock(&data->update_lock);
 315 
 316         data->config &= ~(0x03 << TC654_FAN_PULSE_SHIFT[nr]);
 317         data->config |= (config << TC654_FAN_PULSE_SHIFT[nr]);
 318         ret = i2c_smbus_write_byte_data(client, TC654_REG_CONFIG, data->config);
 319 
 320         mutex_unlock(&data->update_lock);
 321         return ret < 0 ? ret : count;
 322 }
 323 
 324 static ssize_t pwm_mode_show(struct device *dev, struct device_attribute *da,
 325                              char *buf)
 326 {
 327         struct tc654_data *data = tc654_update_client(dev);
 328 
 329         if (IS_ERR(data))
 330                 return PTR_ERR(data);
 331 
 332         return sprintf(buf, "%d\n", !!(data->config & TC654_REG_CONFIG_DUTYC));
 333 }
 334 
 335 static ssize_t pwm_mode_store(struct device *dev, struct device_attribute *da,
 336                               const char *buf, size_t count)
 337 {
 338         struct tc654_data *data = dev_get_drvdata(dev);
 339         struct i2c_client *client = data->client;
 340         unsigned long val;
 341         int ret;
 342 
 343         if (kstrtoul(buf, 10, &val))
 344                 return -EINVAL;
 345 
 346         if (val != 0 && val != 1)
 347                 return -EINVAL;
 348 
 349         mutex_lock(&data->update_lock);
 350 
 351         if (val)
 352                 data->config |= TC654_REG_CONFIG_DUTYC;
 353         else
 354                 data->config &= ~TC654_REG_CONFIG_DUTYC;
 355 
 356         ret = i2c_smbus_write_byte_data(client, TC654_REG_CONFIG, data->config);
 357 
 358         mutex_unlock(&data->update_lock);
 359         return ret < 0 ? ret : count;
 360 }
 361 
 362 static const int tc654_pwm_map[16] = { 77,  88, 102, 112, 124, 136, 148, 160,
 363                                       172, 184, 196, 207, 219, 231, 243, 255};
 364 
 365 static ssize_t pwm_show(struct device *dev, struct device_attribute *da,
 366                         char *buf)
 367 {
 368         struct tc654_data *data = tc654_update_client(dev);
 369         int pwm;
 370 
 371         if (IS_ERR(data))
 372                 return PTR_ERR(data);
 373 
 374         if (data->config & TC654_REG_CONFIG_SDM)
 375                 pwm = 0;
 376         else
 377                 pwm = tc654_pwm_map[data->duty_cycle];
 378 
 379         return sprintf(buf, "%d\n", pwm);
 380 }
 381 
 382 static ssize_t pwm_store(struct device *dev, struct device_attribute *da,
 383                          const char *buf, size_t count)
 384 {
 385         struct tc654_data *data = dev_get_drvdata(dev);
 386         struct i2c_client *client = data->client;
 387         unsigned long val;
 388         int ret;
 389 
 390         if (kstrtoul(buf, 10, &val))
 391                 return -EINVAL;
 392         if (val > 255)
 393                 return -EINVAL;
 394 
 395         mutex_lock(&data->update_lock);
 396 
 397         if (val == 0)
 398                 data->config |= TC654_REG_CONFIG_SDM;
 399         else
 400                 data->config &= ~TC654_REG_CONFIG_SDM;
 401 
 402         data->duty_cycle = find_closest(val, tc654_pwm_map,
 403                                         ARRAY_SIZE(tc654_pwm_map));
 404 
 405         ret = i2c_smbus_write_byte_data(client, TC654_REG_CONFIG, data->config);
 406         if (ret < 0)
 407                 goto out;
 408 
 409         ret = i2c_smbus_write_byte_data(client, TC654_REG_DUTY_CYCLE,
 410                                         data->duty_cycle);
 411 
 412 out:
 413         mutex_unlock(&data->update_lock);
 414         return ret < 0 ? ret : count;
 415 }
 416 
 417 static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
 418 static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
 419 static SENSOR_DEVICE_ATTR_RW(fan1_min, fan_min, 0);
 420 static SENSOR_DEVICE_ATTR_RW(fan2_min, fan_min, 1);
 421 static SENSOR_DEVICE_ATTR_RO(fan1_alarm, fan_alarm, 0);
 422 static SENSOR_DEVICE_ATTR_RO(fan2_alarm, fan_alarm, 1);
 423 static SENSOR_DEVICE_ATTR_RW(fan1_pulses, fan_pulses, 0);
 424 static SENSOR_DEVICE_ATTR_RW(fan2_pulses, fan_pulses, 1);
 425 static SENSOR_DEVICE_ATTR_RW(pwm1_mode, pwm_mode, 0);
 426 static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, 0);
 427 
 428 /* Driver data */
 429 static struct attribute *tc654_attrs[] = {
 430         &sensor_dev_attr_fan1_input.dev_attr.attr,
 431         &sensor_dev_attr_fan2_input.dev_attr.attr,
 432         &sensor_dev_attr_fan1_min.dev_attr.attr,
 433         &sensor_dev_attr_fan2_min.dev_attr.attr,
 434         &sensor_dev_attr_fan1_alarm.dev_attr.attr,
 435         &sensor_dev_attr_fan2_alarm.dev_attr.attr,
 436         &sensor_dev_attr_fan1_pulses.dev_attr.attr,
 437         &sensor_dev_attr_fan2_pulses.dev_attr.attr,
 438         &sensor_dev_attr_pwm1_mode.dev_attr.attr,
 439         &sensor_dev_attr_pwm1.dev_attr.attr,
 440         NULL
 441 };
 442 
 443 ATTRIBUTE_GROUPS(tc654);
 444 
 445 /*
 446  * device probe and removal
 447  */
 448 
 449 static int tc654_probe(struct i2c_client *client,
 450                        const struct i2c_device_id *id)
 451 {
 452         struct device *dev = &client->dev;
 453         struct tc654_data *data;
 454         struct device *hwmon_dev;
 455         int ret;
 456 
 457         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 458                 return -ENODEV;
 459 
 460         data = devm_kzalloc(dev, sizeof(struct tc654_data), GFP_KERNEL);
 461         if (!data)
 462                 return -ENOMEM;
 463 
 464         data->client = client;
 465         mutex_init(&data->update_lock);
 466 
 467         ret = i2c_smbus_read_byte_data(client, TC654_REG_CONFIG);
 468         if (ret < 0)
 469                 return ret;
 470 
 471         data->config = ret;
 472 
 473         hwmon_dev =
 474             devm_hwmon_device_register_with_groups(dev, client->name, data,
 475                                                    tc654_groups);
 476         return PTR_ERR_OR_ZERO(hwmon_dev);
 477 }
 478 
 479 static const struct i2c_device_id tc654_id[] = {
 480         {"tc654", 0},
 481         {"tc655", 0},
 482         {}
 483 };
 484 
 485 MODULE_DEVICE_TABLE(i2c, tc654_id);
 486 
 487 static struct i2c_driver tc654_driver = {
 488         .driver = {
 489                    .name = "tc654",
 490                    },
 491         .probe = tc654_probe,
 492         .id_table = tc654_id,
 493 };
 494 
 495 module_i2c_driver(tc654_driver);
 496 
 497 MODULE_AUTHOR("Allied Telesis Labs");
 498 MODULE_DESCRIPTION("Microchip TC654/TC655 driver");
 499 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */